Line Provisioning
Add and remove inbound_only / Agent plan phone lines via API
Credential-based line management is available for eligible inbound_only / Agent plan accounts. Provisioning adds paid inbound-only phone lines. Accounts with automatic line provisioning enabled use shared quantity billing and also support API deprovisioning. Legacy accounts may still provision lines through the same preview/confirm flow, but do not support API deprovisioning.
Deprecated: The previous ticket-based
POST /accounts/lines/add-lineandGET /accounts/lines/line-request/:lineRequestTicketIdflows have been deprecated for direct line purchases. Use the preview and confirm endpoints below for API line provisioning.
Endpoints
Section titled “Endpoints”Line provisioning and deprovisioning use a two-step flow. Preview validates eligibility and issues a short-lived token. Confirm consumes that token and performs the line operation.
Preview tokens are valid for 10 minutes and can be used once.
Provision a Line
Section titled “Provision a Line”Provisioning charges the card on file and assigns an inbound-only phone number to the account. Automatic line provisioning accounts use shared quantity billing and invoice the prorated cost immediately. Legacy accounts create a per-line subscription and return a top-level subscription_id instead of a billing object.
Step 1: Preview
Section titled “Step 1: Preview”Validate that the account is eligible and that a line is currently available.
POST /accounts/lines/provision-previewExample Request
Section titled “Example Request”curl -X POST "https://api.sendblue.com/accounts/lines/provision-preview" \ -H "sb-api-key-id: YOUR_API_KEY" \ -H "sb-api-secret-key: YOUR_API_SECRET"Success Response (200, Automatic Line Provisioning)
Section titled “Success Response (200, Automatic Line Provisioning)”{ "status": "OK", "preview_token": "lpv_abc123...", "expires_at": "2026-05-18T14:30:00.000Z", "billing": { "model": "quantity", "current_line_count": 41, "new_quantity": 42, "line_minimum": 1 }, "message": "Call /accounts/lines/provision-confirm with this token within 10 minutes to complete the purchase. The added line is prorated and invoiced immediately."}| Field | Type | Description |
|---|---|---|
status | string | OK |
preview_token | string | Single-use token for the confirm step |
expires_at | string | ISO 8601 expiration timestamp |
billing.model | string | Billing model for the account |
billing.current_line_count | number | Current paid line quantity |
billing.new_quantity | number | Paid line quantity after confirm succeeds |
billing.line_minimum | number | Minimum paid line quantity for the account |
message | string | Human-readable next step |
Success Response (200, Legacy Provisioning)
Section titled “Success Response (200, Legacy Provisioning)”{ "status": "OK", "preview_token": "lpv_abc123...", "expires_at": "2026-05-18T14:30:00.000Z", "message": "Call /accounts/lines/provision-confirm with this token within 10 minutes to complete the purchase."}Step 2: Confirm
Section titled “Step 2: Confirm”Consume the preview_token, charge the card on file, and provision the line.
POST /accounts/lines/provision-confirmRequest Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
preview_token | string | Yes | Token returned by POST /accounts/lines/provision-preview |
Example Request
Section titled “Example Request”curl -X POST "https://api.sendblue.com/accounts/lines/provision-confirm" \ -H "sb-api-key-id: YOUR_API_KEY" \ -H "sb-api-secret-key: YOUR_API_SECRET" \ -H "Content-Type: application/json" \ -d '{ "preview_token": "lpv_abc123..." }'Success Response (200, Automatic Line Provisioning)
Section titled “Success Response (200, Automatic Line Provisioning)”{ "status": "OK", "phone_number": "+14155551234", "worker_id": "worker_abc123", "billing": { "model": "quantity", "subscription_id": "sub_abc123", "subscription_item_id": "si_abc123", "quantity": 42 }}| Field | Type | Description |
|---|---|---|
status | string | OK |
phone_number | string | The newly provisioned Sendblue phone number |
worker_id | string | Internal worker ID for the new line |
billing.model | string | Billing model for the account |
billing.subscription_id | string | Stripe subscription ID |
billing.subscription_item_id | string | Stripe subscription item ID |
billing.quantity | number | Paid line quantity after the line is added |
Success Response (200, Legacy Provisioning)
Section titled “Success Response (200, Legacy Provisioning)”{ "status": "OK", "phone_number": "+14155551234", "worker_id": "worker_abc123", "subscription_id": "sub_abc123"}| Field | Type | Description |
|---|---|---|
status | string | OK |
phone_number | string | The newly provisioned Sendblue phone number |
worker_id | string | Internal worker ID for the new line |
subscription_id | string | Stripe subscription ID for the line |
Deprovision a Line
Section titled “Deprovision a Line”Deprovisioning releases an assigned phone number and lowers the paid line quantity by one. The released phone number cannot be recovered. No prorated refund or credit is issued; the lower quantity applies at the next renewal.
Use deprovisioning only for paid/API-billed lines. Do not use API deprovisioning for lines added by Sendblue support as free, comped, or replacement lines unless support has explicitly confirmed that the exact phone number is API-billed and safe to release.
Step 1: Preview
Section titled “Step 1: Preview”Validate that the phone number is assigned to the account and that removing it would not go below the account’s line minimum.
POST /accounts/lines/deprovision-previewRequest Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
phone_number | string | Yes | Assigned Sendblue phone number to remove, in E.164 format |
Example Request
Section titled “Example Request”curl -X POST "https://api.sendblue.com/accounts/lines/deprovision-preview" \ -H "sb-api-key-id: YOUR_API_KEY" \ -H "sb-api-secret-key: YOUR_API_SECRET" \ -H "Content-Type: application/json" \ -d '{ "phone_number": "+14155551234" }'Success Response (200)
Section titled “Success Response (200)”{ "status": "OK", "preview_token": "ldp_abc123...", "expires_at": "2026-05-18T14:30:00.000Z", "phone_number": "+14155551234", "effect": { "new_quantity": 41, "proration": "none", "note": "No refund or credit is issued; billing decreases at the next renewal. The phone number is released and cannot be recovered." }, "message": "Call /accounts/lines/deprovision-confirm with this token within 10 minutes to remove the line. This is irreversible."}| Field | Type | Description |
|---|---|---|
status | string | OK |
preview_token | string | Single-use token for the confirm step |
expires_at | string | ISO 8601 expiration timestamp |
phone_number | string | Phone number that will be removed |
effect.new_quantity | number | Paid line quantity after confirm succeeds |
effect.proration | string | none; no refund or credit is issued |
effect.note | string | Human-readable billing and release effect |
message | string | Human-readable next step |
Step 2: Confirm
Section titled “Step 2: Confirm”Consume the preview_token, release the line, and lower the paid line quantity.
POST /accounts/lines/deprovision-confirmRequest Body
Section titled “Request Body”| Parameter | Type | Required | Description |
|---|---|---|---|
preview_token | string | Yes | Token returned by POST /accounts/lines/deprovision-preview |
Example Request
Section titled “Example Request”curl -X POST "https://api.sendblue.com/accounts/lines/deprovision-confirm" \ -H "sb-api-key-id: YOUR_API_KEY" \ -H "sb-api-secret-key: YOUR_API_SECRET" \ -H "Content-Type: application/json" \ -d '{ "preview_token": "ldp_abc123..." }'Success Response (200)
Section titled “Success Response (200)”{ "status": "OK", "phone_number": "+14155551234", "billing": { "model": "quantity", "subscription_id": "sub_abc123", "subscription_item_id": "si_abc123", "quantity": 41 }}| Field | Type | Description |
|---|---|---|
status | string | OK |
phone_number | string | The removed Sendblue phone number |
billing.model | string | Billing model for the account |
billing.subscription_id | string | Stripe subscription ID |
billing.subscription_item_id | string | Stripe subscription item ID |
billing.quantity | number | Paid line quantity after the line is removed |
Rate Limits
Section titled “Rate Limits”Line management limits are visible with GET /accounts/limits.
| Operation | Window | Default | Override |
|---|---|---|---|
| Provision | Daily, rolling 24 hours | 3 lines | Set limits.api_provision_daily on the account |
| Provision | Monthly, rolling 30 days | 10 lines | Set limits.api_provision_monthly on the account |
| Deprovision | Daily, rolling 24 hours | 3 lines | Set limits.api_deprovision_daily on the account |
| Deprovision | Monthly, rolling 30 days | 10 lines | Set limits.api_deprovision_monthly on the account |
Limits are checked during both preview and confirm.
Error Responses
Section titled “Error Responses”{ "status": "ERROR", "error": "daily_limit_reached", "message": "Maximum 3 lines can be added per day via API"}| HTTP Status | Error | Description |
|---|---|---|
| 400 | - | Required request fields are missing or invalid |
| 401 | - | Invalid API credentials |
| 402 | no_card_on_file | No card is available for the account |
| 402 | billing_not_configured | Automatic line provisioning is enabled but billing setup is incomplete |
| 402 | billing_not_in_good_standing | Account has unpaid invoices that block provisioning |
| 402 | payment_failed | Provisioning charge was declined |
| 403 | not_eligible | Account is not eligible for this line management operation |
| 403 | line_minimum_reached | Deprovisioning would go below the account’s line minimum |
| 403 | - | Preview token belongs to another account |
| 404 | line_not_found | Phone number is not assigned to this account |
| 409 | operation_in_progress | Another line operation is currently running for the account |
| 409 | billing_not_operable | Billing setup exists but is ambiguous or cannot be safely changed automatically |
| 409 | billing_state_changed | Billing state changed since preview; request a new token |
| 409 | eligibility_changed | Account eligibility changed since preview; request a new token |
| 410 | token_expired | Token expired or was already used |
| 429 | daily_limit_reached | Daily line management limit reached |
| 429 | monthly_limit_reached | Monthly line management limit reached |
| 503 | no_lines_available | No lines are currently available for provisioning |
| 503 | deprovision_failed_retryable | The line could not be released and is still assigned; request a new token and retry |
| 500 | provisioning_failed | Line provisioning failed |
| 500 | provisioning_inconsistent | Line was assigned but billing could not be settled or recorded; contact support |
| 500 | deprovisioning_failed | Line deprovisioning failed |
| 500 | deprovision_inconsistent | Line was removed but billing could not be recorded; contact support |
- The account must be on an eligible
inbound_only/ Agent plan. - API deprovisioning requires automatic line provisioning to be enabled for the account.
- Provisioned lines are inbound-only lines.
- A card on file is required for provisioning; accounts without a card receive a 402.
- Deprovisioning is available during payment grace periods because it lowers the paid line quantity.
- Preview tokens are single-use. If confirm fails or the token expires, call preview again.
- All line management endpoints use standard API key and secret authentication.