API reference
Blacklist
A tenant-scoped phone blacklist: full audit history (one row per write), Redis-backed hot reads, and a one-shot 'unblacklist' for support cases.
Resource model. Each write produces a new PhoneBlacklist row — there is no unique constraint on (tenantId, phone). That keeps a full audit trail of who added the number, when, and why. Membership checks are deduplicated at read time via Redis.
?filter_blacklist=true on POST /v1/:phoneNumberId/messages and SigFollow rejects calls to blacklisted recipients with HTTP 422. Without the flag, the blacklist is informational only (use /v1/blacklist/check in your own pipeline).Check a phone
/v1/blacklist/checkScope: blacklist:read
Hot-path membership query. First lookup hits the database and caches the positive result in Redis for 60s; subsequent calls in that window skip the database. Phone normalization is server-side.
| Name | Type | Required | Description |
|---|---|---|---|
| phone | string | yes | Phone to check, 5–32 chars after normalization. |
Example
curl -G https://api.sigfollow.com/v1/blacklist/check \
-H "Authorization: Bearer sflo_live_xxx" \
--data-urlencode "phone={{Recipient-Phone-Number}}"Response
{
"phone": "{{Recipient-Phone-Number}}",
"blacklisted": true
}phone echoes your original input (not the normalized form). blacklisted is true if at least one active blacklist row matches the normalized phone.
Add to blacklist
/v1/blacklistScope: blacklist:write
Creates a new row. Same phone written twice produces two rows— that's by design for audit. To "overwrite" semantics, call remove by phone first.
Body
| Name | Type | Required | Description |
|---|---|---|---|
| phone | string | yes | Phone to block. Normalization tolerant. |
| reason | string | no | Audit note, max 500 chars. Recommended for downstream traceability. |
Example
curl -X POST https://api.sigfollow.com/v1/blacklist \
-H "Authorization: Bearer sflo_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"phone": "{{Recipient-Phone-Number}}",
"reason": "Reported as spam by customer support"
}'Response
{
"id": "cm5bl123abcdef",
"tenantId": "cm5xy000tenant",
"phone": "{{Recipient-Phone-Number}}",
"source": "API",
"reason": "Reported as spam by customer support",
"sessionId": null,
"aiAgentId": null,
"createdById": null,
"createdAt": "2026-05-13T22:40:00.000Z"
}Update reason
/v1/blacklist/:idScope: blacklist:write
Only reason is mutable — phone, source, and provenance fields are immutable audit columns. Pass null or omitreason to clear / leave unchanged.
Example
curl -X PATCH https://api.sigfollow.com/v1/blacklist/cm5bl123 \
-H "Authorization: Bearer sflo_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "reason": "Updated after re-verification" }'reason as currently stored is detected server-side and skipped — no database write, no audit noise. Use this to safely retry PATCH calls.Delete one row
/v1/blacklist/:idScope: blacklist:write
Deletes a single historical row. Other rows for the same phone remain — the phone stays blacklisted while at least one row exists. Use this when you need to remove a specific bad entry but keep the rest of the audit trail.
Example
curl -X DELETE https://api.sigfollow.com/v1/blacklist/cm5bl123 \
-H "Authorization: Bearer sflo_live_xxx"Un-blacklist a phone
/v1/blacklist/by-phoneScope: blacklist:write
Wipes allrows for a given phone. The typical "remove from blacklist" customer support flow. Idempotent — returns removed: 0when the phone wasn't on the list.
| Name | Type | Required | Description |
|---|---|---|---|
| phone | string | yes | Phone to clear, normalization tolerant. |
Example
curl -X DELETE -G https://api.sigfollow.com/v1/blacklist/by-phone \
-H "Authorization: Bearer sflo_live_xxx" \
--data-urlencode "phone={{Recipient-Phone-Number}}"Response
{ "removed": 2 }