Contacts

Check which numbers are on WhatsApp, and save, read and remove contacts.

  • POST/v1/sessions/<CHANNEL_ID>/contacts/check

    Check which numbers are on WhatsApp.

  • GET/v1/sessions/<CHANNEL_ID>/contacts/<CONTACT>

    Get a contact.

  • PUT/v1/sessions/<CHANNEL_ID>/contacts/<CONTACT>

    Save or update a contact.

  • DELETE/v1/sessions/<CHANNEL_ID>/contacts/<CONTACT>

    Remove a contact.

  • GET/v1/sessions/<CHANNEL_ID>/lids/pn/<PHONE>

    Look up the LID for a phone number.

  • GET/v1/sessions/<CHANNEL_ID>/lids/<LID>

    Look up the phone number for a LID.

<CONTACT> is a user JID ([email protected]) or a LID (<digits>@lid). A bare phone number also works.

Checking a long list of numbers you have never talked to is a pattern WhatsApp acts on. Check the people you are about to message, not a bought list. Saving a contact before you message them helps your address book reading (see Your channel and its health). Saving people in bulk that you never message does not.

Check numbers

bash
curl -X POST "https://api-wagate.socialground.co/v1/sessions/<CHANNEL_ID>/contacts/check" \
  -H "Authorization: Bearer <CHANNEL_TOKEN>" -H "Content-Type: application/json" \
  -d '{"phones": ["66XXXXXXXXX", "66YYYYYYYYY"]}'
json
{
  "results": [
    { "query": "+66XXXXXXXXX", "registered": true, "jid": "[email protected]", "is_business": true, "verified_name": "Example Shop" },
    { "query": "+66YYYYYYYYY", "registered": false }
  ]
}
  • 1 to 50 numbers per call. An empty list, more than 50, or a value with no digits is refused with 400.
  • jid appears when the number is on WhatsApp. is_business appears only when it is true. verified_name appears only when WhatsApp has one.
  • Each number counts as one number check. A sandbox channel gets 20 a day (429 sandbox_allowance_exceeded). With warm-up protection on, a daily allowance by number age applies (429 daily_cap_contact_check). See Limits.

Get a contact

bash
curl "https://api-wagate.socialground.co/v1/sessions/<CHANNEL_ID>/contacts/[email protected]" \
  -H "Authorization: Bearer <CHANNEL_TOKEN>"
json
{
  "jid": "[email protected]",
  "push_name": "Customer A",
  "full_name": "Customer A",
  "first_name": "Customer A",
  "found": true,
  "handset": "saved"
}

business_name also appears for a business contact. This reads WAgate's own store and makes no call to WhatsApp.

Save a contact

bash
curl -X PUT "https://api-wagate.socialground.co/v1/sessions/<CHANNEL_ID>/contacts/[email protected]" \
  -H "Authorization: Bearer <CHANNEL_TOKEN>" -H "Content-Type: application/json" \
  -d '{"full_name": "Customer A", "first_name": "Customer A"}'
  • full_name is required. first_name is optional and defaults to full_name. Both are trimmed.
  • The target must be a person: @s.whatsapp.net or @lid. Anything else is a 400.
  • Saving again with the same names changes nothing.
  • The answer is the saved contact read back from the store. A save that did not land is an error, not a 200 with found: false.
  • Each save counts as one contact write. With warm-up protection on, a daily allowance applies (429 daily_cap_contact_write).

The handset field

Saving, reading and removing a contact answer handset. It says whether the linked phone holds the contact under those names. Writing to the phone is switched on per channel by the gateway operator. Where it is off, every save is kept in WAgate only.

`handset`Meaning
savedThe phone confirmed the names.
pendingThe write to the phone is queued.
unknownA write may or may not have reached the phone.
failedThis request did not make it. No phone number is known for the contact yet, the queue is full, or the channel's phone writes are halted.
offPhone writes are not enabled on the channel, so the contact is saved in WAgate only.
removedThe phone confirmed the contact is not in its contact list.

If phone writes are halted, a write that was already queued waits until an operator clears the halt. One that could not be queued is not made, so send it again once the halt is cleared.

Remove a contact

bash
curl -X DELETE "https://api-wagate.socialground.co/v1/sessions/<CHANNEL_ID>/contacts/[email protected]" \
  -H "Authorization: Bearer <CHANNEL_TOKEN>"
  • No body. It clears the stored names and, where phone writes are enabled, removes the contact from the linked phone through the same queue as a save.
  • Removing a contact that is not stored, or already removed, answers 200.
  • Without phone writes enabled it answers 200 with handset: "off", and only the stored names are cleared.
  • It counts as one contact write.

LID lookup

Two read routes map a phone number to its LID and back. They read WAgate's own LID map and make no call to WhatsApp. They answer only on a channel the gateway operator has enabled LID lookup for. Your channel's lid_lookup field says whether yours is. If it is not, both answer 403 lid_lookup_not_granted. Do not retry that error, because it does not change on its own. Email support if you need LID lookup.

<PHONE> is 6 to 20 digits with an optional leading +. <LID> is digits followed by a literal @lid.

bash
curl "https://api-wagate.socialground.co/v1/sessions/<CHANNEL_ID>/lids/pn/66XXXXXXXXX" -H "Authorization: Bearer <CHANNEL_TOKEN>"
json
{ "pn": "[email protected]", "lid": "100000000000000@lid" }

A mapping WAgate does not know is still a 200, with the unknown side left out.

Errors on these routes

409 not_linked, 409 stood_down, 403 blocked, 403 lid_lookup_not_granted (LID routes), 429 daily_cap_contact_check, 429 daily_cap_contact_write, 429 sandbox_allowance_exceeded. See Errors.

Contacts · WAgate docs