Authentication
Authenticate every request with an API key in the X-Api-Key header.
Every request carries your API key in the X-Api-Key header:
curl https://api.softlinksms.co.ke/api/v1/sending-profile \
-H "X-Api-Key: bsk_9fcc4guB2yD.ilIexampleSecretPortionNeverShownAgain"There are no query-string keys, cookies or OAuth flows to manage. Requests over plain HTTP are not served.
API keys
A key has two parts joined by a dot, bsk_<key_id>.<secret>:
bsk_marks it as a SoftLinkSMS key, so secret scanners (GitHub, GitGuardian, TruffleHog) can recognise it if it leaks.key_ididentifies the key. It's safe to log.secretproves you hold it. We store only its SHA-256 hash and compare in constant time.
Each key belongs to one account: its wallet pays for the sends, and its sending access decides what you may send. If you run several accounts, create a key in each.
Create a key
In the dashboard, open Settings → Developer tools and choose Generate key. You confirm your password, then enter a code we email to you. The full key is shown once. Store it in a secret manager or environment variable, never in source control or client-side code.
Rotate a key
You can hold several keys at once, so rotation needs no downtime:
Permissions
A key carries scopes that limit what it can do. Keys created in the dashboard get the account owner's scopes:
| Scope | Allows |
|---|---|
sms:send | POST /sms |
sms:read | GET /sms, GET /sms/{id} |
email:send | POST /email |
email:read | GET /email, GET /email/{id} |
webhooks:read | GET /webhook-endpoint, GET /webhook-events, GET /webhook-events/{id} |
webhooks:write | Set or remove the webhook endpoint, rotate its secret, send a test event, redeliver an event |
A request without the scope it needs gets 403 with code insufficient_scope. For a service that only monitors deliveries, a key with webhooks:read can inspect the event log but can't change where events go.
Authentication errors
| Status | code | Meaning |
|---|---|---|
401 | not_authenticated | No X-Api-Key header was sent. |
401 | authentication_failed | The key is malformed, unknown, revoked, or its account is inactive. |
403 | insufficient_scope | The key is valid but lacks the scope this endpoint needs. |
{
"error": {
"code": "authentication_failed",
"message": "Invalid API key.",
"details": null
}
}Keep keys on the server
Anyone holding your key can spend your wallet. Never ship it in a mobile app, a browser bundle or a public repository. If a key leaks, revoke it and generate a new one straight away.