1Open Slashspace and go to Settings, then Connectors.
2On Discover, search for Saperly and click Connect.
3Sign in to Saperly in your browser. Slashspace updates when the account is connected.
Then ask for what you need in any Agent mode chat. Saperly is on in every chat unless you switch it off.
What your chats can do
30 tools from Saperly.
Bind Connection to NumberAttach a connection (the AI persona / answering brain from SAPERLY_CREATE_CONNECTION) to a phone number, so inbound calls and SMS to that number — and outbound calls placed from it — are handled by that connection. A number without a bound connection cannot answer calls (and PLACE_CALL fails with 422 NumberHasNoConnection), so this is the wiring step that makes a number answerable. Get a connection id from SAPERLY_LIST_CONNECTIONS or create one with SAPERLY_CREATE_CONNECTION. Returns the updated number object. Free.
Check ConsentCheck whether a contact currently has active TCPA consent for one of your Saperly numbers, given numberId (your number) and peerNumber (the contact's E.164 number) as query params. Returns {hasConsent: boolean} and, when hasConsent is true, {type: '<consentType>'} (the 'type' key is ABSENT when hasConsent is false). Saperly REFUSES outbound SMS (SAPERLY_SEND_SMS) and voice calls (SAPERLY_PLACE_CALL) — both of which are paid, balance-metered — to a destination without active consent, so call this free, read-only check FIRST to decide whether you need SAPERLY_RECORD_CONSENT before spending on a paid send/call that would otherwise fail the compliance gate. No side effects.
Create ConnectionCreate a connection: the AI 'brain' that answers calls and (optionally) SMS on a Saperly phone number. A phone number binds to a connection via SAPERLY_ASSIGN_NUMBER_CONNECTION in order to answer calls. Only `name` is required. mode 'hosted' (default) = an in-network STT->LLM->TTS voice assistant driven by `instructions` (the system prompt), `tts` voice (voiceId from SAPERLY_LIST_VOICES), and `language`; mode 'manual' = your own webhook brain (set `manualWebhookUrl`). complianceEnabled defaults true — Saperly then speaks a TCPA `disclosure` as the first uninterruptible utterance, auto-filling a standard org-named disclosure if you leave it empty. Returns the created connection (201). Free. (The 'backend' field is intentionally not exposed: only 'network' works; 'openai_realtime' is server-rejected.)
Delete ConnectionPERMANENTLY AND IRREVERSIBLY delete a connection (the AI answering brain / persona that handles calls and SMS) by its id. THIS CANNOT BE UNDONE — there is no restore. WARNING: any phone number currently bound to this connection will immediately STOP handling inbound calls and SMS (it has no answering brain) until you bind another connection to it. Before deleting, call SAPERLY_LIST_NUMBERS to check which numbers reference this connectionId, and rebind them with SAPERLY_ASSIGN_NUMBER_CONNECTION first. Returns { status: 'deleted' }. Free, but destructive.
End CallEnd an in-progress call by its id, hanging up and settling the metered cost. This is the safe, cheap, RECOMMENDED companion to SAPERLY_PLACE_CALL: placing a call starts per-minute billing, and this tool is how an agent stops that meter — call it as soon as you are done with the call. Ending is itself free (it ends spend rather than adding it). Returns the call object; durationSec and costCents may still be NULL if the call has not settled yet (null does NOT mean free — poll SAPERLY_GET_CALL afterwards for the final cost and duration). Only meaningful while a call is live; ending an already-ended call is a best-effort no-op.
Get CallFetch a single call by its id, returning its status, per-minute rate, final duration (durationSec) and cost (costCents), and the hasRecording / hasTranscript flags. costCents and durationSec are NULL until the call settles (in progress / not yet billed) — null does NOT mean free, so this is the tool to poll after SAPERLY_PLACE_CALL to learn a call's final cost and duration. Check hasRecording / hasTranscript before calling SAPERLY_GET_CALL_RECORDING / SAPERLY_GET_CALL_TRANSCRIPT: those artefact endpoints 404 until the call has ended and been processed, and a 404 there means 'no artefact yet', not 'no such call'. Free, read-only.
Get Call RecordingGet the audio recording for a call and return it as a downloadable file. The API answers with a 302 redirect to a signed download URL when a recording exists; the recording is fetched and returned as a file reference (under `content`). A recording exists only if the call's connection had recordingEnabled=true AND the call actually connected and completed — so for many calls there is simply no recording. The endpoint uses the same 404 response for an unknown call and a call without an artifact, so verify the id and check SAPERLY_GET_CALL.hasRecording=true before calling this. Free, read-only.
Get Call TranscriptFetch the transcript (conversation turns/segments) of a completed call by its id. Transcripts only exist AFTER a call connects, ends, and is processed. The endpoint uses the same 404 for an unknown call and a valid call whose transcript is not ready. Before calling this, poll SAPERLY_GET_CALL until the call has settled (durationSec / costCents are non-null) and hasTranscript is true. The returned payload is exposed under a 'transcript' key with call metadata and ordered role/text/timestamp turns. Free, read-only.
Get ConnectionFetch a single connection (the AI answering brain / persona that handles calls and SMS) by its id, returning its full config: name, mode, backend, instructions, tts voice, language, compliance/disclosure settings, recordingEnabled, and manual webhook URL. Sensitive signing secrets are redacted. Use after SAPERLY_LIST_CONNECTIONS to inspect one connection. Free, read-only.
Get Phone NumberFetch a single phone number by its id, returning its E.164 phoneNumber, bound connectionId, webhookUrl, country, numberType, pricing and lifecycle fields. Use after SAPERLY_LIST_NUMBERS to inspect one number's current configuration. Free, read-only.
Get Usage & BalanceReturn the workspace usage summary and prepaid balance: calls {count, totalCostCents, totalDurationSec}, messages {count}, and balanceCents (the prepaid balance, in cents). ALWAYS call this before any paid action to check balanceCents: SAPERLY_PROVISION_NUMBER (~$2/mo), SAPERLY_SEND_SMS (~2c/segment) and SAPERLY_PLACE_CALL (~26c/min) all draw down this single balance, and a depleted (0) balance causes them to fail. This is also the best whoami / key check: a 200 confirms the connected key is valid and which workspace it maps to (prefer it over /health for that). Pass the optional 'since' (ISO-8601) to scope the usage window. Free, read-only, no pagination.
List CallsReturn the full voice-call history (inbound + outbound) for the connected Saperly workspace. Each call carries its id, numberId, direction, to and from_number (E.164), status, rateCentsPerMin, durationSec, costCents, hasRecording and hasTranscript. Note: durationSec and costCents are null until the call settles (null means 'not yet settled', not 'free'). Use the id with SAPERLY_GET_CALL for full detail, and check hasRecording / hasTranscript before calling SAPERLY_GET_CALL_RECORDING / SAPERLY_GET_CALL_TRANSCRIPT (they 404 when the artifact does not exist yet). Read-only and free. Returns a bare array — there is no pagination and no filter parameter.
List ConnectionsReturn every connection (the AI persona / answering 'brain' that handles calls and SMS) in the connected Saperly workspace. Each carries id, name, mode (hosted|manual), backend, instructions, llm, tts voice, language, mcpServers, callControl, complianceEnabled, smsAutoReply, disclosure and recordingEnabled. Use this to find a connectionId to bind to a number or use on a call. Read-only and free. Returns a bare array (no pagination).
List Consent RecordsReturn every TCPA consent record in the connected Saperly workspace, with each record's id, numberId (the Saperly number contact is authorized FROM), peerNumber (the contact's E.164 number), consentType (explicit_outbound or implied_inbound), source, grantedAt and revokedAt. Consent is Saperly's compliance gate: outbound SMS (SAPERLY_SEND_SMS) and calls (SAPERLY_PLACE_CALL) are only permitted to a destination that has an active consent record, and these records form an immutable TCPA audit trail. Use this to review or export the full consent log; to check a single contact instead, use SAPERLY_CHECK_CONSENT. Read-only and free. Returns a bare array (no pagination).
List LanguagesReturn the spoken languages Saperly supports for voice connections, each as a {code, name} pair (about 42 entries, e.g. {'code':'en','name':'English'}). A language `code` is what you pass as a connection's `language` field, and as the `language` filter to SAPERLY_LIST_VOICES (that filter does a PREFIX match, so 'fr' also matches regional variants such as 'fr-CA'). Note this base-code set is narrower than the /voices language tags, which include regional variants. Read-only and free. Returns a bare array (no pagination).
List MessagesReturn SMS messages in the connected Saperly workspace (both inbound and outbound). Each message has id, numberId, direction, to, from_number, body, segments, status and createdAt. Pass `numberId` to filter to a single phone number's messages; `numberId` is the ONLY filter available. With no filter this returns the FULL message history, which may be large — there is no pagination. Free and read-only; returns a bare array.
List Phone NumbersReturn every phone number provisioned in the connected Saperly workspace, with each number's id, phoneNumber (E.164), the connectionId (answering brain) bound to it, webhookUrl, country, numberType, monthlyPriceCents and lifecycle timestamps. Use this to discover a number's id before sending SMS, placing a call, or configuring the number. Read-only and free. Returns a bare array (no pagination).
List VoicesList the text-to-speech voices available for Saperly connections. Each voice has an id, name, gender and language; a voice id is what you pass as tts.voiceId when creating or updating a connection (SAPERLY_CREATE_CONNECTION / SAPERLY_UPDATE_CONNECTION). ALWAYS pass `language` to filter — the unfiltered list is ~751 voices across 52 language tags, which is expensive to return in full. NOTE the filter is a PREFIX/family match, not exact: language='fr' returns both 'fr' and 'fr-CA'. Get language codes from SAPERLY_LIST_LANGUAGES. Read-only and free; returns a bare array (no pagination).
Place CallPAID / METERED — places a REAL outbound voice call that RINGS A REAL PHONE and BILLS PER MINUTE (~26¢/min); it keeps billing until hung up — end it with SAPERLY_END_CALL to stop the meter. Calls FROM a Saperly number (`fromNumberId` from SAPERLY_LIST_NUMBERS) TO an E.164 destination (`to`, e.g. +14155550123). The connection bound to the originating number answers; a number with NO bound connection cannot hold a conversation (bind one with SAPERLY_ASSIGN_NUMBER_CONNECTION). Optionally override the brain for this call with `connectionId` and/or a per-call `instructions` prompt. CONSENT GATE (TCPA): the destination MUST have active consent — call SAPERLY_RECORD_CONSENT first and SAPERLY_CHECK_CONSENT to verify, or it is rejected (403). Returns the call (201) with id + status; `durationSec`/`costCents` are NULL until the call settles (ends) — null does NOT mean it was free. Pass `idempotency_key` on retries to avoid double-dialing. May fail 402 (funds) or 422 (no connection).
Provision Phone NumberPAID / METERED: provision (buy) a new phone number in a country. This SPENDS MONEY — it charges the workspace prepaid balance an upfront fee plus a RECURRING MONTHLY rent (US local ~ $1.79/mo, varies by country/type). Before calling this: (1) call SAPERLY_QUOTE_NUMBER_PRICE to get the live price and pass it as expectedMonthlyPriceCents / expectedUpfrontPriceCents to guard against price drift (a higher live price fails with 409 PriceChanged unless approveHigherPrice=true); (2) confirm sufficient funds by checking balanceCents via SAPERLY_GET_USAGE. Defaults country='US', numberType='local'. Pass an idempotency_key to avoid double-provisioning on retry. Fails 402 (InsufficientFunds / PaymentMethodRequired), 403 (CountryNotAvailable), 404 (NoNumbersAvailable), 409 (NumberQuotaExceeded / PriceChanged).
Quote Number PriceREAD-ONLY and FREE: quote the price to provision a phone number in a country/type, returning { customerMonthlyCents, customerUpfrontCents }. This DOES NOT provision, reserve, or charge anything — despite the name it has NO side effects. This is exactly the tool to call BEFORE the expensive SAPERLY_PROVISION_NUMBER (which spends ~$2/mo): (1) use it to size the cost and feed customerMonthlyCents / customerUpfrontCents straight into SAPERLY_PROVISION_NUMBER's expectedMonthlyPriceCents / expectedUpfrontPriceCents price-drift guards (the safe provisioning pattern); (2) compare against balanceCents from SAPERLY_GET_USAGE to confirm sufficient funds. Both country and numberType are required. Live-verified: US/local quoted 179 cents monthly and 179 cents upfront.
Record ConsentRecord TCPA consent for a contact so outbound SMS (SAPERLY_SEND_SMS) and calls (SAPERLY_PLACE_CALL) from your number are permitted. Saperly's compliance gate: for a cold contact call this BEFORE sending; confirm with SAPERLY_CHECK_CONSENT, revoke with SAPERLY_REVOKE_CONSENT. LEGAL ARTEFACT — DO NOT FABRICATE CONSENT: it writes to an IMMUTABLE audit trail asserting a real human gave consent to be contacted. Only record consent ACTUALLY obtained (an opt-in the contact gave, or an inbound message/call they initiated). Recording consent not truly obtained is a false compliance record and a legal violation; never do it merely to unblock a send. Requires numberId (your number, from SAPERLY_LIST_NUMBERS), peerNumber (the contact's E.164 number), consentType ('explicit_outbound' = opted in, or 'implied_inbound' = they contacted you first — legally distinct), and source (a note on how/where consent was obtained). Returns 201 with the record. Free.
Release Phone NumberPERMANENTLY AND IRREVERSIBLY release a phone number back to the carrier. THIS CANNOT BE UNDONE: the number leaves the workspace, is returned to the carrier pool, and CANNOT be recovered or reclaimed. Inbound calls and SMS to it STOP IMMEDIATELY, and its monthly rent stops (releasedAt is set). Only call this to permanently decommission a number you are certain you no longer want — there is no undo. Free, but destructive.
Revoke ConsentRevoke a contact's TCPA consent for a given Saperly number, blocking further outbound contact to them. CALL THIS WHEN A RECIPIENT SAYS 'STOP' / 'UNSUBSCRIBE' / 'do not contact me' — honoring an opt-out is a legal compliance obligation, and this is the primary legitimate use. OBSERVABLE EFFECT: once revoked, SAPERLY_SEND_SMS and SAPERLY_PLACE_CALL to this contact from this number are REFUSED (403 RecipientOptedOut) until consent is re-recorded with SAPERLY_RECORD_CONSENT. Consent records are an immutable audit trail: this does NOT delete the record — it marks it revoked by stamping a revokedAt timestamp, preserving the compliance history. Identify the contact by numberId (your number, from SAPERLY_LIST_NUMBERS) and peerNumber (the contact's E.164 number); no consentType is required. Pass idempotency_key to make retries safe. Returns { status: 'revoked' }. Free.
Send SMSPAID / METERED: send a single SMS from one of your Saperly numbers to an E.164 destination. This SPENDS REAL MONEY and sends a REAL text message to a REAL phone (~2 cents per 160-character segment; a long body is split into multiple segments, each billed). TCPA CONSENT GATE (required): the API refuses to send unless the recipient has an active consent record (or messaged you within the last 24h). For cold outbound you MUST first call SAPERLY_RECORD_CONSENT for the destination, and you can verify it with SAPERLY_CHECK_CONSENT — otherwise this fails with 403 RecipientOptedOut / compliance. Before sending, confirm sufficient funds via SAPERLY_GET_USAGE (balanceCents). Pass idempotency_key to prevent a double-send on retry. Returns 201 with the queued message (id, status, segments). NOTE the response echoes the sending number as 'numberId' and 'from_number' (not 'fromNumberId'). Fails 402 (InsufficientFunds / SpendLimitExceeded), 400 (DestinationNotSupported / invalid request).
Set Number Caller ID NameSet the outbound caller ID name / CNAM (1-15 characters: letters, digits, spaces) presented to recipients on outbound calls from a Saperly phone number, or pass callerIdName=null to CLEAR it. callerIdName is required — supply a name to set it, or null to unset it. Returns the updated number object. Note: CNAM display depends on the destination carrier and does not propagate instantly, so recipients may not see the change immediately. Free.
Set Number SMS Sender IDSet the alphanumeric SMS sender id (1-11 alphanumeric chars, e.g. a brand name) shown as the 'from' on outbound SMS from this number, or pass smsSenderId=null to CLEAR it. Returns the updated number object. NOTE: sender-id support and display vary by destination country/carrier (the US and Canada notably restrict alphanumeric sender ids). Free.
Set Number WebhookSet the HTTPS webhook URL that Saperly POSTs this number's events (inbound SMS/calls, status) to. The url is required and must be https://. Returns the updated number object. NOTE: this endpoint has no way to clear the URL back to null — once set it can only be changed to another URL, so set it deliberately. Free.
Transfer CallPAID / METERED — BLIND-transfers a LIVE, in-progress voice call to another destination `to` (an E.164 number like +15551230000, or a `sip:` URI). BLIND means the call is handed off UNCONDITIONALLY: there is NO confirmation from the transferee and the AI agent LOSES CONTROL of the call once transferred — treat it as a one-way, irrecoverable handoff. Only meaningful on a call that is actually connected/in-progress (identify it via SAPERLY_PLACE_CALL or SAPERLY_LIST_CALLS). The transferred leg KEEPS BILLING per minute, so this is not free — the meter runs on the new leg until the call ends. Returns the call object with its updated status; `durationSec` / `costCents` stay NULL until the call settles (null does NOT mean it was free). Pass `idempotency_key` on retries to avoid starting a second transfer leg. Fails 502 CallStartFailed if the transfer leg cannot be started, and 404 if the call id is unknown.
Update ConnectionPartially update a connection (the AI answering brain bound to a number). Send only the fields you want to change (name, mode, instructions, llm, tts, language, mcpServers, callControl, complianceEnabled, smsAutoReply, disclosure, manualWebhookUrl); every unset field is left untouched. Send mcpServers=[] to clear all tools, or manualWebhookUrl="" to clear it. Writing RE-SYNCS the carrier, so an update has side effects beyond the stored record. Returns 200 with the full updated connection. Free.