Authentication

LynSMS uses bearer tokens (API keys) to authenticate every request. Mint scoped keys per environment or workload, and revoke them instantly when no longer needed.

API keys

An API key is a long random string that looks like ds_live_a1b2c3d4e5.... Treat it like a password — keep it server-side, never commit it to source control, and rotate it if it leaks.

Heads up. A full API key is shown only once, immediately after it is created. LynSMS only stores a hash. If you lose the key, you must generate a new one.

Sending the header

Pass your key in the Authorization header on every request:

Authorization: Bearer ds_live_a1b2c3d4e5f6...
curl https://lynsms.com/api/v1/account \
  -H "Authorization: Bearer ds_live_a1b2c3d4..."
const res = await fetch("https://lynsms.com/api/v1/account", {
  headers: { Authorization: `Bearer ${process.env.LYNSMS_API_KEY}` },
});
console.log(await res.json());
import os, requests

resp = requests.get(
    "https://lynsms.com/api/v1/account",
    headers={"Authorization": f"Bearer {os.environ['LYNSMS_API_KEY']}"},
)
print(resp.json())

Scoped permissions

Every key carries one or more permission scopes. Keys with narrower scopes are safer.

ScopeGrants
sms:sendSend single messages via /messages/send.
sms:bulkSend to many recipients via /messages/bulk.
sms:readRead messages via /messages, /messages/{id}.
balance:readRead balance and usage.
dlr:readRead delivery reports.

IP allowlist

You can lock each API key down to a specific set of IPv4 addresses. A request from any other IP is rejected with 403 Forbidden.

Common authentication errors

StatusCodeMeaning
401unauthorizedNo key supplied, or the key is invalid / disabled / expired.
403forbiddenKey is valid but missing the required permission, or the request IP isn't on the allowlist.
429rate_limit_exceededThe per-key rate limit was exceeded — see rate limits.

Rotating keys

  1. Create a new key via POST /v1/api-keys/create or the dashboard.
  2. Deploy the new key to all callers.
  3. Revoke the old key via DELETE /v1/api-keys/{id}.

Because keys are stored hashed and matched at request time, you can run both the old and new key in parallel for as long as you need.