Saperly
MESSAGING · MESSAGING
Phone numbers, the AI voice connections they run on, and SMS in that account.
Connecting Saperly in practice
Saperly enforces telephony compliance before the call rather than logging it afterwards: an outbound call or SMS to a number with no recorded consent is blocked before it leaves, and US A2P SMS only flows once a 10DLC brand is verified and a campaign approved. Keys are a single tier of sap_sk_live_ bearer tokens carrying read, write and admin scopes plus an optional number allow-list and a hard spend cap in cents.
Scopes that draw scrutiny
writePlaces calls, sends SMS, provisions and releases numbers, records consent and writes connections — every action that spends the prepaid balance.admin (the keys:admin capability)Mints child API keys. A child cannot exceed the parent’s scopes, number allow-list or spend cap, but a compromised admin key can still issue working credentials.readLists and reads numbers, connections, messages, calls, usage and consent records — which means conversation metadata and consent provenance.numberScope / spendLimitCentsNot scopes but the other two halves of a key’s grant: an allow-list of number IDs, and a hard cap in cents that returns SpendLimitExceeded rather than spending.
Rate limits
- Rate limiting surfaces as the typed error RateLimited at HTTP 429, carrying a `bucket` field naming which limit was hit, plus a Retry-After header. The docs do not publish per-bucket figures.
- Two other ceilings stop a request without being rate limits: InsufficientFunds (402, with balanceCents and requestedCents) and SpendLimitExceeded (402, with limitCents, priorSpendCents and requestedCents).
Worth knowing
- Retry a mutating call with the same Idempotency-Key. A fresh key on retry defeats the protection, the same key with a different body is rejected as IdempotencyKeyMismatch (422), and a replay while the first request is in flight gets IdempotencyConflict (409).
- Outbound to someone who opted out fails with RecipientOptedOut (403), not a silent drop, so opt-out state has to be handled as a first-class branch.
- A declined 10DLC campaign that you edit and resubmit is charged again as a new registration, and a carrier-suspended campaign keeps accruing monthly fees until you deactivate it.
- Leaving `disclosure` empty with complianceEnabled on makes Saperly speak a standard org-named AI disclosure; setting complianceEnabled to false removes the forced opener entirely, which is a compliance decision hidden in one boolean.
Checked against Authentication (2026-09-29), Errors and idempotency (2026-09-29), Compliance (2026-09-29), Saperly for agents (2026-09-29)
What an agent can do
Each action is granted on its own. An agent allowed to read is not thereby allowed to write, and the scope beside each row is what the acting user must have connected for it to run at all.
Often connected alongside
Put Saperly behind one governed endpoint.
Same permissions, same audit trail, whatever else you connect next.