POST /v1/lookup tells whether a handle, a phone number or an email address, can receive iMessage. This page describes the request, the three kinds of answer, how long an answer is kept, which device runs the check, and the limits. A lookup is never required before a send: read this page when your product shows, or decides something on, whether a contact uses iMessage.
The request
The response contains
handle in its normalized form: E.164 for a phone number, lower case for an email address. A handle that is neither a valid phone number nor a valid email address returns 400 validation_failed.
The three answers
A call that starts a check waits up to 3 seconds for the device’s answer before it returns
202. probe_id is the id of the check, lkp_ followed by 25 characters. No event announces the result of a check: repeat the request to get it. Each repeat counts against the limits.
The SDK resolves lookup.check() the same way on a 200 and on a 202: branch on pending.
How long an answer is kept
iSnap keeps a definite answer,true or false, for 24 hours, and returns it to every caller of iSnap, whatever the account. An answer can therefore be up to 24 hours old, and come from a check that another account started.
An unknown result is not kept. It only prevents a new check of that handle for 60 seconds.
Which device checks
A check runs on the device of one of your lines. The device asks Apple whether the handle is registered with iMessage.- With
from_line_id, the check runs only on that line’s device: when that device cannot run it, the answer isimessage: nullunless a definite answer is already kept for the handle, even when another of your lines could run the check. Without it, the check runs on the device of any of your lines that can run checks. - The device must be connected, and must support lookups. Rented iMessage lines do. A BYOD line does when
lookup_probeisactiveonGET /v1/lines/{id}/health: see Device features. - When none of your lines can run a check, for example when you own only shared lines, which have no device of their own, the answer is
imessage: null, unless a definite answer is already kept for the handle.
from_line_id.
Limits
- Every call that passes validation counts: an answer from the 24-hour store, a
202and a repeat of a pending check count against every limit that applies to the call. A call refused with429 lookup_rate_limit_exceededcounts against the limit that refused it and the limits checked before it, in this order: the account limit, the hourly limit of the line, the daily limit of the line. A call refused with400or404counts against no limit. - The two limits per line apply only to calls that give
from_line_id. - The windows are calendar windows, not rolling ones: they reset at the start of each UTC hour and each UTC day.
- An
isnap_test_key counts against the same limits as anisnap_live_key.
429 lookup_rate_limit_exceeded, with Retry-After set to the seconds until the next UTC hour or the next UTC day. In the SDK it is a QuotaExceededError, and the SDK does not retry it.
Lookups and sending
- A lookup is never required before a send, and a send never waits for one.
- A lookup counts against no sending limit.
imessage: truefor an email address does not make it a recipient:POST /v1/messagestakes a phone number only, and returns400 bad_requestfor an email address.- The line’s device chooses the service of each message when it sends it: see Services and fallback.
Errors
The refusals of the operation are on its reference page:POST /v1/lookup. The errors that every operation shares are in Errors.