Authentication

The JoltSMS API uses API keys to authenticate requests. Include your key as a Bearer token in the Authorization header or send the same key in X-API-Key. API keys can be scoped to personal numbers, selected numbers, or an enterprise contract, so create the narrowest key your integration needs.

Creating API Keys

Generate API keys from the JoltSMS dashboard. Each key is shown only once at creation time -- store it immediately in a secure location.

  1. 1

    Open the Dashboard and navigate to Settings.

  2. 2

    Scroll to the API Keys section.

  3. 3

    Click Create API Key, give it a descriptive name (e.g., "CI Pipeline" or "Claude Agent"), choose an access scope, and optionally enable sensitive capabilities such as SMS replies.

  4. 4

    Copy the key immediately. It will not be shown again.

Key shown once

The full API key is displayed only at creation time. If you lose it, revoke the key and create a new one. You can have up to 5 active keys per account.

Key format

All JoltSMS API keys begin with the prefix jolt_sk_ followed by 32 hexadecimal characters. Example: jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6

Using API Keys

Pass your API key in the Authorization header as a Bearer token, or in the X-API-Key header. All requests must use HTTPS.

curl

curl -X GET https://api.joltsms.com/v1/numbers \
  -H "Authorization: Bearer jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

curl with X-API-Key

curl -X GET https://api.joltsms.com/v1/messages \
  -H "X-API-Key: jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

JavaScript (fetch)

const response = await fetch("https://api.joltsms.com/v1/numbers", {
  headers: {
    "Authorization": "Bearer jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  },
});

const data = await response.json();
console.log(data);

Python (requests)

import requests

response = requests.get(
    "https://api.joltsms.com/v1/numbers",
    headers={"Authorization": "Bearer jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"},
)

print(response.json())

API Key Scopes

API keys are scoped at creation time. Scoped keys affect number and message reads: GET /v1/numbers and GET /v1/messages only return resources allowed by the key.

ScopeCreate fieldsAccess
PERSONALOmit scope fields or set scopeType to PERSONALPersonal and team-shared non-enterprise numbers
ENTERPRISE_CONTRACTscopeType plus enterpriseContractIdAll numbers in one enterprise contract
NUMBER_SETscopeType plus numberIdsOnly the selected numbers

Existing keys created before scoped keys behave as PERSONAL keys. They continue to work for regular personal and team-shared numbers, but they do not automatically expose enterprise contract lines.

Create a contract-scoped key

curl -X POST https://api.joltsms.com/v1/api-keys \
  -H "Content-Type: application/json" \
  -b "joltsms_session=YOUR_SESSION_COOKIE" \
  -d '{
    "name": "Enterprise contract automation",
    "scopeType": "ENTERPRISE_CONTRACT",
    "enterpriseContractId": "contract_uuid_here"
  }'

Create a selected-number key

curl -X POST https://api.joltsms.com/v1/api-keys \
  -H "Content-Type: application/json" \
  -b "joltsms_session=YOUR_SESSION_COOKIE" \
  -d '{
    "name": "Single workflow key",
    "scopeType": "NUMBER_SET",
    "numberIds": ["number_uuid_1", "number_uuid_2"]
  }'

API Key Capabilities

Scopes decide which numbers a key can see. Capabilities decide which sensitive write actions the key can perform. SMS replies are opt-in: a key must include the sms:reply capability to call POST /v1/messages/:id/reply.

Reply capability does not turn JoltSMS into an arbitrary SMS sender. Replies must reference an existing inbound message, the destination is resolved server-side, and destination fields such as to or phone are rejected.

Create a selected-number reply key

curl -X POST https://api.joltsms.com/v1/api-keys \
  -H "Content-Type: application/json" \
  -b "joltsms_session=YOUR_SESSION_COOKIE" \
  -d '{
    "name": "Support inbox replies",
    "scopeType": "NUMBER_SET",
    "numberIds": ["number_uuid_1"],
    "capabilities": ["sms:reply"]
  }'

Rate Limits

API key requests are rate-limited to 120 requests per minute. Session-based requests (from the dashboard) use standard rate limits. Every response includes headers to help you stay within bounds.

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window (120 for API keys)
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetSeconds remaining until the rate limit window resets

Pagination cap

When authenticated with an API key, list endpoints (/v1/numbers, /v1/messages) enforce a maximum page size of 10 results per request. Use cursor-based pagination to retrieve additional pages.

If you exceed the rate limit, the API returns a 429 Too Many Requests response. Back off and retry after the X-RateLimit-Reset time.

Error Responses

Authentication errors return standard HTTP status codes with a JSON body describing the problem.

StatusMeaningCommon Causes
401UnauthorizedMissing, invalid, expired, or revoked API key
403ForbiddenUsing an API key on a session-only endpoint
429Too Many RequestsRate limit exceeded (120 req/min for API keys)

Error response format

// 401 Unauthorized
{
  "error": "UNAUTHORIZED",
  "message": "Authentication required"
}

// 403 Session Required
{
  "error": "SESSION_REQUIRED",
  "message": "This endpoint requires browser session authentication. Bearer tokens cannot be used for this operation."
}

// 429 Rate Limit Exceeded
{
  "error": "RATE_LIMIT_EXCEEDED",
  "message": "Rate limit exceeded, retry in 42 seconds"
}

Session-Only Endpoints

Certain sensitive operations require session authentication (logging in through the dashboard). These endpoints return 403 Forbidden when called with an API key.

CategoryEndpointsReason
API Key ManagementGET/POST/DELETE /v1/api-keysPrevents key escalation
Number ManagementPUT/DELETE /v1/numbers/:idPrevents automated release or mutation of active lines
Password Change/auth/change-passwordRequires active session verification
Two-Factor Authentication/auth/two-factor/*Security-critical account settings

Day-to-day read operations -- listing numbers, reading messages, and checking billing status -- work with API keys. API-key creation/revocation and number management require a browser session.

Security Best Practices

Never commit keys to source control

Add .env and .env.local to your .gitignore. Use a secrets manager (e.g., AWS Secrets Manager, HashiCorp Vault, or your CI/CD provider's secret storage) for production deployments.

Use environment variables

Reference your API key from an environment variable rather than hardcoding it in application code.

export JOLTSMS_API_KEY="jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

# Then in your code:
headers: { "Authorization": `Bearer ${process.env.JOLTSMS_API_KEY}` }

Rotate keys regularly

Create a new key, update your systems, then revoke the old one. With up to 5 active keys, you can rotate without downtime.

Set expiration dates

When creating a key, set an expiration date appropriate for its use case. Short-lived keys for CI/CD pipelines, longer-lived keys for persistent integrations. Expired keys are automatically rejected.

Use descriptive key names

Name each key after its purpose (e.g., "GitHub Actions Deploy", "Claude MCP Agent", "Monitoring Script"). This makes it easy to identify which key to revoke if one is compromised.

Revoke compromised keys immediately

If you suspect a key has been exposed, revoke it from Settings → API Keys in the dashboard. Revocation takes effect within 60 seconds (the Redis cache TTL).