POST /v1/handle-check

Ask the transport behind a line whether an address can receive on its channel, before you try to send.

POST /v1/handle-check

Asks the transport behind a line whether an address can receive on its channel — on an iMessage line, Apple's directory. Use it to avoid sending into a void: a number that is Android-only, or an Apple ID that does not exist.

Unlike commands, this is a synchronous read. The answer is in the HTTP response; nothing arrives on the stream. A check is not a send: it does not assign the address to a line or spend a slot on a person you never message.

Request

Prop

Type

curl https://api.mapier.ai/v1/handle-check \
  -H "Authorization: Bearer $MAPIER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "address": "+14155550100", "channel": "imessage" }'

Response

200 — reachable
{ "address": "+14155550100", "channel": "imessage", "available": true, "reason": null }
200 — not reachable
{ "address": "+14155550100", "channel": "imessage", "available": false, "reason": "not_reachable" }

On an iMessage line, available: false means Apple's directory said the address is not on iMessage. When Apple's lookup cannot give an answer for the address, the check does not answer false: it fails with 503 line_unavailable — see When the check cannot run.

Prop

Type

When the check cannot run

A 503 line_unavailable carries details.reason. No reason is an answer about reachability — the question either never reached the transport or came back unusable. The words this platform mints are listed under Error codes; on an iMessage line the transport may answer with its own, which reach you as details.reason unchanged:

503
{
  "error": { "code": "line_unavailable", "message": "…", "details": { "reason": "read_in_flight" } }
}

On an iMessage line, an address Apple's directory holds no current answer for is looked up again; when that lookup still gives no answer, the check fails here with details.reason read_failed rather than answering available: false. Ask again later.

Reads run one at a time per line, so read_in_flight is common under concurrency. Check addresses serially, or cache the result — reachability rarely changes.

Errors

StatusCodeCause
400bad_requestThe body is not JSON, or the transport refused the request as malformed (details.reason is its word)
401invalid_credentialsNo key, or one that is unknown, revoked or expired
404not_foundThe transport's own not-found, with its word in details.reason; a project with no line to ask is the 503 no_line below
409project_archivedThe project is archived
413payload_too_largeBody over 65,536 bytes
422validation_failedaddress is missing or not a form the channel accepts
429rate_limited30 requests per minute, per key; the Retry-After header says how long to wait (a transport's own rate limit may give details.retryAfter instead)
500internal_errorAn unhandled failure, reported; details.requestId names the log line when present
503no_line · line_unavailable · upstream_unavailableNo line, the line cannot ask right now (see When the check cannot run), or the transport did not answer
503service_busyThe platform had no database connection free in time and did nothing; wait details.retryAfter seconds and ask again

On this page