Record or send
UsePOST /conversations/{conversationId}/messages (messages:write) to record or import a message without customer delivery. Use POST /conversations/{conversationId}/send (messages:send) to send an agent reply on the conversation’s existing channel. The sender, channel, and delivery metadata are set by the server.
A key or OAuth connection with only messages:write cannot send customer replies. Add the separate send permission explicitly.
Send a reply
The conversation must belong to the connected workspace and have the intended customer and channel. Email and WhatsApp require configured channel credentials and a recipient. Chat replies appear in the visitor stream. A test-mode API key still operates on real workspace data.message, queued, undoMsec, and, for scheduled email, scheduledFor. Email and WhatsApp delivery jobs are committed in the same database transaction as the message. A queue failure rolls back the message.
Reuse the exact request and idempotency key after an uncertain response. A replay returns the original result with Idempotency-Replayed: true. Changing the request under the same key returns 409. Request idempotency does not promise exactly-once delivery by an external provider.
Check delivery
ReadGET /messages/{messageId} with conversations:read. For a reply created by the send endpoint, inspect metadata.deliveryStatus:
A queued response is not delivery confirmation. Some delivery failures are retried by the worker; do not create another message merely because a retry is in progress.
Schedule or cancel
Email replies can includesendAt, an RFC3339 timestamp in the future and at most 30 days ahead. Scheduling is not supported for internal notes, test threads, or other channels.
Normal provider sends have a five-second undo window. Call POST /messages/{messageId}/cancel-send with messages:send while the delivery job is pending. Scheduled sends can also be canceled before the worker claims them. Success returns 204. Once claimed, cancellation returns 409; it cannot recall an in-flight provider request.
Internal notes and attachments
Setinternal: true to add an internal note without contacting the customer. Test-thread replies also stay inside Protodesk.
Send attachments must use durable /api/media/WORKSPACE_ID/... references owned by that workspace. Arbitrary external URLs are not fetched or silently treated as delivered attachments. Channel/provider limits still apply.
MCP equivalents
Usesend_message, get_message, and cancel_message_send. Reads require conversations:read; sends and cancellation require messages:send. Call workspace_context first, supply its ID as expectedWorkspaceId on writes, and supply an idempotencyKey for sending.
