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

# Sending Messages

> Learn how to send WhatsApp messages via the API

# Sending Messages

TimelinesAI provides multiple ways to send WhatsApp messages depending on your use case.

## Sending methods

| Method          | Best for                          | Endpoint                         |
| --------------- | --------------------------------- | -------------------------------- |
| By phone number | New contacts, phone from your CRM | `POST /messages`                 |
| By chat ID      | Existing conversations            | `POST /chats/{chat_id}/messages` |
| By chat name    | When you know the contact name    | `POST /messages/to_chat_name`    |
| By JID          | Groups, technical integrations    | `POST /messages/to_jid`          |

## Send to phone number

The most common method. Works even if you haven't messaged this number before.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://app.timelines.ai/integrations/api/messages" \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "phone": "+14155551234",
      "text": "Hello! Thanks for your interest."
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://app.timelines.ai/integrations/api/messages', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      phone: '+14155551234',
      text: 'Hello! Thanks for your interest.'
    })
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://app.timelines.ai/integrations/api/messages',
      headers={
          'Authorization': 'Bearer YOUR_TOKEN',
          'Content-Type': 'application/json'
      },
      json={
          'phone': '+14155551234',
          'text': 'Hello! Thanks for your interest.'
      }
  )
  ```
</CodeGroup>

### Phone number format

Use international format with country code:

* ✅ `+14155551234`
* ✅ `14155551234`
* ❌ `(415) 555-1234`
* ❌ `415-555-1234`

## Send to existing chat

When you have a `chat_id` (from listing chats or webhook events):

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://app.timelines.ai/integrations/api/chats/123456/messages" \
    -H "Authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "text": "Following up on your question..."
    }'
  ```

  ```javascript JavaScript theme={null}
  const chatId = 123456;
  const response = await fetch(
    `https://app.timelines.ai/integrations/api/chats/${chatId}/messages`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        text: 'Following up on your question...'
      })
    }
  );
  ```
</CodeGroup>

## Choosing a WhatsApp account

If you have multiple WhatsApp numbers connected, specify which one to send from:

```json theme={null}
{
  "phone": "+14155551234",
  "text": "Hello!",
  "whatsapp_account_id": "15551234567@s.whatsapp.net"
}
```

<Info>
  If you don't specify `whatsapp_account_id`, the most recently connected account is used.
</Info>

## Message formatting

### Line breaks

Use `\n` for line breaks:

```json theme={null}
{
  "text": "Hello!\n\nHere's your summary:\n- Item 1\n- Item 2"
}
```

Renders as:

> Hello!
>
> Here's your summary:
>
> * Item 1
> * Item 2

### Emojis

Emojis are fully supported:

```json theme={null}
{
  "text": "Thanks for reaching out! 🎉 We'll get back to you soon. 👍"
}
```

## Auto-apply labels

Automatically label chats when sending messages:

```json theme={null}
{
  "phone": "+14155551234",
  "text": "Welcome to our service!",
  "label": "onboarding"
}
```

This is useful for tracking outreach campaigns or categorizing contacts as you message them.

## Tracking delivery

### Get message status

After sending, use the `message_uid` to track delivery:

```bash theme={null}
curl -X GET "https://app.timelines.ai/integrations/api/messages/{message_uid}" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Status values

| Status      | Meaning                                 |
| ----------- | --------------------------------------- |
| `queued`    | Message is waiting to be sent           |
| `sent`      | Message sent to WhatsApp servers        |
| `delivered` | Message delivered to recipient's device |
| `read`      | Recipient opened the message            |
| `failed`    | Message could not be sent               |

### Status history

Get the complete timeline:

```bash theme={null}
curl -X GET "https://app.timelines.ai/integrations/api/messages/{message_uid}/status_history" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

Response:

```json theme={null}
{
  "status": "ok",
  "data": [
    { "status": "queued", "timestamp": "2024-01-15T10:30:00Z" },
    { "status": "sent", "timestamp": "2024-01-15T10:30:02Z" },
    { "status": "delivered", "timestamp": "2024-01-15T10:30:05Z" },
    { "status": "read", "timestamp": "2024-01-15T10:32:15Z" }
  ]
}
```

## Rate limits

Messages are sent with a \~2 second delay between each to avoid WhatsApp spam detection.

<Warning>
  Sending too many messages too quickly may result in WhatsApp flagging your number. Always respect rate limits.
</Warning>

If you have high-volume needs, [contact support](mailto:support@timelines.ai) to discuss Business plan options.

## Credits usage

| Message type      | Credits |
| ----------------- | ------- |
| Text only         | 1       |
| Text + attachment | 2       |
| Failed (refunded) | 0       |

## Common errors

<AccordionGroup>
  <Accordion icon="phone-slash" title="Invalid phone number">
    ```json theme={null}
    { "status": "error", "message": "Invalid phone number format" }
    ```

    **Solution:** Use international format with country code (e.g., `+14155551234`)
  </Accordion>

  <Accordion icon="link-slash" title="WhatsApp account not connected">
    ```json theme={null}
    { "status": "error", "message": "No connected WhatsApp account" }
    ```

    **Solution:** Ensure at least one WhatsApp account is connected in your workspace
  </Accordion>

  <Accordion icon="ban" title="Insufficient quota">
    ```json theme={null}
    { "status": "error", "message": "Message quota exceeded" }
    ```

    **Solution:** Upgrade your plan or wait for quota to reset
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card icon="paperclip" href="/guides/file-attachments" title="Send attachments">
    Learn to send images and files
  </Card>

  <Card icon="webhook" href="/guides/webhooks" title="Set up webhooks">
    Get notified when messages arrive
  </Card>
</CardGroup>
