# Messages

| Method | Path | What it does |
| --- | --- | --- |
| POST | `/v1/messages` | Send a text or an MMS |
| GET | `/v1/messages` | Text and WhatsApp history |
| GET | `/v1/messages/queue` | What an API Messaging key has waiting, and what is left of today |
| DELETE | `/v1/messages/queue` | Cancel everything still waiting |
| DELETE | `/v1/messages/queue/{id}` | Cancel one waiting message |
| GET | `/v1/reports/messages` | The old name for `GET /v1/messages`. It still answers |

## Send: POST /v1/messages

| Field | Meaning |
| --- | --- |
| `platform` | `text`. `whatsapp` answers `422`. |
| `from` | A texting number on your account |
| `to` | A 10-digit US or Canadian number |
| `message` | Up to 1,600 characters |
| `media` | Up to 10 `https` links, for an MMS. `media_url` also works. |
| `name` | Optional. The contact's name, for a new conversation. |
| `members` | Webex numbers only. The email addresses of the people to add to a new conversation space. Leave it out to use the number's default members. |
| `test` | `true` for a dry run |

The answer depends on how the number is set up in Textdock. A Webex number posts the text into the contact's conversation space in Webex, and opens one if needed (`mode: "webex"`). An API or email number sends it straight to the carrier (`mode: "api"` or `"email"`); an email number also sends a copy by email. Either way, `message_sent` says whether it left. The `message_id` a send returns is not guaranteed to match `data.message_id` on the webhook events for that text.

## History: GET /v1/messages

| Parameter | Meaning |
| --- | --- |
| `start_date`, `end_date`, `timezone`, `page`, `limit` | As for calls |
| `sort` | `day_desc` (default) or `day_asc` |
| `direction` | `incoming` or `outgoing` |
| `channel` | `text` or `whatsapp` |
| `status` | Texts always read `delivered` in this list, so other values return WhatsApp messages only |
| `search` | Part of either number or of the text |

Each message has `message_id`, `direction`, `status`, `remote_number`, `group_number`, `sent_time`, `channel`, `type` (`media` when it carries attachments), `body` and `attachments`. Fetch an attachment by its `att_` id through [Media](https://vocatech.com/developers/guide/media).

## The API Messaging queue

An API Messaging key never gets a per-minute `429` on sends. Its whole batch is accepted and sent in order at the key's pace:

- A send that fits the pace goes out at once (`201`). Once anything is waiting, new sends join the back of the line (`202`).
- The pace counts message parts in the last 60 seconds, 60 to start. The day counts messages in the last 24 hours, the waiting ones included, 5,000 to start. Vocatech sets both per key.
- Only the day can refuse a send: `429` when today's allowance, with what is waiting, is spoken for.
- Every number a key texts is looked up for its carrier before the send. Messages to T-Mobile numbers are also held to 960 a day per account (`limits.tmobile_day_allowance`), shared with the account's broadcasts; T-Mobile's day resets at midnight Pacific. When those are spent, a send to a T-Mobile number, or to a number whose carrier is not known yet, joins the queue (`202`) even with the minute open, and T-Mobile messages wait for the next day while the rest keep flowing.
- These sends are paid per message. The account's included texting limit (50 texts an hour and 150 a day as standard) is for the texts its people and the main key send. It never holds an API Messaging key back, and the key's sends never use it up. Incoming texts are free and count toward nothing.
- The queue works through the line about once a minute. A message gets up to 3 tries. Finished messages stay in the list for 7 days.

**curl**

```bash
# What this key has waiting, and what is left of today
curl https://api.vocatech.com/v1/messages/queue \
  -H "Authorization: Bearer $VOCATECH_API_KEY"

# Cancel one waiting message
curl -X DELETE https://api.vocatech.com/v1/messages/queue/48213 \
  -H "Authorization: Bearer $VOCATECH_API_KEY"

# Cancel everything still waiting: the wrong batch went in
curl -X DELETE https://api.vocatech.com/v1/messages/queue \
  -H "Authorization: Bearer $VOCATECH_API_KEY"
```

**Node**

```javascript
import { vt } from './vocatech.mjs';

const { queue, limits } = await vt('GET', '/v1/messages/queue');
console.log(queue.pending, 'waiting,', limits.remaining_today, 'left today');

await vt('DELETE', '/v1/messages/queue/48213'); // one message
const all = await vt('DELETE', '/v1/messages/queue'); // everything still waiting
console.log(all.canceled, 'canceled');
```

**Python**

```python
from vocatech import vt

q = vt("GET", "/v1/messages/queue")
print(q["queue"]["pending"], "waiting,", q["limits"]["remaining_today"], "left today")

vt("DELETE", "/v1/messages/queue/48213")  # one message
done = vt("DELETE", "/v1/messages/queue")  # everything still waiting
print(done["canceled"], "canceled")
```

**PHP**

```php
<?php
require __DIR__ . '/vocatech.php';

$q = vt('GET', '/v1/messages/queue');
echo $q['queue']['pending'], ' waiting, ', $q['limits']['remaining_today'], " left today\n";

vt('DELETE', '/v1/messages/queue/48213'); // one message
$done = vt('DELETE', '/v1/messages/queue'); // everything still waiting
echo $done['canceled'], " canceled\n";
```

**POST /v1/messages response on an API Messaging key202 AcceptedCopy**

```json
{
  "status": "queued",
  "message": {
    "queue_id": 48213,
    "position": 61,
    "from": "7185550100",
    "to": "7185550142",
    "messages_counted": 1,
    "estimated_wait_minutes": 2,
    "info": "Accepted and queued. It goes out automatically, in order, as sending capacity frees up. Track it with GET /v1/messages/queue or cancel it with DELETE /v1/messages/queue/48213."
  }
}
```

**GET /v1/messages/queue response200 OKCopy**

```json
{
  "queue": {
    "pending": 2,
    "items": [
      {
        "queue_id": 48213,
        "to": "7185550142",
        "from": "7185550100",
        "status": "queued",
        "messages_counted": 1,
        "carrier": "tmobile",
        "attempts": 0,
        "error": null,
        "message_id": null,
        "created_at": "2026-09-24 13:15:02",
        "sent_at": null
      }
    ]
  },
  "limits": {
    "per_minute": 60,
    "per_day": 5000,
    "used_today": 812,
    "remaining_today": 4186,
    "tmobile_day_allowance": 960
  }
}
```

The list shows up to 200 items: everything waiting first, then finished ones, newest first. An item's `status` is `queued`, `sending`, `sent`, `failed` or `canceled`, and its times are UTC. Only a `queued` message can be canceled: one already sending or finished answers `409`, and an id that is not this key's answers `404`.

[Messages in the API reference](https://vocatech.com/developers/reference/messages)
