Skip to main content

Overview

POST /check-imessage tells you whether a single address can receive an iMessage, before you spend a send on it. You pass one phone number or email address. You get back two booleans: imessage and rcs. POST /check-imessage-bulk does the same thing for up to 100 addresses in one call and returns a result for each one. Both endpoints are read only. Nothing is sent to the address, and the person on the other end sees nothing. They use POST instead of GET so contact data stays in the request body and never lands in a URL, a proxy log, or a browser history. Base URL for every BlueReacher endpoint:

Why check before you send

Checking first is the difference between a clean campaign and a broken one.
  • You stop burning sends. An iMessage aimed at an Android number cannot be delivered as an iMessage. Check first, and you route that contact to RCS or SMS instead of watching the send fail.
  • Your reply rate stays honest. Undeliverable addresses sit in your denominator and drag every campaign metric down. Filter them out before launch and your numbers describe real conversations.
  • Your line stays healthy. Repeatedly pushing traffic at addresses that cannot receive it is a bad pattern. BlueReacher gives you dedicated iMessage lines, managed for you, with no A2P registration required, and the fastest way to protect that line is to only message people who can actually receive the message.
  • Your list stays current. People switch phones. A number that was on iMessage in March can be on Android in July. A bulk check the morning of a send catches that.
  • Checks are free. Availability checks are not billed as messages and do not count against your message volume. Only rate limits apply.
The practical pattern: run check-imessage-bulk over your list right before a campaign, split the results into iMessage, RCS, and SMS groups, then send each group on the channel it can receive.

Authentication

Every request needs your API key in the Authorization header and a JSON content type:
Keys are workspace scoped and are created in your BlueReacher dashboard. Call these endpoints from your server. A key shipped in browser or mobile code can be read by anyone who opens the network tab.

Check one address

POST https://api.bluereacher.com/functions/v1/check-imessage Looks up a single address and returns its channel availability.

Request fields

No other fields are accepted. Unknown fields in the body are ignored.

Example request

Response fields

Successful lookups return 200 OK.

Example response

A number that is not on iMessage but can take RCS:

Error notes

400 with invalid_address is the one you will hit most. It almost always means the number was not in E.164. Normalize before you call: strip spaces, parentheses, and dashes, then add the country code. Full list in Errors.

Check up to 100 addresses

POST https://api.bluereacher.com/functions/v1/check-imessage-bulk Checks a batch of addresses in one call. Use this for list hygiene and pre-campaign segmentation. It is roughly ten times more throughput per minute than looping the single endpoint.

Request fields

Duplicates are collapsed and checked once. Results come back in the order each address first appears in your array, so you can zip them against your input after deduping.

Example request

Response fields

A well formed request returns 200 OK even when some addresses fail. Per-address problems live inside results, not in the HTTP status. Check results[].error on every item. Per-address error codes:

Example response

Error notes

The whole call fails with a 4xx only when the request itself is wrong: bad JSON, missing addresses, an empty array, or more than 100 entries. Anything address-specific comes back inside results with a 200.

Splitting a larger list

Lists longer than 100 have to be chunked. Both examples below also handle a 429 by waiting the number of seconds in the Retry-After header, then retrying the same chunk.

Picking a channel from the result

The channel field on a send accepts "imessage", "rcs", or "sms". Map the check straight onto it: Skip any result where error is not null. You do not know that contact’s availability, so do not guess a channel for it.

Freshness and caching

Results are cached for 24 hours per address. A repeat check inside that window returns the stored result, and checked_at shows the original lookup time rather than the time of your call. Compare checked_at to now if you need to know how fresh a result is. Cached responses still count against your rate limit. Two habits that keep this accurate:
  1. Check within 24 hours of sending, not weeks ahead. Availability changes when people change phones.
  2. Store imessage, rcs, and checked_at on your contact record. Re-check anything older than 24 hours instead of trusting a stale flag.

Rate limits

Limits are per API key, counted across your whole workspace, over a rolling 60 second window. Batching is the cheaper path by a wide margin. Use check-imessage-bulk for anything over a handful of addresses and save the single endpoint for real time lookups, like a form submission or a CRM record opening. Every response carries the current state of your limit: Going over returns 429 Too Many Requests:
Wait the number of seconds in Retry-After, then retry the same request. Both endpoints are read only and have no side effects, so retrying is always safe. If you are running a large list check on a schedule, watch X-RateLimit-Remaining and slow down before you hit zero rather than driving into 429s.

Errors

Errors use one shape across the whole API:
One rule worth writing into your code: never read an error as a negative result. imessage: false means the address cannot receive iMessage. An error means you do not know yet. Retry or hold the contact back instead of downgrading them to SMS on bad information.