Messages
A message is a single communication to one recipient over one channel (text, email, or voice). You can send a message directly through the API, schedule it for later, and attach it to a client, event, payment, case, or form so its merge tags resolve from that record.
This page assumes the shared API Conventions for pagination, filtering, and references. All endpoints use your region's base URL and a Bearer token.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /v1/messages | List messages |
GET | /v1/messages/total | Count messages matching filters |
GET | /v1/messages/{uuid} | Get a single message (by UUID or token) |
GET | /v1/messages/{uuid}/statuses | Get a message's current delivery status |
GET | /v1/messages/{uuid}/metas | Get a message's meta event history |
GET | /v1/messages/{uuid}/medias | List a message's MMS media |
POST | /v1/messages/oneoffs | Send a one-off message |
POST | /v1/messages/bulks | Send many messages in one request |
POST | /v1/messages | Send a message to one or more clients (resolves their contacts) |
POST | /v1/messages/{uuid}/send | Send a scheduled message now |
POST | /v1/messages/dispatch | Send a message immediately (idempotent by UUID) |
POST | /v1/messages/resend | Resend recently sent messages |
POST | /v1/messages/delay | Delay upcoming scheduled messages |
PATCH | /v1/messages/{uuid} | Update a scheduled message |
DELETE | /v1/messages/{uuid} | Delete a scheduled message (soft delete) |
DELETE | /v1/messages | Delete scheduled or simulated messages in bulk |
The Message Object
| Field | Type | Description |
|---|---|---|
uuid | string | Unique identifier, generated when the message is created. |
to | string | Recipient: a phone number (E.164) for text and voice, or an email address for email. |
from | string | Sender: an agency phone number or email address. Defaults to the agency's primary sender for the channel. |
channel | string | text (default), email, or voice. Set to email automatically when to is an email address. |
subject | string | Subject line (used for email). |
content | string | Message body. Merge tags in the body are resolved before sending. |
direction | string | outbound or inbound. Messages you create are outbound. |
scheduled_at | string | When the message is scheduled to send, UTC (YYYY-MM-DD HH:MM:SS). |
last_status | string | Current delivery status, such as scheduled, delivered, failed, or opted-out. |
sent | integer | 1 once the message has been sent (or short-circuited, as with an opted-out recipient), otherwise 0. |
test | integer | 1 for a simulated message that is stored but not actually sent, otherwise 0. |
mms | integer | 1 when the message carries media. |
segments | integer | Number of text segments the body will use. |
credits | integer | Credits the message consumes, computed from the channel, segment count, MMS flag, and the recipient's country (international numbers apply a multiplier). |
language | string | Language code, defaults to en. |
token | string | Identifier for an inbound or threaded message. |
type | string | Message type, defaults to one-off for one-off sends. |
client | string | Attached client UUID. |
event | string | Attached event UUID. |
payment | string | Attached payment UUID. |
case | string | Attached case UUID. |
form | string | Attached form UUID. |
file | string | Attached file UUID. |
location | string | Attached location UUID. |
url | string | Unique slug for the message's tracking link. |
error_code | string | Provider error code when delivery failed. |
created_at | string | Creation timestamp, UTC. |
updated_at | string | Last update timestamp, UTC. |
deleted_at | string | Set when the message is deleted, otherwise null. |
Send a One-Off Message
POST /v1/messages/oneoffs
Request:
curl -X POST "$BASE_URL/v1/messages/oneoffs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "+15551234567",
"subject": "Court Reminder",
"content": "Your hearing is scheduled for March 15 at 9:00 AM."
}'
Response (201):
{
"uuid": "{message_uuid}",
"from": "+15559876543",
"to": "+15551234567",
"channel": "text",
"subject": "Court Reminder",
"content": "Your hearing is scheduled for March 15 at 9:00 AM.",
"direction": "outbound",
"last_status": "scheduled",
"sent": 0,
"test": 0,
"segments": 1,
"credits": 1,
"scheduled_at": "2024-03-01 14:52:05"
}
Request Fields
| Field | Description |
|---|---|
to | Required. A phone number or email address. Phone numbers are normalized to E.164. When to is an email address, the channel is set to email. |
content | The message body. message is an accepted alias. |
subject | Subject line, used for email. |
channel | text (default), email, or voice. Overridden to email when to is an email address. |
from | The sender. Defaults to the agency's primary phone (text/voice) or email (email). |
type | Message type. Defaults to one-off. |
test | Set to a truthy value to simulate: the message is stored with test: 1 and not actually sent. |
file_url | A media URL. Setting it marks the message as MMS (mms: 1). |
Scheduling and Sending Now
A one-off is scheduled rather than sent instantly by default. Its scheduled_at is set from the agency's send delay, and last_status comes back as scheduled.
To send immediately, pass "send_now": true. Immediate sending also requires the message not to be scheduled into the future (the agency's send delay must be 0) and does not apply to MMS. Separately, an agency can enable a Send Immediately setting that sends without send_now. A message whose scheduled_at is already in the past (more than 60 minutes ago) is also sent right away.
Attaching Records
Attach the message to a related record so its merge tags resolve and it appears on that record. Each expects the related record's UUID:
| Field | Attaches |
|---|---|
client | A client. |
event | An event. |
payment | A payment. |
case | A case. |
form | A form. |
file | A file. |
location | A location, used for location merge tags. |
For example, attach a payment and use [PaymentAmount] and [PaymentLink] in the body (see Merge Tags).
Validation and Special Cases
- Required fields: the message must resolve a
from, ato, and ascheduled_at. A missing one returns400withMessage is missing {field}. Iffromis an email address,tomust be an email address too. - Past schedule: a
scheduled_atmore than 4 hours in the past returns400. - Opted-out recipient: when the agency's auto-create-contacts setting is enabled and the recipient matches a contact that has opted out, the message is stored with
last_status: opted-outandsent: 1, and is not delivered. - Duplicate: a message that duplicates a recent one returns
409withMessage is a duplicate. - Long messages: a body longer than one text segment is split automatically, and
segmentsreflects the count.
Send Bulk Messages
POST /v1/messages/bulks
Send many messages in one request by passing a messages array, where each entry follows the same rules as a one-off. Entries that fail validation are skipped rather than failing the whole request; the response contains only the messages that were stored.
curl -X POST "$BASE_URL/v1/messages/bulks" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"to": "+15551234567", "content": "Reminder 1"},
{"to": "jane.doe@example.com", "subject": "Reminder", "content": "Reminder 2"}
]
}'
Response (201): a JSON array of the stored message records.
Returns 400 with Messages are required when the messages array is missing or empty, or No valid messages to process when every entry failed validation. For very large sends, split the work into multiple requests within your rate limits.
Send to Clients
POST /v1/messages
Send a message to one or more clients by UUID and let eCourtDate resolve each client's contacts, rather than specifying a to address yourself. Pass client (a single UUID) or clients (an array or comma-separated list of UUIDs), along with the content and other one-off fields.
Response (201): a JSON array of the messages created for the clients' contacts.
List Messages
GET /v1/messages
curl -X GET "$BASE_URL/v1/messages?client={client_uuid}&status=delivered&limit=50" \
-H "Authorization: Bearer $TOKEN"
Response (200): a data envelope, not a bare array:
{
"data": [
{ "uuid": "{message_uuid}", "to": "+15551234567", "last_status": "delivered" }
]
}
Add total=true to include the count: {"total": 128, "data": [...]}.
Query Parameters
Filtering:
| Parameter | Description |
|---|---|
client | Filter by client UUID. clients accepts a comma-separated list. |
event | Filter by attached event UUID. |
payment | Filter by attached payment UUID. |
case | Filter by attached case UUID. |
form | Filter by attached form UUID. |
file | Filter by attached file UUID. |
status | Filter by delivery status. last_status is an accepted alias. |
type | Filter by message type. |
channel | Filter by channel. not_channel excludes a channel. |
direction | Filter by outbound or inbound. |
from | Filter by sender. |
to | Filter by recipient. |
sent | Set to 1 to return only sent messages. sent=0 is ignored by the filter; use scheduled=1 to list unsent scheduled messages. |
scheduled | Set to 1 to return only scheduled, unsent messages. |
token | Filter by token. |
url | Filter by tracking slug. |
location | Filter by attached location. |
subject | Filter by subject. |
content | Filter by content. |
language | Filter by language. |
error_code | Filter by provider error code. |
test | Set to 1 to return only simulated (test) messages. simulate is an accepted alias. |
live | Set to 1 to return only non-test messages that have already been sent (test=0 and sent=1). |
Pagination and shaping (limit, skip, sort, sortDirection, fields) follow the shared conventions.
Get a Message
GET /v1/messages/{uuid}
The path value accepts a message UUID or a token. When the message is MMS, the response includes a medias array. Returns 404 with a message of Message {uuid} not found when no message matches.
Update a Scheduled Message
PATCH /v1/messages/{uuid}
Edit a message that has not been sent yet, for example to change its content or scheduled_at. Only an unsent, outbound message that is still scheduled in the future can be edited; anything else returns 404 with Scheduled message not found. The content merge tags are re-resolved, and segments and credits are recomputed. Rescheduling more than 4 hours into the past returns 400.
curl -X PATCH "$BASE_URL/v1/messages/{message_uuid}" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "Updated: your hearing is now at 10:30 AM.",
"scheduled_at": "2024-03-14 13:00:00"
}'
Delete a Scheduled Message
DELETE /v1/messages/{uuid}
Soft-deletes an unsent, outbound message that is still scheduled in the future so it will not send. Returns 404 with Scheduled message not found when there is no matching message, or 204 on success.
Send a Scheduled Message Now
POST /v1/messages/{uuid}/send
Sends a specific scheduled message immediately instead of waiting for its scheduled_at. Returns 404 with Scheduled message not found, 400 with Message not sent when delivery fails, or 201 with the sent message on success.
Dispatch a Message
POST /v1/messages/dispatch
Sends a message immediately and de-duplicates by uuid, so a repeated dispatch of the same message is a safe no-op. Returns 400 with UUID is required when no uuid is sent, 200 with Message already dispatched when it was dispatched before, 200 with Message not sent when delivery fails, or 201 with the sent message on success.
Resend Messages
POST /v1/messages/resend
Reschedules recently sent outbound messages to be sent again, useful for recovering from a delivery problem. Parameters:
| Parameter | Default | Description |
|---|---|---|
since | 1 | Look back this many hours for sent messages to resend. |
delay | 60 | Minutes from now to schedule the resends. |
type | - | Restrict to a message type (partial match). |
test | - | Set truthy to resend only simulated messages. |
error | - | Set truthy to resend only messages that had an error. |
Response (200):
{"message": "3 messages scheduled to be resent"}
Delay Messages
POST /v1/messages/delay
Pushes upcoming scheduled messages later, useful to pause an imminent batch. Parameters:
| Parameter | Default | Description |
|---|---|---|
max | 1 | Only delay messages scheduled within this many hours from now. |
delay | 15 | Minutes from now to reschedule the affected messages. |
type | - | Restrict to a message type (exact match). |
Response (200):
{"message": "12 messages delayed"}
Delete Messages in Bulk
DELETE /v1/messages
Cancels many messages at once. By default this deletes simulated (test) messages. Pass scheduled=true to instead delete upcoming scheduled, unsent outbound messages, optionally narrowed by event, payment, or client.
Response (202):
{"message": "42 scheduled messages deleted"}
Delivery Tracking
GET /v1/messages/{uuid}/statusesreturns the message's current delivery status, performing a live provider lookup for text and voice.GET /v1/messages/{uuid}/metasreturns the message's meta event history (delivery and interaction events).GET /v1/messages/{uuid}/mediaslists the media attached to an MMS message.
The message object's last_status field always reflects the most recent delivery status.
FAQs
How do I send a text or email right now instead of scheduling it?
Pass "send_now": true on the one-off. This also requires the agency's send delay to be 0 (so the message is not scheduled into the future) and does not apply to MMS. An agency can also enable a Send Immediately setting that sends without send_now.
How do I attach a message to a client, event, or payment?
Include the record's UUID in the matching field (client, event, payment, case, form, file). These fields expect a UUID on create, not a reference. Attaching links the message to that record and lets the record's merge tags resolve in the body.
How do I check whether a message was delivered?
Read the last_status field on the message for the current status. Call GET /v1/messages/{uuid}/statuses for a live provider lookup, or GET /v1/messages/{uuid}/metas for the full event history.
How many messages can I send in one request?
One per POST /v1/messages/oneoffs, and many per POST /v1/messages/bulks (passed as a messages array and stored as a batch). Split very large sends across multiple requests within your rate limits.
Why did my message come back with last_status: opted-out?
The recipient matches a contact that has opted out. This check applies when the agency's auto-create-contacts setting is enabled; the message is then stored but not delivered. Check the recipient's contact opt-in status before sending.
What does a 409 on a one-off mean?
The message duplicates a recent one. eCourtDate returns Message is a duplicate rather than sending twice. Vary the content or recipient, or wait, if the resend is intentional.
How do I cancel messages that are scheduled but not yet sent?
Delete a single one with DELETE /v1/messages/{uuid}, or cancel many with DELETE /v1/messages?scheduled=true (optionally filtered by event, payment, or client). To postpone rather than cancel, use POST /v1/messages/delay.
Related Documentation
- API Conventions: shared listing, filtering, and reference behavior
- Contacts: recipient channels and opt-in status
- Merge Tags: dynamic content in message bodies
- Sending Limits: delivery and throughput limits
- Error Handling: status codes and error responses