HomeGuidesAPI Reference
ChangelogHelp CenterCommunityContact Us
API Reference

Text Messaging API overview

OpenAPI Spec

Machine-readable spec for the Text Messaging API: stable/categories/text_messaging.json

Before you begin

Check out our general API overview to make sure you're ready to get started with specific endpoints.

The Text Messaging API lets you set up and manage an account's SMS sending capability programmatically: create the account's text messaging configuration, provision toll-free senders, and track each sender's carrier registration. It exposes the same records the dashboard uses under Settings > Text messages, so you can stand up SMS sending for an account end to end without the UI.

These endpoints configure SMS sending — they do not send messages. You cannot send an SMS through the Text Messaging API. Once a configuration and an approved sender are in place, the account sends SMS through Klaviyo campaigns and flows.

Use cases

Here are example use cases supported by the Text Messaging API:

  • Set up an account's text messaging configuration to enable SMS sending.
  • Provision a toll-free sender for an account and submit its carrier registration in a single call.
  • Poll a sender's registration status and surface the carrier's decision (approved or rejected) in your own tooling.
  • Resubmit a corrected registration after a rejection, using the failure reasons returned by the API.
  • List an account's senders and their registration status to build an internal SMS-readiness dashboard.

Required scopes

To use Text Messaging API endpoints, your API key or OAuth app needs the following scopes:

  • sender-config:read — required to retrieve configurations, senders, and registrations.
  • sender-config:write — required to create a configuration, provision a sender, or resubmit a registration.

A key without the required scope receives a 403 response. See Troubleshooting.

Data model

The API has three resources.

Text messaging configuration

The text-messaging-configuration resource is the account-level record that enables SMS for a company. It is a singleton: an account has at most one, and its id is the account's company id. Create it before provisioning any senders.

  • org_prefix — a branding prefix prepended to outbound messages so recipients can identify the sender. Maximum 50 characters.
  • opt_out_language — the opt-out instructions appended to outbound messages.
  • status — active or disabled.
  • created_at, updated_at — ISO 8601 timestamps.

Text messaging sender

The text-messaging-sender resource is a provisioned sending number. Toll-free is the currently supported sender type.

  • sender_type — the kind of sender. Currently toll_free.
  • sender_details — attributes specific to the sender type. For toll-free, this is the country (ISO 3166-1 alpha-2, for example US).
  • status — the sender lifecycle state: pending_registration, registering, active, registration_failed, or suspended.
  • forwarding_number — the E.164 number that inbound voice calls are forwarded to, or null when forwarding is not configured.
  • sender_identifier — the sender's outbound address (the E.164 phone number). For toll-free, the number is assigned at provision time, so it's populated as soon as the sender is created — including while status is pending_registration. A toll-free number's US and Canada records share the same sender_identifier.
  • created_at — ISO 8601 timestamp.
  • Relationship: text-messaging-sender-registration — the sender's most recent carrier registration.

Text messaging sender registration

The text-messaging-sender-registration resource is a sender's carrier registration — the record carriers review before a toll-free number may send.

  • status — action_required, in_review, approved, or rejected. A registration is created in in_review and ends in approved or rejected; action_required means the carrier needs more information before it can proceed.
  • failures — a list of objects, each with a detail string describing a reason the registration was rejected. Populated only when status is rejected.
  • submitted_at — when the registration was submitted, or null until it is.
  • decided_at — when the carrier approved or rejected the registration, or null until a decision is returned.
  • created_at, updated_at — ISO 8601 timestamps.
  • Relationship: text-messaging-sender — the sender this registration belongs to.

Set up the account's configuration

Setting up a text messaging configuration is the first step — create it before any other action. Until it exists, the sender and registration endpoints return 403.

curl --request POST \
  --url 'https://a.klaviyo.com/api/text-messaging-configurations' \
  --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --header 'revision: 2026-10-15' \
  --data '{
    "data": {
      "type": "text-messaging-configuration",
      "attributes": {
        "org_prefix": "Acme"
      }
    }
  }'
{
  "data": {
    "type": "text-messaging-configuration",
    "id": "AbC123",
    "attributes": {
      "org_prefix": "Acme",
      "opt_out_language": "Text STOP to opt-out",
      "status": "active",
      "created_at": "2026-07-13T14:30:00+00:00",
      "updated_at": "2026-07-13T14:30:00+00:00"
    },
    "links": {
      "self": "https://a.klaviyo.com/api/text-messaging-configurations/AbC123/"
    }
  }
}

Retrieve the configuration with GET /api/text-messaging-configurations/{id}, where {id} is the account's company id. Because the configuration is a singleton, requesting any other id returns 404.

Provision a sender

POST /api/text-messaging-senders provisions a toll-free number and submits its initial carrier registration in one call. The registration details are embedded in the request under the text-messaging-sender-registration relationship.

📘

Provisioning a toll-free sender assigns a real toll-free number that can send in both the US and Canada, and counts against the account's number limit. A toll-free number is registered in both regions, so creating one region's sender creates the other's at the same time. Both records are the same number — they share the same sender_identifier — and they share one carrier registration, so registering (or resubmitting) one registers the other. The response returns the record for the country you requested; match on sender_identifier to relate the pair in list and retrieve responses, and read sender_details.country for the region.

curl --request POST \
  --url 'https://a.klaviyo.com/api/text-messaging-senders' \
  --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --header 'revision: 2026-10-15' \
  --data '{
    "data": {
      "type": "text-messaging-sender",
      "attributes": {
        "sender_type": "toll_free",
        "sender_details": {
          "country": "US"
        },
        "text-messaging-sender-registration": {
          "data": {
            "type": "text-messaging-sender-registration",
            "attributes": {
              "first_name": "Jane",
              "last_name": "Doe",
              "phone_number": "+16175551212",
              "email": "[email protected]",
              "address": {
                "street_address_1": "125 Summer Street",
                "city": "Boston",
                "region": "MA",
                "postal_code": "02110",
                "country": "US"
              },
              "business_name": "Acme Corp",
              "business_website": "https://www.acme.com",
              "business_type": "corporation",
              "business_registration_country": "US",
              "business_registration_authority": "EIN",
              "business_registration_number": "12-3456789"
            }
          }
        }
      }
    }
  }'
{
  "data": {
    "type": "text-messaging-sender",
    "id": "01HX2Z8RG7Y4PWFQK3V0M5N1B7",
    "attributes": {
      "sender_type": "toll_free",
      "sender_details": {
        "country": "US"
      },
      "status": "pending_registration",
      "forwarding_number": null,
      "sender_identifier": "+18885551234",
      "created_at": "2026-07-13T14:35:00+00:00"
    },
    "relationships": {
      "text-messaging-sender-registration": {
        "data": {
          "type": "text-messaging-sender-registration",
          "id": "01HX2Z8RG7Y4PWFQK3V0M5N1C8"
        },
        "links": {
          "self": "https://a.klaviyo.com/api/text-messaging-senders/01HX2Z8RG7Y4PWFQK3V0M5N1B7/relationships/text-messaging-sender-registration/",
          "related": "https://a.klaviyo.com/api/text-messaging-senders/01HX2Z8RG7Y4PWFQK3V0M5N1B7/text-messaging-sender-registration/"
        }
      }
    },
    "links": {
      "self": "https://a.klaviyo.com/api/text-messaging-senders/01HX2Z8RG7Y4PWFQK3V0M5N1B7/"
    }
  }
}

A successful request returns 201 Created with the sender for the requested country. The embedded registration is created in in_review.

List and retrieve senders

Use GET /api/text-messaging-senders to list the account's senders. The endpoint supports cursor pagination (page[size] up to 20), sorting on created_at, and sparse fieldsets. Use GET /api/text-messaging-senders/{id} to retrieve a single sender.

Include each sender's current registration inline with ?include=text-messaging-sender-registration:

curl --request GET \
  --url 'https://a.klaviyo.com/api/text-messaging-senders?include=text-messaging-sender-registration' \
  --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
  --header 'accept: application/json' \
  --header 'revision: 2026-10-15'

The response is a JSON:API compound document: the senders are in data, and their registrations are in the top-level included array.

Because a toll-free number can send in both the US and Canada, the list includes a record for each region, both sharing the same sender_identifier. Match on sender_identifier to treat the pair as a single number — for example, when counting numbers in a dashboard — and read sender_details.country for the region.

Track and resubmit a registration

A registration starts in in_review and transitions to approved or rejected once the carrier returns a decision. Retrieve a registration directly with GET /api/text-messaging-sender-registrations/{id}, or fetch a sender's most recent registration with the related-resource link GET /api/text-messaging-senders/{id}/text-messaging-sender-registration. Both support ?include=text-messaging-sender to include the linked sender inline.

A toll-free number's US and Canada records share one carrier registration, so submitting or resubmitting for one applies to both regions.

When a registration is rejected, the failures array explains why:

{
  "data": {
    "type": "text-messaging-sender-registration",
    "id": "01HX2Z8RG7Y4PWFQK3V0M5N1C8",
    "attributes": {
      "status": "rejected",
      "failures": [
        {
          "detail": "Invalid business details"
        }
      ],
      "submitted_at": "2026-07-13T14:35:00+00:00",
      "decided_at": "2026-07-13T14:52:00+00:00",
      "created_at": "2026-07-13T14:35:00+00:00",
      "updated_at": "2026-07-13T14:52:00+00:00"
    },
    "relationships": {
      "text-messaging-sender": {
        "data": {
          "type": "text-messaging-sender",
          "id": "01HX2Z8RG7Y4PWFQK3V0M5N1B7"
        }
      }
    }
  }
}

After a rejection, correct the details and resubmit with POST /api/text-messaging-sender-registrations. Send the same registration attributes as a create, plus a relationship to the sender you are resubmitting for:

curl --request POST \
  --url 'https://a.klaviyo.com/api/text-messaging-sender-registrations' \
  --header 'Authorization: Klaviyo-API-Key your-private-api-key' \
  --header 'accept: application/json' \
  --header 'content-type: application/json' \
  --header 'revision: 2026-10-15' \
  --data '{
    "data": {
      "type": "text-messaging-sender-registration",
      "attributes": {
        "first_name": "Jane",
        "last_name": "Doe",
        "phone_number": "+16175551212",
        "email": "[email protected]",
        "address": {
          "street_address_1": "125 Summer Street",
          "city": "Boston",
          "region": "MA",
          "postal_code": "02110",
          "country": "US"
        },
        "business_name": "Acme Corp",
        "business_website": "https://www.acme.com",
        "business_type": "corporation",
        "business_registration_country": "US",
        "business_registration_authority": "EIN",
        "business_registration_number": "12-3456789"
      },
      "relationships": {
        "text-messaging-sender": {
          "data": {
            "type": "text-messaging-sender",
            "id": "01HX2Z8RG7Y4PWFQK3V0M5N1B7"
          }
        }
      }
    }
  }'

A successful resubmission returns 201 Created with a new registration in in_review. You can only resubmit when the sender has no in-flight registration; resubmitting while a registration is still in_review returns 409.

Rate limits

Text Messaging API endpoints use these rate limit tiers:

  • Read endpoints (retrieve a configuration, list or retrieve senders, retrieve a registration): SMALL — 3 requests/second burst and 60 requests/minute steady.
  • Write endpoints (create a configuration, provision a sender, resubmit a registration): EXTRA_SMALL — 1 request/second burst and 15 requests/minute steady.

See rate limits for more information.

Troubleshooting

Status codeReasons
400Invalid input: an unsupported or lowercase country, a sender_type other than toll_free, invalid contact or business registration details, or a missing/too-long org_prefix.
401Missing or invalid API credentials.
403The key is missing the required sender-config scope, or no text messaging configuration exists for the account yet (sms_account_required).
404The resource does not exist, belongs to another account, uses a configuration id other than the account's company id, or refers to a deleted sender.
409A configuration already exists for the account (sms_account_already_exists), a registration is still in review (registration_in_flight), or the account has reached its toll-free number limit (phone_number_limit_reached).
429Rate limit exceeded. See rate limits.
502A downstream carrier or provider request failed. Retry the request.

Additional resources