Chats, contacts and groups
Wherever a path has {phone}, use the person's number in international format, or a chat_id ending in @lid from a webhook.
Reads from the phone. An instance's contacts, groups, channels, a group's invite link and the profile are read from the linked phone while you wait. The lists and the invite link are kept for 30 seconds, so a change made on the phone can take that long to show; a change made through the API shows at once. An instance answers two such reads at a time: a third at the same moment gets 429 with the code busy and a Retry-After of a few seconds. Read these one after another, not all at once.
Chats
- Your chats:
GET /v1/chatslists each person your instances talk with, newest first, with the latest message (from the last 30 days, as messages are kept) andwaiting_for_reply(they wrote last, and nobody marked the chat done in the panel).waiting=1lists only those;instance_idone instance's. - History from the phone:
GET /v1/instances/{id}/chats/{phone}/historyreads the messages WhatsApp keeps for a one-to-one chat on the linked phone: what the phone synced when you linked it (about a day before) and everything since, typed on the phone included. Newest first,limita page (up to 100, 50 by default; a page may hold fewer) andoffsetfor older ones. Each has WhatsApp'sid, ourmessage_idwhen it is also inGET /v1/messages,from_me,body,has_media(files are not included) andsent_at. Only a chat the instance has (anyone else is 404), never a group; OTP codes are masked. It sends nothing to WhatsApp; at most 30 pages a minute per instance. - Archive and unread:
POST /v1/instances/{id}/chats/{phone}/archive,/unarchiveor/unread, as in the app.
Contacts
GET /v1/instances/{id}/contactslists the WhatsApp contacts on the linked phone:nameas saved there,push_nameas they show it. 100 to a page; a page may hold fewer, and an empty one is the end.GET /v1/instances/{id}/contacts/{phone}gives one person the instance knows (a contact on the phone, or someone it has a chat with), withpicture_url, their profile picture as WhatsApp serves it (it expires; null when they have none or hide it). Anyone else is 404, since looking up strangers is what WhatsApp treats as scraping. It needs a key that may send.
Contact lookups, archive and unread share a limit of 20 a minute per instance.
Contact fields
Contact fields are what your team keeps about the people who write to you, such as a customer number or a city. An admin makes the fields on the panel's Chats page, and your team fills them in from a chat.
GET /v1/contact-fieldslists your fields: eachkey,name,kind(text,number,dateorlist) and a list'soptions.GET /v1/chats/{phone}/contact-fieldsgives what they say about one person: every key underfields, with null where nothing is kept.PUT /v1/chats/{phone}/contact-fieldssets them. Sendfieldsas key and value pairs. A key you leave out stays as it is, and null clears it. It needs a full-access key.
curl -X PUT https://threadwire.net/api/v1/chats/201012345678/contact-fields \
-H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" \
-d '{"fields": {"city": "Giza", "renewal": "2026-12-01"}}'
A date is written YYYY-MM-DD, a list takes one of its options, and values come back as text. A value its field cannot take is a 422 that names the key.
The same person has the same fields on every instance of yours, whether you name them by phone or by the chat_id a webhook gave. Changes made with a key show in your activity log as one line an hour for that key, however many people it changed. They are only for someone who wrote to you: anyone else is 404, and there is no import. A field's key is also a placeholder in a broadcast.
Labels (WhatsApp Business app only)
GETandPOST /v1/instances/{id}/labels(name,color0 to 19).PUTorDELETE /v1/instances/{id}/labels/{label}; a deleted label comes off every chat.GET /v1/instances/{id}/labels/{label}/chats: the chats with a label.GETorPUT /v1/instances/{id}/chats/{phone}/labels: a chat's labels.PUTtakes the whole list of labelids; ones left out come off.
The phone shows them too.
Statuses
POST /v1/instances/{id}/statuses posts a WhatsApp status (a story your contacts see for 24 hours): text on a background_color (and a font 0 to 5), or an image, video or voice by url or base64 data, with text as the caption (as data it counts toward the account's files as base64 for the day). audience (phones) limits who sees it. It answers queued, and turns posted once WhatsApp has it.
- Everyone in the
audiencemust know the instance's number (they wrote to it, or are saved contacts on the phone) and must not have written "STOP": a status from a number you do not know is what people report, so a request naming anyone else answers422naming them. Checking whether someone is a saved contact asks WhatsApp, so at most 20 people who never wrote can be checked a minute (429past that). - At most 30 a day per instance.
GETlists them withviewsand theviewers' phones;DELETE /v1/instances/{id}/statuses/{status}removes one; only a posted status can be deleted (409otherwise).
Orders and products
An order someone sends from your WhatsApp Business catalog arrives with type order (and order: order_id, title, items, total, currency), a shared product with type product. Managing the catalog itself is not available yet.
Groups
GET /v1/instances/{id}/groupslists the groups the instance is in, with theirchat_id.POSTcreates one with asubjectandparticipants.GET, orPATCH(subject,description,messages_admin_only: only admins may write,info_admin_only: only admins may change its name and description),/v1/instances/{id}/groups/{group}.POST …/participantswithactionadd,remove,promoteordemote.GET …/invitegives the invite link;POST …/invite/revokemakes a new one, so the old one stops working.POST …/leaveleaves it;POST /v1/instances/{id}/groups/joinwith aninvitejoins one.
Who can be added: only people who know the instance's number (they wrote to it, or are saved contacts on the phone), and never someone who wrote "STOP". Being added to a group by a stranger is what people report most, so share the invite link with everyone else. Each person to add who has not written to the instance is looked up on WhatsApp and counts toward the instance's 20 contact lookups a minute, so at most 20 such people in one request. Creating, joining or leaving a group, and adding or removing people, need a full-access key.
Limits per instance: at most 5 groups created, 5 joined and 50 people added a day.
Channels
GET /v1/instances/{id}/channels (role owner, admin or subscriber); POST creates one with a name (at most 2 a day); GET or DELETE /v1/instances/{id}/channels/{channel}.
Sending to a group or channel
POST /v1/messages with chat_id (a group's …@g.us or a channel's …@newsletter) instead of to. Paced like any message; at most 200 group messages and 30 channel posts a day per instance, and 20 an hour to one group.
Group messages people write arrive as group.message webhooks (the group is chat_id, the writer participant; files posted in groups are named but not kept), and changes to a group as group.update; tick both under Developers → Webhooks → Events to receive them. Someone who wrote in a group has not written to your instance: a message to them alone is still a first message.