---
title: "Create an SMS messaging profile"
canonical: "https://bird.com/docs/api/reference/create-sms-messaging-profile"
---

# Create an SMS messaging profile

`POST /v1/sms/messaging-profiles`

Creates a messaging profile for one program in your workspace.

A profile chooses the sender for each destination country, lists the numbers that receive replies, and sets defaults such as the category and smart encoding. Every sender and number must belong to your workspace, and a number can belong to one profile at a time. A send that names the profile in `messaging_profile_id` takes its sender, default category, and smart encoding from it when the send leaves them out. The values on a profile are defaults: an explicit `from`, `category`, or `options.smart_encoding` on the send wins.

## Servers

- `https://{region}.platform.bird.com`: Regional API endpoint. Use the host for the region your organization is hosted in. Official Bird SDKs and the CLI select it automatically from your API key, so you rarely need to set it by hand.
  - `region`: `us1`, `eu1`. Default: `us1`. The region your organization's data is hosted in.
- `https://platform.bird.com`: Region-independent endpoint for authentication and account administration.
- `http://localhost:8080`: Local development.

## Authentication

Use one authentication option:

- `BearerAuth`: HTTP bearer authentication. Pass the API key as a bearer token in the `Authorization` header. Workspace
keys use `bk_{region}_*`; organization master keys use `bm_{region}_*`.
The prefix identifies the region and selects the
API endpoint. Official Bird SDKs and the CLI derive the region from the key.

- `CookieAuth`: Send `bird_session` in cookie. Session cookie set after signing in to the Bird dashboard. The cookie
value is an opaque session token; no session data is stored in the cookie
itself.

## Code samples

**CLI**

```sh
bird sms messaging-profiles create --body-file - <<'JSON'
{
  "name": "device-activation",
  "senders": [
    {
      "country_code": "US",
      "sender_id": "snd_01krdgeqcxet5s7t44vh8rt9mg"
    }
  ],
  "inbound": {
    "numbers": [
      {
        "number": "+14155550100"
      }
    ]
  },
  "default_category": "authentication"
}
JSON
```

Examples: [CLI](/docs/api/reference/create-sms-messaging-profile.cli.md) · [MCP](/docs/api/reference/create-sms-messaging-profile.mcp.md) · [cURL](/docs/api/reference/create-sms-messaging-profile.curl.md)

## Example response `201`

```json
{
  "id": "mpr_01krdgeqcxet5s7t44vh8rt9mg",
  "name": "device-activation",
  "senders": [
    {
      "country_code": "US",
      "sender_id": "snd_01krdgeqcxet5s7t44vh8rt9mg"
    }
  ],
  "inbound": {
    "numbers": [
      {
        "country_code": "US",
        "number": "34001"
      }
    ],
    "callback_url": "https://receipts.example.com/bird/sms/inbound",
    "outbound_matching": {
      "enabled": false,
      "time_window": "1d"
    }
  },
  "default_category": "authentication",
  "validity_period": 3600,
  "cost_center": "CC001234",
  "options": {
    "smart_encoding": false,
    "ignore_suppression": false,
    "callback_url": "https://receipts.example.com/bird/sms/activation"
  },
  "callback_events": [
    "sms.delivered",
    "sms.failed"
  ]
}
```

## Header parameters

- `Idempotency-Key` (string, optional)

  Client-supplied key. On operations supporting request deduplication, a retained
  response is replayed for duplicate requests with the same key within the
  idempotency window (3 hours by default). This protection requires a workspace,
  organization, or staff-account scope. User-only and unscoped unauthenticated operations,
  streams, and operations with a separate replay contract do not use this
  response replay.

  On a supported operation, if idempotency protection is unavailable before execution, the API returns
  `503 IdempotencyUnavailable` (E01033) without executing this attempt. Retry with
  backoff using the same key and request. An operation that takes effect before
  its response is retained can still execute again on retry.

  Two distinct 409 errors signal misuse:

  - `request_in_progress` (E01004): The same key is currently being
    processed by a concurrent request. Wait briefly and retry. The lock expires within 30 seconds.
  - `idempotency_key_reuse` (E01005): The same key has already completed
    against a different request body or method. Generate a new key.

  Recommended key format is `<event-type>/<entity-id>` (for example `welcome-user/usr_abc123`).
- `X-Workspace-Id` (string, optional): Workspace context for the request. Required for dashboard authentication and master keys. Workspace keys and access tokens already identify their workspace; send that workspace or omit the header. A different one is rejected.
- `X-Organization-Id` (string, optional): Organization context for the request. Required for dashboard authentication. An API key or access token carries its own organization, so send either that organization or no header at all; a different one is rejected.

## Request body

- `name` (string, required): A label for the profile. Names are not unique, so two profiles can share one.
- `senders` (array of object): The sender for each destination country, and optionally a default sender. Each country appears at most once, and at most one entry omits `country_code`.
- `senders.country_code` (string): The destination country this sender is used for, as an uppercase ISO 3166-1 alpha-2 code. Omit it to make this the default sender, which is used for every destination country that has no entry of its own. A profile can have one entry per country and one default. An empty string is rejected rather than treated as the default.
- `senders.sender_id` (string, required): The sender to use, as returned by the list SMS senders operation.
- `inbound` (object): How the profile receives replies. Omit it for a profile that only sends.
- `inbound.numbers` (array of object): The numbers that receive replies for this profile.
- `inbound.numbers.country_code` (string): The country of a short code, as an uppercase ISO 3166-1 alpha-2 code. Required for a short code. Omit it for a number in E.164 format, which receives replies from subscribers in any country.
- `inbound.numbers.number` (string, required): A short code as digits, or a number in E.164 format. It must be a number your workspace holds that can receive SMS, and it can belong to one profile at a time.
- `inbound.callback_url` (string): The HTTPS URL that receives `sms.received` events for replies on this profile's numbers, signed with your workspace callback signing secret. Without it, replies use `options.callback_url`, then your webhook subscriptions. While a URL applies, a reply skips your plain webhook endpoints. It must be an absolute HTTPS URL of at most 2048 characters with a public host: an HTTP URL, a malformed one, or a private, loopback or link-local host returns `422`.
- `inbound.outbound_matching` (object): Settings for pairing each reply with the message it answers, reported as the reply's `in_reply_to_message`. Bird pairs only messages sent from one of this profile's reply numbers while matching is on. Turning it off stops pairing, and turning it back on resumes it for messages still inside their window.
- `inbound.outbound_matching.enabled` (boolean): Whether replies are paired with the messages they answer. A new profile defaults to `false`.
- `inbound.outbound_matching.time_window` (string)

  How long after a message is sent a reply can still be paired with it: one hour (`1h`), 24 hours (`1d`), or 168 hours (`7d`). `1d` is the default.

  Possible values: `1h`, `1d`, `7d`
- `default_category` (string)

  The category a free-text send that names this profile uses when it sets none: `transactional`, `marketing`, `authentication`, or `service`. A template send takes the template's category.

  Possible values: `transactional`, `marketing`, `authentication`, `service`
- `validity_period` (integer): How many seconds a message stays valid before it expires undelivered. A send that omits `validity_period` uses it.
- `cost_center` (string): A label for assigning the cost of this profile's messages. A send that omits `cost_center` uses it.
- `options` (object): Sending options for messages that do not set their own. Booleans default to `false`.
- `options.smart_encoding` (boolean): Whether text is converted to the GSM-7 character set where possible.
- `options.ignore_suppression` (boolean): Whether messages are sent even if the recipient is suppressed for the sender, including after replying STOP. Messages that do not set `ignore_suppression` use this value. Only `authentication` and `transactional` messages can skip suppressions. It cannot be `true` when `default_category` is `marketing` or `service`. Bird must enable it for your workspace; until then, messages that use it are refused.
- `options.callback_url` (string): The HTTPS URL that receives this profile's message events instead of your webhook endpoints. Messages that do not set `callback_url` use it, and so do replies on the profile's numbers that have no `inbound.callback_url`. Each event is a signed POST, signed with your workspace callback signing secret, which `rotateWebhookCallbackSigningSecret` creates and returns once. While a URL applies, a message's events skip your plain webhook endpoints. MCP Events subscriptions and connector endpoints still receive them. It must be an absolute HTTPS URL of at most 2048 characters with a public host: an HTTP URL, a malformed one, or a private, loopback or link-local host returns `422`.
- `callback_events` (array of string): The events of this profile's outbound messages that go to a callback URL. The list is fixed when a message is accepted, and applies only while the message has a callback URL: an event outside it then reaches neither the URL nor a plain webhook endpoint. Without a callback URL the list has no effect, and every event goes to your webhook endpoints. A value other than `sms.accepted`, `sms.sent`, `sms.delivered`, `sms.undelivered`, `sms.failed`, `sms.rejected` or `sms.expired` returns `422`. `sms.received` is never filtered. Omit it to deliver every event.

## Response body

- `id` (string, required): Identifier of this profile.
- `name` (string, required): A label for the profile. Names are not unique, so two profiles can share one.
- `senders` (array of object, required): The sender for each destination country, and the default sender when an entry has no `country_code`.
- `senders.country_code` (string): The destination country this sender is used for, as an uppercase ISO 3166-1 alpha-2 code. Omit it to make this the default sender, which is used for every destination country that has no entry of its own. A profile can have one entry per country and one default. An empty string is rejected rather than treated as the default.
- `senders.sender_id` (string, required): The sender to use, as returned by the list SMS senders operation.
- `inbound` (object, required): How the profile receives replies. A profile without numbers only sends.
- `inbound.numbers` (array of object, required): The numbers that receive replies for this profile.
- `inbound.numbers.country_code` (string): The country of a short code, as an uppercase ISO 3166-1 alpha-2 code. Required for a short code. Omit it for a number in E.164 format, which receives replies from subscribers in any country.
- `inbound.numbers.number` (string, required): A short code as digits, or a number in E.164 format. It must be a number your workspace holds that can receive SMS, and it can belong to one profile at a time.
- `inbound.callback_url` (nullable string, required): The HTTPS URL that receives `sms.received` events for replies on this profile's numbers, signed with your workspace callback signing secret. Null when none is set, in which case replies use `options.callback_url`, then your webhook subscriptions. While a URL applies, a reply skips your plain webhook endpoints.
- `inbound.outbound_matching` (object, required): Settings for pairing each reply with the message it answers, reported as the reply's `in_reply_to_message`. Bird pairs only messages sent from one of this profile's reply numbers while matching is on. Turning it off stops pairing, and turning it back on resumes it for messages still inside their window.
- `inbound.outbound_matching.enabled` (boolean, required): Whether replies are paired with the messages they answer.
- `inbound.outbound_matching.time_window` (string, required)

  How long after a message is sent a reply can still be paired with it: one hour (`1h`), 24 hours (`1d`), or 168 hours (`7d`). `1d` is the default.

  Possible values: `1h`, `1d`, `7d`
- `default_category` (nullable string, required): The category a free-text send that names this profile uses when it sets none: `transactional`, `marketing`, `authentication`, or `service`. A template send takes the template's category. Null when none is set.
- `validity_period` (nullable integer, required): How many seconds a message stays valid before it expires undelivered. Null when none is set. A send that omits `validity_period` uses it.
- `cost_center` (nullable string, required): A label for assigning the cost of this profile's messages. Null when none is set. A send that omits `cost_center` uses it.
- `options` (object, required): Sending options that messages from this profile use when a message does not set its own.
- `options.smart_encoding` (boolean, required): Whether text is converted to the GSM-7 character set where possible, to fit more characters in a segment.
- `options.ignore_suppression` (boolean, required): Whether messages are sent even if the recipient is suppressed for the sender, including after replying STOP. Messages that do not set `ignore_suppression` use this value. Only `authentication` and `transactional` messages can skip suppressions. It cannot be `true` while `default_category` is `marketing` or `service`. Bird must enable it for your workspace; until then, messages that use it are refused.
- `options.callback_url` (nullable string, required): The HTTPS URL that receives this profile's message events instead of your webhook endpoints. Null when none is set. Messages that do not set `callback_url` use it, and so do replies on the profile's numbers that have no `inbound.callback_url`. Each event is a signed POST, signed with your workspace callback signing secret, which `rotateWebhookCallbackSigningSecret` creates and returns once. While a URL applies, a message's events skip your plain webhook endpoints. MCP Events subscriptions and connector endpoints still receive them.
- `callback_events` (nullable array, required): The events of this profile's outbound messages that go to a callback URL: `sms.accepted`, `sms.sent`, `sms.delivered`, `sms.undelivered`, `sms.failed`, `sms.rejected`, and `sms.expired`. The list is fixed when a message is accepted, and applies only while the message has a callback URL: an event outside it then reaches neither the URL nor a plain webhook endpoint. Without a callback URL the list has no effect, and every event goes to your webhook endpoints. `sms.received` is never filtered. Null means every outbound event goes to the URL.
- `created_at` (string, required): When the profile was created.
- `updated_at` (string, required): When the profile was last changed.

## Related resources

- [Should I use a Bird SDK or call the API directly?](/explained/platform/should-i-use-an-sdk-or-call-the-api-directly) (answer)
- [Build your first integration](/learn/paths/integration) (course)
- [Send your first email](/docs/get-started/send-your-first-email) (docs)

[Get an implementation brief](/learn/workspace?topic=api-basics)
