---
title: Line Provisioning | Sendblue Docs
description: 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-line` and `GET /accounts/lines/line-request/:lineRequestTicketId` flows have been deprecated for direct line purchases. Use the preview and confirm endpoints below for API line provisioning.

## 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

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

Validate that the account is eligible and that a line is currently available.

```
POST /accounts/lines/provision-preview
```

#### Example Request

Terminal window

```
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)

```
{
  "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)

```
{
  "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

Consume the `preview_token`, charge the card on file, and provision the line.

```
POST /accounts/lines/provision-confirm
```

#### Request Body

| Parameter       | Type   | Required | Description                                                |
| --------------- | ------ | -------- | ---------------------------------------------------------- |
| `preview_token` | string | Yes      | Token returned by `POST /accounts/lines/provision-preview` |

#### Example Request

Terminal window

```
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)

```
{
  "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)

```
{
  "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

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

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-preview
```

#### Request Body

| Parameter      | Type   | Required | Description                                               |
| -------------- | ------ | -------- | --------------------------------------------------------- |
| `phone_number` | string | Yes      | Assigned Sendblue phone number to remove, in E.164 format |

#### Example Request

Terminal window

```
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)

```
{
  "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

Consume the `preview_token`, release the line, and lower the paid line quantity.

```
POST /accounts/lines/deprovision-confirm
```

#### Request Body

| Parameter       | Type   | Required | Description                                                  |
| --------------- | ------ | -------- | ------------------------------------------------------------ |
| `preview_token` | string | Yes      | Token returned by `POST /accounts/lines/deprovision-preview` |

#### Example Request

Terminal window

```
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)

```
{
  "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

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

```
{
  "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                 |

## Notes

- 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.
