Skip to main content

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

MethodPathDescription
GET/v1/messagesList messages
GET/v1/messages/totalCount messages matching filters
GET/v1/messages/{uuid}Get a single message (by UUID or token)
GET/v1/messages/{uuid}/statusesGet a message's current delivery status
GET/v1/messages/{uuid}/metasGet a message's meta event history
GET/v1/messages/{uuid}/mediasList a message's MMS media
POST/v1/messages/oneoffsSend a one-off message
POST/v1/messages/bulksSend many messages in one request
POST/v1/messagesSend a message to one or more clients (resolves their contacts)
POST/v1/messages/{uuid}/sendSend a scheduled message now
POST/v1/messages/dispatchSend a message immediately (idempotent by UUID)
POST/v1/messages/resendResend recently sent messages
POST/v1/messages/delayDelay upcoming scheduled messages
PATCH/v1/messages/{uuid}Update a scheduled message
DELETE/v1/messages/{uuid}Delete a scheduled message (soft delete)
DELETE/v1/messagesDelete scheduled or simulated messages in bulk

The Message Object

FieldTypeDescription
uuidstringUnique identifier, generated when the message is created.
tostringRecipient: a phone number (E.164) for text and voice, or an email address for email.
fromstringSender: an agency phone number or email address. Defaults to the agency's primary sender for the channel.
channelstringtext (default), email, or voice. Set to email automatically when to is an email address.
subjectstringSubject line (used for email).
contentstringMessage body. Merge tags in the body are resolved before sending.
directionstringoutbound or inbound. Messages you create are outbound.
scheduled_atstringWhen the message is scheduled to send, UTC (YYYY-MM-DD HH:MM:SS).
last_statusstringCurrent delivery status, such as scheduled, delivered, failed, or opted-out.
sentinteger1 once the message has been sent (or short-circuited, as with an opted-out recipient), otherwise 0.
testinteger1 for a simulated message that is stored but not actually sent, otherwise 0.
mmsinteger1 when the message carries media.
segmentsintegerNumber of text segments the body will use.
creditsintegerCredits the message consumes, computed from the channel, segment count, MMS flag, and the recipient's country (international numbers apply a multiplier).
languagestringLanguage code, defaults to en.
tokenstringIdentifier for an inbound or threaded message.
typestringMessage type, defaults to one-off for one-off sends.
clientstringAttached client UUID.
eventstringAttached event UUID.
paymentstringAttached payment UUID.
casestringAttached case UUID.
formstringAttached form UUID.
filestringAttached file UUID.
locationstringAttached location UUID.
urlstringUnique slug for the message's tracking link.
error_codestringProvider error code when delivery failed.
created_atstringCreation timestamp, UTC.
updated_atstringLast update timestamp, UTC.
deleted_atstringSet 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

FieldDescription
toRequired. 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.
contentThe message body. message is an accepted alias.
subjectSubject line, used for email.
channeltext (default), email, or voice. Overridden to email when to is an email address.
fromThe sender. Defaults to the agency's primary phone (text/voice) or email (email).
typeMessage type. Defaults to one-off.
testSet to a truthy value to simulate: the message is stored with test: 1 and not actually sent.
file_urlA 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:

FieldAttaches
clientA client.
eventAn event.
paymentA payment.
caseA case.
formA form.
fileA file.
locationA 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, a to, and a scheduled_at. A missing one returns 400 with Message is missing {field}. If from is an email address, to must be an email address too.
  • Past schedule: a scheduled_at more than 4 hours in the past returns 400.
  • 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-out and sent: 1, and is not delivered.
  • Duplicate: a message that duplicates a recent one returns 409 with Message is a duplicate.
  • Long messages: a body longer than one text segment is split automatically, and segments reflects 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:

ParameterDescription
clientFilter by client UUID. clients accepts a comma-separated list.
eventFilter by attached event UUID.
paymentFilter by attached payment UUID.
caseFilter by attached case UUID.
formFilter by attached form UUID.
fileFilter by attached file UUID.
statusFilter by delivery status. last_status is an accepted alias.
typeFilter by message type.
channelFilter by channel. not_channel excludes a channel.
directionFilter by outbound or inbound.
fromFilter by sender.
toFilter by recipient.
sentSet to 1 to return only sent messages. sent=0 is ignored by the filter; use scheduled=1 to list unsent scheduled messages.
scheduledSet to 1 to return only scheduled, unsent messages.
tokenFilter by token.
urlFilter by tracking slug.
locationFilter by attached location.
subjectFilter by subject.
contentFilter by content.
languageFilter by language.
error_codeFilter by provider error code.
testSet to 1 to return only simulated (test) messages. simulate is an accepted alias.
liveSet 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:

ParameterDefaultDescription
since1Look back this many hours for sent messages to resend.
delay60Minutes 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:

ParameterDefaultDescription
max1Only delay messages scheduled within this many hours from now.
delay15Minutes 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}/statuses returns the message's current delivery status, performing a live provider lookup for text and voice.
  • GET /v1/messages/{uuid}/metas returns the message's meta event history (delivery and interaction events).
  • GET /v1/messages/{uuid}/medias lists 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.