Connext REST API (1.0.0)

Download OpenAPI specification:

Introduction

The Connext REST API lets you programmatically manage subscribers, send messages, schedule blasts, and view delivery logs for your organization.

All endpoints return JSON and use standard HTTP methods (GET, POST, PATCH, DELETE) with RESTful URL paths.

Base URL

https://api.connext.ms/api/v1

All endpoints in this document are relative to this base URL.

Authentication

Every request must include an API key in the Authorization header:

Authorization: Bearer cnxt_your_api_key_here

API keys are scoped to the user who created them. A key inherits the user's organization and permissions — it can only access data within that organization and is limited to the actions the user is allowed to perform.

Generating an API key

  1. Log in to the Connext admin panel.
  2. Click your profile icon in the top-right corner and select API Key from the dropdown menu.
  3. Click Create API Key and give it a descriptive name (e.g., "CRM Integration", "Zapier").
  4. Copy the key immediately — it is only displayed once and cannot be retrieved later.

Managing API keys

From the API Key page (accessible via the profile dropdown) you can:

  • View all keys for your organization.
  • Deactivate a key to temporarily suspend access without deleting it.
  • Reactivate a previously deactivated key.
  • Delete a key to permanently revoke access.

Security best practices

  • Store keys in environment variables or a secrets manager — never hard-code them in source code.
  • Use separate keys for each integration so you can revoke one without affecting others.
  • Set an expiration date for keys used in short-lived or third-party integrations.
  • If a key is compromised, delete it immediately from the admin panel.

Errors

The API returns standard HTTP status codes:

Status Meaning
200 Success
201 Resource created
204 Resource deleted (no body)
400 Bad request — missing or invalid parameters
401 Unauthorized — invalid or missing API key
403 Forbidden — valid key but insufficient permissions
404 Not found — resource doesn't exist or is outside your organization
405 Method not allowed
500 Server error

Error responses include a JSON body:

{
  "message": "Description of what went wrong"
}

Response conventions

  • GET (list) returns a JSON array of objects directly.
  • GET (single) returns the object directly.
  • POST returns 201 with the created resource.
  • PATCH returns 200 with the updated resource.
  • DELETE returns 204 with no body.
  • Action endpoints (send, test, estimate, cancel) return 200 with an operation result.

Pagination

List endpoints (GET /subscribers, GET /schedules, GET /logs) accept limit and offset query parameters.

GET /v1/subscribers?limit=25&offset=0

Subscribers

List subscribers

Authorizations:
bearerAuth
query Parameters
keyword
string

Search across name, phone, email, address

group
string

Filter by group number

sort
string
Enum: "phone" "email" "first" "last"
order
string
Enum: "asc" "desc"
limit
integer
Default: 10
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a subscriber

Authorizations:
bearerAuth
Request Body schema: application/json
required
Any of
phone
required
string^\d{10}$
email
string <email>
first
string
last
string
address
string
city
string
state
string
zip
string
enabled
boolean
type
string
Enum: "sms" "phone"
groups
Array of integers (GroupMembership)

An array of group numbers (not IDs)

Responses

Request samples

Content type
application/json
{
  • "phone": "string",
  • "email": "user@example.com",
  • "first": "string",
  • "last": "string",
  • "address": "string",
  • "city": "string",
  • "state": "string",
  • "zip": "string",
  • "enabled": true,
  • "type": "sms",
  • "groups": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "first": "string",
  • "last": "string",
  • "phone": "string",
  • "type": "sms",
  • "enabled": true,
  • "address": "string",
  • "city": "string",
  • "state": "string",
  • "zip": "string",
  • "email": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "groups": [
    ]
}

Update a subscriber

Authorizations:
bearerAuth
path Parameters
id
required
integer
Request Body schema: application/json
required
non-empty
phone
string^\d{10}$
email
string <email>
first
string
last
string
address
string
city
string
state
string
zip
string
enabled
boolean
type
string
Enum: "sms" "phone"
groups
Array of integers (GroupMembership)

An array of group numbers (not IDs)

Responses

Request samples

Content type
application/json
{
  • "phone": "string",
  • "email": "user@example.com",
  • "first": "string",
  • "last": "string",
  • "address": "string",
  • "city": "string",
  • "state": "string",
  • "zip": "string",
  • "enabled": true,
  • "type": "sms",
  • "groups": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "first": "string",
  • "last": "string",
  • "phone": "string",
  • "type": "sms",
  • "enabled": true,
  • "address": "string",
  • "city": "string",
  • "state": "string",
  • "zip": "string",
  • "email": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "groups": [
    ]
}

Delete a subscriber

Authorizations:
bearerAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}

List blocklist entries

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Add to blocklist

Authorizations:
bearerAuth
Request Body schema: application/json
required
recipient
required
string

10-digit phone number or email address

Responses

Request samples

Content type
application/json
{
  • "recipient": "string"
}

Response samples

Content type
application/json
{
  • "recipient": "string",
  • "type": "phone",
  • "reason": "string",
  • "created_at": "2019-08-24T14:15:22Z"
}

Remove from blocklist

Removes blocklist entries for the recipient from your account only (global entries are never affected). Only self-removable reasons can be cleared here: manual (entries you added), invalid (auto-added for an unreachable/bad number), and blocked (auto-added for a carrier block). Opt-out (stop) and email complaint/bounce entries can't be removed via the API — use the removal-request flow instead. This endpoint is idempotent: it returns 204 even when nothing matched.

Authorizations:
bearerAuth
Request Body schema: application/json
required
recipient
required
string

10-digit phone number or email address to unblock

reason
string
Enum: "manual" "invalid" "blocked"

Optional. Remove only entries with this reason. Omit to remove every self-removable entry for the recipient.

Responses

Request samples

Content type
application/json
{
  • "recipient": "string",
  • "reason": "manual"
}

Response samples

Content type
application/json
{
  • "message": "string"
}

Blasts

Send a blast message

Targets groups (groups), individual recipients (recipients), or both — at least one is required. A recipient need not be a subscriber of the account.

Supports file attachments via multipart/form-data. When uploading files, send the JSON parameters in a form field named body and attach files in fields prefixed with media (for SMS/email) or audio (for audio blasts).

  • SMS/email attachments: max 3.5 MB per file, audio/image/text types only for SMS
  • Audio blasts: max 10 MB per file, mp3/wav only
  • Maximum 5 files per request
Authorizations:
bearerAuth
Request Body schema:
required
types
required
Array of strings (MessageTypes) non-empty
Items Enum: "sms" "voice" "email" "audio"
message
string
subject
string

Email subject line

ivr
integer or null

ID of the IVR flow to play on outbound audio calls. Omit/null/0 for no IVR.

shorten_links
boolean
Default: false
email_template_id
integer or null

If set and email is in types, the server resolves the template at send time and uses its rendered HTML + subject for the email channel (the request's subject and the email portion of message are ignored). Non-email channels in a mixed-channel send continue to use the request's message. Silently ignored when email is not in types.

from
string^[0-9]{10}$

10-digit number to send from. Must be a provisioned number on this account. Omit to use the account's primary number.

Array of integers or string (GroupNumbers)

Groups a message targets: an array of group numbers (not IDs), or the string "all" to target every group in the organization. Responses use the same shape — an all-subscribers send comes back as the string "all".

dnc
Array of integers (GroupMembership)

An array of group numbers (not IDs)

recipients
Array of strings <= 500 items

Individual recipients, whether or not they are subscribers of this account. A value containing @ is an email address, anything else a 10-digit phone number. May be combined with groups; at least one of the two is required. Duplicates are sent once (emails case-insensitively), and every recipient must be reachable by one of the selected types — naming an email address on an SMS-only send, or the reverse, is rejected. One combination is refused with a 400: groups: "all" together with recipients. Name the groups explicitly to reach every group plus individual recipients.

Responses

Request samples

Content type
{
  • "types": [
    ],
  • "message": "string",
  • "subject": "string",
  • "ivr": 0,
  • "shorten_links": false,
  • "email_template_id": 0,
  • "from": "string",
  • "groups": [
    ],
  • "dnc": [
    ],
  • "recipients": [
    ]
}

Response samples

Content type
application/json
{
  • "message": "string"
}

Send a test blast

Sends a preview to the one to five recipients you name — typically yourself — so you can see the message as it will arrive. Groups are not accepted here; use /blasts/send to reach an audience.

Supports the same file upload options as /blasts/send — use multipart/form-data with a body field and file fields prefixed with media or audio.

Authorizations:
bearerAuth
Request Body schema:
required
types
required
Array of strings (MessageTypes) non-empty
Items Enum: "sms" "voice" "email" "audio"
message
string
subject
string

Email subject line

ivr
integer or null

ID of the IVR flow to play on outbound audio calls. Omit/null/0 for no IVR.

shorten_links
boolean
Default: false
email_template_id
integer or null

If set and email is in types, the server resolves the template at send time and uses its rendered HTML + subject for the email channel (the request's subject and the email portion of message are ignored). Non-email channels in a mixed-channel send continue to use the request's message. Silently ignored when email is not in types.

from
string^[0-9]{10}$

10-digit number to send from. Must be a provisioned number on this account. Omit to use the account's primary number.

recipients
required
Array of strings [ 1 .. 5 ] items

Who to send the preview to — at least one, at most five. A value containing @ is an email address, anything else a 10-digit phone number. They need not be subscribers of this account.

Responses

Request samples

Content type
{
  • "types": [
    ],
  • "message": "string",
  • "subject": "string",
  • "ivr": 0,
  • "shorten_links": false,
  • "email_template_id": 0,
  • "from": "string",
  • "recipients": [
    ]
}

Response samples

Content type
application/json
{
  • "message": "string"
}

Estimate blast cost

Authorizations:
bearerAuth
Request Body schema: application/json
required
types
required
Array of strings (MessageTypes) non-empty
Items Enum: "sms" "voice" "email" "audio"
Array of integers or string (GroupNumbers)

Groups a message targets: an array of group numbers (not IDs), or the string "all" to target every group in the organization. Responses use the same shape — an all-subscribers send comes back as the string "all".

dnc
Array of integers (GroupMembership)

An array of group numbers (not IDs)

recipients
Array of strings <= 500 items

Individual recipients to price alongside groups, whether or not they are subscribers. A value containing @ is an email address, anything else a 10-digit phone number. At least one of groups or recipients is required. Duplicates are counted once (emails case-insensitively), and every recipient must be reachable by one of the selected types. Cannot be combined with groups: "all" (400) — name the groups explicitly to price every group plus individual recipients.

message
string
has_media
boolean
shorten_links
boolean

Responses

Request samples

Content type
application/json
{
  • "types": [
    ],
  • "groups": [
    ],
  • "dnc": [
    ],
  • "recipients": [
    ],
  • "message": "string",
  • "has_media": true,
  • "shorten_links": true
}

Response samples

Content type
application/json
{
  • "cost": 0
}

List message templates

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a template

Supports file attachments via multipart/form-data. Send the JSON parameters in a body form field and attach files in fields prefixed with media or audio. Same limits as /blasts/send.

Authorizations:
bearerAuth
Request Body schema:
required
title
required
string non-empty
types
required
Array of strings (MessageTypes) non-empty
Items Enum: "sms" "voice" "email" "audio"
message
string
subject
string
voice_fallback
boolean
Array of integers or string (GroupNumbers)

Groups a message targets: an array of group numbers (not IDs), or the string "all" to target every group in the organization. Responses use the same shape — an all-subscribers send comes back as the string "all".

dnc
Array of integers (GroupMembership)

An array of group numbers (not IDs)

shorten_links
boolean
Default: false
ivr
integer or null

ID of the IVR flow this template plays. Null for none.

email_template_id
integer or null

Id of an email template owned by this organization. Stored on the blast template so that re-loading it restores the selected email template. Send null to clear.

Responses

Request samples

Content type
{
  • "title": "string",
  • "types": [
    ],
  • "message": "string",
  • "subject": "string",
  • "voice_fallback": true,
  • "groups": [
    ],
  • "dnc": [
    ],
  • "shorten_links": false,
  • "ivr": 0,
  • "email_template_id": 0
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "types": [
    ],
  • "message": "string",
  • "subject": "string",
  • "voice_fallback": true,
  • "files": [
    ],
  • "groups": [
    ],
  • "dnc": [
    ],
  • "shorten_links": true,
  • "ivr": 0,
  • "email_template_id": 0
}

Update a template

Supports file attachments via multipart/form-data. Same format as template creation.

Authorizations:
bearerAuth
path Parameters
id
required
integer
Request Body schema:
required
non-empty
title
string non-empty
types
Array of strings (MessageTypes) non-empty
Items Enum: "sms" "voice" "email" "audio"
message
string
subject
string
voice_fallback
boolean
Array of integers or string (GroupNumbers)

Groups a message targets: an array of group numbers (not IDs), or the string "all" to target every group in the organization. Responses use the same shape — an all-subscribers send comes back as the string "all".

dnc
Array of integers (GroupMembership)

An array of group numbers (not IDs)

shorten_links
boolean
Default: false
ivr
integer or null

ID of the IVR flow this template plays. Null for none.

email_template_id
integer or null

Id of an email template owned by this organization. Stored on the blast template so that re-loading it restores the selected email template. Send null to clear.

files
Array of strings

URLs of files to retain on the template. Each entry must match a URL already on the template — send [] to clear all, or omit to preserve the current list. New media must be uploaded via multipart/form-data; URLs cannot be injected through this field.

Responses

Request samples

Content type
{
  • "title": "string",
  • "types": [
    ],
  • "message": "string",
  • "subject": "string",
  • "voice_fallback": true,
  • "groups": [
    ],
  • "dnc": [
    ],
  • "shorten_links": false,
  • "ivr": 0,
  • "email_template_id": 0,
  • "files": [
    ]
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "types": [
    ],
  • "message": "string",
  • "subject": "string",
  • "voice_fallback": true,
  • "files": [
    ],
  • "groups": [
    ],
  • "dnc": [
    ],
  • "shorten_links": true,
  • "ivr": 0,
  • "email_template_id": 0
}

Delete a template

Authorizations:
bearerAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}

Schedules

List scheduled messages

Authorizations:
bearerAuth
query Parameters
keyword
string

Search in title or message

limit
integer
Default: 10
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a scheduled message

Supports file attachments via multipart/form-data. Same upload format and limits as /blasts/send.

Authorizations:
bearerAuth
Request Body schema:
required
startDate
required
string <date>
startTime
required
string^\d{1,2}:\d{2}(:\d{2})?$

HH:MM format

title
required
string non-empty
types
required
Array of strings (MessageTypes) non-empty
Items Enum: "sms" "voice" "email" "audio"
required
Array of integers or string (GroupNumbers)

Groups a message targets: an array of group numbers (not IDs), or the string "all" to target every group in the organization. Responses use the same shape — an all-subscribers send comes back as the string "all".

dnc
Array of integers (GroupMembership)

An array of group numbers (not IDs)

message
string
subject
string
ivr
integer or null

ID of the IVR flow to play on outbound audio calls. Omit/null/0 for no IVR.

shorten_links
boolean
Default: false
frequency
string
Enum: "minutes" "hours" "days" "weeks" "months"

Makes the schedule recurring

every
integer >= 1

Interval for recurrence. Required if frequency is set, and rejected with 400 if it is not.

remaining
integer >= 1

Max number of iterations

days
integer [ 0 .. 127 ]

Day-of-week bitmap, only valid alongside frequency; sending one without a frequency is rejected with 400. A one-time schedule has no cadence to roll to an allowed day, so a day mask on one would leave a schedule that can never fire.

email_template_id
integer or null

Persisted on the schedule row. Resolved at send time (late binding): edits to the underlying email template take effect on the next firing.

from
string^[0-9]{10}$

10-digit number to send from. Must be a provisioned number on this account. Omit to use the account's primary number.

Responses

Request samples

Content type
{
  • "startDate": "2019-08-24",
  • "startTime": "string",
  • "title": "string",
  • "types": [
    ],
  • "groups": [
    ],
  • "dnc": [
    ],
  • "message": "string",
  • "subject": "string",
  • "ivr": 0,
  • "shorten_links": false,
  • "frequency": "minutes",
  • "every": 1,
  • "remaining": 1,
  • "days": 127,
  • "email_template_id": 0,
  • "from": "string"
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "subject": "string",
  • "message": "string",
  • "groups": [
    ],
  • "dnc": [
    ],
  • "types": [
    ],
  • "active": true,
  • "next": "2019-08-24T14:15:22Z",
  • "media": [
    ],
  • "every": 0,
  • "frequency": "minutes",
  • "remaining": 0,
  • "days": 0,
  • "email_template_id": 0
}

Update a scheduled message

Authorizations:
bearerAuth
path Parameters
id
required
integer
Request Body schema: application/json
required
non-empty
message
string
subject
string
title
string
Array of integers or string (GroupNumbers)

Groups a message targets: an array of group numbers (not IDs), or the string "all" to target every group in the organization. Responses use the same shape — an all-subscribers send comes back as the string "all".

dnc
Array of integers (GroupMembership)

An array of group numbers (not IDs)

every
integer >= 1

Only valid on a recurring schedule. every, frequency and days are validated against the row as it will be AFTER the patch is applied, so any of the three sent alone is checked against the schedule's current values for the other two.

frequency
string
Enum: "minutes" "hours" "days" "weeks" "months"

Repeat unit. Setting one on a one-time schedule makes it recurring, and requires every in the same request. The reverse is not expressible: this enum has no empty-string member, so a recurring schedule cannot be turned back into a one-time one through the API.

remaining
integer
active
integer
Enum: 0 1
days
integer [ 0 .. 127 ]

Day-of-week bitmap. Only valid on a recurring schedule.

startDate
string <date>

Must be paired with startTime

startTime
string^\d{1,2}:\d{2}(:\d{2})?$

Must be paired with startDate

email_template_id
integer or null

Send null to clear the selected email template.

Responses

Request samples

Content type
application/json
{
  • "message": "string",
  • "subject": "string",
  • "title": "string",
  • "groups": [
    ],
  • "dnc": [
    ],
  • "every": 1,
  • "frequency": "minutes",
  • "remaining": 0,
  • "active": 0,
  • "days": 127,
  • "startDate": "2019-08-24",
  • "startTime": "string",
  • "email_template_id": 0
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "subject": "string",
  • "message": "string",
  • "groups": [
    ],
  • "dnc": [
    ],
  • "types": [
    ],
  • "active": true,
  • "next": "2019-08-24T14:15:22Z",
  • "media": [
    ],
  • "every": 0,
  • "frequency": "minutes",
  • "remaining": 0,
  • "days": 0,
  • "email_template_id": 0
}

Delete a scheduled message

Authorizations:
bearerAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}

Logs

List message logs

Authorizations:
bearerAuth
query Parameters
keyword
string

Search in username or message

limit
integer
Default: 10
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get log details for a message

Authorizations:
bearerAuth
path Parameters
id
required
integer
query Parameters
keyword
string

Filter by recipient (phone/email) or matched subscriber name

status
string
Enum: "queued" "sent" "delivered" "failed" "clicked"
limit
integer
Default: 10
offset
integer
Default: 0
getClicks
string
Value: "true"

Include click counts per recipient

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get delivery statistics for a message

Authorizations:
bearerAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "statuses": {
    },
  • "errors": [
    ],
  • "clicks": 0
}

Cancel a pending message

Authorizations:
bearerAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}

List individual messages

Every individual message for the account, newest first — inbound replies as well as outbound sends, and non-blast traffic (keyword auto-replies, one-offs) as well as blasts. One row per recipient per message. Contrast with /logs, which returns one aggregated row per blast, and /logs/{id}, which returns the recipients of a single blast.

Authorizations:
bearerAuth
query Parameters
keyword
string

Filter by recipient (phone/email) or matched subscriber name

message_id
string

Return only the message with this id — the message_id POST /messages hands back. Ids are unique, so the result is at most one row; use it to check the delivery status of a send you made. Scoped to your own account, so an id from elsewhere returns an empty list. Note this returns the one attempt that id names, not any retry or fallback that superseded it — filter by keyword (the recipient) to see those.

direction
string
Enum: "in" "out"

Restrict to inbound or outbound; omit for both

dateFrom
string <date>

Inclusive lower bound on message date (YYYY-MM-DD)

dateTo
string <date>

Inclusive upper bound on message date (YYYY-MM-DD)

types
string

Comma-separated channel filter, e.g. sms,email

limit
integer
Default: 10

Maximum rows to return (capped at 500)

offset
integer
Default: 0

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Send a direct message

Sends one message to one recipient — an order confirmation, an appointment reminder, a password reset. Use /blasts/send to reach an audience.

The recipient does not have to be a subscriber of your account, and the send is not recorded as a blast, so transactional traffic never appears in /logs. It does open a conversation thread in the portal's chat inbox, so a reply from the recipient reaches your staff.

Subject to the account's daily per-channel limit, which this shares with every other send; a message to a blocked recipient is refused.

Authorizations:
bearerAuth
Request Body schema: application/json
required
to
required
string

The recipient — a 10-digit phone number, or an email address when type is email. They do not have to be a subscriber of this account.

type
string
Default: "sms"
Enum: "sms" "email"

Channel to send on.

message
required
string non-empty
subject
string

Subject line for an email send. It is not transmitted on an SMS — there it is only quoted onto the chat thread record — so leave it off for SMS.

from
string^[0-9]{10}$

10-digit number to send from. Must be a provisioned number on this account. Omit to continue on the number this conversation last used, falling back to the account's primary. Ignored on an email send.

Responses

Request samples

Content type
application/json
{
  • "to": "string",
  • "type": "sms",
  • "message": "string",
  • "subject": "string",
  • "from": "string"
}

Response samples

Content type
application/json
{
  • "message": "string",
  • "message_id": "string"
}

Groups

List groups

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a group

Authorizations:
bearerAuth
Request Body schema: application/json
required
name
required
string^\S+$

Group name. Cannot contain spaces (subscribers text JOIN <name>).

number
integer

Auto-assigned if omitted

private
boolean
Default: false

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "number": 0,
  • "private": false
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "number": 0
}

Update a group

Authorizations:
bearerAuth
path Parameters
id
required
integer
Request Body schema: application/json
required
name
required
string^\S+$

Group name. Cannot contain spaces (subscribers text JOIN <name>).

number
required
integer
private
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "number": 0,
  • "private": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "name": "string",
  • "number": 0
}

Delete a group

Authorizations:
bearerAuth
path Parameters
id
required
integer

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}

Account

List the account's phone numbers

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "numbers": [
    ]
}

Buy a phone number

Buys the first number available in the requested area code and adds it to your organization. This is the API equivalent of the portal's two-step search-then-request flow, collapsed into one call for integrations that have no UI to drive.

Purchasing is off by default. It is limited to an allowlist of organizations maintained by Connext; every account that is not on it gets 403. Contact support to have it enabled.

A successful purchase charges a $5 purchase fee to the default card on file (any account balance is applied first) and begins the number's monthly rental. At most one number per hour may be bought on an organization — a second attempt inside that hour returns 429, as does a request that arrives while another purchase on the same organization is still running. A number that was bought and then released still counts against the hour.

The number comes back with status: 1 (ordering). Carrier provisioning and campaign registration complete out of band over the following minutes, and the number cannot send until its status reaches 3 — poll GET /numbers to watch it advance through 2 (campaign pending) to 3 (ready to send).

Buying a number also restarts the organization's 30-day number-change cooldown, which runs from the most recent number acquired.

Authorizations:
bearerAuth
Request Body schema: application/json
required
area_code
required
string^[0-9]{3}$

The 3-digit North American area code to buy in, as a string.

label
string <= 50 characters

Optional name for the number, returned by GET /numbers.

Responses

Request samples

Content type
application/json
{
  • "area_code": "string",
  • "label": "string"
}

Response samples

Content type
application/json
{
  • "phone": "string",
  • "status": 0
}

Release a phone number

Gives a number back to the carrier and removes it from your organization. This is free and immediate: no fee is charged, and no payment method is required — an organization whose sending is currently disabled can still release a number, since handing one back only reduces what it costs to run.

Like buying, releasing is restricted to organizations Connext has enabled for multiple numbers, and returns 403 for any other account.

Your organization's primary number cannot be released, which also means an organization can never release its last remaining number. Change the primary from the portal first if you need to give that one up.

Releasing is permanent. The number goes back into the carrier's pool, it stops receiving, and any message history recorded against it stays on the organization.

Because it is permanent, a number is not released while work is still pointing at it: if messages are queued to go out from it, or scheduled blasts are set to send from it, the request is refused with 409 and nothing changes. Let the queue finish, and move or delete those schedules, then try again. Messages already delivered never block a release.

Authorizations:
bearerAuth
path Parameters
phone
required
string

The number to release. Non-digit characters are stripped before it is matched, so 5550000001 and 555-000-0001 are equivalent; what remains must be exactly 10 digits.

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}