Send text message
Sends a normalized text message through the selected provider account. message.text must be non-empty; provider_data carries provider-specific fields such as parse_mode, and quoted replies use the top-level reply_to field. Optional opaque WhatsApp reply handle returned after a successful send when the channel provides a referable message identifier. Pass it back unchanged; it is not a parent message id.
https://api.unifyport.ai/v1/messagesHeaders
X-Api-KeyWorkspace API key. The workspace is resolved from this header.
Content-TypeUse application/json when sending a JSON request body.
Path parameters
This endpoint has no path parameters.
Request body
account_idProvider account that sends the message.
minLength: 1
toobjectrequiredRecipient target with id and type.
toRecipient target with id and type.
idChannel-side recipient identifier.
minLength: 1
typeRecipient type: user, group, or channel.
enum: user, group, channel
messageobjectrequiredNormalized message payload. Text uses message.text; media uses message.url.
messageNormalized message payload. Text uses message.text; media uses message.url.
typeMessage type: text, image, video, audio, document, file, or contact.
enum: text, image, video, audio, document, file, contact
textNon-empty text content required when message.type is text.
minLength: 1
captionOptional caption for image, video, document, or file messages.
urlNon-empty absolute HTTP(S) media URL. Media messages require url, file_url, or file_key.
format: uri · pattern: ^[Hh][Tt][Tt][Pp][Ss]?://
file_urlNon-empty alternative absolute HTTP(S) media URL. Media messages require url, file_url, or file_key.
format: uri · pattern: ^[Hh][Tt][Tt][Pp][Ss]?://
file_keyNon-empty provider or storage file reference. Media messages require url, file_url, or file_key.
minLength: 1
contacts[]object[]Non-empty array of structured contact cards required when message.type is contact.
minItems: 1
contacts[]Non-empty array of structured contact cards required when message.type is contact.
minItems: 1
nameNon-empty contact display name required for every contact card.
minLength: 1
phones[]object[]Phone entries included in the contact card.
phones[]Phone entries included in the contact card.
numberPhone number; required for every phone entry.
typeOptional phone label such as CELL or WORK.
emails[]object[]Email entries included in the contact card.
emails[]Email entries included in the contact card.
addressEmail address; required for every email entry.
format: email
typeOptional email label such as WORK or HOME.
organizationOptional organization associated with the contact.
titleOptional job title associated with the contact.
provider_dataobjectProvider-specific options such as Telegram parse_mode or WhatsApp audio / video seconds, which use a non-negative integer. For video only, the allowed range is 0 to 4294967295; waveform remains audio-only. Use top-level reply_to for quoted replies.
provider_dataProvider-specific options such as Telegram parse_mode or WhatsApp audio / video seconds, which use a non-negative integer. For video only, the allowed range is 0 to 4294967295; waveform remains audio-only. Use top-level reply_to for quoted replies.
secondsOptional non-negative integer duration in seconds for WhatsApp audio and video messages. For video only, the allowed range is 0 to 4294967295.
minimum: 0
waveformOptional waveform data for WhatsApp audio messages. Non-empty values must use standard Base64 encoding and decode to parseable JSON waveform data; an empty string is treated as omitted, and invalid formats return HTTP 400 provider_invalid_request.
reply_toobjectQuoted-reply target. Copy data.message.reply_token from the inbound webhook into reply_to.reply_token unchanged when supported.
reply_toQuoted-reply target. Copy data.message.reply_token from the inbound webhook into reply_to.reply_token unchanged when supported.
reply_tokenOpaque reply token copied unchanged from data.message.reply_token in the inbound webhook.
minLength: 1
mentions[]object[]Group-message @ target list. type=member uses the corresponding Provider member id; type=all mentions everyone only when the Provider supports it, otherwise unsupported_message_type is returned.
mentions[]Group-message @ target list. type=member uses the corresponding Provider member id; type=all mentions everyone only when the Provider supports it, otherwise unsupported_message_type is returned.
typeMention target type. Omit it for member compatibility; type=member requires id, while type=all omits id and only applies to group chats.
enum: member, all
idProvider member identifier required when type=member.
minLength: 1
Response body
message_idUnifyPort message identifier (msg_...) for the accepted message.
account_idProvider account this response refers to.
statusAcceptance status; accepted means the message was queued for delivery to the provider.
provider_refProvider-side message reference, once the provider assigns one.
reply_tokenOptional opaque WhatsApp reply handle returned after a successful send when the channel provides a referable message identifier. Pass it back unchanged; it is not a parent message id.
Responses
200Request succeeded. See the example response body.
400The request body, path, or parameters are invalid.
401The X-Api-Key header is missing or invalid.
409The requested operation conflicts with an existing provider account or resource.
500The service encountered an unexpected error.
501The selected provider does not implement this operation.
502The provider adapter or upstream provider could not complete the operation.
Request
curl -X POST https://api.unifyport.ai/v1/messages \
-H "X-Api-Key: <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"account_id": "acc_example",
"to": {
"id": "user_example",
"type": "user"
},
"message": {
"type": "text",
"text": "Hello from UnifyPort"
},
"provider_data": {
"parse_mode": "markdown"
}
}'Response
{
"data": {
"message_id": "msg_example",
"account_id": "acc_example",
"status": "accepted",
"provider_ref": "provider_msg_example",
"reply_token": "<opaque WhatsApp reply handle>"
}
}