> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pam.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SMS Conversations

> Start and manage outbound SMS conversations.

Use `POST /v1/sms-conversations` to create a single SMS conversation. PAM sends the first outbound SMS immediately, then continues the conversation through inbound replies, assistant turns, and optional tool calls.

## Create an SMS Conversation

```bash theme={null}
curl https://api.pamhq.com/v1/sms-conversations \
  -X POST \
  -H "Authorization: Bearer $PAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agentSlug": "sms-recall",
    "toNumber": "+15555550199",
    "fromNumber": "+15555550123",
    "welcomeMessage": "Hi Ada, this is PAM Motors following up on your service recall.",
    "dynamicVariables": {
      "contact_first_name": "Ada",
      "contact_last_name": "Lovelace",
      "dealership_name": "PAM Motors",
      "recall_id": "24V-123",
      "service_ids": "RECALL_SERVICE",
      "vin": "1HGBH41JXMN109186",
      "vehicle_year": "2021",
      "vehicle_make": "Honda",
      "vehicle_model": "Accord"
    },
    "metadata": {
      "externalContactId": "contact_123"
    },
    "externalReferenceId": "touchpoint_123",
    "idempotencyKey": "sms_01HV7K4ZD3Q9X8P1M8Y2K9A0BC",
    "webhookUrl": "https://partner.example.com/pam/webhooks"
  }'
```

Successful requests return `201 Created`:

```json theme={null}
{
  "data": {
    "id": "b7ee8d1b-5e3e-4a1a-8f0a-9e2a4f8f1aa2",
    "conversationId": "b7ee8d1b-5e3e-4a1a-8f0a-9e2a4f8f1aa2",
    "providerMessageId": "403d5977-fc3b-4b9f-9d7b-9f7bb0c9d8e1",
    "status": "in_progress"
  },
  "meta": {
    "requestId": "req_abc123"
  }
}
```

`in_progress` means the opening SMS was accepted by the provider and persisted by PAM.

## Request Fields

| Field                 | Required                                                         | Description                                                                                                                                                                                                                               |
| --------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `agentSlug`           | one of `agentSlug` or `agentId`                                  | Stable slug for a PAM-managed SMS agent, such as `sms-recall`, `sms-retention`, or `sms-declined-services`.                                                                                                                               |
| `agentId`             | one of `agentSlug` or `agentId`                                  | UUID of a specific SMS agent.                                                                                                                                                                                                             |
| `toNumber`            | yes                                                              | Customer phone number in E.164 format.                                                                                                                                                                                                    |
| `fromNumber`          | PAM-managed agents only                                          | Sender phone number in E.164 format. For custom agents with a configured number, PAM uses the agent's number.                                                                                                                             |
| `welcomeMessage`      | PAM-managed agents only                                          | Exact first SMS body sent to the customer.                                                                                                                                                                                                |
| `dynamicVariables`    | PAM-managed recall, retention, and declined-services agents only | Public string variables used to build the SMS agent context and tools. See [PAM Agents](/guides/agents) for the required variables for each managed agent.                                                                                |
| `metadata`            | no                                                               | Opaque reconciliation data stored with the conversation.                                                                                                                                                                                  |
| `externalReferenceId` | no                                                               | Opaque caller-owned reference echoed as top-level `externalReferenceId` on webhook events for this conversation. PAM does not interpret this value. It does not need to be globally unique and is not a replacement for `idempotencyKey`. |
| `idempotencyKey`      | no                                                               | Stable key for safely retrying this create request.                                                                                                                                                                                       |
| `webhookUrl`          | no                                                               | HTTPS URL that receives webhook events for this SMS conversation instead of the default webhook registration URL. Event subscriptions, custom headers, and signing secret still come from your matching webhook registration.             |

Your API key determines the client organization for attribution and billing. Do not send `clientOrgId` in the request body.

Use `externalReferenceId` when your system needs to map webhooks back to one of your own objects, such as a touchpoint, campaign, or workflow run. PAM stores the value and echoes it on webhooks when provided.

For PAM-managed agents, PAM generates internal prompt context blocks from the submitted `dynamicVariables` plus server-owned client configuration. Those generated context blocks are not returned by SMS conversation GET or list responses.

## Opening Message Rules

PAM-managed SMS agents require `welcomeMessage`. Build the message from your customer, dealership, and outreach context, then pass the resolved text in the create request.

Custom SMS agents can use their configured opening behavior. For those agents, PAM can generate the opening turn from the agent configuration and `dynamicVariables`.

## Supersede Behavior

Only one open SMS conversation should exist for the same `(fromNumber, toNumber)` pair. When you create a new SMS conversation for a pair that already has open conversations, PAM closes the older open conversations with:

```text theme={null}
superseded_by_new_conversation
```

Use the new `conversationId` returned by the create response for all future reconciliation.

## List Conversations

Use `GET /v1/sms-conversations` to list SMS conversations for your organization.

```bash theme={null}
curl "https://api.pamhq.com/v1/sms-conversations?limit=20" \
  -H "Authorization: Bearer $PAM_API_KEY"
```

You can filter by `status`, `agentId`, `toNumber`, `fromNumber`, `createdAfter`, and `createdBefore`.

Results are cursor-paginated:

```json theme={null}
{
  "data": [
    {
      "id": "b7ee8d1b-5e3e-4a1a-8f0a-9e2a4f8f1aa2",
      "conversationId": "b7ee8d1b-5e3e-4a1a-8f0a-9e2a4f8f1aa2",
      "status": "in_progress",
      "agentId": "2c4a1e72-7a5d-4b6e-9c2a-01a78b7b3f3f",
      "agentVersionId": "7a9c7b3e-8d0f-4c40-a156-dcc78c89b127",
      "fromNumber": "+15555550123",
      "toNumber": "+15555550199",
      "dynamicVariables": {
        "contact_first_name": "Ada",
        "contact_last_name": "Lovelace",
        "dealership_name": "PAM Motors",
        "recall_id": "24V-123"
      },
      "metadata": {
        "externalContactId": "contact_123"
      },
      "startedAt": "2026-04-10T14:00:00.000Z",
      "endedAt": null,
      "endReason": null,
      "createdAt": "2026-04-10T14:00:00.000Z",
      "updatedAt": "2026-04-10T14:00:00.000Z"
    }
  ],
  "meta": {
    "requestId": "req_abc123",
    "pagination": {
      "cursor": null,
      "hasMore": false
    }
  }
}
```

If `hasMore` is `true`, pass the returned `cursor` in the next request.

## Get Conversation Status

Use `GET /v1/sms-conversations/{id}` to get the current status for one SMS conversation.

```bash theme={null}
curl https://api.pamhq.com/v1/sms-conversations/b7ee8d1b-5e3e-4a1a-8f0a-9e2a4f8f1aa2 \
  -H "Authorization: Bearer $PAM_API_KEY"
```

```json theme={null}
{
  "data": {
    "id": "b7ee8d1b-5e3e-4a1a-8f0a-9e2a4f8f1aa2",
    "conversationId": "b7ee8d1b-5e3e-4a1a-8f0a-9e2a4f8f1aa2",
    "status": "completed",
    "agentId": "2c4a1e72-7a5d-4b6e-9c2a-01a78b7b3f3f",
    "agentVersionId": "7a9c7b3e-8d0f-4c40-a156-dcc78c89b127",
    "fromNumber": "+15555550123",
    "toNumber": "+15555550199",
    "dynamicVariables": {
      "contact_first_name": "Ada",
      "contact_last_name": "Lovelace",
      "dealership_name": "PAM Motors",
      "recall_id": "24V-123"
    },
    "metadata": {
      "externalContactId": "contact_123"
    },
    "startedAt": "2026-04-10T14:00:00.000Z",
    "endedAt": "2026-04-10T14:45:00.000Z",
    "endReason": "inactivity_timeout",
    "createdAt": "2026-04-10T14:00:00.000Z",
    "updatedAt": "2026-04-10T14:45:00.000Z"
  },
  "meta": {
    "requestId": "req_abc123"
  }
}
```

These read endpoints are useful when a webhook is delayed, retried, or missed by your system.

## Status Meanings

| Status        | Meaning                                                                                    |
| ------------- | ------------------------------------------------------------------------------------------ |
| `queued`      | PAM created the conversation, but the opening SMS has not completed provider dispatch yet. |
| `in_progress` | The opening SMS was accepted by the provider and the conversation is open.                 |
| `completed`   | The conversation ended normally. Check `endReason` for why it ended.                       |
| `failed`      | The conversation could not start or hit an unrecoverable error.                            |
| `cancelled`   | The conversation was cancelled before normal completion.                                   |

## Lifecycle Webhooks

Subscribe to these events to follow the conversation:

| Event                          | When it fires                                                                 |
| ------------------------------ | ----------------------------------------------------------------------------- |
| `sms.message_sent`             | An outbound SMS has been sent and persisted, including the opening message.   |
| `sms.message_received`         | An inbound SMS from the customer has been persisted.                          |
| `sms.message_delivery_updated` | The provider reported a canonical delivery status update for an outbound SMS. |
| `sms.tool_call_invocation`     | The assistant invoked a tool during the SMS loop.                             |
| `sms.tool_call_result`         | A tool result was persisted.                                                  |

Delivery updates are canonical PAM states, not raw provider events. A message can receive duplicate or out-of-order provider signals; PAM normalizes those before emitting `sms.message_delivery_updated`.

## Close a Conversation

Use `POST /v1/sms-conversations/{id}/close` to manually close an open SMS conversation.

```bash theme={null}
curl https://api.pamhq.com/v1/sms-conversations/b7ee8d1b-5e3e-4a1a-8f0a-9e2a4f8f1aa2/close \
  -X POST \
  -H "Authorization: Bearer $PAM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "customer_resolved"
  }'
```

If `reason` is omitted, PAM uses `admin_closed`.

## Common Errors

* `400 validation_error` — invalid phone format, invalid or non-HTTPS `webhookUrl`, both `agentId` and `agentSlug` were provided, or neither was provided.
* `400 validation_error` — `fromNumber` is missing for a PAM-managed agent.
* `400 validation_error` — `welcomeMessage` is missing or blank for a PAM-managed SMS agent.
* `400 validation_error` — a managed agent request is missing required `dynamicVariables`.
* `401 unauthorized` — missing, expired, revoked, or invalid API key.
* `404 not_found` — the agent could not be resolved or the conversation does not belong to the authenticated client.
