UnifyPort API Update: Conversation Labels, Contact Messages, and Request Tracing — UnifyPort
Three weeks after the v1 stable release, the UnifyPort API picks up its first feature batch: conversation labels for organizing WhatsApp chats, a contact-card message type, request tracing across every call, and a set of developer-experience improvements that make the webhook event reference substantially more useful.
Here’s what shipped, with the real endpoints and field names.
Conversation labels — 4 new endpoints
You can now create, list, update, and delete labels on conversations, and tag or untag conversations in bulk. This is the same label system WhatsApp exposes natively — UnifyPort surfaces it through four endpoints under the Conversations category.
List labels
GET /v1/accounts/{account_id}/conversations/labels?limit=50&cursor=
Returns paginated labels, each with id and name:
{
"data": {
"items": [
{ "id": "label_example", "name": "VIP" }
],
"next_cursor": "",
"has_more": false
}
}
Create or update a label
POST /v1/accounts/{account_id}/conversations/labels/upsert
Pass an empty label_id to create; pass an existing label_id to rename:
{
"label_id": "",
"name": "VIP"
}
Delete a label
POST /v1/accounts/{account_id}/conversations/labels/delete
{
"label_id": "label_example"
}
Tag or untag conversations
POST /v1/accounts/{account_id}/conversations/labels
action is add or remove; conversation_ids must contain at least one ID:
{
"label_id": "label_example",
"action": "add",
"conversation_ids": ["peer_example"]
}
All four endpoints are WhatsApp-only for now. Other providers return 501 unsupported_by_provider. The corresponding error codes — list_conversation_labels_failed, upsert_label_failed, delete_label_failed, set_label_members_failed — are documented in the error reference.
Contact (vCard) message type
POST /v1/messages now accepts message.type: "contact" with a structured contacts array. UnifyPort generates the vCard for you — you send structured JSON, the provider receives a proper contact card.
{
"account_id": "acc_example",
"to": {
"id": "user_example",
"type": "user"
},
"message": {
"type": "contact",
"contacts": [
{
"name": "Jane Doe",
"phones": [{ "number": "+8613800000000", "type": "CELL" }],
"emails": [{ "address": "jane@example.com" }],
"organization": "ACME",
"title": "PM"
}
]
}
}
Each card requires name. The phones[].number, emails[].address, organization, and title fields are optional. You can send a single card or multiple cards in the array — WhatsApp maps single cards to its contact type and multiple cards to contact_array.
An empty contacts array or a card missing name returns 400 invalid_request. Non-WhatsApp providers return 400 unsupported_message_type until support ships for those channels.
Request tracing — request_id and X-Request-Id
Every API response — success and error — now carries a top-level request_id field and returns the same value as the X-Request-Id response header. Quote it when reporting issues or debugging failed calls.
For client-side reconciliation, send your own X-Request-Id request header and it’s echoed back as client_request_id in the response. This lets you correlate outbound API calls with your own internal request IDs without maintaining a separate mapping layer.
Real webhook payload samples
The API reference now includes real payload shapes for webhook events, drawn from the actual device-webhook parsers (Telegram and WhatsApp).
message.received shows payloads by content type — text, image, voice, document, and location — so you can see the exact field structure for each variant instead of guessing from a generic data: {} placeholder.
group.updated shows payloads by change kind:
- Renamed —
changes[].kind: "renamed"with the new groupname - Members added/removed —
changes[].kind: "member_added"or"member_removed"withmembers[]arrays of participant IDs - Admin promoted/demoted —
changes[].kind: "promoted"or"demoted"withmembers[]
A single group.updated event can carry several changes at once — for example, a rename plus a member addition in the same snapshot.
Three new developer tools
The tools page now includes three browser-based utilities, all running client-side:
- HMAC Signature Generator — generate and verify HMAC-SHA1/SHA256/SHA512 signatures in your browser; useful for debugging webhook
signing_secretverification - Unix Timestamp Converter — convert Unix timestamps to human-readable dates and back, with auto-detection of seconds vs. milliseconds
- JSON Formatter — format, minify, and validate JSON with syntax highlighting and one-click JSON Path copying
Breaking change: two fields removed
Two undocumented fields have been removed from the POST /v1/messages reference to match the actual API surface:
idempotency_key— removed. It was documented but never implemented in the device API.provider_data.reply_to— removed from the documented surface. Theprovider_dataobject now documentsparse_modeas its example field.
If your code was sending idempotency_key or provider_data.reply_to, check whether you were relying on behavior that was already a no-op. Neither field was processed by the API.
What’s next
Conversation labels and contact messages ship WhatsApp-first because WhatsApp’s upstream API supports them natively. As other providers add equivalent capabilities — or as the normalization layer can bridge the gap — they’ll light up on additional channels with the same endpoint surface. The 501 unsupported_by_provider response is intentional: it tells you exactly which provider doesn’t support a feature yet, rather than silently dropping the request.
The full API reference is live at unifyport.ai/docs.