Authentication

Every API request needs two headers: your secret key and your organization ID.

HTTP
Authorization:    Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
X-JKASMS-Org-Id:  ORG_XXXXXXXXXXXX
Headers
Authorization
stringrequired
Your secret key, prefixed with Bearer . Starts with sk_test_ or sk_live_.
X-JKASMS-Org-Id
stringrequired
Your organization ID, shown in the dashboard. Starts with ORG_.
Idempotency-Key
string
Optional but recommended on any send. See Send a message.

Why two headers?

The organization ID is not redundant. It scopes the key lookup to one account, which lets us verify your key against a single record rather than every key that shares a prefix.

Key verification uses argon2id, which is deliberately slow — that is what makes a stolen key database useless. An unscoped lookup would turn that deliberate slowness into a denial-of-service vector.

The three values a key gives you

Creating a key shows you a secret and a webhook secret once. Two other identifiers stay available on the API keys page forever — knowing which is which saves a support ticket.

ValueSecret?What it is for
sk_… secret keyYes — shown onceAuthenticates every request, in the Authorization header.
whsec_… webhook secretYes — shown onceVerifies the signature on webhooks we send you. See Verifying webhooks.
ORG_… organization IDNoScopes the key lookup, in the X-JKASMS-Org-Id header.
pk_… key IDNoYou never send it. We send it to you, as X-JKASMS-Key-Id on every webhook, so you can tell which key a callback belongs to.
Only the two secrets are unrecoverable — they are argon2-hashed and there is no reveal endpoint. The organization ID and key ID are listed against every key in your dashboard, so there is nothing to lose there.

Test and live keys

PrefixBehaviour
sk_test_Full pipeline, nothing reaches a handset, nothing is charged. Works immediately, even while your account is under review.
sk_live_Real messages, real money. Can only be created once your account is approved.

Both use the same base URL. There is no separate sandbox host — the key prefix alone decides.

Keeping keys safe

Your secret key is shown once, at creation, and stored only as an argon2 hash. There is no “reveal key” feature and support cannot recover it. If you lose it, revoke the key and create another.
  • Keep keys server-side. A key in browser or mobile app code is public, whatever it is wrapped in.
  • Use a test key in development, and a separate live key per environment, so revoking one does not take down the others.
  • Revoke immediately if a key is exposed. Revocation takes effect on the next request.

IP allowlisting

Optional, and off by default. Once enabled in Settings, requests from any other address are refused even with a valid key.

Ranges broader than /16, and private ranges, are rejected — an allowlist that matches everything is not an allowlist. You cannot enable it with an empty list, because that would lock you out of your own API.

Errors

StatusCodeCause
401INVALID_API_KEYMissing, malformed, revoked or wrong key
403ACCOUNT_SUSPENDEDAccount suspended, or a live key used before approval
403FORBIDDENRequest IP is not in your allowlist