# Powerful Developer SMS API

> Integrate SMS communications into anything and everything: your own projects, or for your clients. PureSMS API, built on Divergent Connect.

- **Performance**: ~40ms API completion time, thousands of SMS in a single batch call
- **Reliability**: 99.99% uptime, redundant direct Tier 1 network routing
- **Interface**: HTTPS/REST with first-class .NET and Node.js SDKs
- **Features**: single SMS, bulk SMS, scheduling, inbound replies, delivery receipts
- **Security**: API key auth + HMAC-signed webhooks
- **Rebilling**: [Client Tagging](https://the.divergent.guide/connect/developers/client-tagging/) tracks usage and cost per end customer for seamless rebilling

Get an API key in 2 minutes at [new.puresms.app](https://new.puresms.app). Full developer documentation, including request/response schemas, webhooks and SDK references, lives at [the.divergent.guide](https://the.divergent.guide/puresms/developers/).

## C# / .NET

Install the [Divergent.Connect](https://www.nuget.org/packages/Divergent.Connect) NuGet package:

```bash
dotnet add package Divergent.Connect
```

In a .NET 8+ application, register the client during host startup:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.AddDivergentConnect();
var app = builder.Build();
```

Then drop your API key in `appsettings.json`:

```json
{
  "Divergent": {
    "Connect": {
      "ApiKey": "your-api-key",
      "DefaultSmsSender": "YourSender"
    }
  }
}
```

Now inject `IConnectSms` wherever you need to send a message:

```csharp
using Divergent.Connect;

public class WelcomeService(IConnectSms smsClient)
{
    public async Task SendWelcomeSms(string phoneNumber)
    {
        await smsClient.SendSmsAsync(new ConnectSmsMessage
        {
            To = phoneNumber,
            Content = "Hello world, from PureSMS!"
        });
    }
}
```

Need to schedule, set a client reference, or force Unicode? It's all on the message:

```csharp
await smsClient.SendSmsAsync(new ConnectSmsMessage
{
    To = "+447700900123",
    Content = "Your appointment is tomorrow at 10am",
    DateSendAtUtc = DateTime.UtcNow.AddHours(1),
    ClientReference = "appointment-reminder-123",
    UnicodeMode = UnicodeMode.Allow
});
```

Not on the host builder? Build a client manually:

```csharp
var smsClient = new ConnectClientBuilder()
    .WithApiKey("your-api-key")
    .WithDefaultSmsSender("YourSender")
    .BuildSmsClient();
```

## cURL / HTTP

Fire a POST at `/sms/send` with your API key in the `X-Api-Key` header:

```bash
curl -X POST https://connect-api.divergent.cloud/sms/send \
  -H "X-Api-Key: { API_KEY }" \
  --json '{
    "sender": "{ SENDER_NAME }",
    "recipient": "{ RECIPIENT_NUMBER }",
    "content": "Hello world, from PureSMS!"
  }'
```

Sending in bulk? Same API key, different endpoint: `POST https://connect-api.divergent.cloud/sms/send/bulk` with body shape `{ "messages": [{ "sender": "...", "recipient": "...", "content": "..." }, ...] }`. The response gives you back a `batchId` and `messageCount`.

## PHP

```php
$apiKey = "My API Key";
$outboundSms = array(
    'sender' => 'Somebody',
    'recipient' => '447700900123',
    'content' => 'Hello this is my first SMS'
);
$curl = curl_init('https://connect-api.divergent.cloud/sms/send');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($outboundSms));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
    'X-Api-Key: ' . $apiKey,
    'Content-Type: application/json'));
$result = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
```

Prefer a proper SDK? Richard Leishman of [Webforward](https://webfwd.co.uk/) created a [community PHP SDK](https://github.com/mrl22/puresms-sdk) (`composer require mrl22/puresms-sdk`). We can't offer support for this library, but it looks great!

## Webhooks: delivery receipts & inbound SMS

Webhooks are configured at the workspace level under Settings → Webhooks. Add an endpoint URL, optionally set a signing secret, and pick which event types to subscribe to. Every webhook arrives as an HTTP POST with the same envelope:

```json
{
  "id": "evt_abc123",
  "timestamp": "2026-01-15T10:30:00Z",
  "workspaceId": "ws_xyz789",
  "eventType": 1,
  "data": { }
}
```

`eventType` tells you what's inside `data`:

- **1 (Delivery Receipt)**: the status of an outbound message changed. Statuses: Queued, Dispatched, Delivered (final), Failed (final, see `errorCode`), Expired (final), Rejected (final), Cancelled (final), Deleted (final), Unknown.
- **2 (Inbound SMS)**: a reply (or any message) was received on one of your virtual numbers. Inbound webhooks need a virtual number, so pick one up in the dashboard.

**Responding**: return any 2xx status as soon as you can, within 45 seconds. We retry on failure (immediate, then 5m, 15m, 1h, 4h, 8h, 12h) and auto-disable the endpoint after five consecutive failures, so wire up a healthcheck.

**Verifying signatures**: if you set a signing secret, every request includes `X-Webhook-Signature` (base64 HMAC-SHA256) and `X-Webhook-Timestamp` (Unix seconds). The signed string is `{timestamp}.{rawJsonBody}`.

## Client Tagging: rebill your own customers

Pass a free-form `clientTag` with any send and PureSMS tracks usage and cost per tag automatically, with no setup. Pull per-tag message counts, costs and daily breakdowns from the reporting API at invoice time. Full docs: [Client Tagging](https://the.divergent.guide/connect/developers/client-tagging/).

**Get an API key** at [new.puresms.app](https://new.puresms.app) — takes 2 minutes, no credit card required.
