API Reference

The JoltSMS REST API lets you manage phone numbers, read SMS messages, control billing, configure notifications, and collaborate with team members. All requests use the base URL https://api.joltsms.com/v1 and require an Authorization: Bearer jolt_sk_xxx header.

OpenAPI Specification

Download the machine-readable OpenAPI spec to auto-generate API clients, create Custom GPT Actions, or build LangChain toolkits.

https://api.joltsms.com/openapi.json

Common Patterns

Cursor Pagination

All list endpoints return paginated results with the same envelope. Pass the cursor value from the previous response to fetch the next page. limit defaults to 20 (capped at 10 for API key authentication).

{
  "data": [ ... ],
  "meta": {
    "hasMore": true,
    "nextCursor": "MjAyNS0wNi0xNVQxMjowMDowMC4wMDBafGFiY2QxMjM0",
    "total": 42,
    "limit": 20
  }
}

Error Format

Errors follow a consistent JSON structure across all endpoints.

{
  "error": "NOT_FOUND",
  "message": "Number not found or you do not have access"
}

Rate Limit Headers

Every response includes rate limit headers. API key requests are limited to 120 requests per minute.

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

Numbers

Manage your dedicated phone numbers. Each number is a real-SIM U.S. number that receives inbound SMS.

GET/v1/numbers

List your phone numbers with optional status and scope filtering.

ParameterTypeDescription
scopestringFilter by ownership: "all" (default), "owned", or "shared".
statusstringFilter by status: active, provisioning, releasing, released, failed, suspended, cancelled.
cursorstringPagination cursor from a previous response.
limitnumberResults per page. Default 20, max 10 for API keys.
POST/v1/numbers/rent

Provision a new phone number. This creates a Stripe subscription and begins the provisioning process.

ParameterTypeDescription
areaCodestringPreferred 3-digit U.S. area code (e.g., "609"). Optional -- omit for any available number.
preferredAreaCodebooleanIf true, falls back to any available number when the requested area code is unavailable. Default false.
autoRenewbooleanEnable auto-renewal at end of billing cycle. Default true.
GET/v1/numbers/:id

Retrieve a single number by ID, including message counts, subscription details, and team access info.

PUT/v1/numbers/:id

Update a number's notes or tags.

ParameterTypeDescription
notesstringFree-text notes about this number.
tagsstring[]Array of tag strings for categorization.

Example

curl -X GET "https://api.joltsms.com/v1/numbers?scope=owned&status=active" \
  -H "Authorization: Bearer jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

Response:

{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "phoneNumber": "+16094130666",
      "status": "ACTIVE",
      "serviceName": "Any Service",
      "tags": ["primary", "otp"],
      "notes": "Used for PayPal verification",
      "createdAt": "2025-06-15T12:00:00.000Z",
      "rentedAt": "2025-06-15T12:05:00.000Z",
      "expiresAt": "2025-07-15T12:05:00.000Z",
      "messageCount": 23,
      "unreadCount": 2,
      "lastMessageAt": "2025-06-20T08:30:00.000Z",
      "isShared": false,
      "accessRole": "OWNER"
    }
  ],
  "meta": {
    "hasMore": false,
    "total": 1,
    "limit": 20
  }
}

Messages

Read inbound SMS messages across all your numbers (owned and shared). Messages from vendor systems are automatically filtered out.

GET/v1/messages

List SMS messages with optional filtering by number, sender, recipient, or date.

ParameterTypeDescription
numberIdstringFilter to messages for a specific number (UUID).
fromstringFilter by sender phone number.
tostringFilter by recipient phone number.
sincestringISO 8601 datetime -- only return messages after this time.
cursorstringPagination cursor from a previous response.
limitnumberResults per page. Default 20, max 10 for API keys.
GET/v1/messages/search

Full-text search across message bodies. Supports all the same filters as the list endpoint.

ParameterTypeDescription
q*stringSearch query (1-100 characters).
numberIdstringLimit search to a specific number.
cursorstringPagination cursor.
limitnumberResults per page. Default 20, max 50.
GET/v1/messages/:id

Retrieve a single message by ID.

PUT/v1/messages/:id/read

Mark a single message as read.

PUT/v1/messages/mark-all-read

Mark all messages as read, optionally scoped to a single number.

ParameterTypeDescription
numberIdstringIf provided, only mark messages for this number as read.

Example

curl -X GET "https://api.joltsms.com/v1/messages?numberId=a1b2c3d4-e5f6-7890-abcd-ef1234567890&limit=5" \
  -H "Authorization: Bearer jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"

Response:

{
  "data": [
    {
      "id": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
      "numberId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "number": {
        "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "phoneNumber": "+16094130666"
      },
      "from": "+18005551234",
      "to": "+16094130666",
      "body": "Your verification code is 847293. Do not share this with anyone.",
      "parsedCode": "847293",
      "isRead": false,
      "receivedAt": "2025-06-20T08:30:00.000Z",
      "ingestedAt": "2025-06-20T08:30:01.000Z"
    }
  ],
  "meta": {
    "hasMore": false,
    "nextCursor": null,
    "total": 1,
    "limit": 5,
    "filters": {
      "numberId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    }
  }
}

Billing

Inspect subscriptions, invoices, and payment methods. Billing is handled through Stripe with 30-day cycles aligned to your SMS provider.

GET/v1/billing/subscriptions

List all subscriptions for your account, including billing health status.

POST/v1/billing/subscriptions/:id/auto-renew

Toggle auto-renewal for a subscription. Disabling auto-renew schedules cancellation at the end of the current billing period.

ParameterTypeDescription
enabled*booleanSet to true to enable auto-renew, false to cancel at period end.
GET/v1/billing/invoices

List invoices for your account. Includes amount, status, and PDF download links. Uses Stripe-style pagination (not cursor-based).

ParameterTypeDescription
startingAfterstringStripe invoice ID to paginate after (e.g., "in_xxx"). Fetch the next page by passing the last invoice ID from the previous response.
statusstringFilter by invoice status: "draft", "open", "paid", "void", or "uncollectible".
limitnumberResults per page. Default 20, max 100.
GET/v1/billing/payment-methods

List saved payment methods. Returns last-4 digits, brand, and expiration.

Example

curl -X POST "https://api.joltsms.com/v1/billing/subscriptions/a1b2c3d4-e5f6-7890-abcd-ef1234567890/auto-renew" \
  -H "Authorization: Bearer jolt_sk_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": false }'

Response:

{
  "success": true
}

Billing health states

Subscriptions include a billingHealth field that summarizes the payment state: healthy, payment_failing, suspended, ending, canceled, or setup_required. SMS reception is active for healthy, payment_failing, and ending.

Notifications

Configure multi-channel notification delivery for SMS events, billing alerts, and number lifecycle changes. Supported channels: Slack, Discord, Email, Telegram, and custom Webhooks (HMAC-SHA256 signed).

Endpoints

GET/v1/notifications/endpoints

List all notification endpoints for your account. Optionally filter by number or endpoint type.

ParameterTypeDescription
numberIdstringFilter endpoints associated with a specific number.
typestringFilter by type: slack, discord, email, telegram, webhook.
POST/v1/notifications/endpoints

Create a new notification endpoint. Webhook URLs are validated against SSRF.

ParameterTypeDescription
type*stringEndpoint type: slack, discord, email, telegram, or webhook.
name*stringDisplay name for the endpoint.
config*objectChannel-specific configuration (e.g., webhookUrl for Slack, email address for email).
PATCH/v1/notifications/endpoints/:id

Update an existing notification endpoint's name, config, or active status.

DELETE/v1/notifications/endpoints/:id

Delete a notification endpoint. System-managed endpoints (auto-created email) cannot be deleted.

Rules

Rules bind events to endpoints. You can create account-level defaults or per-number overrides. Limits: 15 endpoints per user, 10 rules per number.

GET/v1/notifications/rules

List notification rules. Filter by number, event type, or endpoint.

ParameterTypeDescription
numberIdstringFilter rules for a specific number.
eventstringFilter by event type (e.g., SMS_RECEIVED, NUMBER_EXPIRING_7D).
endpointIdstringFilter rules for a specific endpoint.
enabledbooleanFilter by enabled/disabled status.
POST/v1/notifications/rules

Create a notification rule linking an event to an endpoint. Omit numberId for account-level defaults.

ParameterTypeDescription
endpointId*stringThe endpoint to deliver notifications to.
event*stringEvent type: SMS_RECEIVED, NUMBER_EXPIRING_7D, NUMBER_EXPIRING_1D, BILLING_ISSUE.
numberIdstringScope rule to a specific number. Omit for account-level default.
enabledbooleanWhether the rule is active. Default true.
PATCH/v1/notifications/rules/:id

Update a rule's enabled status or event binding.

DELETE/v1/notifications/rules/:id

Delete a notification rule.

Delivery Logs

GET/v1/notifications/attempts

View delivery attempt history. Useful for debugging failed notifications.

ParameterTypeDescription
endpointIdstringFilter attempts for a specific endpoint.
eventstringFilter by event type.
statusstringFilter by delivery status: success, failed, pending.
cursorstringPagination cursor.
limitnumberResults per page.

Team

Share number access with other JoltSMS users. Invite team members with VIEWER (read-only) or MANAGER (configuration and team management) roles. Invitations expire after 7 days.

Team endpoints require the caller to be the owner of the number (except for accepting/declining invitations). Both session and API key authentication are supported.

POST/v1/team/invite

Invite a user to access a number. Sends an email invitation with a 7-day expiry.

ParameterTypeDescription
numberId*stringUUID of the number to share access to.
email*stringEmail address of the user to invite.
rolestringRole to assign: "VIEWER" (default) or "MANAGER".
GET/v1/team/:numberId/members

List all team members for a number, including pending invitations.

PATCH/v1/team/:numberId/members/:userId/role

Update a team member's role.

ParameterTypeDescription
role*string"VIEWER" or "MANAGER".
DELETE/v1/team/:numberId/members/:userId

Remove a team member's access to a number.

Example

curl -X POST "https://api.joltsms.com/v1/team/invite" \
  -H "Cookie: better-auth.session_token=..." \
  -H "Content-Type: application/json" \
  -d '{ "numberId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "email": "[email protected]", "role": "VIEWER" }'

Response:

{
  "success": true,
  "invitationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "message": "Invitation sent successfully"
}

HTTP Status Codes

The API uses standard HTTP status codes to indicate the outcome of each request.

CodeMeaning
200Request succeeded.
201Resource created (e.g., new subscription, new endpoint).
400Bad request -- invalid parameters or request body.
401Unauthorized -- missing, invalid, expired, or revoked API key.
402Payment required -- subscription creation needs valid payment or 3DS confirmation.
403Forbidden -- insufficient permissions or API key used on session-only route.
404Resource not found or you do not have access.
409Conflict -- duplicate idempotency key or resource already exists.
429Too many requests -- rate limit exceeded (120/min for API keys).
500Internal server error. If persistent, contact support.