All integrations

Saperly

MESSAGING · MESSAGING

Phone numbers, the AI voice connections they run on, and SMS in that account.

Acts as the person, not as itself

Each user connects their own account. Every call carries both identities — the agent and the person it is acting for — so the agent can never reach past what that individual can already do.

Credentials never touch the agent

Tokens live in the vault and attach server-side at call time. The agent holds a session, not a secret, and revoking access does not mean rotating a key.

Every call on the record

Who asked, which agent acted, which action ran, and the verdict that let it through — one audit trail across every integration, not one per vendor.

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.

saperly_delete_connections_by_idWRITE

Delete a connection. (DELETE https://api.saperly.com/connections/{id})

api
saperly_get_callsREAD

List calls. (GET https://api.saperly.com/calls)

api
saperly_get_calls_by_idREAD

Get a call by id. (GET https://api.saperly.com/calls/{id})

api
saperly_get_calls_by_id_recordingREAD

Get a call recording (302 redirect to a download URL). Saperly answers this with a 302 to a time-limited download URL rather than with audio. This integration does not stream the media through the gateway: it follows the redirect and returns a JSON descriptor naming the resolved `url`, `contentType` and `contentLength`, so fetch the recording from that URL. (GET https://api.saperly.com/calls/{id}/recording)

api
saperly_get_calls_by_id_transcriptREAD

Get a call transcript. (GET https://api.saperly.com/calls/{id}/transcript)

api
saperly_get_connectionsREAD

List all connections in the workspace. (GET https://api.saperly.com/connections)

api
saperly_get_connections_by_idREAD

Get a connection by id. (GET https://api.saperly.com/connections/{id})

api
saperly_get_consentREAD

List all consent records in the workspace. (GET https://api.saperly.com/consent)

api
saperly_get_consent_checkREAD

Check whether a contact has active consent. (GET https://api.saperly.com/consent/check)

api
saperly_get_healthREAD

Liveness probe. NEEDS NO CREDENTIAL: measured 2026-09-16, this route answers 200 {"status":"ok"} with no Authorization header at all. It proves the Saperly API is reachable, NOT that this connection's key is valid -- call any other tool for that. (GET https://api.saperly.com/health)

api
saperly_get_languagesREAD

List the supported spoken languages. (GET https://api.saperly.com/languages)

api
saperly_get_messagesREAD

List messages (optionally filtered by number). (GET https://api.saperly.com/messages)

api
saperly_get_numbersREAD

List all phone numbers in the workspace. (GET https://api.saperly.com/numbers)

api
saperly_get_numbers_by_idREAD

Get a phone number by id. (GET https://api.saperly.com/numbers/{id})

api
saperly_get_pricing_quoteREAD

Quote the price of a phone number. (GET https://api.saperly.com/pricing/quote)

api
saperly_get_usageREAD

Get a usage summary (optionally since a timestamp). (GET https://api.saperly.com/usage)

api
saperly_get_voicesREAD

List available voices (optionally filtered by language). (GET https://api.saperly.com/voices)

api
saperly_get_workspaces_by_slug_audit_eventsREAD

List the workspace audit-log events. `slug` must be the workspace this connection's key belongs to: measured 2026-09-16, the key reaches these routes, and any OTHER slug answers 403 {"_tag":"AuthorizationDenied","reason":"token is not scoped to this workspace"} -- a distinct reason from the bogus-key "invalid_or_insufficient_token". (GET https://api.saperly.com/workspaces/{slug}/audit-events)

api
saperly_get_workspaces_by_slug_membersREAD

List the workspace members. `slug` must be the workspace this connection's key belongs to: measured 2026-09-16, the key reaches these routes, and any OTHER slug answers 403 {"_tag":"AuthorizationDenied","reason":"token is not scoped to this workspace"} -- a distinct reason from the bogus-key "invalid_or_insufficient_token". (GET https://api.saperly.com/workspaces/{slug}/members)

api
saperly_get_workspaces_by_slug_webhooksREAD

List the workspace webhook endpoints. Returns every webhook endpoint for the workspace, each including its full `signingSecret` (`whsec_…`) — the reveal surface, so the secret can be re-copied at any time to verify delivery signatures. `slug` must be the workspace this connection's key belongs to: measured 2026-09-16, the key reaches these routes, and any OTHER slug answers 403 {"_tag":"AuthorizationDenied","reason":"token is not scoped to this workspace"} -- a distinct reason from the bogus-key "invalid_or_insufficient_token". SIGNING SECRETS ARE REDACTED: each endpoint's `signingSecret` is replaced with a placeholder by this integration before the response reaches you -- a webhook signing secret can forge deliveries your system would accept as genuine, and a tool answer is replayed into transcripts and logs. Every other field is the provider's own. Read the real secret in Saperly: Settings > Webhooks. (GET https://api.saperly.com/workspaces/{slug}/webhooks)

api
saperly_get_workspaces_by_slug_webhooks_by_webhookid_deliveriesREAD

List a webhook endpoint's recent delivery attempts. Returns the endpoint's most recent delivery attempts (newest first), each with the event type, outcome (`delivered`/`failed`), HTTP `responseStatus`, attempt number, and timestamps — so you can see exactly why a delivery did or didn't land (e.g. a run of `failed` with `responseStatus: 530` means your receiver is unreachable). `slug` must be the workspace this connection's key belongs to: measured 2026-09-16, the key reaches these routes, and any OTHER slug answers 403 {"_tag":"AuthorizationDenied","reason":"token is not scoped to this workspace"} -- a distinct reason from the bogus-key "invalid_or_insufficient_token". (GET https://api.saperly.com/workspaces/{slug}/webhooks/{webhookId}/deliveries)

api
saperly_patch_connections_by_idWRITE

Update a connection (re-syncs the carrier). (PATCH https://api.saperly.com/connections/{id})

api
saperly_post_api_tokensWRITE

Mint a scoped API key. (POST https://api.saperly.com/api-tokens)

api
saperly_post_api_tokens_by_id_revokeWRITE

Revoke an API key. (POST https://api.saperly.com/api-tokens/{id}/revoke)

api
saperly_post_assistant_answerWRITE

Ask the workspace assistant a question. (POST https://api.saperly.com/assistant/answer)

api
saperly_post_callsWRITE

Place an outbound call. (POST https://api.saperly.com/calls)

api
saperly_post_calls_by_id_endWRITE

End a live call. (POST https://api.saperly.com/calls/{id}/end)

api
saperly_post_calls_by_id_transferWRITE

Blind-transfer a live call. (POST https://api.saperly.com/calls/{id}/transfer)

api
saperly_post_connectionsWRITE

Create a connection (provisions inline). (POST https://api.saperly.com/connections)

api
saperly_post_consentWRITE

Record consent for a contact. (POST https://api.saperly.com/consent)

api
saperly_post_consent_revokeWRITE

Revoke consent for a contact. (POST https://api.saperly.com/consent/revoke)

api
saperly_post_messagesWRITE

Send an SMS message. (POST https://api.saperly.com/messages)

api
saperly_post_numbersWRITE

Provision a phone number. (POST https://api.saperly.com/numbers)

api
saperly_post_numbers_by_id_caller_idWRITE

Set the outbound caller ID name (CNAM). (POST https://api.saperly.com/numbers/{id}/caller-id)

api
saperly_post_numbers_by_id_connectionWRITE

Bind a connection to a number. (POST https://api.saperly.com/numbers/{id}/connection)

api
saperly_post_numbers_by_id_releaseWRITE

Release a phone number. (POST https://api.saperly.com/numbers/{id}/release)

api
saperly_post_numbers_by_id_sms_senderWRITE

Set the alphanumeric SMS sender id. (POST https://api.saperly.com/numbers/{id}/sms-sender)

api
saperly_post_numbers_by_id_webhookWRITE

Set a number's manual-mode brain URL. Sets the per-number manual-mode conversation-brain URL (a fallback for the connection's `manualWebhookUrl`). NOT an event-notification webhook — to receive call/SMS events, register a workspace webhook endpoint via `POST /workspaces/:slug/webhooks`. (POST https://api.saperly.com/numbers/{id}/webhook)

api
saperly_post_workspaces_by_slug_api_tokensWRITE

Create a scoped API token. `slug` must be the workspace this connection's key belongs to: measured 2026-09-16, the key reaches these routes, and any OTHER slug answers 403 {"_tag":"AuthorizationDenied","reason":"token is not scoped to this workspace"} -- a distinct reason from the bogus-key "invalid_or_insufficient_token". (POST https://api.saperly.com/workspaces/{slug}/api-tokens)

api
saperly_post_workspaces_by_slug_api_tokens_by_tokenid_revokeWRITE

Revoke an API token. `slug` must be the workspace this connection's key belongs to: measured 2026-09-16, the key reaches these routes, and any OTHER slug answers 403 {"_tag":"AuthorizationDenied","reason":"token is not scoped to this workspace"} -- a distinct reason from the bogus-key "invalid_or_insufficient_token". (POST https://api.saperly.com/workspaces/{slug}/api-tokens/{tokenId}/revoke)

api
saperly_post_workspaces_by_slug_invitationsWRITE

Invite a member by email. `slug` must be the workspace this connection's key belongs to: measured 2026-09-16, the key reaches these routes, and any OTHER slug answers 403 {"_tag":"AuthorizationDenied","reason":"token is not scoped to this workspace"} -- a distinct reason from the bogus-key "invalid_or_insufficient_token". (POST https://api.saperly.com/workspaces/{slug}/invitations)

api
saperly_post_workspaces_by_slug_webhooksWRITE

Create a webhook endpoint. Registers an outbound webhook endpoint and returns it with its full `signingSecret`. Use the secret to verify each delivery’s `x-saperly-signature: v1=<hex>` header (HMAC-SHA256 over `${x-saperly-timestamp}.${rawBody}`). `slug` must be the workspace this connection's key belongs to: measured 2026-09-16, the key reaches these routes, and any OTHER slug answers 403 {"_tag":"AuthorizationDenied","reason":"token is not scoped to this workspace"} -- a distinct reason from the bogus-key "invalid_or_insufficient_token". SIGNING SECRET IS REDACTED: Saperly returns the new endpoint's `signingSecret` here and this integration replaces it with a placeholder, for the reason above. The webhook IS created and every other field is real; read its secret in Saperly: Settings > Webhooks. (POST https://api.saperly.com/workspaces/{slug}/webhooks)

api

Put Saperly behind one governed endpoint.

Same permissions, same audit trail, whatever else you connect next.