API reference

Opt-outs

Every recipient can opt out of receiving messages from your account. BlueReplies auto-detects opt-out keywords on inbound messages and blocks future sends to that recipient — across all your lines.

Automatic opt-out detection

We watch every inbound message for these keywords (case-insensitive):

STOP STOPALL UNSUBSCRIBE END QUIT CANCEL OPTOUT REVOKE

When matched, we automatically:

  • Insert a row in opt_outs
  • Fire a contact.opted_out webhook
  • Block all future /v1/messages sends to that phone number with 409 CONFLICT + error.details.reason: "opted_out"
  • Send a one-time auto-reply confirming the opt-out (configurable per-account)

STOP isn't iMessage policy

Unlike SMS, iMessage doesn't enforce STOP at the carrier level. We enforce it ourselves because spam reports are the #1 reason lines get flagged.

List opted-out phones

GET/v1/opt-outs

Query

FieldTypeDescription
limitintegerMax 100. Default 25.
cursorstring
sincestringISO 8601. Only opt-outs after this timestamp.

Manually opt-out a number

POST/v1/opt-outs
{
"phoneNumber": "+15551234567"
}

Bulk opt-out

POST/v1/opt-outs/bulk

Up to 500 phone numbers per request.

Re-allow a number (opt back in)

DELETE/v1/opt-outs/:phoneNumber

Get explicit consent first

Only remove an opt-out if the recipient explicitly re-confirms they want to receive messages. Otherwise you risk spam reports that get your line banned — see rate limits.

Send-time behavior

Attempting to send to an opted-out number:

HTTP/1.1 409 Conflict
{
"error": {
"code": "CONFLICT",
"message": "Recipient has opted out",
"details": {
"reason": "opted_out",
"optedOutAt": "2026-05-19T14:21:09Z",
"matchedKeyword": "STOP"
}
}
}

Handle this in your code by marking the contact as inactive — don't keep retrying.