> For the complete documentation index, see [llms.txt](https://developers.mobile-text-alerts.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.mobile-text-alerts.com/manage-dedicated-number-pools-via-api.md).

# Manage Dedicated Number Pools via API

Learn how to create, register, configure, and manage Dedicated Number Pools with the Mobile Text Alerts API

This guide walks through the full lifecycle of a Dedicated Number Pool with the Mobile Text Alerts API: submitting a new pool for registration, waiting for brand and campaign review, adding numbers and sending once the pool is approved, and managing the pool over time. It uses several endpoints together in a single worked example.

A Dedicated Number Pool is a group of dedicated [10DLC](https://developers.mobile-text-alerts.com/messaging-routes/10dlc) numbers that share a single registered brand and campaign and are managed as one unit. Each pool carries its own brand and campaign registration, independent of your account's own [brand registration](https://developers.mobile-text-alerts.com/api-reference/brand-registration), and an account can have as many pools as it needs.

Pools also give you pool-wide sending behavior that would otherwise need to be configured on every send:

* **Sticky sender:** The first time a subscriber receives a message through the pool, Mobile Text Alerts remembers which pool number sent it. That number "sticks" to the subscriber and is used for all future sends to them through the pool, so each subscriber sees a consistent sending number.
* **Gated sending:** Enable gated sending for every message sent through the pool, rather than specifying it on each individual send.

{% hint style="info" %}
This page covers how the Dedicated Number Pool endpoints work together. See the [Dedicated Number Pools](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) API reference for complete endpoint, field, and response details.
{% endhint %}

## Dedicated Number Pool lifecycle overview

The following is the typical lifecycle of a Dedicated Number Pool:

Submit the pool for registration <i class="fa-arrow-right">:arrow-right:</i> Brand and campaign review (1–3 business days) <i class="fa-arrow-right">:arrow-right:</i> Add numbers to the active pool <i class="fa-arrow-right">:arrow-right:</i> Send messages through the pool <i class="fa-arrow-right">:arrow-right:</i> Manage the pool over time

**Implementation steps:**

{% stepper %}
{% step %}

## Submit the pool for registration

You submit a new pool with its brand, campaign, and pool configuration in a single request.
{% endstep %}

{% step %}

## Wait for review

The pool enters the `in_review` status while its brand and campaign are reviewed.
{% endstep %}

{% step %}

## Poll for approval

You poll the pool's status until it becomes `active`.
{% endstep %}

{% step %}

## Add numbers

You add dedicated numbers to the pool, optionally by area code.
{% endstep %}

{% step %}

## Send messages

You send messages through the pool by including its `poolId` on [`POST /send`](https://developers.mobile-text-alerts.com/api-reference/send#post-send) requests.
{% endstep %}

{% step %}

## Manage the pool

You update pool details, remove numbers, or deactivate the pool as your needs change.
{% endstep %}
{% endstepper %}

```mermaid
sequenceDiagram
    participant App as Your Application
    participant MTA as Mobile Text Alerts

    App->>MTA: POST /dedicated-numbers/dedicated-number-pools (brand, campaign, pool)
    MTA-->>App: Pool created (id, status: in_review, editable: true)
    Note over MTA: Brand and campaign review (1–3 business days)
    loop Hourly, until status is active
        App->>MTA: GET /dedicated-numbers/dedicated-number-pools/{poolId}
        MTA-->>App: status, editable
    end
    App->>MTA: POST /dedicated-numbers/dedicated-number-pools/{poolId}/number/{areaCode}
    MTA-->>App: phoneNumber
    App->>MTA: POST /send (poolId, recipients, message)
    MTA-->>App: messageId
```

### Pool statuses

Every pool returns a `status` field with one of the following values:

| Status      | Meaning                                                 | What you can do                                                                                   |
| ----------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `in_review` | The pool's brand and campaign are being reviewed.       | Update the pool `name` and `settings`. Update brand and campaign data while `editable` is `true`. |
| `active`    | The pool is approved and ready for use.                 | Add and remove numbers, send messages, update the pool `name` and `settings`.                     |
| `inactive`  | The pool has been deactivated and its numbers released. | Nothing. Contact your Account Manager to discuss reactivation.                                    |

### Prerequisites

Before working with Dedicated Number Pools you need to have:

* Completed the steps in [Getting Started](https://developers.mobile-text-alerts.com/getting-started/get-an-api-key) and have a valid API key.
* Complete brand information for the business the pool will send on behalf of, including its Tax ID / EIN. See **Gather brand information** below for the full list.
* A live, publicly accessible opt-in page served over HTTPS that shows how recipients consent to receive messages from this brand.
* *(Optional)* A webhook endpoint, if you want to receive events for this pool separately from the rest of your account. See **Route pool events to a webhook** below.

## Store pool data

Mobile Text Alerts holds the pool's registration and numbers, but you will need a few values from the API in your own system. At minimum, keep the following for each pool:

| Field      | Purpose                                                                                                                                                  |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `poolId`   | The pool's `id`, returned when the pool is created. Required for every other pool request, for sending through the pool, and for pool-specific webhooks. |
| `status`   | The pool's last known status, used to decide when to stop polling and start adding numbers.                                                              |
| `editable` | Whether the pool's brand and campaign data can still be updated through the API.                                                                         |
| `campaign` | The ID of the campaign assigned to the pool once registration is complete. Useful when referencing the pool's registration with your Account Manager.    |

{% hint style="info" %}
Pool IDs are strings (for example, `7d28a848-9234-4647-84a2-96b2c2ff36f6`), unlike most other IDs in the Mobile Text Alerts API, which are numbers.
{% endhint %}

## Submit a new pool for registration

A new pool is created with a single [`POST /dedicated-numbers/dedicated-number-pools`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) request. The request body contains three objects:

* `brand` - The business identity this pool's messages are sent on behalf of.
* `campaign` - The type of messaging this pool will send, and where recipients opt in.
* `pool` - The pool's name and sending settings.

{% stepper %}
{% step %}

## Gather brand information

The `brand` object describes the business this pool configuration is registered for. All brand fields are reviewed during registration, so provide accurate, complete information that matches the business's official records.

| Field                      | Type     | Description                                                                                                                                                                                                                           |
| -------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `entityType` *(required)*  | `string` | The type of legal entity: `PRIVATE_PROFIT`, `PUBLIC_PROFIT`, `NON_PROFIT`, or `GOVERNMENT`.                                                                                                                                           |
| `companyName` *(required)* | `string` | The business's legal name.                                                                                                                                                                                                            |
| `displayName` *(required)* | `string` | The business's DBA ("doing business as") name, as recipients will know it.                                                                                                                                                            |
| `ein` *(required)*         | `string` | The business's Tax ID / EIN.                                                                                                                                                                                                          |
| `street` *(required)*      | `string` | Street address of the business.                                                                                                                                                                                                       |
| `city` *(required)*        | `string` | City.                                                                                                                                                                                                                                 |
| `state` *(required)*       | `string` | State.                                                                                                                                                                                                                                |
| `postalCode` *(required)*  | `string` | ZIP code.                                                                                                                                                                                                                             |
| `country` *(required)*     | `string` | Two-letter ISO country code (for example, `US`).                                                                                                                                                                                      |
| `phone` *(required)*       | `string` | The business's phone number. E.164 format is recommended, see [Phone Number Format Guide](https://developers.mobile-text-alerts.com/tutorials/phone-number-format-guide).                                                             |
| `email` *(required)*       | `string` | A contact email address for the business.                                                                                                                                                                                             |
| `website` *(required)*     | `string` | The business's website URL.                                                                                                                                                                                                           |
| `vertical` *(required)*    | `string` | The business's industry. See the [Dedicated Number Pools](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) API reference for the full list of values, such as `HEALTHCARE`, `RETAIL`, or `TECHNOLOGY`. |
| `stockSymbol`              | `string` | Stock ticker symbol. Provide for `PUBLIC_PROFIT` entities.                                                                                                                                                                            |
| `stockExchange`            | `string` | Exchange the stock is listed on, such as `NASDAQ` or `NYSE`. Provide for `PUBLIC_PROFIT` entities.                                                                                                                                    |
| `businessContactEmail`     | `string` | An additional business contact email address.                                                                                                                                                                                         |
| {% endstep %}              |          |                                                                                                                                                                                                                                       |

{% step %}

## Choose a campaign use case

The `campaign` object describes how the pool's numbers will be used.

| Field                   | Type     | Description                                                                                                                     |
| ----------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `usecase` *(required)*  | `string` | The primary type of messaging this pool will send.                                                                              |
| `optInUrl` *(required)* | `string` | The URL of the page where recipients opt in to receive messages from this brand. Must be a live, publicly accessible HTTPS URL. |

Supported `usecase` values:

`2FA`, `ACCOUNT_NOTIFICATION`, `CHARITY`, `CUSTOMER_CARE`, `DELIVERY_NOTIFICATION`, `HIGHER_EDUCATION`, `LOW_VOLUME`, `M2M`, `MARKETING`, `MIXED`, `POLITICAL`, `POLLING_VOTING`, `SECURITY_ALERT`

{% hint style="warning" %}
Choose the use case that accurately reflects the messages the pool will send. Messages sent through the pool should stay within the registered use case. Your Account Manager can help you confirm the right use case before you submit.
{% endhint %}
{% endstep %}

{% step %}

## Configure the pool

The `pool` object sets the pool's name and its pool-wide sending behavior.

| Field                                   | Type      | Description                                                                                                                                                   |
| --------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name` *(required)*                     | `string`  | A name for the pool, for your own reference.                                                                                                                  |
| `settings.useStickySender` *(required)* | `boolean` | If `true`, each subscriber is always sent messages from the same pool number after their first send through the pool.                                         |
| `settings.gated_send_method`            | `string`  | Enables gated sending for every message sent through the pool. One of `age`, `otp`, `age_and_otp`, or `link_expires`. Omit to send without gating by default. |
| {% endstep %}                           |           |                                                                                                                                                               |

{% step %}

## Send the request

Combine the three objects into a request to [`POST /dedicated-numbers/dedicated-number-pools`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools). Remember to include the [Authorization](https://developers.mobile-text-alerts.com/getting-started/get-an-api-key#bearer-token-authentication) header.

{% tabs %}
{% tab title="cURL" %}

```bash
curl --location 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools' \
  --header 'Authorization: Bearer <APIKey>' \
  --header 'Content-Type: application/json' \
  --data '{
    "brand": {
      "entityType": "PRIVATE_PROFIT",
      "companyName": "Riverside Dental Group LLC",
      "displayName": "Riverside Dental",
      "ein": "12-3456789",
      "street": "100 Main Street",
      "city": "Indianapolis",
      "state": "IN",
      "postalCode": "46204",
      "country": "US",
      "phone": "+13175551111",
      "email": "office@riversidedental.example.com",
      "website": "https://riversidedental.example.com",
      "vertical": "HEALTHCARE"
    },
    "campaign": {
      "usecase": "CUSTOMER_CARE",
      "optInUrl": "https://riversidedental.example.com/text-alerts"
    },
    "pool": {
      "name": "Riverside Dental Reminders",
      "settings": {
        "useStickySender": true
      }
    }
  }'
```

{% endtab %}

{% tab title="Node.js" %}
Requirements: Node.js `18+` (native `fetch`) and an `MTA_API_KEY` environment variable.

```js
async function createPool() {
  const response = await fetch(
    'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools',
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.MTA_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        brand: {
          entityType: 'PRIVATE_PROFIT',
          companyName: 'Riverside Dental Group LLC',
          displayName: 'Riverside Dental',
          ein: '12-3456789',
          street: '100 Main Street',
          city: 'Indianapolis',
          state: 'IN',
          postalCode: '46204',
          country: 'US',
          phone: '+13175551111',
          email: 'office@riversidedental.example.com',
          website: 'https://riversidedental.example.com',
          vertical: 'HEALTHCARE'
        },
        campaign: {
          usecase: 'CUSTOMER_CARE',
          optInUrl: 'https://riversidedental.example.com/text-alerts'
        },
        pool: {
          name: 'Riverside Dental Reminders',
          settings: { useStickySender: true }
        }
      })
    }
  );

  const { data } = await response.json();
  // Persist data.id as this pool's poolId
  console.log('Pool created:', data.id, data.status);
}

createPool();
```

{% endtab %}

{% tab title="Python" %}
Requirements: `pip install requests` and an `MTA_API_KEY` environment variable.

```python
import os
import requests

response = requests.post(
    "https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools",
    headers={"Authorization": f"Bearer {os.environ['MTA_API_KEY']}"},
    json={
        "brand": {
            "entityType": "PRIVATE_PROFIT",
            "companyName": "Riverside Dental Group LLC",
            "displayName": "Riverside Dental",
            "ein": "12-3456789",
            "street": "100 Main Street",
            "city": "Indianapolis",
            "state": "IN",
            "postalCode": "46204",
            "country": "US",
            "phone": "+13175551111",
            "email": "office@riversidedental.example.com",
            "website": "https://riversidedental.example.com",
            "vertical": "HEALTHCARE",
        },
        "campaign": {
            "usecase": "CUSTOMER_CARE",
            "optInUrl": "https://riversidedental.example.com/text-alerts",
        },
        "pool": {
            "name": "Riverside Dental Reminders",
            "settings": {"useStickySender": True},
        },
    },
)

data = response.json()["data"]
# Persist data["id"] as this pool's poolId
print("Pool created:", data["id"], data["status"])
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

## Store the pool ID

The response contains the new pool. Store its `id` as the `poolId`, you will need it for every remaining step.

```json
{
  "data": {
    "id": "7d28a848-9234-4647-84a2-96b2c2ff36f6",
    "name": "Riverside Dental Reminders",
    "settings": {
      "useStickySender": true
    },
    "brand": "Riverside Dental Group LLC",
    "status": "in_review",
    "numbers": [],
    "editable": true
  }
}
```

New pools always start with a `status` of `in_review` and no numbers.
{% endstep %}
{% endstepper %}

## Wait for brand and campaign review

After submission, the pool's brand and campaign are reviewed for registration. This typically takes **1–3 business days**. The pool stays in the `in_review` status for the duration of the review, and its status changes to `active` once the pool is approved.

{% hint style="warning" %}
While a pool is `in_review` you cannot add numbers to it, send messages through it, or deactivate it.
{% endhint %}

### Check the review status

There is no webhook event for pool status changes. To find out when a pool is approved, retrieve the pool with [`GET /dedicated-numbers/dedicated-number-pools/{poolId}`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) and check its `status`.

Because review takes 1–3 business days, poll no more than **once per hour**. More frequent polling will not speed up review and counts against your account's [rate limits](https://developers.mobile-text-alerts.com/api-basics/rate-limits).

{% tabs %}
{% tab title="cURL" %}

```bash
curl --location 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/7d28a848-9234-4647-84a2-96b2c2ff36f6' \
  --header 'Authorization: Bearer <APIKey>'
```

{% endtab %}

{% tab title="Node.js" %}

```js
const POOL_ID = '7d28a848-9234-4647-84a2-96b2c2ff36f6';
const ONE_HOUR = 60 * 60 * 1000;

async function checkPoolStatus() {
  const response = await fetch(
    `https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/${POOL_ID}`,
    { headers: { 'Authorization': `Bearer ${process.env.MTA_API_KEY}` } }
  );
  const { data } = await response.json();

  if (data.status === 'active') {
    console.log('Pool approved. Campaign ID:', data.campaign);
    // Continue to "Set up the pool for sending"
    return;
  }

  console.log(`Pool is ${data.status} (editable: ${data.editable}). Checking again in 1 hour.`);
  setTimeout(checkPoolStatus, ONE_HOUR);
}

checkPoolStatus();
```

{% endtab %}

{% tab title="Python" %}

```python
import os
import time
import requests

POOL_ID = "7d28a848-9234-4647-84a2-96b2c2ff36f6"
ONE_HOUR = 60 * 60

while True:
    response = requests.get(
        f"https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/{POOL_ID}",
        headers={"Authorization": f"Bearer {os.environ['MTA_API_KEY']}"},
    )
    data = response.json()["data"]

    if data["status"] == "active":
        print("Pool approved. Campaign ID:", data["campaign"])
        # Continue to "Set up the pool for sending"
        break

    print(f"Pool is {data['status']} (editable: {data['editable']}). Checking again in 1 hour.")
    time.sleep(ONE_HOUR)
```

{% endtab %}
{% endtabs %}

In production, run this check from a scheduled job (for example, an hourly cron task across all of your `in_review` pools) rather than a long-running process.

### Response fields during review

| Field      | Description                                                                                                                                                                            |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`   | `in_review` until the pool is approved, then `active`.                                                                                                                                 |
| `editable` | `true` while the pool's brand and campaign data can still be updated through the API. Once `editable` is `false`, the brand and campaign data are locked and can no longer be changed. |
| `brand`    | The `companyName` submitted for the pool's brand.                                                                                                                                      |
| `campaign` | The ID of the campaign assigned to the pool, once one has been assigned.                                                                                                               |
| `data`     | The brand, campaign, and pool information submitted for registration. Only populated while the pool is `in_review`.                                                                    |

### Correct brand or campaign information

If you need to correct brand or campaign information after submitting, and the pool's `editable` value is `true`, send the corrected information in the `data` field of [`PATCH /dedicated-numbers/dedicated-number-pools/{poolId}`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools). The `data` field uses the same `brand`, `campaign`, and `pool` structure as the create request.

{% hint style="warning" %}
**`data` is a full overwrite**

The `data` field replaces the pool's entire registration submission. Always include the complete `brand`, `campaign`, and `pool` objects, not only the fields you are changing. Any field you leave out is removed from the submission. You can retrieve the current submission from the `data` field of [`GET /dedicated-numbers/dedicated-number-pools/{poolId}`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) while the pool is `in_review`, make your corrections, and send it back.
{% endhint %}

{% tabs %}
{% tab title="cURL" %}

```bash
curl --location --request PATCH 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/7d28a848-9234-4647-84a2-96b2c2ff36f6' \
  --header 'Authorization: Bearer <APIKey>' \
  --header 'Content-Type: application/json' \
  --data '{
    "data": {
      "brand": {
        "entityType": "PRIVATE_PROFIT",
        "companyName": "Riverside Dental Group LLC",
        "displayName": "Riverside Dental",
        "ein": "12-3456789",
        "street": "100 Main Street, Suite 200",
        "city": "Indianapolis",
        "state": "IN",
        "postalCode": "46204",
        "country": "US",
        "phone": "+13175551111",
        "email": "office@riversidedental.example.com",
        "website": "https://riversidedental.example.com",
        "vertical": "HEALTHCARE"
      },
      "campaign": {
        "usecase": "CUSTOMER_CARE",
        "optInUrl": "https://riversidedental.example.com/text-alerts"
      },
      "pool": {
        "name": "Riverside Dental Reminders",
        "settings": { "useStickySender": true }
      }
    }
  }'
```

{% endtab %}

{% tab title="Node.js" %}

```js
// correctedSubmission has the same brand / campaign / pool structure as the create request
await fetch(
  `https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/${poolId}`,
  {
    method: 'PATCH',
    headers: {
      'Authorization': `Bearer ${process.env.MTA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ data: correctedSubmission })
  }
);
```

{% endtab %}

{% tab title="Python" %}

```python
# corrected_submission has the same brand / campaign / pool structure as the create request
requests.patch(
    f"https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/{pool_id}",
    headers={"Authorization": f"Bearer {os.environ['MTA_API_KEY']}"},
    json={"data": corrected_submission},
)
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Updating brand or campaign data does not restart the review timeline. If `editable` is `false` and the pool's registration information needs to change, contact your Account Manager.
{% endhint %}

A pool may remain `in_review` for longer than 3 business days if its registration needs additional attention. Your Account Manager will reach out directly if anything is needed from you.

## Set up the pool for sending

Once the pool's `status` is `active`, add numbers to it and start sending.

### Add numbers to the pool

Numbers are added to a pool one at a time. Each request adds a single new dedicated 10DLC number to the pool and returns that number. There are two ways to add a number:

| Endpoint                                                                                                                                                      | Use when                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| [`POST /dedicated-numbers/dedicated-number-pools/{poolId}/number`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools)            | Any available number will do.                                                                |
| [`POST /dedicated-numbers/dedicated-number-pools/{poolId}/number/{areaCode}`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) | You want a number with a specific area code, for example to match the business's local area. |

Neither request takes a request body. Repeat the request once for each number you want in the pool.

{% tabs %}
{% tab title="cURL" %}

```bash
# Add a number with the 317 area code
curl --location --request POST 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/7d28a848-9234-4647-84a2-96b2c2ff36f6/number/317' \
  --header 'Authorization: Bearer <APIKey>'
```

{% endtab %}

{% tab title="Node.js" %}

```js
async function addNumbers(poolId, areaCode, count) {
  const added = [];

  for (let i = 0; i < count; i++) {
    const response = await fetch(
      `https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/${poolId}/number/${areaCode}`,
      {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${process.env.MTA_API_KEY}` }
      }
    );

    if (!response.ok) {
      const error = await response.json();
      console.error(`Could not add a ${areaCode} number:`, error.message);
      break; // e.g. no remaining numbers available in this area code
    }

    const { data } = await response.json();
    added.push(data.phoneNumber);
  }

  return added;
}

const numbers = await addNumbers('7d28a848-9234-4647-84a2-96b2c2ff36f6', '317', 3);
console.log('Added:', numbers);
```

{% endtab %}

{% tab title="Python" %}

```python
import os
import requests

def add_numbers(pool_id: str, area_code: str, count: int) -> list[str]:
    added = []
    for _ in range(count):
        response = requests.post(
            f"https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/{pool_id}/number/{area_code}",
            headers={"Authorization": f"Bearer {os.environ['MTA_API_KEY']}"},
        )
        if not response.ok:
            print(f"Could not add a {area_code} number:", response.json().get("message"))
            break  # e.g. no remaining numbers available in this area code
        added.append(response.json()["data"]["phoneNumber"])
    return added

numbers = add_numbers("7d28a848-9234-4647-84a2-96b2c2ff36f6", "317", 3)
print("Added:", numbers)
```

{% endtab %}
{% endtabs %}

**Example Response**

```json
{
  "data": {
    "phoneNumber": "+13175550142"
  }
}
```

{% hint style="warning" %}
**Area code availability**

If no numbers are available in the requested area code, the request returns an error and no number is added. Try a nearby area code, or add a number without an area code using `POST .../{poolId}/number`.
{% endhint %}

### Verify the pool's numbers

To confirm which numbers are in a pool, call [`GET /dedicated-numbers/dedicated-number-pools/{poolId}/numbers`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools). The response is paginated, see [Pagination of Large Results](https://developers.mobile-text-alerts.com/api-basics/pagination-of-large-results).

```bash
curl --location 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/7d28a848-9234-4647-84a2-96b2c2ff36f6/numbers' \
  --header 'Authorization: Bearer <APIKey>'
```

**Example Response**

```json
{
  "data": {
    "rows": [13175550142, 13175550187, 13175550203],
    "page": 0,
    "pageSize": 25,
    "total": 3
  }
}
```

### Route pool events to a webhook

By default, events for messages sent through a pool are delivered to your account's global webhooks. To route a pool's events to a different endpoint, register a webhook with the pool's `poolId`:

```bash
curl --location --request POST 'https://api.mobile-text-alerts.com/v3/webhooks' \
  --header 'Authorization: Bearer <APIKey>' \
  --header 'Content-Type: application/json' \
  --data '{
    "event": "message-reply",
    "url": "https://www.example.com/hooks/riverside-dental",
    "secret": "abc123-abc2-cde1-1234-xyz123456",
    "poolId": "7d28a848-9234-4647-84a2-96b2c2ff36f6"
  }'
```

When a pool-specific webhook exists for an event, that event is delivered only to the pool-specific webhook. Events with no matching pool-specific webhook fall back to your global webhook for that event type. Register one webhook per event type you want to route for the pool.

See [Configuring Webhooks for Dedicated Number Pools](https://developers.mobile-text-alerts.com/api-reference/webhooks#configuring-webhooks-for-dedicated-number-pools) for full details.

### Send messages through the pool

To send through a pool, include its `poolId` on a [`POST /send`](https://developers.mobile-text-alerts.com/api-reference/send#post-send) request. The message is delivered to the specified recipients using numbers from that pool, applying the pool's sticky sender and gated sending settings. All other `/send` fields work as described in [Send a Message](https://developers.mobile-text-alerts.com/getting-started/send-a-message).

{% tabs %}
{% tab title="cURL" %}

```bash
curl --location 'https://api.mobile-text-alerts.com/v3/send' \
  --header 'Authorization: Bearer <APIKey>' \
  --header 'Content-Type: application/json' \
  --data '{
    "poolId": "7d28a848-9234-4647-84a2-96b2c2ff36f6",
    "subscribers": ["+13175551111"],
    "message": "Riverside Dental: Your cleaning is tomorrow at 2:30 PM. Reply C to confirm. STOP to end"
  }'
```

{% endtab %}

{% tab title="Node.js" %}

```js
const response = await fetch('https://api.mobile-text-alerts.com/v3/send', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.MTA_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    poolId: '7d28a848-9234-4647-84a2-96b2c2ff36f6',
    subscribers: ['+13175551111'],
    message: 'Riverside Dental: Your cleaning is tomorrow at 2:30 PM. Reply C to confirm. STOP to end'
  })
});

const { data } = await response.json();
console.log('Message ID:', data.messageId);
```

{% endtab %}

{% tab title="Python" %}

```python
response = requests.post(
    "https://api.mobile-text-alerts.com/v3/send",
    headers={"Authorization": f"Bearer {os.environ['MTA_API_KEY']}"},
    json={
        "poolId": "7d28a848-9234-4647-84a2-96b2c2ff36f6",
        "subscribers": ["+13175551111"],
        "message": "Riverside Dental: Your cleaning is tomorrow at 2:30 PM. Reply C to confirm. STOP to end",
    },
)
print("Message ID:", response.json()["data"]["messageId"])
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Delivery Status**

A successful `200` response from the Send Message endpoint does not indicate the message has been delivered. [Learn more about checking the delivery status of messages.](https://developers.mobile-text-alerts.com/check-delivery-status)
{% endhint %}

## Manage a pool

### List pools

[`GET /dedicated-numbers/dedicated-number-pools`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) returns every pool on your account with its current status. The response is paginated, and the `query` parameter can be used to search pools by name.

```bash
curl --location 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools?query=Riverside' \
  --header 'Authorization: Bearer <APIKey>'
```

### Update pool details

Use [`PATCH /dedicated-numbers/dedicated-number-pools/{poolId}`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) to change a pool's `name` or `settings` at any time while the pool is `in_review` or `active`. Only the fields included in the request are changed.

```bash
curl --location --request PATCH 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/7d28a848-9234-4647-84a2-96b2c2ff36f6' \
  --header 'Authorization: Bearer <APIKey>' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Riverside Dental - All Locations",
    "settings": {
      "useStickySender": true,
      "gated_send_method": "link_expires"
    }
  }'
```

Changes to `settings` apply to messages sent through the pool after the update. To change brand or campaign information, see **Correct brand or campaign information** above.

### Remove a number from a pool

Use [`DELETE /dedicated-numbers/dedicated-number-pools/{poolId}/number/{phoneNumber}`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) to remove a single number. The `phoneNumber` path parameter accepts the number with or without the leading `+`. If you include the `+`, URL-encode it as `%2B`. See the [Phone Number Format Guide](https://developers.mobile-text-alerts.com/tutorials/phone-number-format-guide) for more on number formats.

```bash
curl --location --request DELETE 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/7d28a848-9234-4647-84a2-96b2c2ff36f6/number/13175550142' \
  --header 'Authorization: Bearer <APIKey>'
```

{% hint style="danger" %}
**Removed numbers are released**

A removed number is released entirely. It does not return to your account and cannot be added back to the pool. If sticky sender is enabled, subscribers who were assigned the removed number are assigned a different pool number on their next send.
{% endhint %}

### Deactivate a pool

Use [`DELETE /dedicated-numbers/dedicated-number-pools/{poolId}`](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) to deactivate a pool you no longer need. Pools can only be deactivated once they are `active`.

```bash
curl --location --request DELETE 'https://api.mobile-text-alerts.com/v3/dedicated-numbers/dedicated-number-pools/7d28a848-9234-4647-84a2-96b2c2ff36f6' \
  --header 'Authorization: Bearer <APIKey>'
```

{% hint style="danger" %}
**Deactivation releases every number in the pool**

When a pool is deactivated, its status changes to `inactive` and all of its numbers are released. An inactive pool cannot be used to send messages, and it cannot be reactivated through the API. Reactivating a pool generally requires a new brand and campaign submission. Contact your Account Manager if you need to reactivate a pool.
{% endhint %}

## Learn More

* [Dedicated Number Pools](https://developers.mobile-text-alerts.com/api-reference/dedicated-number-pools) — full API reference for the Dedicated Number Pool endpoints.
* [10DLC](https://developers.mobile-text-alerts.com/messaging-routes/10dlc) — background on 10DLC numbers and registration.
* [Send a Message](https://developers.mobile-text-alerts.com/getting-started/send-a-message) — the complete set of `/send` request fields.
* [Webhooks](https://developers.mobile-text-alerts.com/api-reference/webhooks#configuring-webhooks-for-dedicated-number-pools) — registering pool-specific webhooks.
* [Phone Number Format Guide](https://developers.mobile-text-alerts.com/tutorials/phone-number-format-guide) — formatting phone numbers for requests.
* [Pagination of Large Results](https://developers.mobile-text-alerts.com/api-basics/pagination-of-large-results) — iterating through list endpoints.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://developers.mobile-text-alerts.com/manage-dedicated-number-pools-via-api.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
