Communications API
Send texts and emails, read and triage inbox conversations, manage opt-outs, phone numbers, call routing and the dialer through the Goliath developer API
About
Send texts and emails as the key owner; read the key owner’s inbox, full text and email threads, call recordings and meeting transcripts; mark inbox rows read, star or handle text threads; manage opt-outs and Do Not Contact; render content templates (spintax + merge tokens); and manage the organization’s phone numbers, inbound call routing and dialer settings.
All operations go through the developer API gateway — one endpoint, called by
operationId. If you haven’t set up a key yet, start with the
Developer API Overview.
Operations
Reading channels and conversations (READ scope)
| operationId | What it does |
|---|---|
listCommunicationChannels |
List every org phone line (each with its assigned user and canSendSms), the organization’s textingReadiness, the calling user’s connected mailboxes and, in myDisconnectedMailboxes, any mailbox of theirs that disconnected (with disconnectedAt). Call this first to pick a sending line or mailbox: your lines are those whose user.id equals currentUser.id. |
getSendingLimits |
How much can be texted and emailed today: per line, brand (team) and mailbox used / cap / remaining, a line’s last-7-day volume, the sending queue, and textingReadiness (whether the organization may text at all, and why not). |
getTextingRegistrationStatus |
The organization’s A2P 10DLC texting registration, status only: each brand (status, statusLabel, useCaseLabel) and its sending campaigns (sendReady true = approved and able to text; rejectionReasons when a carrier refused it). Registering, resubmitting and retrying happen in the app (Settings → Phone → Registration). |
getSendConsentAttestation |
Whether the organization’s send consent attestation stands: attested, attestedAt, attestedByUserId. Every operation that messages a contact is refused until it does. |
renderContentTemplate |
Render a content template against a contact: collapse [a|b] spintax and substitute {{merge}} tokens, returning the subject/body plus missingVariables. |
listInboxThreads |
Page the key owner’s unified text, call, and email inbox, with filters for unread, channel, response state, sender kind, sentiment, search, and teammate access. Pass all three returned channel cursors to the next request; the feed is complete only when all three are null. |
listContactTextThreads |
List text-thread ids, contactE164PhoneNumber, phoneLineId, and twilioPhoneNumberE164 for one contact, without message bodies. Use it to disambiguate before reading a thread. |
getTextThreadMessages |
Page one text conversation’s full message bodies (default 50, max 100), newest first by default. Requires contactPhoneNumber; pass conversationId for the exact thread or phoneLineId to pin its line. An empty list can mean the thread is absent or outside the key owner’s phone visibility. |
getEmailThread |
Read one email conversation oldest first, including plain-text bodies when available and attachment names. Returns the key owner’s copies and copies from mailboxes shared with the organization, deduplicated across its threads; a teammate’s private mailbox is not readable, even to an admin. |
getCallRecording |
Read one call’s time-limited recording URL, transcript, summary, disposition, and handler. Returns null when there is no recording, the call is outside the org, or the id does not exist. |
listMeetingSummaries |
The organization’s notetaker calls created after after, in any status, oldest first (limit default 25, at most 50 per page): each call’s status (COMPLETED and FAILED are terminal), its summary note id and text (null when the key owner may not read it), who sent the notetaker, the appointment title, and the meeting’s contacts. Page by advancing after to the last startedAt; read a transcript with getMeetingTranscript. |
getMeetingTranscript |
The speaker-by-speaker transcript behind a meeting-summary note, as a pageable window of ordered { speaker, text } utterances. Pass the noteId of the meeting-summary note (from getContact notes[] or a NOTE entry in listContactActivities). Capped at 300 utterances per call. Returns null — not an error — when the note isn’t a meeting-summary note, is hidden from the caller, or has no archive. |
listInboxThreads with channel: NEEDS_RESPONSE returns conversations where
the contact spoke last, excluding text threads a teammate has since marked
handled. A new inbound text makes a handled thread need a response again.
optedOut defaults to INCLUDE, retaining opted-out text threads for
integrations. Use EXCLUDE to hide threads suppressed by an opt-out or
Do Not Contact state as the app does, or ONLY to read just those threads.
starredOnly: true returns starred text threads. MESSAGE rows carry
isStarred and isNeedsReplyHandled; inbox and text-detail line ids are
named phoneLineId.
replySentiments: [POSITIVE] includes threads that had a positive reply and
have not opted out since. respondedOnly and replySentiments exclude calls;
sentBy applies to calls, but WORKFLOW matches no calls because calls carry
no campaign linkage. Without userIds, this is the key owner’s inbox.
Reading a teammate’s inbox requires VIEW_ALL_PHONES.
Sending texts and emails (WRITE scope)
| operationId | What it does |
|---|---|
sendText |
Send an SMS as the key owner to toPhoneNumber (E.164; an unparseable number is rejected up front with INVALID_PHONE_NUMBER). Omit fromPhoneLineId to use your assigned line; another user’s assigned line needs VIEW_ALL_PHONES (org-shared bulk lines don’t). Runs the checks the app’s composer runs: opt-out and Do Not Contact, the A2P campaign gate, send throttles and daily caps, find-or-create the contact from the number, and conversation + activity logging. Honors Idempotency-Key. |
sendEmail |
Send an email as the key owner through their connected Gmail or Outlook mailbox: fromClientId + fromEmail (from listCommunicationChannels), to, optional cc/bcc, subject, bodyHtml, and an optional contactId to attach it to that contact’s timeline. On failure ok is false and failureReason (NO_CONNECTED_MAILBOX, INVALID_SENDER, MAILBOX_MISSING_SEND_SCOPE, PROVIDER_SEND_FAILED) + failureMessage say why — except a Do-Not-Contact-blocked contactId, which returns a GraphQL error. No attachments or threading. Honors Idempotency-Key. |
Send consent attestation (ADMIN scope)
| operationId | What it does |
|---|---|
setSendConsentAttestation |
Attest (attested: true) or withdraw (false) the organization’s send consent: the admin who owns the key states once that every contact the organization messages through the API consented. Opens every operation that messages a contact to the organization’s developer-API keys. |
Inbox triage (WRITE scope)
| operationId | What it does |
|---|---|
markInboxThreadsRead |
Set isRead: true or false across channels. Pass MESSAGE row ids in textConversationIds, CALL row ids and all groupedCallIds in callIds, and EMAIL row ids in emailMessageIds. Text/call results are changed-row counts; email returns the affected rows. Inaccessible ids are skipped, so inspect the result. |
setInboxThreadStarred |
Set starred for one textConversationId, for everyone in the organization. Calls and emails cannot be starred. Returns false when the thread cannot be acted on. |
setInboxThreadHandled |
Mark a text thread as needing no reply, for everyone in the organization. Pass textConversationId and the newest inbound handledThroughMessageId you read; a newer reply keeps it in Needs reply. Explicit null clears the handled state. Returns false for an inaccessible thread or a message that is not its inbound. |
Dismissing inbox items (ADMIN scope)
| operationId | What it does |
|---|---|
dismissInboxItem |
Hide an inbox row using its itemId and itemType (MESSAGE, CALL, or EMAIL). A CALL dismisses that number’s whole day of calls; an EMAIL dismisses its whole thread. There is no undo or view of dismissed rows. |
Use markInboxThreadsRead to clear an unread badge. Confirm before
dismissing: the row disappears from future listInboxThreads results.
Opt-outs and Do Not Contact (WRITE scope)
| operationId | What it does |
|---|---|
suppressChannel |
Value-level opt-out — suppress a phone number or email address for your organization on one medium (SMS | VOICE | EMAIL). Keyed on the normalized value, not a contact: it blocks that channel for every contact carrying the value, present and future, enforced by the Do-Not-Contact guard on send. Suppresses only the medium you name — send a second request to also cover VOICE. Idempotent: re-suppressing re-activates the row without duplicating it. |
clearChannelSuppression |
Lift an organization-wide opt-out (suppressChannel’s undo): the value can be texted, called or emailed again on that medium, on every contact carrying it. Only on the recipient’s own word. Idempotent; a value that is not suppressed is a no-op. |
clearContactDoNotContact |
Take one contact off Do Not Contact, as the contact page’s toggle does, so texts, calls, emails and workflows reach them again. Only when the contact asked to be contacted again. A value-level opt-out on one of their numbers or addresses stays until clearChannelSuppression lifts it. |
Phone numbers (READ + ADMIN scopes)
| operationId | Scope | What it does |
|---|---|---|
searchAvailablePhoneNumbers |
READ |
Search for buyable numbers, optionally narrowed by areaCode (a 3-digit US area code). Returns candidates (E.164 phoneNumber plus locality and region) to feed provisionPhoneNumber. Searching costs nothing. |
provisionPhoneNumber |
ADMIN |
Buy a number returned by searchAvailablePhoneNumbers and assign it to targetUserId (normally the key owner; a user outside your organization is rejected). It shows at once in listCommunicationChannels, ready to send from. A number past the plan’s included numbers is refused (PHONE_NUMBER_ALLOWANCE_REFUSED) unless confirmExtraPhoneNumberCharge is true. Honors Idempotency-Key. |
getVoiceTrustSummary |
READ |
The organization’s caller-trust registration (what keeps calls from showing as “Spam Likely”): accountState (FAILED > REGISTERING > REGISTERED > SELF_MANAGED > NOT_ELIGIBLE, the loudest wins), line counts by registration and carrier health, and needsAttention — the one flag meaning a person must act now. Registration runs on its own schedule. |
setPhoneLineLabel |
WRITE |
Name a phone line (“Facebook campaign”), or label: null to clear it. Admins only. |
setPhoneLineRunsOnMetaAds |
WRITE |
Mark a tracking number as one the organization runs only on Meta ads (its calls are attributed there), or false to clear it. Admins only. |
Inbound call routing (READ + WRITE scopes)
| operationId | Scope | What it does |
|---|---|---|
getPhoneRouting |
READ |
Who answers an inbound call or text (the Automations Map’s Phone calls area): the organization’s default ring policy (humanStage — who rings first, for how long and when; aiStage — the AI employee that picks up a missed call), the default inbound setup (who gets a new contact), and each line with its override ids (null = follows the default). |
getPhoneLineRingPolicy |
READ |
One line’s own ring policy, in getPhoneRouting’s shape; null when the line follows the default. |
setOrgDefaultRingPolicy |
WRITE |
Replace the organization’s default ring policy — humanStage (targetKind, ringSeconds 5–60, its target, an optional schedule) then aiStage (AI employees whose calls are on, SINGLE or ROUND_ROBIN). It saves the whole policy, so read it first and send it back changed; an omitted schedule or area-code map keeps what is saved. policy: null deletes the default. |
setPhoneLineRingPolicy |
WRITE |
Replace one line’s own ring policy, in the same shape; policy: null deletes it and the line follows the default. |
Routing changes take effect from the next call — confirm the new path with the person before writing it. See also the Automations Map API and AI Employees API.
Bulk-dialing rotation (READ + WRITE + ADMIN scopes)
The numbers call lists dial out on.
| operationId | Scope | What it does |
|---|---|---|
getDialingPool |
READ |
The organization’s bulk-dialing rotation: each line (id, number, label), its calls today against its daily limit, restUntil, and the day’s room. |
getMyDialingRoom |
READ |
Whether the key owner can start a call list now: null when they have no phone line of their own, else linesInRotation and linesResting. None in rotation, or all resting, means a call list cannot dial. |
addNumbersToDialingPool |
WRITE |
Put numbers the organization already owns into the rotation. A teammate’s line is allowed; an AI employee’s is refused. Admins only. |
removeNumbersFromDialingPool |
WRITE |
Take numbers out of the rotation; they stay owned. Their warm-up restarts if they come back. Admins only. |
restDialingPoolNumber |
WRITE |
Bench one rotation line for the standard rest window; it returns on its own at restUntil. Admins only. |
unrestDialingPoolNumber |
WRITE |
Return a benched line to the rotation now, whoever benched it. Admins only. |
buyDialingPoolNumbers |
ADMIN |
Buy numbers straight into the rotation, each a recurring monthly charge: either count (with an optional preferred areaCode) or phoneNumbers (E.164s from searchAvailablePhoneNumbers; one taken meanwhile is a shortfall, never swapped). confirmExtraPhoneNumberCharge as provisionPhoneNumber. Mint one purchaseAttemptKey per intended purchase and resend it unchanged on every retry, so a lost response never buys twice. Returns addedLines and, when some failed, failure. |
Dialer settings (READ + WRITE scopes)
| operationId | Scope | What it does |
|---|---|---|
getCallWorkspaceSettings |
READ |
The dialer’s settings (Settings → Calls): auto-advance, the after-call actions in order, callCardFieldIds (contact custom fields on the call card), callerIdTableColumnId, and a person’s voicemail drops (userId, default the key owner). |
updateCallOutcome |
WRITE |
Record or correct a call’s outcome (disposition) and note (at most 280 characters), as the dialer’s outcome step does — by callSid, or by contactId for the key owner’s latest outbound call to that contact. Sends nothing. |
reorderAfterCallActions |
WRITE |
Order the after-call actions the dialer offers: items list every kind once with its displayOrder. Admins only. |
setCallCardFields |
WRITE |
Replace the contact custom fields shown on the call card (at most 8, in order); send the whole list. Admins only. |
setCallerIdTableColumn |
WRITE |
Set the PHONE_LINE Workflow Table column the dialer reads each contact’s outbound caller ID from, or null to stop. Admins only. |
renameVoicemailTemplate |
WRITE |
Rename a voicemail drop (templateId from getCallWorkspaceSettings). |
reorderVoicemailTemplates |
WRITE |
Set the order of a person’s voicemail drops: items are { id, displayOrder } for that userId. |
deleteVoicemailTemplate |
WRITE |
Delete a voicemail drop. It leaves the dialer at once and nothing restores it; the person records it again. |
Example
Opt a phone number out of SMS for your whole organization. Suppression is keyed on the normalized value, so it covers every contact carrying that number:
curl -X POST https://server.goliathdata.com/api/v1/call \
-H "Authorization: Bearer gsk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"operationId": "suppressChannel",
"variables": {
"value": "+13235550100",
"medium": "SMS",
"reason": "Asked to stop by phone"
}
}'
To also block calls to the same number, send a second request with
"medium": "VOICE".
Full variable schemas, response shapes, and worked examples for every operation are available from the discovery endpoint.