XYPNNew! XYPN has partnered with CurrentClientRead the announcement ›
Ping us at sales@currentclient.com
Skip to content
Public API

Build on CurrentClient

Pull call recordings and transcripts, send texts, and keep contacts in sync from your own systems. Plain JSON over HTTPS, OAuth sign-in, cursor pagination.

Overview

The public CurrentClient API: calls, messages, contacts, inboxes, your profile, and team members.

Everything is JSON. Timestamps on calls and messages are unix seconds. Phone numbers are E.164, like +14155552671. List endpoints return records plus a meta object whose cursor you pass back to get the next page.

Base URL
https://api.currentclient.com
Authentication
OAuth authorization code flow. The access token goes on every request as a bearer token. How to get a token
Surface
35 endpoints across 10 resources.
Spec
Version 9f349e2, synced October 16, 2026. Raw OpenAPI JSON

Authentication

Access is by OAuth client using the authorization code flow. A person in the workspace signs in to CurrentClient once, your app receives tokens for them, and you send the access token as a bearer token on every request. A refresh token keeps it going without another sign-in. There are no long-lived API keys.

Authorization endpoint
https://auth.currentclient.com/oauth2/authorize
Token endpoint
https://auth.currentclient.com/oauth2/token
User info endpoint
https://auth.currentclient.com/oauth2/userInfo
Scopes
openidprofileemail
Request all three. Grant type authorization_code.
1

Request an OAuth client

API access is by OAuth client. Email us with the workspace name, what you plan to build, and the redirect URI your app will use, and we will issue a client id and secret for that workspace.

2

Send the person to sign in

Build the authorization URL with your client id, the redirect URI we registered for you, the three scopes, and a random state value you check when they come back. CurrentClient shows the sign-in page and redirects to your URI with a code in the query string.

Authorization URL
https://auth.currentclient.com/oauth2/authorize
  ?response_type=code
  &client_id=$CLIENT_ID
  &redirect_uri=https://yourapp.example/callback
  &scope=openid+profile+email
  &state=$RANDOM_STATE
3

Exchange the code for tokens

From your server, post the code to the token endpoint with your client id and secret as HTTP basic auth. Keep the secret on the server; never ship it in a browser or mobile app.

curl -X POST https://auth.currentclient.com/oauth2/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=$CODE&redirect_uri=https://yourapp.example/callback"

You get an access token for the API, an id token describing the person, a refresh token, and how long the access token lives in seconds. Store the refresh token securely; it is what keeps the integration running.

Token response
{
  "access_token": "eyJraWQiOiJ...",
  "id_token": "eyJraWQiOiJ...",
  "refresh_token": "eyJjdHkiOiJ...",
  "token_type": "Bearer",
  "expires_in": 3600
}
4

Refresh before it expires

Trade the refresh token for a new access token with the same basic auth. Do this a little before expires_in runs out rather than on every call.

curl -X POST https://auth.currentclient.com/oauth2/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token&refresh_token=$REFRESH_TOKEN"

Access tokens expire. Read expires_in from the token response, cache the token, and use the refresh token to get a new one shortly before it runs out rather than sending the person through sign-in again.

5

Send the access token on every request

Send the access token in the Authorization header. A missing or malformed token gets a 401 with a plain text body. The same token also works against the user info endpoint if you want the person's name and email.

curl https://api.currentclient.com/api/v1/profile \
  -H "Authorization: Bearer $TOKEN"

curl https://auth.currentclient.com/oauth2/userInfo \
  -H "Authorization: Bearer $TOKEN"

Treat the client secret and refresh tokens like passwords. Keep them on a server, load them from an environment variable or secret manager, and never embed them in a browser, mobile app, or public repository. If a secret leaks, email us and we will rotate it.

Every public endpoint uses the JWTBearer security scheme, an HTTP bearer token. The spec also lists CcAdminJWTBearer, which is internal and not issued to partners.

Rate limits

Requests from your integration are rate limited so no single integration can crowd out everyone else on the API. The limit is a token bucket: you can burst up to 10 requests, then it refills at 1 request per second (about 60 a minute) sustained.

The bucket is keyed to the signed-in user whose access token you're using, not to your OAuth client. If more than one integration acts on behalf of the same person, they share the same budget.

Burst
10 requests
Sustained
1 request / second
Scope
Per signed-in user
Over the limit
HTTP 429
Rate limited
HTTP/1.1 429 Too Many Requests
content-type: text/plain

Too Many Requests - User Rate Limit Exceeded

A 429 carries no Retry-After header today, so don't retry immediately in a tight loop. Back off at least a second and add jitter if you're running more than one worker against the same user's token.

Recipes

The jobs most integrations start with, end to end. Pick a language once and every example on the page follows.

A small helper the examples below use
# Set these once in your shell
export TOKEN="eyJraWQiOiJ..."

Get an access token

Sign a person in with the authorization code flow and exchange the code for tokens.

1

Send the person to sign in

Build the authorization URL with your client id, the redirect URI we registered for you, the three scopes, and a random state value you check when they come back. CurrentClient shows the sign-in page and redirects to your URI with a code in the query string.

https://auth.currentclient.com/oauth2/authorize
  ?response_type=code
  &client_id=$CLIENT_ID
  &redirect_uri=https://yourapp.example/callback
  &scope=openid+profile+email
  &state=$RANDOM_STATE
2

Exchange the code for tokens

From your server, post the code to the token endpoint with your client id and secret as HTTP basic auth. Keep the secret on the server; never ship it in a browser or mobile app.

curl -X POST https://auth.currentclient.com/oauth2/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=$CODE&redirect_uri=https://yourapp.example/callback"
3

Read the response

You get an access token for the API, an id token describing the person, a refresh token, and how long the access token lives in seconds. Store the refresh token securely; it is what keeps the integration running.

{
  "access_token": "eyJraWQiOiJ...",
  "id_token": "eyJraWQiOiJ...",
  "refresh_token": "eyJjdHkiOiJ...",
  "token_type": "Bearer",
  "expires_in": 3600
}
4

Refresh before it expires

Trade the refresh token for a new access token with the same basic auth. Do this a little before expires_in runs out rather than on every call.

curl -X POST https://auth.currentclient.com/oauth2/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token&refresh_token=$REFRESH_TOKEN"
5

Use the access token on every request

Send the access token in the Authorization header. A missing or malformed token gets a 401 with a plain text body. The same token also works against the user info endpoint if you want the person's name and email.

curl https://api.currentclient.com/api/v1/profile \
  -H "Authorization: Bearer $TOKEN"

curl https://auth.currentclient.com/oauth2/userInfo \
  -H "Authorization: Bearer $TOKEN"

Find your UserId and inbox numbers

Two lookups you will do once and cache. Sending a message needs both.

1

Get your profile

The UserId on the profile is the account that owns the token. Sending a message requires it.

curl https://api.currentclient.com/api/v1/profile \
  -H "Authorization: Bearer $TOKEN"
2

List your inboxes

Each inbox has a Number in E.164 form. That is the UserNumber you send from. The record also tells you whether the inbox records and transcribes calls.

curl "https://api.currentclient.com/api/v1/inboxes/?showWorkspace=true" \
  -H "Authorization: Bearer $TOKEN"

Pull call recordings and transcripts

List recent calls, keep the ones with a finished recording, and download the audio, transcript, and summary.

1

List calls since a point in time

Pass since as a unix timestamp in seconds. Results come newest first. Use a limit that fits your batch size and follow the cursor for more.

curl "https://api.currentclient.com/api/v1/calls?since=1725235200&limit=100" \
  -H "Authorization: Bearer $TOKEN"
2

Keep the calls with a finished recording

IsRecorded says the inbox recorded the call. RecordingStatus says whether the file is ready. Only download when it is completed; in-progress means the recording is still being processed and absent means there is nothing to fetch.

const ready = calls.filter(
  (call) => call.IsRecorded && call.RecordingStatus === "completed" && call.RecordingUrl,
);
3

Download the audio and read the analysis

RecordingUrl points at the audio file. Fetch it soon after listing rather than storing the link long term. The transcript and summary live on the same record once CallAnalysisStatus is completed.

curl -L "$RECORDING_URL" -o call.mp3

Send a text message

Send from one of your inboxes and check what happened to it.

1

Send the message

UserId comes from your profile and UserNumber is one of your inbox numbers. ContactNumber is the recipient in E.164 form. Add setStatus=CLOSED for one-way notices so the conversation does not sit open in the inbox waiting for a reply.

curl -X POST "https://api.currentclient.com/api/v1/messages/send?setStatus=CLOSED" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "UserId": "user_9f3a2c",
    "UserNumber": "+14155550100",
    "ContactNumber": "+14155552671",
    "Message": "Hi Jane, your documents are ready to sign. Reply here with any questions."
  }'
2

Check the result

The response is the message record. Status starts at queued or sending and moves to delivered as the carrier reports back. An unsubscribed or blocked recipient shows up here too, so read the Status rather than assuming success.

if (["unsubscribed", "blockednumber", "failed"].includes(message.Status)) {
  console.warn("Not delivered:", message.Status, message.ErrorMessage);
}

Page through results

Every list endpoint uses the same cursor pattern.

1

Follow the cursor

A list response has records and meta. When meta.cursor is a string, pass it back as the cursor query parameter to get the next page. When it is null you have everything. Keep the other query parameters the same on every page.

async function* pages(path, params = {}) {
  let cursor = null;
  do {
    const qs = new URLSearchParams(params);
    if (cursor) qs.set("cursor", cursor);
    const page = await api(`${path}?${qs}`);
    yield page.records;
    cursor = page.meta?.cursor ?? null;
  } while (cursor);
}

for await (const records of pages("/api/v1/messages", { limit: "100" })) {
  console.log(records.length);
}

Receive events with webhooks

Have us POST to your server when a message arrives, a call ends, a recording is ready, and more, instead of polling.

Read the full webhooks guide
1

Add an endpoint

In CurrentClient open Settings, then Developers, then Webhooks, and click Add endpoint. Give it a name and the URL we should POST to, pick the events you want, and save. The endpoint gets its own signing secret the moment it is created; you can view it again any time with Reveal on the endpoint's card.

2

Verify every delivery

Each request carries X-CC-Signature (hex HMAC-SHA256) and X-CC-Timestamp (Unix seconds). Rebuild the signature from "{timestamp}.{raw_body}" using your signing secret and compare it in constant time. Use the raw body bytes, not re-serialized JSON, and reject timestamps more than a few minutes old.

import { createHmac, timingSafeEqual } from "node:crypto";

const SECRET = process.env.CC_WEBHOOK_SECRET;
const TOLERANCE_SECONDS = 300;

// rawBody must be the unparsed request body (a Buffer or string).
function verifyWebhook(rawBody, timestampHeader, signatureHeader) {
  const timestamp = Number.parseInt(timestampHeader ?? "", 10);
  if (!Number.isFinite(timestamp) || !signatureHeader) return false;
  if (Math.abs(Math.floor(Date.now() / 1000) - timestamp) > TOLERANCE_SECONDS) return false;

  const expected = createHmac("sha256", SECRET)
    .update(`${timestamp}.`)
    .update(rawBody)
    .digest("hex");
  const a = Buffer.from(expected, "utf8");
  const b = Buffer.from(signatureHeader, "utf8");
  return a.length === b.length && timingSafeEqual(a, b);
}

// Express example (needs express.raw({ type: "*/*" }) so req.body is a Buffer):
app.post("/webhooks/currentclient", (req, res) => {
  const ok = verifyWebhook(req.body, req.get("X-CC-Timestamp"), req.get("X-CC-Signature"));
  if (!ok) return res.sendStatus(401);
  const event = JSON.parse(req.body.toString("utf8"));
  console.log(event.type);
  res.sendStatus(200);
});
3

Respond quickly, then do the work

Return a 2xx as soon as the signature checks out and process the event afterwards. Deliveries that fail or time out are retried, and an endpoint that keeps failing is paused until you re-enable it. The full guide covers every event type, the payload shapes, retries, delivery logs, and rotating your signing secret.

Create, tag, and find contacts

Keep contacts in step with another system.

1

Create contacts in a batch

The body is an array. FirstName, LastName, and Phone are required. Turn on isVerifyNumbers to learn each number's carrier and whether it can receive texts.

curl -X POST "https://api.currentclient.com/api/v1/contacts/?isVerifyNumbers=true" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    { "FirstName": "Jane", "LastName": "Doe", "Phone": "+14155552671", "Email": "jane@example.com", "Tags": ["client"] }
  ]'
2

Add a tag without replacing the others

Updates replace Tags unless you pass isAddTag=true. Send only the fields you are changing.

curl -X PUT "https://api.currentclient.com/api/v1/contacts/$CONTACT_ID?isAddTag=true" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "Tags": ["reviewed-2026"] }'
3

Find contacts by field

useFilter takes Field:Operator:Value. Repeat it to combine conditions. Look up a caller by phone, or pull everyone with a tag.

curl "https://api.currentclient.com/api/v1/contacts/?useFilter=Phone:eq:%2B14155552671" \
  -H "Authorization: Bearer $TOKEN"

curl "https://api.currentclient.com/api/v1/contacts/?useFilter=Tags:contains:client&limit=200" \
  -H "Authorization: Bearer $TOKEN"

Calls

Every call placed or received through CurrentClient, including voicemails and calls handled by an AI agent. When recording, transcription, or call summaries are on for the inbox, each record carries the recording URL, the transcript, and the AI summary.

  • Pull recordings and transcripts into your own storage, CRM, or review tooling
  • Report on call volume and outcomes by team member, contact, or disposition
  • React when a call is missed or goes to voicemail
GET/api/v1/calls

List calls

Returns calls visible to the authenticated caller, most recent first.

Use this when

Pull calls for a time window and work through them page by page. This is the call to use for recordings, transcripts, and AI summaries: each record carries RecordingUrl, CallAnalysisTranscript, and CallAnalysisSummary.

Good to know

  • since and until are unix timestamps in seconds, not milliseconds.
  • Only trust RecordingUrl when RecordingStatus is completed. A call that just ended may still be in-progress, and absent means nothing was recorded.
  • CallAnalysisStatus tells you whether the transcript and summary are ready. Poll again later if it is queued or processing.
  • Results are newest first. Keep following meta.cursor until it comes back null.

Recipes: Pull call recordings and transcripts, Page through results

Query parameters

  • contactIdstring | null

    PRO-10477: only calls with this saved contact.

  • contactNumberstring | null
  • cursorstring | null
  • directionenum | null
    INBOUNDOUTBOUND
  • dispositionIdstring | null
  • isAgentCallboolean | null
  • isContactboolean | null
  • isVoicemailboolean | null
  • limitinteger (uint16)

    Default 100

  • memberIdstring | null

    PRO-10477: only calls this teammate placed, answered, was transferred to, or took part in on either side of an internal call.

  • searchstring | null
  • sinceinteger | null

    Unix timestamp in seconds

  • transferTargetMemberIdstring | null

    PRO-7266: "For you" tab — voicemails a live-agent transfer left for this member, wherever the mainline conversation they landed under.

  • untilinteger | null

    Unix timestamp in seconds

  • userNumberstring | null

Example request

curl "https://api.currentclient.com/api/v1/calls?since=1725235200&limit=50" \
  -H "Authorization: Bearer $TOKEN"

Responses

200
Response fields
Example response
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "AgentInteractions": [
        {}
      ],
      "AnsweredBy": "human",
      "AnsweredByMemberId": "member_9f3a2c",
      "ArchiverIds": {},
      "CallAnalysisStatus": "completed",
      "CallAnalysisSummary": "Jane asked about rolling over her 401(k). Agreed to send the transfer form.",
      "CallAnalysisSummaryPending": "string",
      "CallAnalysisTranscript": "Agent: Thanks for calling. Jane: Hi, I had a question about my 401(k).",
      "CallDurationTime": "184",
      "CallEndedTime": 1725321600,
      "CallId": "call_9f3a2c",
      "CallSid": "CA7f3e2b9c1d4a5e6f",
      "CallSummaryReviewStatus": "pending",
      "CallSummaryReviewedAt": "2026-09-03T14:30:00Z",
      "CallSummaryReviewedBy": "string",
      "CallerMemberId": "member_9f3a2c",
      "CallerName": "Jane Doe",
      "Comments": [
        {}
      ],
      "ContactId": "contact_9f3a2c",
      "ContactMemberId": "member_9f3a2c",
      "ContactName": "Jane Doe",
      "ContactNumber": "+18008675309",
      "CreatedTime": 1725321600,
      "CrmIds": {},
      "Direction": "OUTBOUND",
      "DispositionId": "disposition_9f3a2c",
      "IsAgentCall": false,
      "IsForwarded": false,
      "IsMissedCall": false,
      "IsOutsideHours": false,
      "IsRecorded": true,
      "IsSipAnswered": false,
      "IsTeamCall": false,
      "IsVoicemail": false,
      "Meta": {},
      "Note": "Follow up next week about the rollover.",
      "NotetakerIds": {},
      "NumberForwardedTo": "+14155552671",
      "Participants": [
        {}
      ],
      "Quality": {},
      "RecordingDurationTime": "184",
      "RecordingSid": "RE7f3e2b9c1d4a5e6f",
      "RecordingStatus": "completed",
      "RecordingUrl": "https://recordings.currentclient.com/RE7f3e2b9c1d4a5e6f.mp3",
      "Status": "completed",
      "StatusCallSid": "CA7f3e2b9c1d4a5e6f",
      "StatusSequence": 20,
      "StatusWeight": 0,
      "Tags": [
        "client"
      ],
      "TranscriptionStatus": "string",
      "TranscriptionText": "string",
      "TransferredAtTime": 1725321600,
      "TransferredByMemberId": "member_9f3a2c",
      "TransferredToMemberId": "member_9f3a2c",
      "TransferredToNumber": "string",
      "UpdatedTime": 1725321600,
      "UserId": "1234-abcd-4567-ABCD",
      "UserNumber": "+18008675309"
    }
  ]
}
GET/api/v1/calls/{call_id}

Get a call

Returns one call by id, if the caller can access it.

Example request

curl "https://api.currentclient.com/api/v1/calls/{call_id}" \
  -H "Authorization: Bearer $TOKEN"

Responses

200
Response fields
  • AgentInteractionsmap[] | null

    List of AI agent interactions on this call. Each entry contains agentId, conversationId, dialplanId, nextNodeId, and firmName.

  • AnsweredBystring | null

    Twilio AMD result for outbound calls: 'human', 'machine_start', 'machine_end_silence', 'machine_end_beep', 'machine_end_other', 'fax', or 'unknown'. None when AMD was not run.

  • AnsweredByMemberIdstring | null

    The id of the member that answered a call

  • ArchiverIdsmap | null

    Dictionary to store archiver ids - key is ArchiverId, value is ArchiverType

  • CallAnalysisStatusenum | null

    Ai summary status of the call

    queuedprocessingcompletederror
  • CallAnalysisSummarystring | null

    Analysis generated for the call

  • CallAnalysisSummaryPendingstring | null

    Ai summary held for review; copied to CallAnalysisSummary on approval so no other reader sees unreviewed text

  • CallAnalysisTranscriptstring | null

    Transcript generated for the call

  • CallDurationTimestring | null

    Time in seconds of the call

  • CallEndedTimeinteger | null

    The time the call ended

  • CallIdstringrequired
  • CallSidstring | null

    Specific call sid for the call, useful for twilio api

  • CallSummaryReviewStatusenum | null

    PRO-6946: human review state of the AI call summary

    pendingapproved
  • CallSummaryReviewedAtstring | null

    ISO timestamp the ai summary was approved

  • CallSummaryReviewedBystring | null

    User id that approved the ai summary

  • CallerMemberIdstring | null

    Member id for the caller

  • CallerNamestring | null

    Name of the caller for quick reference

  • CommentsCallComment[] | null

    Comments about the call

  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactMemberIdstring | null

    The called team member on a direct team-member call

  • ContactNamestring | null

    Name of the contact for quick reference

  • ContactNumberstring

    Phone number in E.164 format

  • CreatedTimeinteger | null
  • CrmIdsmap | null

    Dictionary to store CRM ids - key is CrmId, value is CrmType

  • Directionenum

    Direction of the call, whether it was outbound or inbound

    OUTBOUNDINBOUND
  • DispositionIdstring | null

    Workspace disposition assigned to this call (PRO-4164). Null until set; filterable via the calls list endpoint.

  • IsAgentCallboolean | null

    Whether an AI agent handled this call

  • IsForwardedboolean | null

    If the call is forwarded

  • IsMissedCallboolean | null

    Explicitly set to True when the call is confirmed missed by the application layer (is_done=True). Prevents premature missed-call notifications from intermediate DynamoDB stream events during parallel dial.

  • IsOutsideHoursboolean | null

    If the call is outside business hours

  • IsRecordedboolean | null

    If the call is recorded

  • IsSipAnsweredboolean | null

    PRO-7119: set once the <Sip> leg of a VoiceProvider=sip inbound call actually answers, via the sip-answered statusCallback. Positive answer evidence for is_inbound_unattended, the same role IsAgentCall plays for the ElevenLabs agent dial -- a SIP-answered call stamps none of the other answer signals (AnsweredByMemberId is written only from a per-leg <Client> statusCallback, and the cc-sip CDR keys on cc-sip's own call_id, not the Twilio CallSid, so it never reaches this record).

  • IsTeamCallboolean | null

    True for a direct call between two workspace team members

  • IsVoicemailboolean | null

    True when this call was routed to voicemail

  • Metamap | null

    Key values of meta data for this call, will be published as attributes to topic on callbacks

  • Notestring | null

    Note about the call

  • NotetakerIdsmap | null

    Dictionary to store notetaker ids

  • NumberForwardedTostring | null

    If the call is forwarded, this is the number it went to

  • ParticipantsCallParticipant[]

    List of participants currently in the call

  • QualityCallQuality | null

    Audio quality of a cc-sip call (MOS, jitter, round-trip time); null when the call was not measured

  • RecordingDurationTimestring | null

    Time in seconds of the call recording

  • RecordingSidstring | null

    Specific recording sid for the call, useful for twilio api

  • RecordingStatusenum | null

    Recording Status of the call

    in-progresscompletedabsent
  • RecordingUrlstring | null

    Url to the call recording

  • Statusenum

    Status of the call

    createdinitiatedringingin-progresstransferredblockedcompletedfailedbusyno-answercanceled
  • StatusCallSidstring | null

    The Twilio CallSid that produced the current StatusSequence.

  • StatusSequenceinteger | null

    Highest Twilio SequenceNumber processed for status updates. Stored as a DynamoDB N type for correct numeric comparison.

  • StatusWeightinteger | null

    Numeric weight of the current Status, used to prevent cross-CallSid status regressions.

  • Tagsstring[] | null

    Tags for the message

  • TranscriptionStatusstring | null

    Status of the transcription

  • TranscriptionTextstring | null

    Text of the voicemail

  • TransferredAtTimeinteger | null

    Epoch timestamp when the call was transferred

  • TransferredByMemberIdstring | null

    The id of the member that transferred the call away. On the unattended transfer_to_inbox path the transferred record is de-keyed off GSI4 and a NEW destination leg reuses the call id, so the destination's AnsweredByMemberId is the RECIPIENT, not the transferrer. read_call backfills this from the source record's AnsweredByMemberId (PRO-7260). The attended path (CRUDCall.transfer) stamps in place and keeps GSI4, so there AnsweredByMemberId is already the transferrer and this stays unset.

  • TransferredToMemberIdstring | null

    The id of the member that the call was transferred to

  • TransferredToNumberstring | null

    The phone number that the call was transferred to

  • UpdatedTimeinteger | null
  • UserIdstring

    Id of the app user

  • UserNumberstring

    Number with a leading +1, or `member:<id>` on a direct team-member call (PRO-8680)

Example response
{
  "AgentInteractions": [
    {}
  ],
  "AnsweredBy": "human",
  "AnsweredByMemberId": "member_9f3a2c",
  "ArchiverIds": {},
  "CallAnalysisStatus": "completed",
  "CallAnalysisSummary": "Jane asked about rolling over her 401(k). Agreed to send the transfer form.",
  "CallAnalysisSummaryPending": "string",
  "CallAnalysisTranscript": "Agent: Thanks for calling. Jane: Hi, I had a question about my 401(k).",
  "CallDurationTime": "184",
  "CallEndedTime": 1725321600,
  "CallId": "call_9f3a2c",
  "CallSid": "CA7f3e2b9c1d4a5e6f",
  "CallSummaryReviewStatus": "pending",
  "CallSummaryReviewedAt": "2026-09-03T14:30:00Z",
  "CallSummaryReviewedBy": "string",
  "CallerMemberId": "member_9f3a2c",
  "CallerName": "Jane Doe",
  "Comments": [
    {
      "CallCommentId": "comment_9f3a2c",
      "Comment": "Client confirmed the meeting time.",
      "CreatedByUserId": "user_9f3a2c",
      "CreatedByUserName": "Jane Doe",
      "CreatedTime": 1725321600,
      "Mentions": [
        "string"
      ],
      "UpdatedAt": "2026-09-03T14:30:00Z"
    }
  ],
  "ContactId": "contact_9f3a2c",
  "ContactMemberId": "member_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+18008675309",
  "CreatedTime": 1725321600,
  "CrmIds": {},
  "Direction": "OUTBOUND",
  "DispositionId": "disposition_9f3a2c",
  "IsAgentCall": false,
  "IsForwarded": false,
  "IsMissedCall": false,
  "IsOutsideHours": false,
  "IsRecorded": true,
  "IsSipAnswered": false,
  "IsTeamCall": false,
  "IsVoicemail": false,
  "Meta": {},
  "Note": "Follow up next week about the rollover.",
  "NotetakerIds": {},
  "NumberForwardedTo": "+14155552671",
  "Participants": [
    {
      "CallSid": "CA7f3e2b9c1d4a5e6f",
      "CallStatus": "connecting",
      "ContactId": "contact_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100",
      "TeamMemberId": "member_9f3a2c",
      "Type": "contact"
    }
  ],
  "Quality": {
    "JitterMsMax": 0,
    "MosAvg": 0,
    "MosMin": 0,
    "RttMsMax": 0
  },
  "RecordingDurationTime": "184",
  "RecordingSid": "RE7f3e2b9c1d4a5e6f",
  "RecordingStatus": "completed",
  "RecordingUrl": "https://recordings.currentclient.com/RE7f3e2b9c1d4a5e6f.mp3",
  "Status": "completed",
  "StatusCallSid": "CA7f3e2b9c1d4a5e6f",
  "StatusSequence": 20,
  "StatusWeight": 0,
  "Tags": [
    "client"
  ],
  "TranscriptionStatus": "string",
  "TranscriptionText": "string",
  "TransferredAtTime": 1725321600,
  "TransferredByMemberId": "member_9f3a2c",
  "TransferredToMemberId": "member_9f3a2c",
  "TransferredToNumber": "string",
  "UpdatedTime": 1725321600,
  "UserId": "1234-abcd-4567-ABCD",
  "UserNumber": "+18008675309"
}

Messages

Texts sent and received across your inboxes, with delivery status and any attached media. Sending through the API behaves exactly like sending from the app: the message lands in the conversation, is archived, and honors unsubscribes and blocked numbers.

  • Send appointment reminders or document-ready notices from your own systems
  • Mirror conversations into a CRM or data warehouse
  • Audit delivery status for compliance reporting
GET/api/v1/messages

List messages

Returns messages visible to the authenticated caller, most recent first.

Use this when

Read message history for reporting, syncing into another system, or building your own view of a conversation. Filter by contactNumber to get one thread, or by userNumber to get everything through one inbox.

Good to know

  • Direction is SENT or RECEIVED from the inbox's point of view.
  • Attachments arrive as MessageMediaItems with a MediaUrl you can download.
  • Group messages are excluded unless includeGroups is true.

Recipes: Page through results

Query parameters

  • contactNumberstring | null
  • cursorstring | null
  • includeGroupsboolean | null
  • limitinteger (uint16)

    Default 100

  • orderenum | null

    PRO-4251: `asc` for oldest-first, `desc` (default) for newest-first.

    ascdesc
  • searchstring | null
  • sinceinteger | null

    Unix timestamp in seconds

  • untilinteger | null

    Unix timestamp in seconds

  • userNumberstring | null

Example request

curl "https://api.currentclient.com/api/v1/messages?contactNumber=%2B14155552671&limit=50" \
  -H "Authorization: Bearer $TOKEN"

Responses

200
Response fields
Example response
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "ArchiverIds": {},
      "BestDeliveryStatus": "string",
      "ChannelType": "sms",
      "Comments": [
        {}
      ],
      "ContactId": "contact_9f3a2c",
      "ContactName": "Jane Doe",
      "ContactNumber": "+14155552671",
      "ConversationId": "conversation_9f3a2c",
      "CreatedTime": 1725321600,
      "CrmIds": {},
      "Direction": "SENT",
      "ErrorCode": null,
      "ErrorMessage": null,
      "HoldUntil": 0,
      "IsIgnored": false,
      "IsSilenced": false,
      "LinkedComplianceMessageId": "message_9f3a2c",
      "LocalMessageId": "message_9f3a2c",
      "MediaTwilioSids": [
        "CA7f3e2b9c1d4a5e6f"
      ],
      "Message": "Hi Jane, your documents are ready to sign.",
      "MessageId": "message_9f3a2c",
      "MessageMediaItems": [
        {}
      ],
      "Meta": {},
      "SenderMemberId": "member_9f3a2c",
      "SenderName": "Jane Doe",
      "Status": "delivered",
      "Tags": [
        "client"
      ],
      "TwilioNumOfSegments": "string",
      "TwilioSid": "CA7f3e2b9c1d4a5e6f",
      "UndeliveredContactNumber": "+14155552671",
      "UndeliveredContactNumbers": [
        "+14155552671"
      ],
      "UndeliveredParticipantSids": [
        "CA7f3e2b9c1d4a5e6f"
      ],
      "UserId": "user_9f3a2c",
      "UserNumber": "+14155550100",
      "WebhookUrlStatus": "string",
      "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
      "WhatsAppContentVariables": {},
      "WhatsAppTemplateId": "template_9f3a2c"
    }
  ]
}
PUT/api/v1/messages/receipts/archiver/xyarchive

Batch update message xyarchive archiver ids

Batch tag messages with XYARCHIVE archiver receipts. Accepts admin tokens (userId query param required) or workspace-scoped tokens issued to the XYArchive OAuth client (workspace from token).

Query parameters

  • userIdstringAdmin only

    Id for the owner of the resource

Request body application/json, required

  • MessageIdsstring[]required
Example body
{
  "MessageIds": [
    "message_9f3a2c"
  ]
}

Example request

curl -X PUT "https://api.currentclient.com/api/v1/messages/receipts/archiver/xyarchive" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "MessageIds": [
    "message_9f3a2c"
  ]
}'

Responses

200Successful Response
Response fields
  • MessageIdsstring[]required
Example response
{
  "MessageIds": [
    "message_9f3a2c"
  ]
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid",
  "message": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed",
  "message": "A message for why the server failed"
}
POST/api/v1/messages/send

Send a message

Sends an outbound message from one of the caller's inboxes.

Use this when

Send a text from one of your inboxes. Use it for reminders, document notices, and any message your own system decides to send. The message shows up in the app like any other and is archived automatically.

Good to know

  • UserId comes from the profile endpoint and UserNumber must be a number from the inboxes endpoint. Both belong to the token's workspace.
  • Contacts who unsubscribed or were blocked are not messaged. The returned Status tells you what happened.
  • Pass setStatus=CLOSED when the message is a one-way notice you do not need a reply to, so it does not sit open in the inbox.

Recipes: Find your UserId and inbox numbers, Send a text message

Query parameters

  • setStatusenum | null
    OPENCLOSED

Request body application/json, required

  • ArchiverIdsany
  • ChannelTypeenum | null
    smswhatsapp
  • CommentsComment[] | null
  • ContactIdstring | null
  • ContactNamestring | null
  • ContactNumberstringrequired
  • ConversationIdstring | null
  • CrmIdsany
  • ErrorCodestring | null
  • ErrorMessagestring | null
  • IsIgnoredboolean | null
  • IsSilencedboolean | null
  • LocalMessageIdstring | null
  • Messagestring | null
  • MessageMediaItemsMediaItem[] | null
  • Metaany
  • SenderMemberIdstring | null
  • SenderNamestring | null
  • Tagsstring[] | null
  • UserIdstring

    PRO-10657: optional on the wire. A user token's workspace always overwrites it, so a public API client (Slant) has no reason to send it, and requiring it 422'd every such send. Python's `MessageBase` defaults it to None for the same reason. A system caller must still name the workspace; the handler refuses an empty one.

  • UserNumberstring | null
Example body
{
  "UserId": "user_9f3a2c",
  "UserNumber": "+14155550100",
  "ContactNumber": "+14155552671",
  "Message": "Hi Jane, your documents are ready to sign. Reply here with any questions.",
  "Tags": [
    "documents"
  ]
}

Example request

curl -X POST "https://api.currentclient.com/api/v1/messages/send" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "UserId": "user_9f3a2c",
  "UserNumber": "+14155550100",
  "ContactNumber": "+14155552671",
  "Message": "Hi Jane, your documents are ready to sign. Reply here with any questions.",
  "Tags": [
    "documents"
  ]
}'

Responses

200
Response fields
  • ArchiverIdsmap | null

    Dictionary to store archiver ids - key is ArchiverId, value is ArchiverType

  • BestDeliveryStatusstring | null

    For a group-conversation message, the highest-ranked leg success (delivered/read, by MESSAGE_STATUS_WEIGHT) ever recorded on this row, kept independent of the row's own Status. Written on every success receipt via the group-delivery path and never downgraded. Exists because a later failing leg can resolve the row's Status to partiallydelivered -- a single scalar that cannot also encode 'and the best success so far was read' -- so once that happens, prior_status stops being a usable record of it. Without this field, a read receipt followed by a failing leg followed by that leg merely CORRECTING to delivered (rather than read) permanently lost the fact that someone had already read the message (PRO-7413). Populated only via the onDeliveryUpdated group-delivery path (crud.message.update_status resolve_as_group_delivery=True); unset for a 1:1 message.

  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • CommentsMessageComment[] | null

    Comments about the message

  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null

    Name of the contact for quick reference

  • ContactNumberstring | null

    Phone with a leading +1 or a short code

  • ConversationIdstring | null

    A Twilio conversation ID or our number TO number format

  • CreatedTimeinteger | null
  • CrmIdsmap | null

    Dictionary to store CRM ids - key is CrmId, value is CrmType

  • Directionenum | null

    Direction of the message, whether it was sent or received

    SENTRECEIVED
  • ErrorCodestring | null
  • ErrorMessagestring | null
  • HoldUntilinteger | null

    PRO-8559: epoch-seconds when a Status=pending message's undo-send grace period ends and it is actually handed to Twilio. Set only while Status is pending; the frontend renders the remaining hold from this instead of re-deriving its own client-side timer, so the window survives a reload. Never cleared -- it stays on the row, stale, once the message leaves pending -- so consumers must gate on Status==pending, not merely on this field being set.

  • IsIgnoredboolean | null
  • IsSilencedboolean | null
  • LinkedComplianceMessageIdstring | null

    PRO-8589: set on a held real (non-compliance) message whose first-contact compliance sub-message was ALSO held for the same undo-send grace window, pointing at that sub-message's own MessageId. cancel_pending_send follows it to cancel the compliance row in lockstep with this one, so undoing a first-ever send never leaves the contact holding a bare Reply-STOP line with no message attached to it. Unset for every other message -- compliance resends, and automated / admin-or-service / CH sends, which skip the hold entirely.

  • LocalMessageIdstring | null
  • MediaTwilioSidsstring[] | null
  • Messagestring | null

    Field of message to send

  • MessageIdstringrequired
  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap | null

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • SenderMemberIdstring | null

    Member id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • Statusenum | null

    Status of the message

    createdpendingreadycancelledblockednumberunsubscribercannotrouteerrorinvalidnosmspresenderrorsenderrorunsubscribedsessionexpiredaccepteddeliveredfailedqueuedreadsendingsentundeliveredreceivedreceivingpartiallydelivered
  • Tagsstring[] | null

    Tags for the message

  • TwilioNumOfSegmentsstring | null
  • TwilioSidstring | null
  • UndeliveredContactNumberstring | null

    For a group-conversation message, the specific participant number whose relay leg failed, resolved from Twilio's per-recipient onDeliveryUpdated ParticipantSid (PRO-6630/PRO-6632) since the message row's own ContactNumber can't name one recipient out of several. Unset for a 1:1 message, where ContactNumber already identifies the recipient, and unset if the participant lookup failed.

  • UndeliveredContactNumbersstring[] | null

    For a group-conversation message, every participant leg that is CURRENTLY known-failed, by number -- the per-recipient state the PRO-7304 failure alert renders from, since a group send's single Status can only ever describe one aggregate outcome and UndeliveredContactNumber (singular) only ever named the most recently-resolved failure. Index-aligned with UndeliveredParticipantSids (entry i failed as participant i). A NEW failing participant is appended; the SAME participant later correcting to a success (PRO-5002's shape, not a second person's independent failure) removes that entry instead of leaving it stuck forever (PRO-7304 round 3 -- this list is NOT append-only despite an earlier round of this same ticket documenting it that way). Populated only via the onDeliveryUpdated group-delivery path (crud.message.update_status resolve_as_group_delivery=True); unset for a 1:1 message and for a clean group delivery with no failures at all. An ENTRY may be None: the leg is known-failed but Twilio's participant lookup could not resolve its number. The entry is still recorded, because dropping it would leave that leg with no UndeliveredParticipantSids entry either, and its own later correction could then never be matched -- pinning the row at partiallydelivered forever with nothing able to clear it (ironhide, PR #875 round 7). Consumers rendering this list must skip None entries; the count of failed LEGS is the list length, the count of NAMEABLE ones is smaller.

  • UndeliveredParticipantSidsstring[] | null

    Twilio ParticipantSid for each entry in UndeliveredContactNumbers, same index. The identity that lets update_status tell a same-participant DLR correction (PRO-5002: this exact leg corrected itself, remove it) apart from a second, independent participant's receipt (PRO-7304: two different people, two different facts, neither erases the other) -- Status and ContactNumber alone can't distinguish those. Backend-internal: not meant for the frontend to render, only to let this field's sibling list self-correct accurately. An entry can itself be None (a legacy row seeded from the pre-sid-tracking singular UndeliveredContactNumber field, or the Twilio Participant lookup failed) -- update_status's correction matching requires an actual sid on BOTH sides, so a None entry here can never be mistaken for a match against an incoming None sid.

  • UserIdstring

    Id of the app user

  • UserNumberstring | null

    Number with a leading +1

  • WebhookUrlStatusstring | null
  • WhatsAppContentSidstring | null

    Server-resolved Twilio Content SID for a template send. Not client-settable.

  • WhatsAppContentVariablesmap | null

    Server-resolved positional {'1': value, ...} substitutions for a template send. Not client-settable.

  • WhatsAppTemplateIdstring | null

    An approved WhatsAppTemplate to send this message with, bypassing the 24h session window

Example response
{
  "ArchiverIds": {},
  "BestDeliveryStatus": "string",
  "ChannelType": "sms",
  "Comments": [
    {
      "Comment": "Client confirmed the meeting time.",
      "CreatedByUserId": "user_9f3a2c",
      "CreatedByUserName": "Jane Doe",
      "CreatedTime": "2026-09-03T14:30:00Z",
      "Mentions": [
        "string"
      ],
      "MessageCommentId": "comment_9f3a2c",
      "UpdatedAt": "2026-09-03T14:30:00Z"
    }
  ],
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": 1725321600,
  "CrmIds": {},
  "Direction": "SENT",
  "ErrorCode": null,
  "ErrorMessage": null,
  "HoldUntil": 0,
  "IsIgnored": false,
  "IsSilenced": false,
  "LinkedComplianceMessageId": "message_9f3a2c",
  "LocalMessageId": "message_9f3a2c",
  "MediaTwilioSids": [
    "CA7f3e2b9c1d4a5e6f"
  ],
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageId": "message_9f3a2c",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "Status": "delivered",
  "Tags": [
    "client"
  ],
  "TwilioNumOfSegments": "string",
  "TwilioSid": "CA7f3e2b9c1d4a5e6f",
  "UndeliveredContactNumber": "+14155552671",
  "UndeliveredContactNumbers": [
    "+14155552671"
  ],
  "UndeliveredParticipantSids": [
    "CA7f3e2b9c1d4a5e6f"
  ],
  "UserId": "user_9f3a2c",
  "UserNumber": "+14155550100",
  "WebhookUrlStatus": "string",
  "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
  "WhatsAppContentVariables": {},
  "WhatsAppTemplateId": "template_9f3a2c"
}

Contacts

The people your team texts and calls. A contact can carry tags, custom fields, several numbers, and a household link. If a CRM sync is connected, the CRM stays the source of truth, so prefer updating there and let the sync bring changes in.

  • Create contacts from a form, a signup flow, or another system of record
  • Tag contacts so broadcasts and routines can target them
  • Look up who a number belongs to before you act on a call or message
GET/api/v1/contacts/

List contacts

Get contact records

Use this when

Page through contacts, or narrow them with useFilter and saved segments. Good for syncing your list into another system or finding who a number belongs to.

Good to know

  • useFilter takes one or more Field:Operator:Value strings, for example Phone:eq:+14155552671 or Tags:contains:client. Operators: eq, ne, like, notlike, contains, notcontains, beginswith, isin, between, gt, gte, lt, lte, exists, notexists.
  • limit must be between 10 and 200.
  • versions returns the full edit history of every contact, which is much larger. Leave it off unless you need it.

Recipes: Create, tag, and find contacts, Page through results

Query parameters

  • cursorstring | null

    Pagination cursor provided by previous paginated response

  • limitinteger | null

    Pagination page size

    Default 100. 10 to 200

  • qstring | null

    Free-text search: case-insensitive contains match on first name, last name, phone and email. Combines with useFilter, useSegment and cursor. Blank values are ignored.

  • useFilterstring[] | null

    Filter results with a Field:Operator:Value string, e.g. `FirstName:beginswith:Jo` or `Tags:contains:abc123`. Repeat the parameter to add more filters (`useFilter=A:eq:1&useFilter=B:gt:2`); all filters must match (AND). Field is a contact field name (e.g. FirstName, LastName, Email, City, State, Tags) or a custom field. Operator is one of: eq, ne, like, notlike, contains, notcontains, containsany, beginswith, isin, between, gt, gte, lt, lte, exists, notexists. When useFilter is used on its own, LastName honors only beginswith (a name prefix) and between (a letter range such as `LastName:between:A-M`); other LastName operators are ignored. Value may contain letters, digits, whitespace and . , _ @ / # & + -. Pattern: ([A-Za-z0-9:]+):(eq|ne|like|notlike|contains|containsany|beginswith|isin|between|notcontains|gt|gte|lt|lte|exists|notexists):([\w\d\s.,_@/#&+-]*)

  • userIdstring | nullAdmin only

    Id for the owner of the resource

  • useSegmentstring | null

    Restrict results to a saved segment, given the segment ID (list segments with GET /segments/). Can be combined with useFilter; the filters are then applied within the segment.

  • versionsboolean | null

    Return all versions of all contacts

Example request

curl "https://api.currentclient.com/api/v1/contacts/?useFilter=Tags%3Acontains%3Aclient&limit=50" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
Example response
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "Address1": "100 Market St",
      "Address2": "Suite 400",
      "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
      "BirthDate": "1975-04-12",
      "City": "San Francisco",
      "ContactId": "contact_9f3a2c",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "CustomFields": {},
      "DeletedAt": "2026-09-03T14:30:00Z",
      "Email": "jane@example.com",
      "EnrichCallerName": "Jane Doe",
      "EnrichCallerType": "consumer",
      "EnrichLookupAt": "2026-09-03T14:30:00Z",
      "EnrichMeta": {},
      "FirstName": "Jane",
      "HouseholdId": "household_9f3a2c",
      "HouseholdName": "Jane Doe",
      "HouseholdTitle": "The Doe household",
      "IsArchived": false,
      "LastContactedTime": "2026-09-03T14:30:00Z",
      "LastName": "Doe",
      "LastSubmittedTime": "2026-09-03T14:30:00Z",
      "LastSyncTime": "2026-09-03T14:30:00Z",
      "MiddleName": "Q",
      "Nickname": "Janie",
      "NumberCarrierName": "Jane Doe",
      "NumberCarrierType": "mobile",
      "NumberLookupAt": "2026-09-03T14:30:00Z",
      "NumberMeta": {},
      "Numbers": [
        {}
      ],
      "OwnerId": "owner_9f3a2c",
      "OwnerSourceId": "source_9f3a2c",
      "OwnerSourceName": "Jane Doe",
      "Phone": "+14155552671",
      "SourceId": "source_9f3a2c",
      "SourceMeta": {},
      "SourceSyncFlow": "string",
      "SourceType": "wealthbox",
      "State": "CA",
      "Tags": [
        "client"
      ],
      "UpdatedAt": "2026-09-03T14:30:00Z",
      "UploadId": "upload_9f3a2c",
      "UserId": "user_9f3a2c",
      "Version": 0,
      "Versions": [
        {}
      ],
      "Zip": "94107",
      "shareExpiresTtl": 0
    }
  ]
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
POST/api/v1/contacts/

Create contacts

Create contact record

Use this when

Add one or many contacts in a single request. The body is always an array, even for one contact.

Good to know

  • FirstName, LastName, and Phone are required. Phone should be E.164, for example +14155552671.
  • isVerifyNumbers=true looks up each number's carrier and type so you know whether it can receive texts.
  • If a CRM sync is connected, consider creating the contact in the CRM instead so the two never disagree.

Recipes: Create, tag, and find contacts

Query parameters

  • isVerifyNumbersboolean | null

    Default false

  • syncboolean | null
  • userIdstring | nullAdmin only

    Id for the owner of the resource

Request body application/json, required

Array of ContactCreate

  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • CustomFieldsmap | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestringrequired
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestringrequired
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestringrequired
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UploadIdstring | integer | null
  • Zipstring | null
Example body
[
  {
    "FirstName": "Jane",
    "LastName": "Doe",
    "Phone": "+14155552671",
    "Email": "jane@example.com",
    "Tags": [
      "client",
      "retirement"
    ]
  }
]

Example request

curl -X POST "https://api.currentclient.com/api/v1/contacts/?isVerifyNumbers=true" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
  {
    "FirstName": "Jane",
    "LastName": "Doe",
    "Phone": "+14155552671",
    "Email": "jane@example.com",
    "Tags": [
      "client",
      "retirement"
    ]
  }
]'

Responses

200Successful Response
Response fields

Array of Contact

  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • ContactIdstringrequired
  • CreatedAtstringrequired
  • CustomFieldsmap | null
  • DeletedAtstring | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestringrequired
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestringrequired
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestringrequired
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UpdatedAtstring | null
  • UploadIdstring | integer | null
  • UserIdstringrequired
  • Versionintegerrequired
  • VersionsContactVersion[] | null
  • Zipstring | null
  • shareExpiresTtlinteger | null
Example response
[
  {
    "Address1": "100 Market St",
    "Address2": "Suite 400",
    "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
    "BirthDate": "1975-04-12",
    "City": "San Francisco",
    "ContactId": "contact_9f3a2c",
    "CreatedAt": "2026-09-03T14:30:00Z",
    "CustomFields": {},
    "DeletedAt": "2026-09-03T14:30:00Z",
    "Email": "jane@example.com",
    "EnrichCallerName": "Jane Doe",
    "EnrichCallerType": "consumer",
    "EnrichLookupAt": "2026-09-03T14:30:00Z",
    "EnrichMeta": {},
    "FirstName": "Jane",
    "HouseholdId": "household_9f3a2c",
    "HouseholdName": "Jane Doe",
    "HouseholdTitle": "The Doe household",
    "IsArchived": false,
    "LastContactedTime": "2026-09-03T14:30:00Z",
    "LastName": "Doe",
    "LastSubmittedTime": "2026-09-03T14:30:00Z",
    "LastSyncTime": "2026-09-03T14:30:00Z",
    "MiddleName": "Q",
    "Nickname": "Janie",
    "NumberCarrierName": "Jane Doe",
    "NumberCarrierType": "mobile",
    "NumberLookupAt": "2026-09-03T14:30:00Z",
    "NumberMeta": {},
    "Numbers": [
      {
        "IsDoNotContact": false,
        "IsPreferred": true,
        "Label": "Mobile",
        "Meta": {},
        "Phone": "+14155552671"
      }
    ],
    "OwnerId": "owner_9f3a2c",
    "OwnerSourceId": "source_9f3a2c",
    "OwnerSourceName": "Jane Doe",
    "Phone": "+14155552671",
    "SourceId": "source_9f3a2c",
    "SourceMeta": {},
    "SourceSyncFlow": "string",
    "SourceType": "wealthbox",
    "State": "CA",
    "Tags": [
      "client"
    ],
    "UpdatedAt": "2026-09-03T14:30:00Z",
    "UploadId": "upload_9f3a2c",
    "UserId": "user_9f3a2c",
    "Version": 0,
    "Versions": [
      {
        "Address1": "100 Market St",
        "Address2": "Suite 400",
        "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
        "BirthDate": "1975-04-12",
        "City": "San Francisco",
        "CreatedAt": "2026-09-03T14:30:00Z",
        "CustomFields": {},
        "Email": "jane@example.com",
        "EnrichCallerName": "Jane Doe",
        "EnrichCallerType": "consumer",
        "EnrichLookupAt": "2026-09-03T14:30:00Z",
        "EnrichMeta": {},
        "FirstName": "Jane",
        "HouseholdId": "household_9f3a2c",
        "HouseholdName": "Jane Doe",
        "HouseholdTitle": "The Doe household",
        "IsArchived": false,
        "LastContactedTime": "2026-09-03T14:30:00Z",
        "LastName": "Doe",
        "LastSubmittedTime": "2026-09-03T14:30:00Z",
        "LastSyncTime": "2026-09-03T14:30:00Z",
        "MiddleName": "Q",
        "Nickname": "Janie",
        "NumberCarrierName": "Jane Doe",
        "NumberCarrierType": "mobile",
        "NumberLookupAt": "2026-09-03T14:30:00Z",
        "NumberMeta": {},
        "Numbers": [],
        "OwnerId": "owner_9f3a2c",
        "OwnerSourceId": "source_9f3a2c",
        "OwnerSourceName": "Jane Doe",
        "Phone": "+14155552671",
        "SourceId": "source_9f3a2c",
        "SourceMeta": {},
        "SourceSyncFlow": "string",
        "SourceType": "wealthbox",
        "State": "CA",
        "Tags": [],
        "UpdatedAt": "2026-09-03T14:30:00Z",
        "UploadId": "upload_9f3a2c",
        "Version": 0,
        "Zip": "94107"
      }
    ],
    "Zip": "94107",
    "shareExpiresTtl": 0
  }
]
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
GET/api/v1/contacts/{contactId}/notes/

Read contact notes

Get contacts note records

Path parameters

  • contactIdstringin pathrequired

Query parameters

  • cursorstring | null

    Pagination cursor provided by previous paginated response

  • limitinteger | null

    Pagination page size

    Default 100. 10 to 200

Example request

curl "https://api.currentclient.com/api/v1/contacts/contact_9f3a2c/notes/" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
Example response
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "ContactId": "contact_9f3a2c",
      "CreatedTime": "2026-09-03T14:30:00Z",
      "Message": "Hi Jane, your documents are ready to sign.",
      "NoteId": "note_9f3a2c",
      "UserId": "user_9f3a2c"
    }
  ]
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
POST/api/v1/contacts/{contactId}/notes/

Create note

Create note record

Path parameters

  • contactIdstringin pathrequired

Request body application/json, required

  • Messagestringrequired
Example body
{
  "Message": "Hi Jane, your documents are ready to sign."
}

Example request

curl -X POST "https://api.currentclient.com/api/v1/contacts/contact_9f3a2c/notes/" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "Message": "Hi Jane, your documents are ready to sign."
}'

Responses

200Successful Response
Response fields
  • ContactIdstringrequired
  • CreatedTimestring | integerrequired
  • Messagestringrequired
  • NoteIdstring | integerrequired
  • UserIdstringrequired
Example response
{
  "ContactId": "contact_9f3a2c",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Message": "Hi Jane, your documents are ready to sign.",
  "NoteId": "note_9f3a2c",
  "UserId": "user_9f3a2c"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
PUT/api/v1/contacts/{contactId}/notes/{noteId}

Update note

Update note record

Path parameters

  • contactIdstringin pathrequired
  • noteIdstringin pathrequired

Request body application/json, required

  • Messagestring | null
Example body
{
  "Message": "Hi Jane, your documents are ready to sign."
}

Example request

curl -X PUT "https://api.currentclient.com/api/v1/contacts/contact_9f3a2c/notes/note_9f3a2c" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "Message": "Hi Jane, your documents are ready to sign."
}'

Responses

200Successful Response
Response fields
  • Messagestring | null
Example response
{
  "Message": "Hi Jane, your documents are ready to sign."
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
DELETE/api/v1/contacts/{contactId}/notes/{noteId}

Delete note

Delete note record

Path parameters

  • contactIdstringin pathrequired
  • noteIdstringin pathrequired

Example request

curl -X DELETE "https://api.currentclient.com/api/v1/contacts/contact_9f3a2c/notes/note_9f3a2c" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • ContactIdstringrequired
  • CreatedTimestring | integerrequired
  • Messagestringrequired
  • NoteIdstring | integerrequired
  • UserIdstringrequired
Example response
{
  "ContactId": "contact_9f3a2c",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Message": "Hi Jane, your documents are ready to sign.",
  "NoteId": "note_9f3a2c",
  "UserId": "user_9f3a2c"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
GET/api/v1/contacts/{id}

Get a contact

Get contact record

Use this when

Fetch one contact by its ContactId, for example the ContactId on a call or message record.

Good to know

  • Set versions=true to include the contact's edit history.

Recipes: Create, tag, and find contacts

Path parameters

  • idstringin pathrequired

Query parameters

  • teamMemberUserIdstring | nullAdmin only

    Team Member User Id for the owner of the resource

  • userIdstring | nullAdmin only

    Id for the owner of the resource

  • versionsboolean | null

    Include all the versions for the contact

Example request

curl "https://api.currentclient.com/api/v1/contacts/cnt_9f3a2c" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • ContactIdstringrequired
  • CreatedAtstringrequired
  • CustomFieldsmap | null
  • DeletedAtstring | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestringrequired
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestringrequired
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestringrequired
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UpdatedAtstring | null
  • UploadIdstring | integer | null
  • UserIdstringrequired
  • Versionintegerrequired
  • VersionsContactVersion[] | null
  • Zipstring | null
  • shareExpiresTtlinteger | null
Example response
{
  "Address1": "100 Market St",
  "Address2": "Suite 400",
  "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
  "BirthDate": "1975-04-12",
  "City": "San Francisco",
  "ContactId": "contact_9f3a2c",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "CustomFields": {},
  "DeletedAt": "2026-09-03T14:30:00Z",
  "Email": "jane@example.com",
  "EnrichCallerName": "Jane Doe",
  "EnrichCallerType": "consumer",
  "EnrichLookupAt": "2026-09-03T14:30:00Z",
  "EnrichMeta": {},
  "FirstName": "Jane",
  "HouseholdId": "household_9f3a2c",
  "HouseholdName": "Jane Doe",
  "HouseholdTitle": "The Doe household",
  "IsArchived": false,
  "LastContactedTime": "2026-09-03T14:30:00Z",
  "LastName": "Doe",
  "LastSubmittedTime": "2026-09-03T14:30:00Z",
  "LastSyncTime": "2026-09-03T14:30:00Z",
  "MiddleName": "Q",
  "Nickname": "Janie",
  "NumberCarrierName": "Jane Doe",
  "NumberCarrierType": "mobile",
  "NumberLookupAt": "2026-09-03T14:30:00Z",
  "NumberMeta": {},
  "Numbers": [
    {
      "IsDoNotContact": false,
      "IsPreferred": true,
      "Label": "Mobile",
      "Meta": {},
      "Phone": "+14155552671"
    }
  ],
  "OwnerId": "owner_9f3a2c",
  "OwnerSourceId": "source_9f3a2c",
  "OwnerSourceName": "Jane Doe",
  "Phone": "+14155552671",
  "SourceId": "source_9f3a2c",
  "SourceMeta": {},
  "SourceSyncFlow": "string",
  "SourceType": "wealthbox",
  "State": "CA",
  "Tags": [
    "client"
  ],
  "UpdatedAt": "2026-09-03T14:30:00Z",
  "UploadId": "upload_9f3a2c",
  "UserId": "user_9f3a2c",
  "Version": 0,
  "Versions": [
    {
      "Address1": "100 Market St",
      "Address2": "Suite 400",
      "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
      "BirthDate": "1975-04-12",
      "City": "San Francisco",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "CustomFields": {},
      "Email": "jane@example.com",
      "EnrichCallerName": "Jane Doe",
      "EnrichCallerType": "consumer",
      "EnrichLookupAt": "2026-09-03T14:30:00Z",
      "EnrichMeta": {},
      "FirstName": "Jane",
      "HouseholdId": "household_9f3a2c",
      "HouseholdName": "Jane Doe",
      "HouseholdTitle": "The Doe household",
      "IsArchived": false,
      "LastContactedTime": "2026-09-03T14:30:00Z",
      "LastName": "Doe",
      "LastSubmittedTime": "2026-09-03T14:30:00Z",
      "LastSyncTime": "2026-09-03T14:30:00Z",
      "MiddleName": "Q",
      "Nickname": "Janie",
      "NumberCarrierName": "Jane Doe",
      "NumberCarrierType": "mobile",
      "NumberLookupAt": "2026-09-03T14:30:00Z",
      "NumberMeta": {},
      "Numbers": [
        {}
      ],
      "OwnerId": "owner_9f3a2c",
      "OwnerSourceId": "source_9f3a2c",
      "OwnerSourceName": "Jane Doe",
      "Phone": "+14155552671",
      "SourceId": "source_9f3a2c",
      "SourceMeta": {},
      "SourceSyncFlow": "string",
      "SourceType": "wealthbox",
      "State": "CA",
      "Tags": [
        "client"
      ],
      "UpdatedAt": "2026-09-03T14:30:00Z",
      "UploadId": "upload_9f3a2c",
      "Version": 0,
      "Zip": "94107"
    }
  ],
  "Zip": "94107",
  "shareExpiresTtl": 0
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
PUT/api/v1/contacts/{id}

Update a contact

Update contact record

Use this when

Change fields on an existing contact. Send only the fields you want to change; everything else is left alone.

Good to know

  • Tags are replaced by default. Pass isAddTag=true to add to the existing tags instead.
  • Every update creates a new version unless inPlace=true.

Recipes: Create, tag, and find contacts

Path parameters

  • idstringin pathrequired

Query parameters

  • connectSyncboolean | null

    Update the record in place with the sync info, dont version it

    Default false

  • inPlaceboolean | null

    Update the record in place, dont version it

    Default false

  • isAddTagboolean | null

    Add the tags, dont replace

    Default false

  • userIdstring | nullAdmin only

    Id for the owner of the resource

Request body application/json, required

  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • CustomFieldsmap | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestring | null
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestring | null
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestring | null
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UploadIdstring | integer | null
  • Zipstring | null
Example body
{
  "Tags": [
    "reviewed-2026"
  ],
  "Nickname": "Janie"
}

Example request

curl -X PUT "https://api.currentclient.com/api/v1/contacts/cnt_9f3a2c?isAddTag=true" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "Tags": [
    "reviewed-2026"
  ],
  "Nickname": "Janie"
}'

Responses

200Successful Response
Response fields
  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • CustomFieldsmap | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestring | null
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestring | null
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestring | null
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UploadIdstring | integer | null
  • Zipstring | null
Example response
{
  "Address1": "100 Market St",
  "Address2": "Suite 400",
  "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
  "BirthDate": "1975-04-12",
  "City": "San Francisco",
  "CustomFields": {},
  "Email": "jane@example.com",
  "EnrichCallerName": "Jane Doe",
  "EnrichCallerType": "consumer",
  "EnrichLookupAt": "2026-09-03T14:30:00Z",
  "EnrichMeta": {},
  "FirstName": "Jane",
  "HouseholdId": "household_9f3a2c",
  "HouseholdName": "Jane Doe",
  "HouseholdTitle": "The Doe household",
  "IsArchived": false,
  "LastContactedTime": "2026-09-03T14:30:00Z",
  "LastName": "Doe",
  "LastSubmittedTime": "2026-09-03T14:30:00Z",
  "LastSyncTime": "2026-09-03T14:30:00Z",
  "MiddleName": "Q",
  "Nickname": "Janie",
  "NumberCarrierName": "Jane Doe",
  "NumberCarrierType": "mobile",
  "NumberLookupAt": "2026-09-03T14:30:00Z",
  "NumberMeta": {},
  "Numbers": [
    {
      "IsDoNotContact": false,
      "IsPreferred": true,
      "Label": "Mobile",
      "Meta": {},
      "Phone": "+14155552671"
    }
  ],
  "OwnerId": "owner_9f3a2c",
  "OwnerSourceId": "source_9f3a2c",
  "OwnerSourceName": "Jane Doe",
  "Phone": "+14155552671",
  "SourceId": "source_9f3a2c",
  "SourceMeta": {},
  "SourceSyncFlow": "string",
  "SourceType": "wealthbox",
  "State": "CA",
  "Tags": [
    "client"
  ],
  "UploadId": "upload_9f3a2c",
  "Zip": "94107"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
GET/api/v1/contacts/phones/{phone}/

Read contacts by phone

Get all the contacts records that have a phone

Path parameters

  • phonestringin pathrequired

Query parameters

  • limitinteger | null

    Pagination page size

    Default 1000. 1 to 1000

  • userIdstring | nullAdmin only

    Id for the owner of the resource

  • versionsboolean | null

    Return contacts versions as well

Example request

curl "https://api.currentclient.com/api/v1/contacts/phones/string/" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields

Array of Contact

  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • ContactIdstringrequired
  • CreatedAtstringrequired
  • CustomFieldsmap | null
  • DeletedAtstring | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestringrequired
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestringrequired
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestringrequired
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UpdatedAtstring | null
  • UploadIdstring | integer | null
  • UserIdstringrequired
  • Versionintegerrequired
  • VersionsContactVersion[] | null
  • Zipstring | null
  • shareExpiresTtlinteger | null
Example response
[
  {
    "Address1": "100 Market St",
    "Address2": "Suite 400",
    "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
    "BirthDate": "1975-04-12",
    "City": "San Francisco",
    "ContactId": "contact_9f3a2c",
    "CreatedAt": "2026-09-03T14:30:00Z",
    "CustomFields": {},
    "DeletedAt": "2026-09-03T14:30:00Z",
    "Email": "jane@example.com",
    "EnrichCallerName": "Jane Doe",
    "EnrichCallerType": "consumer",
    "EnrichLookupAt": "2026-09-03T14:30:00Z",
    "EnrichMeta": {},
    "FirstName": "Jane",
    "HouseholdId": "household_9f3a2c",
    "HouseholdName": "Jane Doe",
    "HouseholdTitle": "The Doe household",
    "IsArchived": false,
    "LastContactedTime": "2026-09-03T14:30:00Z",
    "LastName": "Doe",
    "LastSubmittedTime": "2026-09-03T14:30:00Z",
    "LastSyncTime": "2026-09-03T14:30:00Z",
    "MiddleName": "Q",
    "Nickname": "Janie",
    "NumberCarrierName": "Jane Doe",
    "NumberCarrierType": "mobile",
    "NumberLookupAt": "2026-09-03T14:30:00Z",
    "NumberMeta": {},
    "Numbers": [
      {
        "IsDoNotContact": false,
        "IsPreferred": true,
        "Label": "Mobile",
        "Meta": {},
        "Phone": "+14155552671"
      }
    ],
    "OwnerId": "owner_9f3a2c",
    "OwnerSourceId": "source_9f3a2c",
    "OwnerSourceName": "Jane Doe",
    "Phone": "+14155552671",
    "SourceId": "source_9f3a2c",
    "SourceMeta": {},
    "SourceSyncFlow": "string",
    "SourceType": "wealthbox",
    "State": "CA",
    "Tags": [
      "client"
    ],
    "UpdatedAt": "2026-09-03T14:30:00Z",
    "UploadId": "upload_9f3a2c",
    "UserId": "user_9f3a2c",
    "Version": 0,
    "Versions": [
      {
        "Address1": "100 Market St",
        "Address2": "Suite 400",
        "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
        "BirthDate": "1975-04-12",
        "City": "San Francisco",
        "CreatedAt": "2026-09-03T14:30:00Z",
        "CustomFields": {},
        "Email": "jane@example.com",
        "EnrichCallerName": "Jane Doe",
        "EnrichCallerType": "consumer",
        "EnrichLookupAt": "2026-09-03T14:30:00Z",
        "EnrichMeta": {},
        "FirstName": "Jane",
        "HouseholdId": "household_9f3a2c",
        "HouseholdName": "Jane Doe",
        "HouseholdTitle": "The Doe household",
        "IsArchived": false,
        "LastContactedTime": "2026-09-03T14:30:00Z",
        "LastName": "Doe",
        "LastSubmittedTime": "2026-09-03T14:30:00Z",
        "LastSyncTime": "2026-09-03T14:30:00Z",
        "MiddleName": "Q",
        "Nickname": "Janie",
        "NumberCarrierName": "Jane Doe",
        "NumberCarrierType": "mobile",
        "NumberLookupAt": "2026-09-03T14:30:00Z",
        "NumberMeta": {},
        "Numbers": [],
        "OwnerId": "owner_9f3a2c",
        "OwnerSourceId": "source_9f3a2c",
        "OwnerSourceName": "Jane Doe",
        "Phone": "+14155552671",
        "SourceId": "source_9f3a2c",
        "SourceMeta": {},
        "SourceSyncFlow": "string",
        "SourceType": "wealthbox",
        "State": "CA",
        "Tags": [],
        "UpdatedAt": "2026-09-03T14:30:00Z",
        "UploadId": "upload_9f3a2c",
        "Version": 0,
        "Zip": "94107"
      }
    ],
    "Zip": "94107",
    "shareExpiresTtl": 0
  }
]
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}

Inboxes

An inbox is a phone number plus everything attached to it: business hours, auto-replies, the recording and transcription switches, and who is in the ring group. The numbers you can send from all come from here.

  • Find the numbers your token is allowed to send from
  • Check whether recording or transcription is on before relying on those fields on calls
GET/api/v1/inboxes/

List inboxes

Get list of inboxes

Use this when

Discover the phone numbers your token can send from and how each one is configured. Run this once and cache the Number values.

Good to know

  • showWorkspace=true returns every inbox in the workspace, not just the ones assigned to the token's user.
  • IsEnableAutoRecordCalls and IsEnableCallTranscription tell you whether call records from this inbox will carry recordings and transcripts.

Recipes: Find your UserId and inbox numbers

Query parameters

  • cursorstring | null

    Pagination cursor provided by previous paginated response

  • showHiddenboolean

    Show hidden inboxes

    Default false

  • showMutedboolean

    Show muted inboxes

    Default true

  • showWorkspaceboolean

    Show inboxes for the entire workspace

    Default false

  • teamMemberUserIdstring | nullAdmin only

    Team Member User Id for the owner of the resource

  • userIdstring | nullAdmin only

    Id for the owner of the resource

  • workspaceIdstring | null

    Workspace Id to get data for

Example request

curl "https://api.currentclient.com/api/v1/inboxes/?showWorkspace=true" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
Example response
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "BusinessSchedule": [
        {}
      ],
      "BusinessTimezone": "America/Los_Angeles",
      "CallRingDuration": "15",
      "CallRingOrderType": "string",
      "CallTeamMemberIds": [
        "member_9f3a2c"
      ],
      "CallflowId": "callflow_9f3a2c",
      "ComplianceMessage": "You can call or text us at this number. Primarily, you can expect to receive brief news and updates from us. Msg & data rates may apply. Reply STOP to opt-out anytime. Questions? You are welcome to reply.",
      "ComplianceVCardId": "card_9f3a2c",
      "DeletedTime": 1725321600,
      "Dialplan": "string",
      "ForwardingTimeout": 20,
      "ForwardingVoicemailMode": "DESTINATION",
      "GreetingAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
      "HiddenFor": [
        "string"
      ],
      "Holidays": [
        {}
      ],
      "InboundType": "RING",
      "IsComplianceAutoSuppress": false,
      "IsComplianceEnabled": false,
      "IsDropCallerId": false,
      "IsEnableAutoConferenceNotetaker": false,
      "IsEnableAutoIncomingMessage": false,
      "IsEnableAutoMissedCall": false,
      "IsEnableAutoOutOfOfficeIncomingMessage": false,
      "IsEnableAutoOutOfOfficeMissedCall": false,
      "IsEnableAutoOutsideHoursIncomingMessage": false,
      "IsEnableAutoOutsideHoursMissedCall": false,
      "IsEnableAutoRecordCalls": true,
      "IsEnableBusinessHours": false,
      "IsEnableCallSummary": true,
      "IsEnableCallTranscription": true,
      "IsEnableFilterProfanity": false,
      "IsEnableForwardCall": false,
      "IsEnableGreeting": false,
      "IsEnablePhoneMenu": false,
      "IsEnableRecordGreeting": false,
      "IsEnableRecordingAnnouncement": false,
      "IsEnableTranscribeVoicemail": false,
      "IsFaxCapable": false,
      "IsRequireCallSummaryReview": false,
      "IsSmsCapable": false,
      "IsSmsHosting": false,
      "MutedFor": [
        "string"
      ],
      "Name": "Jane Doe",
      "NotetakerPhoneNumber": "string",
      "NotetakerProvider": "JUMP",
      "Number": "+14155550100",
      "NumberForwardTo": "+14155550100",
      "OrgA2pId": "p_9f3a2c",
      "OrgA2pStatus": "PORTING_IN",
      "OutOfOfficeEndDate": "2026-09-03T14:30:00Z",
      "OutOfOfficeEndTime": "2026-09-03T14:30:00Z",
      "OutOfOfficeStartDate": "2026-09-03T14:30:00Z",
      "OutOfOfficeStartTime": "2026-09-03T14:30:00Z",
      "OutOfOfficeVoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
      "OutsideHoursVoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
      "Permissions": {},
      "PortOutUnlocked": false,
      "RecordingAnnouncementPromptRef": "string",
      "SkipTeamMemberIds": [
        "member_9f3a2c"
      ],
      "Symbol": "JD",
      "TeamMemberId": "member_9f3a2c",
      "TextAutoAutoOutsideHoursMissedCall": "string",
      "TextAutoIncomingMessage": "string",
      "TextAutoMissedCall": "string",
      "TextAutoOutOfOfficeIncomingMessage": "string",
      "TextAutoOutOfOfficeMissedCall": "string",
      "TextAutoOutsideHoursIncomingMessage": "string",
      "TwilioMessagingServiceSid": "CA7f3e2b9c1d4a5e6f",
      "Type": "REGULAR",
      "UserId": "user_9f3a2c",
      "VoiceProvider": "twilio",
      "VoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
      "WabaId": "waba_9f3a2c",
      "WhatsappSenderNumber": "string"
    }
  ]
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
GET/api/v1/inboxes/{number}

Get an inbox

Returns one inbox by phone number. Requires a bearer token (Authorization: Bearer <token>).

Path parameters

  • numberstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl "https://api.currentclient.com/api/v1/inboxes/string" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • BusinessSchedulemap[] | null
  • BusinessTimezonestring | null
  • CallRingDurationstring | null
  • CallRingOrderTypestring | null
  • CallTeamMemberIdsstring[] | null
  • CallflowIdstring | null
  • ComplianceMessagestring | null
  • ComplianceVCardIdstring | null
  • DeletedTimeinteger | null
  • Dialplanstring | null
  • ForwardingTimeoutinteger
  • ForwardingVoicemailModeenum | null

    PRO-6628: which voicemail should win the race when a forwarded call goes unanswered. - DESTINATION (default, `None`/absent behaves identically): the forwarded-to number's own carrier voicemail. `ForwardingTimeout` is floored at `crud.MIN_FORWARD_RING_SEC` so that voicemail has a real chance to answer. - CURRENTCLIENT: CurrentClient's own voicemail. `ForwardingTimeout` is passed through unfloored so a short ring lets it win instead.

    DESTINATIONCURRENTCLIENT
  • GreetingAudioUrlstring | null
  • HiddenForstring[] | null
  • HolidaysInboxHoliday[] | null
  • InboundTypeenum | null

    Determines how incoming calls are handled for this inbox: - RING: Ring the team members in the app - FORWARD: Forward the call to an external number - DIALPLAN: Route through a custom dial plan

    RINGFORWARDDIALPLAN
  • IsComplianceAutoSuppressboolean | null
  • IsComplianceEnabledboolean | null
  • IsDropCallerIdboolean | null
  • IsEnableAutoConferenceNotetakerboolean | null
  • IsEnableAutoIncomingMessageboolean | null
  • IsEnableAutoMissedCallboolean | null
  • IsEnableAutoOutOfOfficeIncomingMessageboolean | null
  • IsEnableAutoOutOfOfficeMissedCallboolean | null
  • IsEnableAutoOutsideHoursIncomingMessageboolean | null
  • IsEnableAutoOutsideHoursMissedCallboolean | null
  • IsEnableAutoRecordCallsboolean | null
  • IsEnableBusinessHoursboolean | null
  • IsEnableCallSummaryboolean | null
  • IsEnableCallTranscriptionboolean | null
  • IsEnableFilterProfanityboolean | null
  • IsEnableForwardCallboolean | null
  • IsEnableGreetingboolean | null
  • IsEnablePhoneMenuboolean | null
  • IsEnableRecordGreetingboolean | null
  • IsEnableRecordingAnnouncementboolean | null
  • IsEnableTranscribeVoicemailboolean | null
  • IsFaxCapableboolean
  • IsRequireCallSummaryReviewboolean | null
  • IsSmsCapableboolean
  • IsSmsHostingboolean | null
  • MutedForstring[] | null
  • Namestring | null
  • NotetakerPhoneNumberstring | null
  • NotetakerProviderenum | null

    PRO-7319: which AI notetaker's dedicated phone number this inbox should auto-conference into a call once it connects. Purely a visual/reference label for the team (which icon/name to show in settings) -- it has no effect on how the dial-in itself works, since that always just dials `NotetakerPhoneNumber`. OTHER covers any notetaker not in this list yet; new named providers get appended here as they're added.

    JUMPZOCKSHAZELWEALTHBOXOTHER
  • Numberstringrequired
  • NumberForwardTostring | null
  • OrgA2pIdstring | null
  • OrgA2pStatusenum | string | null
  • OutOfOfficeEndDatestring | null
  • OutOfOfficeEndTimestring | null
  • OutOfOfficeStartDatestring | null
  • OutOfOfficeStartTimestring | null
  • OutOfOfficeVoicemailAudioUrlstring | null
  • OutsideHoursVoicemailAudioUrlstring | null
  • PermissionsPermissionSettings | null
  • PortOutUnlockedboolean
  • RecordingAnnouncementPromptRefstring | null
  • SkipTeamMemberIdsstring[] | null
  • Symbolstring | null
  • TeamMemberIdstring | null
  • TextAutoAutoOutsideHoursMissedCallstring | null
  • TextAutoIncomingMessagestring | null
  • TextAutoMissedCallstring | null
  • TextAutoOutOfOfficeIncomingMessagestring | null
  • TextAutoOutOfOfficeMissedCallstring | null
  • TextAutoOutsideHoursIncomingMessagestring | null
  • TwilioMessagingServiceSidstring | null
  • Typeenum

    PRO-4150 shipped this as a mutable flip on one row per number -- "an inbox is either REGULAR or WHATSAPP, never both." PRO-7929 corrects that: a number can hold a REGULAR inbox and a WHATSAPP inbox at the same time, as two separate coexisting records (see `Inbox.make_sk`). This enum still names the two channels; it is no longer a toggle on a single record, and outbound channel is still determined by which of the two inbox records you composed from.

    REGULARWHATSAPP
  • UserIdstring | null
  • VoiceProviderenum

    PRO-7115: which voice stack places and receives calls for THIS inbox. Per inbox, deliberately not per workspace: one workspace has to be able to run a Twilio inbox and a CC SIP inbox side by side, both live in the same session. Values are lowercase, unlike the ALL-CAPS `InboundTypeEnum` / `ForwardingVoicemailModeEnum` above. That is not a style slip: cc-app-core passes this string verbatim from `resolveProviderConfig` into `createVoiceDriver`, whose registered driver ids are lowercase (`registerVoiceDriver('twilio', ...)`), and there is no normalization seam between the two. An ALL-CAPS value here would raise UnknownVoiceProviderError in the client.

    twiliosip
  • VoicemailAudioUrlstring | null
  • WabaIdstring | null
  • WhatsappSenderNumberstring | null
Example response
{
  "BusinessSchedule": [
    {}
  ],
  "BusinessTimezone": "America/Los_Angeles",
  "CallRingDuration": "15",
  "CallRingOrderType": "string",
  "CallTeamMemberIds": [
    "member_9f3a2c"
  ],
  "CallflowId": "callflow_9f3a2c",
  "ComplianceMessage": "You can call or text us at this number. Primarily, you can expect to receive brief news and updates from us. Msg & data rates may apply. Reply STOP to opt-out anytime. Questions? You are welcome to reply.",
  "ComplianceVCardId": "card_9f3a2c",
  "DeletedTime": 1725321600,
  "Dialplan": "string",
  "ForwardingTimeout": 20,
  "ForwardingVoicemailMode": "DESTINATION",
  "GreetingAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
  "HiddenFor": [
    "string"
  ],
  "Holidays": [
    {
      "CustomDate": "2026-09-03T14:30:00Z",
      "HolidayId": "holiday_9f3a2c",
      "IsEnabled": false,
      "IsRecurringYearly": false,
      "Name": "Jane Doe",
      "TextAutoIncomingMessage": "string",
      "TextAutoMissedCall": "string",
      "VoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3"
    }
  ],
  "InboundType": "RING",
  "IsComplianceAutoSuppress": false,
  "IsComplianceEnabled": false,
  "IsDropCallerId": false,
  "IsEnableAutoConferenceNotetaker": false,
  "IsEnableAutoIncomingMessage": false,
  "IsEnableAutoMissedCall": false,
  "IsEnableAutoOutOfOfficeIncomingMessage": false,
  "IsEnableAutoOutOfOfficeMissedCall": false,
  "IsEnableAutoOutsideHoursIncomingMessage": false,
  "IsEnableAutoOutsideHoursMissedCall": false,
  "IsEnableAutoRecordCalls": true,
  "IsEnableBusinessHours": false,
  "IsEnableCallSummary": true,
  "IsEnableCallTranscription": true,
  "IsEnableFilterProfanity": false,
  "IsEnableForwardCall": false,
  "IsEnableGreeting": false,
  "IsEnablePhoneMenu": false,
  "IsEnableRecordGreeting": false,
  "IsEnableRecordingAnnouncement": false,
  "IsEnableTranscribeVoicemail": false,
  "IsFaxCapable": false,
  "IsRequireCallSummaryReview": false,
  "IsSmsCapable": false,
  "IsSmsHosting": false,
  "MutedFor": [
    "string"
  ],
  "Name": "Jane Doe",
  "NotetakerPhoneNumber": "string",
  "NotetakerProvider": "JUMP",
  "Number": "+14155550100",
  "NumberForwardTo": "+14155550100",
  "OrgA2pId": "p_9f3a2c",
  "OrgA2pStatus": "PORTING_IN",
  "OutOfOfficeEndDate": "2026-09-03T14:30:00Z",
  "OutOfOfficeEndTime": "2026-09-03T14:30:00Z",
  "OutOfOfficeStartDate": "2026-09-03T14:30:00Z",
  "OutOfOfficeStartTime": "2026-09-03T14:30:00Z",
  "OutOfOfficeVoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
  "OutsideHoursVoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
  "Permissions": {
    "Editors": [
      "string"
    ],
    "Viewers": [
      "string"
    ]
  },
  "PortOutUnlocked": false,
  "RecordingAnnouncementPromptRef": "string",
  "SkipTeamMemberIds": [
    "member_9f3a2c"
  ],
  "Symbol": "JD",
  "TeamMemberId": "member_9f3a2c",
  "TextAutoAutoOutsideHoursMissedCall": "string",
  "TextAutoIncomingMessage": "string",
  "TextAutoMissedCall": "string",
  "TextAutoOutOfOfficeIncomingMessage": "string",
  "TextAutoOutOfOfficeMissedCall": "string",
  "TextAutoOutsideHoursIncomingMessage": "string",
  "TwilioMessagingServiceSid": "CA7f3e2b9c1d4a5e6f",
  "Type": "REGULAR",
  "UserId": "user_9f3a2c",
  "VoiceProvider": "twilio",
  "VoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
  "WabaId": "waba_9f3a2c",
  "WhatsappSenderNumber": "string"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}

Profile

The account behind your token. This is where you get the UserId and workspace details that other calls need.

GET/api/v1/profile

Get your profile

Get user profile record

Use this when

The first call to make with a new token. It confirms the token works and returns the UserId that sending a message requires.

Recipes: Get an access token, Find your UserId and inbox numbers

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl "https://api.currentclient.com/api/v1/profile" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • AddOnProductIdsstring[] | null
  • Address1string | null
  • Address2string | null
  • AdminBrandImageUrlstring | null
  • AdminEmailstring | null
  • AdminFirstNamestring | null
  • AdminImageUrlstring | null
  • AdminLastNamestring | null
  • BillingBilling | null
  • Biostring | null
  • BrandImageUrlstring | null
  • Citystring | null
  • CompanyNamestring | null
  • CompanyWebsiteUrlstring | null
  • CreatedAtstring | null
  • Crmstring | null
  • DefaultInboxNumberstring | null
  • Emailstring | null
  • ExternalConnectorIdstring | null
  • ExternalDataExternalDataWealthBox | null
  • ExternalIdstring | null
  • ExternalLastUpdatedinteger | null
  • ExternalTypeenum | string | null
  • FirstNamestring | null
  • Industrystring | null
  • IsActiveboolean | null
  • IsAiSummaryFreeboolean | null
  • IsAllowAiContactCreateboolean | null
  • IsDeleteRequestedboolean | null
  • IsFreeboolean | null
  • IsGovernorboolean | null
  • IsHasCrmSyncboolean | null
  • IsManagedBillingboolean | null
  • IsSubscriptionActiveboolean | null
  • IsTeamMemberboolean | null
  • IsUserboolean | null
  • JobTitlestring | null
  • LastNamestring | null
  • LegalDisclosurestring | null
  • MessagingServiceIdstring | null
  • MilestonesMilestones | null
  • NetworkEnrolledAtstring | null
  • NetworkIdstring | null
  • OrganizationIdstring | null
  • Phonestring | null
  • PlanProductIdstring | null
  • RegisteredNumberRegisteredNumber | null
  • SourceAttributionstring | null
  • Statestring | null
  • TeamMemberUserIdstring | null
  • UserIdstringrequired
  • VoiceMeteringSourcestring | null
  • WorkspaceIdstring | null
  • WorkspaceNamestring | null
  • Zipstring | null
Example response
{
  "AddOnProductIds": [
    "product_9f3a2c"
  ],
  "Address1": "100 Market St",
  "Address2": "Suite 400",
  "AdminBrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "AdminEmail": "jane@example.com",
  "AdminFirstName": "Jane",
  "AdminImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "AdminLastName": "Doe",
  "Billing": {
    "AddonIds": [
      "addon_9f3a2c"
    ],
    "AddonNames": [
      "Jane Doe"
    ],
    "BillingType": "string",
    "BundleIds": [
      "bundle_9f3a2c"
    ],
    "BundleNames": [
      "Jane Doe"
    ],
    "CancelAtTime": 1725321600,
    "CanceledAtTime": 1725321600,
    "CreatedTime": 1725321600,
    "PriceIds": [
      "price_9f3a2c"
    ],
    "ProductDescription": "string",
    "ProductId": "product_9f3a2c",
    "ProductName": "Jane Doe",
    "StripeCustomerId": "customer_9f3a2c",
    "SubscriptionId": "subscription_9f3a2c",
    "SubscriptionStatus": "active"
  },
  "Bio": "Helping families plan for what is next.",
  "BrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "City": "San Francisco",
  "CompanyName": "Acme Wealth Advisors",
  "CompanyWebsiteUrl": "https://example.com",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "Crm": "string",
  "DefaultInboxNumber": "string",
  "Email": "jane@example.com",
  "ExternalConnectorId": "connector_9f3a2c",
  "ExternalData": {
    "Groups": [
      "string"
    ]
  },
  "ExternalId": "external_9f3a2c",
  "ExternalLastUpdated": 0,
  "ExternalType": "wealthbox",
  "FirstName": "Jane",
  "Industry": "Financial services",
  "IsActive": true,
  "IsAiSummaryFree": false,
  "IsAllowAiContactCreate": false,
  "IsDeleteRequested": false,
  "IsFree": false,
  "IsGovernor": false,
  "IsHasCrmSync": false,
  "IsManagedBilling": false,
  "IsSubscriptionActive": false,
  "IsTeamMember": false,
  "IsUser": true,
  "JobTitle": "Financial Advisor",
  "LastName": "Doe",
  "LegalDisclosure": "string",
  "MessagingServiceId": "service_9f3a2c",
  "Milestones": {
    "IsCompletedOnboarding": false
  },
  "NetworkEnrolledAt": "2026-09-03T14:30:00Z",
  "NetworkId": "network_9f3a2c",
  "OrganizationId": "organization_9f3a2c",
  "Phone": "+14155552671",
  "PlanProductId": "product_9f3a2c",
  "RegisteredNumber": {
    "AddressRequirements": "string",
    "Capabilities": {
      "IsMMSEnabled": false,
      "IsSMSEnabled": false,
      "IsVoiceEnabled": false
    },
    "DateCreated": "string",
    "DateUpdated": "string",
    "FriendlyName": "Jane Doe",
    "Origin": "string",
    "PhoneNumber": "string",
    "Sid": "CA7f3e2b9c1d4a5e6f",
    "SmsFallbackMethod": "string",
    "SmsFallbackUrl": "https://example.com",
    "SmsMethod": "string",
    "SmsUrl": "https://example.com",
    "Status": "string",
    "StatusCallback": "string",
    "StatusCallbackMethod": "string"
  },
  "SourceAttribution": "string",
  "State": "CA",
  "TeamMemberUserId": "user_9f3a2c",
  "UserId": "user_9f3a2c",
  "VoiceMeteringSource": "string",
  "WorkspaceId": "workspace_9f3a2c",
  "WorkspaceName": "Acme Wealth Advisors",
  "Zip": "94107"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}

Team members

Everyone in the workspace, with role flags and contact details. Use it to turn the member ids on calls and messages back into people.

GET/api/v1/team-members

List team members

Returns the team members visible to the authenticated caller's workspace.

Use this when

Map the member ids that appear on calls and messages (AnsweredByMemberId, SenderMemberId) back to names and emails.

Good to know

  • Pass isActive=true to skip people who have left the workspace.

Query parameters

  • isActiveboolean | null

Example request

curl "https://api.currentclient.com/api/v1/team-members?isActive=true" \
  -H "Authorization: Bearer $TOKEN"

Responses

200
Response fields
Example response
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "Bio": "Helping families plan for what is next.",
      "BrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
      "CognitoUserId": "user_9f3a2c",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "Email": "jane@example.com",
      "ExternalConnectorId": "connector_9f3a2c",
      "ExternalData": {},
      "ExternalId": "external_9f3a2c",
      "ExternalLastUpdated": 0,
      "ExternalType": "wealthbox",
      "FirstName": "Jane",
      "IsActive": true,
      "IsAdmin": false,
      "IsAiSummaryFree": false,
      "IsFree": false,
      "IsGovernor": false,
      "IsInvited": false,
      "IsJoined": true,
      "IsMember": true,
      "IsXypnMember": false,
      "JobTitle": "Financial Advisor",
      "LastName": "Doe",
      "Phone": "+14155552671",
      "TeamMemberId": "member_9f3a2c",
      "UpdatedAt": "2026-09-03T14:30:00Z",
      "UserId": "user_9f3a2c"
    }
  ]
}
GET/api/v1/team-members/{id}

Get a team member

Example request

curl "https://api.currentclient.com/api/v1/team-members/{id}" \
  -H "Authorization: Bearer $TOKEN"

Responses

200
Response fields
  • Biostring | null
  • BrandImageUrlstring | null
  • CognitoUserIdstring | null
  • CreatedAtstringrequired
  • Emailstringrequired
  • ExternalConnectorIdstring | null
  • ExternalDataExternalDataWealthBox | null
  • ExternalIdstring | null
  • ExternalLastUpdatedinteger | null
  • ExternalTypeenum | string | null
  • FirstNamestring | null
  • IsActiveboolean | null
  • IsAiSummaryFreeboolean | null
  • IsFreeboolean | null
  • IsInvitedboolean | null
  • IsJoinedboolean | null
  • IsMemberboolean | null
  • IsXypnMemberboolean | null
  • JobTitlestring | null
  • LastNamestring | null
  • Phonestring | null
  • TeamMemberIdstringrequired
  • UpdatedAtstring | null
  • UserIdstringrequired
Example response
{
  "Bio": "Helping families plan for what is next.",
  "BrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "CognitoUserId": "user_9f3a2c",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "Email": "jane@example.com",
  "ExternalConnectorId": "connector_9f3a2c",
  "ExternalData": {
    "Groups": [
      "string"
    ]
  },
  "ExternalId": "external_9f3a2c",
  "ExternalLastUpdated": 0,
  "ExternalType": "wealthbox",
  "FirstName": "Jane",
  "IsActive": true,
  "IsAiSummaryFree": false,
  "IsFree": false,
  "IsInvited": false,
  "IsJoined": true,
  "IsMember": true,
  "IsXypnMember": false,
  "JobTitle": "Financial Advisor",
  "LastName": "Doe",
  "Phone": "+14155552671",
  "TeamMemberId": "member_9f3a2c",
  "UpdatedAt": "2026-09-03T14:30:00Z",
  "UserId": "user_9f3a2c"
}

Other

GET/api/v1/conversations

List conversations

Returns conversations visible to the authenticated caller, most recent first.

Query parameters

  • assignedTostring | null

    PRO-6906: `?assignedTo=<memberId>` filter.

  • cursorstring | null
  • folderIdstring | null
  • isSnoozedboolean | null
  • isUnreadboolean | null
  • limitinteger (uint16)

    Default 100

  • searchstring | null
  • statusenum | null
    OPENCLOSED
  • userNumberstring | null

Example request

curl "https://api.currentclient.com/api/v1/conversations" \
  -H "Authorization: Bearer $TOKEN"

Responses

200
Response fields
Example response
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "AssignedByUserId": "user_9f3a2c",
      "AssignedTime": "2026-09-03T14:30:00Z",
      "AssignedToUserId": "user_9f3a2c",
      "ChannelType": "sms",
      "ContactId": "contact_9f3a2c",
      "ContactName": "Jane Doe",
      "ConversationFolderId": "folder_9f3a2c",
      "ConversationId": "conversation_9f3a2c",
      "CreatedTime": 1725321600,
      "IsCancelSnoozeOnReply": false,
      "IsRead": false,
      "IsReadByMe": false,
      "IsSnoozed": false,
      "IsSnoozedAlert": false,
      "Label": "Mobile",
      "LastInboundTime": 1725321600,
      "LatestCall": {},
      "LatestMessage": {},
      "Name": "Jane Doe",
      "NumberReadStates": {},
      "Owner": "string",
      "Participants": [
        {}
      ],
      "SnoozedUntilTime": "2026-09-03T14:30:00Z",
      "Status": "OPEN",
      "UpdatedTime": 1725321600,
      "UserId": "user_9f3a2c",
      "UserNumbers": [
        "+14155550100"
      ],
      "Viewers": {},
      "WhatsAppOptIn": {}
    }
  ]
}
GET/api/v1/conversations/{conversation_id}

Get a conversation

Returns one conversation by id, if the caller can access it.

Example request

curl "https://api.currentclient.com/api/v1/conversations/{conversation_id}" \
  -H "Authorization: Bearer $TOKEN"

Responses

200
Response fields
  • AssignedByUserIdstring | null

    Member ID of the team member who made the assignment

  • AssignedTimestring | null

    ISO-8601 timestamp of when the assignment was made

  • AssignedToUserIdstring | null

    Member ID of the team member this conversation is assigned to

  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • ContactIdstring | null
  • ContactNamestring | null
  • ConversationFolderIdstring | null
  • ConversationIdstringrequired
  • CreatedTimeintegerrequired
  • IsCancelSnoozeOnReplyboolean | null
  • IsReadboolean
  • IsReadByMeboolean | null
  • IsSnoozedboolean | null
  • IsSnoozedAlertboolean | null
  • Labelstring | null
  • LastInboundTimeinteger | null
  • LatestCallCallInDB | null
  • LatestMessageMessageInDB | null
  • Namestring | null
  • NumberReadStatesmap

    Per-inbox read state for group conversations. Maps team phone number to has-read boolean.

  • Ownerstring | null

    Member ID of the first team member to send an outbound message or call in this conversation

  • SnoozedUntilTimestring | null
  • Statusenum

    Status of the conversation

    OPENCLOSED
  • UpdatedTimeinteger | null
  • UserIdstringrequired
  • UserNumbersstring[]

    List of user numbers associated with this conversation

  • Viewersmap | null
  • WhatsAppOptInWhatsAppOptInInfo | null
Example response
{
  "AssignedByUserId": "user_9f3a2c",
  "AssignedTime": "2026-09-03T14:30:00Z",
  "AssignedToUserId": "user_9f3a2c",
  "ChannelType": "sms",
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ConversationFolderId": "folder_9f3a2c",
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": 1725321600,
  "IsCancelSnoozeOnReply": false,
  "IsRead": false,
  "IsReadByMe": false,
  "IsSnoozed": false,
  "IsSnoozedAlert": false,
  "Label": "Mobile",
  "LastInboundTime": 1725321600,
  "LatestCall": {
    "AgentInteractions": [
      {}
    ],
    "AnsweredBy": "human",
    "AnsweredByMemberId": "member_9f3a2c",
    "ArchiverIds": {},
    "CallAnalysisStatus": "completed",
    "CallAnalysisSummary": "Jane asked about rolling over her 401(k). Agreed to send the transfer form.",
    "CallAnalysisSummaryPending": "string",
    "CallAnalysisTranscript": "Agent: Thanks for calling. Jane: Hi, I had a question about my 401(k).",
    "CallDurationTime": "184",
    "CallEndedTime": 1725321600,
    "CallId": "call_9f3a2c",
    "CallSid": "CA7f3e2b9c1d4a5e6f",
    "CallSummaryReviewStatus": "pending",
    "CallSummaryReviewedAt": "2026-09-03T14:30:00Z",
    "CallSummaryReviewedBy": "string",
    "CallerMemberId": "member_9f3a2c",
    "CallerName": "Jane Doe",
    "Comments": [
      {}
    ],
    "ContactId": "contact_9f3a2c",
    "ContactMemberId": "member_9f3a2c",
    "ContactName": "Jane Doe",
    "ContactNumber": "+18008675309",
    "CreatedTime": 1725321600,
    "CrmIds": {},
    "Direction": "OUTBOUND",
    "DispositionId": "disposition_9f3a2c",
    "GSI1PK": "string",
    "GSI1SK": "string",
    "GSI2PK": "string",
    "GSI2SK": "string",
    "GSI3PK": "string",
    "GSI3SK": "string",
    "GSI4PK": "string",
    "GSI4SK": "string",
    "IsAgentCall": false,
    "IsForwarded": false,
    "IsMissedCall": false,
    "IsOutsideHours": false,
    "IsRecorded": true,
    "IsSipAnswered": false,
    "IsTeamCall": false,
    "IsVoicemail": false,
    "Meta": {},
    "Note": "Follow up next week about the rollover.",
    "NotetakerIds": {},
    "NumberForwardedTo": "+14155552671",
    "PK": "string",
    "Participants": [
      {}
    ],
    "ParticipantsVersion": 0,
    "Quality": {
      "JitterMsMax": 0,
      "MosAvg": 0,
      "MosMin": 0,
      "RttMsMax": 0
    },
    "RecordingDurationTime": "184",
    "RecordingSid": "RE7f3e2b9c1d4a5e6f",
    "RecordingStatus": "completed",
    "RecordingUrl": "https://recordings.currentclient.com/RE7f3e2b9c1d4a5e6f.mp3",
    "RefusedAddKeys": [
      "string"
    ],
    "SK": "string",
    "Searchable": "string",
    "SourceCallSK": "string",
    "Status": "completed",
    "StatusCallSid": "CA7f3e2b9c1d4a5e6f",
    "StatusSequence": 20,
    "StatusWeight": 0,
    "TYPE": "string",
    "Tags": [
      "client"
    ],
    "TranscriptionStatus": "string",
    "TranscriptionText": "string",
    "TransferredAtTime": 1725321600,
    "TransferredByMemberId": "member_9f3a2c",
    "TransferredToMemberId": "member_9f3a2c",
    "TransferredToNumber": "string",
    "UpdatedTime": 1725321600,
    "UserId": "1234-abcd-4567-ABCD",
    "UserNumber": "+18008675309"
  },
  "LatestMessage": {
    "ArchiverIds": {},
    "BestDeliveryStatus": "string",
    "ChannelType": "sms",
    "Comments": [
      {}
    ],
    "ContactId": "contact_9f3a2c",
    "ContactName": "Jane Doe",
    "ContactNumber": "+14155552671",
    "ConversationId": "conversation_9f3a2c",
    "CreatedTime": 1725321600,
    "CrmIds": {},
    "Direction": "SENT",
    "ErrorCode": null,
    "ErrorMessage": null,
    "GSI1PK": "string",
    "GSI1SK": "string",
    "GSI2PK": "string",
    "GSI2SK": "string",
    "GSI3PK": "string",
    "GSI3SK": "string",
    "GSI6PK": "string",
    "GSI6SK": "string",
    "HoldUntil": 0,
    "IsIgnored": false,
    "IsSilenced": false,
    "LinkedComplianceMessageId": "message_9f3a2c",
    "LocalMessageId": "message_9f3a2c",
    "MediaTwilioSids": [
      "CA7f3e2b9c1d4a5e6f"
    ],
    "Message": "Hi Jane, your documents are ready to sign.",
    "MessageId": "message_9f3a2c",
    "MessageMediaItems": [
      {}
    ],
    "Meta": {},
    "PK": "string",
    "SK": "string",
    "Searchable": "string",
    "SenderMemberId": "member_9f3a2c",
    "SenderName": "Jane Doe",
    "Status": "delivered",
    "TYPE": "string",
    "Tags": [
      "client"
    ],
    "TwilioNumOfSegments": "string",
    "TwilioSid": "CA7f3e2b9c1d4a5e6f",
    "UndeliveredContactNumber": "+14155552671",
    "UndeliveredContactNumbers": [
      "+14155552671"
    ],
    "UndeliveredParticipantSids": [
      "CA7f3e2b9c1d4a5e6f"
    ],
    "UserId": "user_9f3a2c",
    "UserNumber": "+14155550100",
    "WebhookUrlStatus": "string",
    "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
    "WhatsAppContentVariables": {},
    "WhatsAppTemplateId": "template_9f3a2c"
  },
  "Name": "Jane Doe",
  "NumberReadStates": {},
  "Owner": "string",
  "Participants": [
    {
      "ContactId": "contact_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100",
      "Type": "contact"
    }
  ],
  "SnoozedUntilTime": "2026-09-03T14:30:00Z",
  "Status": "OPEN",
  "UpdatedTime": 1725321600,
  "UserId": "user_9f3a2c",
  "UserNumbers": [
    "+14155550100"
  ],
  "Viewers": {},
  "WhatsAppOptIn": {
    "OptedIn": false,
    "Source": "inbound_message",
    "Time": 1725321600
  }
}
GET/api/v1/conversations/{conversation_id}/messages

List a conversation's messages

Returns the messages in one conversation, most recent first, if the caller can access it.

Query parameters

  • cursorstring | null
  • limitinteger (uint16)

    Default 100

  • searchstring | null

Example request

curl "https://api.currentclient.com/api/v1/conversations/{conversation_id}/messages" \
  -H "Authorization: Bearer $TOKEN"

Responses

200
Response fields
Example response
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "ArchiverIds": {},
      "BestDeliveryStatus": "string",
      "ChannelType": "sms",
      "Comments": [
        {}
      ],
      "ContactId": "contact_9f3a2c",
      "ContactName": "Jane Doe",
      "ContactNumber": "+14155552671",
      "ConversationId": "conversation_9f3a2c",
      "CreatedTime": 1725321600,
      "CrmIds": {},
      "Direction": "SENT",
      "ErrorCode": null,
      "ErrorMessage": null,
      "HoldUntil": 0,
      "IsIgnored": false,
      "IsSilenced": false,
      "LinkedComplianceMessageId": "message_9f3a2c",
      "LocalMessageId": "message_9f3a2c",
      "MediaTwilioSids": [
        "CA7f3e2b9c1d4a5e6f"
      ],
      "Message": "Hi Jane, your documents are ready to sign.",
      "MessageId": "message_9f3a2c",
      "MessageMediaItems": [
        {}
      ],
      "Meta": {},
      "SenderMemberId": "member_9f3a2c",
      "SenderName": "Jane Doe",
      "Status": "delivered",
      "Tags": [
        "client"
      ],
      "TwilioNumOfSegments": "string",
      "TwilioSid": "CA7f3e2b9c1d4a5e6f",
      "UndeliveredContactNumber": "+14155552671",
      "UndeliveredContactNumbers": [
        "+14155552671"
      ],
      "UndeliveredParticipantSids": [
        "CA7f3e2b9c1d4a5e6f"
      ],
      "UserId": "user_9f3a2c",
      "UserNumber": "+14155550100",
      "WebhookUrlStatus": "string",
      "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
      "WhatsAppContentVariables": {},
      "WhatsAppTemplateId": "template_9f3a2c"
    }
  ]
}

scheduled messages

GET/api/v1/scheduled-messages/

List scheduled messages

Get scheduled messages records

Query parameters

  • cursorstring | null

    Pagination cursor provided by previous paginated response

  • isShowScheduledOnlyboolean | null

    Filter records that are still scheduled

  • limitinteger | null

    Pagination page size

    Default 100. 10 to 100

  • searchstring | null

    Filter to records containing value

Example request

curl "https://api.currentclient.com/api/v1/scheduled-messages/" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
Example response
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "ChannelType": "sms",
      "Condition": "NOREPLYSINCE",
      "ContactId": "contact_9f3a2c",
      "ContactName": "Jane Doe",
      "ContactNumber": "+14155552671",
      "Contacts": [
        {}
      ],
      "ConversationId": "conversation_9f3a2c",
      "CreatedTime": "2026-09-03T14:30:00Z",
      "Message": "Hi Jane, your documents are ready to sign.",
      "MessageMediaItems": [
        {}
      ],
      "Meta": {},
      "ScheduledMessageId": "message_9f3a2c",
      "SendAttempted": false,
      "SendAttemptsCount": 0,
      "SendTime": "2026-09-03T14:30:00Z",
      "SenderMemberId": "member_9f3a2c",
      "SenderName": "Jane Doe",
      "SourceType": "wealthbox",
      "Status": "SENT",
      "UpdatedTime": 1725321600,
      "UserId": "user_9f3a2c",
      "UserNumber": "+18008675309"
    }
  ]
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
POST/api/v1/scheduled-messages/

Create scheduled message

Create scheduled message record If you provide contacts, a conversation id will be generated for that group of contacts

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Request body application/json, required

  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • Conditionenum | null

    Enum for condition check

    NOREPLYSINCENONE
  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null
  • ContactNumberstring | null

    Phone with a leading +1

  • ContactsConversationContact[] | null
  • ConversationIdstring | null

    Id of the conversation for outbounds

  • Messagestring | null

    Field of message to send

  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • SendAttemptedboolean | null

    PRO-7740: whether the outbounds SMS POST was attempted before the failure this update records. Set only on a FAILED write coming from module-messages' SendScheduledMessage. Once true, the row is terminal regardless of remaining retry budget -- the SMS may already have reached the customer (WithRequests' 5s timeout means a slow-but-accepted POST looks identical to a failed one), so a retry can only send it again, never repair it. False/absent means the failure happened before any send was attempted (e.g. GetUserProfile/CheckCondition), which IS safely retryable.

  • SendAttemptsCountinteger | null
  • SendTimestringrequired
  • SenderMemberIdstring | null

    Memeber id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • SourceTypeenum | null

    Enum for source type

    AUTOMATIONMANUAL
  • UserNumberstringrequired

    Number with a leading +1

Example body
{
  "ChannelType": "sms",
  "Condition": "NOREPLYSINCE",
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "Contacts": [
    {
      "Id": "cnt_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100"
    }
  ],
  "ConversationId": "conversation_9f3a2c",
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "SendAttempted": false,
  "SendAttemptsCount": 0,
  "SendTime": "2026-09-03T14:30:00Z",
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "SourceType": "wealthbox",
  "UserNumber": "+18008675309"
}

Example request

curl -X POST "https://api.currentclient.com/api/v1/scheduled-messages/" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "Message": "Hi Jane, your documents are ready to sign.",
  "SendTime": "2026-09-03T14:30:00Z",
  "UserNumber": "+18008675309"
}'

Responses

200Successful Response
Response fields
  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • Conditionenum | null

    Enum for condition check

    NOREPLYSINCENONE
  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null
  • ContactNumberstring | null

    Phone with a leading +1

  • ContactsConversationContact[] | null
  • ConversationIdstring | null

    Id of the conversation for outbounds

  • CreatedTimestring | integerrequired
  • Messagestring | null

    Field of message to send

  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • ScheduledMessageIdstringrequired
  • SendAttemptedboolean | null

    PRO-7740: whether the outbounds SMS POST was attempted before the failure this update records. Set only on a FAILED write coming from module-messages' SendScheduledMessage. Once true, the row is terminal regardless of remaining retry budget -- the SMS may already have reached the customer (WithRequests' 5s timeout means a slow-but-accepted POST looks identical to a failed one), so a retry can only send it again, never repair it. False/absent means the failure happened before any send was attempted (e.g. GetUserProfile/CheckCondition), which IS safely retryable.

  • SendAttemptsCountinteger | null
  • SendTimestringrequired
  • SenderMemberIdstring | null

    Memeber id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • SourceTypeenum | null

    Enum for source type

    AUTOMATIONMANUAL
  • Statusenumrequired

    Status of the message

    SCHEDULEDSENTCANCELLEDFAILED
  • UpdatedTimeinteger | null
  • UserIdstringrequired
  • UserNumberstringrequired

    Number with a leading +1

Example response
{
  "ChannelType": "sms",
  "Condition": "NOREPLYSINCE",
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "Contacts": [
    {
      "Id": "cnt_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100"
    }
  ],
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "ScheduledMessageId": "message_9f3a2c",
  "SendAttempted": false,
  "SendAttemptsCount": 0,
  "SendTime": "2026-09-03T14:30:00Z",
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "SourceType": "wealthbox",
  "Status": "SENT",
  "UpdatedTime": 1725321600,
  "UserId": "user_9f3a2c",
  "UserNumber": "+18008675309"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
GET/api/v1/scheduled-messages/{id}

Read scheduled message

Get scheduled message record

Path parameters

  • idstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl "https://api.currentclient.com/api/v1/scheduled-messages/cnt_9f3a2c" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • Conditionenum | null

    Enum for condition check

    NOREPLYSINCENONE
  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null
  • ContactNumberstring | null

    Phone with a leading +1

  • ContactsConversationContact[] | null
  • ConversationIdstring | null

    Id of the conversation for outbounds

  • CreatedTimestring | integerrequired
  • Messagestring | null

    Field of message to send

  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • ScheduledMessageIdstringrequired
  • SendAttemptedboolean | null

    PRO-7740: whether the outbounds SMS POST was attempted before the failure this update records. Set only on a FAILED write coming from module-messages' SendScheduledMessage. Once true, the row is terminal regardless of remaining retry budget -- the SMS may already have reached the customer (WithRequests' 5s timeout means a slow-but-accepted POST looks identical to a failed one), so a retry can only send it again, never repair it. False/absent means the failure happened before any send was attempted (e.g. GetUserProfile/CheckCondition), which IS safely retryable.

  • SendAttemptsCountinteger | null
  • SendTimestringrequired
  • SenderMemberIdstring | null

    Memeber id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • SourceTypeenum | null

    Enum for source type

    AUTOMATIONMANUAL
  • Statusenumrequired

    Status of the message

    SCHEDULEDSENTCANCELLEDFAILED
  • UpdatedTimeinteger | null
  • UserIdstringrequired
  • UserNumberstringrequired

    Number with a leading +1

Example response
{
  "ChannelType": "sms",
  "Condition": "NOREPLYSINCE",
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "Contacts": [
    {
      "Id": "cnt_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100"
    }
  ],
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "ScheduledMessageId": "message_9f3a2c",
  "SendAttempted": false,
  "SendAttemptsCount": 0,
  "SendTime": "2026-09-03T14:30:00Z",
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "SourceType": "wealthbox",
  "Status": "SENT",
  "UpdatedTime": 1725321600,
  "UserId": "user_9f3a2c",
  "UserNumber": "+18008675309"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
DELETE/api/v1/scheduled-messages/{id}

Delete scheduled message

Delete scheduled_message record

Path parameters

  • idstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl -X DELETE "https://api.currentclient.com/api/v1/scheduled-messages/cnt_9f3a2c" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • Conditionenum | null

    Enum for condition check

    NOREPLYSINCENONE
  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null
  • ContactNumberstring | null

    Phone with a leading +1

  • ContactsConversationContact[] | null
  • ConversationIdstring | null

    Id of the conversation for outbounds

  • CreatedTimestring | integerrequired
  • Messagestring | null

    Field of message to send

  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • ScheduledMessageIdstringrequired
  • SendAttemptedboolean | null

    PRO-7740: whether the outbounds SMS POST was attempted before the failure this update records. Set only on a FAILED write coming from module-messages' SendScheduledMessage. Once true, the row is terminal regardless of remaining retry budget -- the SMS may already have reached the customer (WithRequests' 5s timeout means a slow-but-accepted POST looks identical to a failed one), so a retry can only send it again, never repair it. False/absent means the failure happened before any send was attempted (e.g. GetUserProfile/CheckCondition), which IS safely retryable.

  • SendAttemptsCountinteger | null
  • SendTimestringrequired
  • SenderMemberIdstring | null

    Memeber id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • SourceTypeenum | null

    Enum for source type

    AUTOMATIONMANUAL
  • Statusenumrequired

    Status of the message

    SCHEDULEDSENTCANCELLEDFAILED
  • UpdatedTimeinteger | null
  • UserIdstringrequired
  • UserNumberstringrequired

    Number with a leading +1

Example response
{
  "ChannelType": "sms",
  "Condition": "NOREPLYSINCE",
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "Contacts": [
    {
      "Id": "cnt_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100"
    }
  ],
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "ScheduledMessageId": "message_9f3a2c",
  "SendAttempted": false,
  "SendAttemptsCount": 0,
  "SendTime": "2026-09-03T14:30:00Z",
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "SourceType": "wealthbox",
  "Status": "SENT",
  "UpdatedTime": 1725321600,
  "UserId": "user_9f3a2c",
  "UserNumber": "+18008675309"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}

tags

GET/api/v1/tags/

Read tags

Get tag records

Query parameters

  • cursorstring | null

    Pagination cursor provided by previous paginated response

  • limitinteger | null

    Pagination page size

    Default 100. 10 to 1000

  • userIdstring | nullAdmin only

    Id for the owner of the resource

Example request

curl "https://api.currentclient.com/api/v1/tags/" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
Example response
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "Color": "string",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "Description": "string",
      "IsMutable": false,
      "IsPinned": false,
      "LastSyncTime": "2026-09-03T14:30:00Z",
      "SourceId": "source_9f3a2c",
      "SourceType": "wealthbox",
      "TagId": "tag_9f3a2c",
      "Title": "string",
      "UpdatedAt": "2026-09-03T14:30:00Z",
      "UserId": "user_9f3a2c"
    }
  ]
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}

webhooks

GET/api/v1/webhooks/

Read webhook endpoints

List this account's webhook endpoints.

Query parameters

  • cursorstring | null

    Pagination cursor provided by previous paginated response

  • limitinteger | null

    Pagination page size

    Default 100. 10 to 100

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl "https://api.currentclient.com/api/v1/webhooks/" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
Example response
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "ConnectorName": "Jane Doe",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "IsEnabled": false,
      "Url": "https://example.com",
      "WebhookEndpointId": "endpoint_9f3a2c"
    }
  ]
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
POST/api/v1/webhooks/

Create webhook endpoint

Create a webhook endpoint. Returns the freshly generated signing secret exactly once -- it is never returned by any subsequent read; call POST /{id}/rotate-secret to get a new one if it's lost.

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Request body application/json, required

  • ConnectorNamestring | null

    Display name; defaults to a generated name if omitted

  • IsEnabledboolean | null
  • Urlstringrequired

    HTTPS URL deliveries are POSTed to

Example body
{
  "ConnectorName": "Jane Doe",
  "IsEnabled": false,
  "Url": "https://example.com"
}

Example request

curl -X POST "https://api.currentclient.com/api/v1/webhooks/" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "Url": "https://example.com"
}'

Responses

200Successful Response
Response fields
  • ConnectorNamestringrequired
  • CreatedAtstringrequired
  • IsEnabledbooleanrequired
  • Secretstringrequired

    HMAC-SHA256 signing secret; shown only here and on rotate

  • Urlstring | null
  • WebhookEndpointIdstringrequired

    The connector id

Example response
{
  "ConnectorName": "Jane Doe",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "IsEnabled": false,
  "Secret": "string",
  "Url": "https://example.com",
  "WebhookEndpointId": "endpoint_9f3a2c"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
GET/api/v1/webhooks/{id}

Read webhook endpoint

Get a single webhook endpoint. Never returns the signing secret -- that's only ever returned once, by POST / or POST /{id}/rotate-secret.

Path parameters

  • idstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl "https://api.currentclient.com/api/v1/webhooks/cnt_9f3a2c" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • ConnectorNamestringrequired
  • CreatedAtstringrequired
  • IsEnabledbooleanrequired
  • Urlstring | null
  • WebhookEndpointIdstringrequired

    The connector id

Example response
{
  "ConnectorName": "Jane Doe",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "IsEnabled": false,
  "Url": "https://example.com",
  "WebhookEndpointId": "endpoint_9f3a2c"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
PUT/api/v1/webhooks/{id}

Update webhook endpoint

Update a webhook endpoint's URL, name, and/or enabled state. Never accepts a signing secret -- call POST /{id}/rotate-secret to get a new one.

Path parameters

  • idstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Request body application/json, required

  • ConnectorNamestring | null
  • IsEnabledboolean | null
  • Urlstring | null
Example body
{
  "ConnectorName": "Jane Doe",
  "IsEnabled": false,
  "Url": "https://example.com"
}

Example request

curl -X PUT "https://api.currentclient.com/api/v1/webhooks/cnt_9f3a2c" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Responses

200Successful Response
Response fields
  • ConnectorNamestringrequired
  • CreatedAtstringrequired
  • IsEnabledbooleanrequired
  • Urlstring | null
  • WebhookEndpointIdstringrequired

    The connector id

Example response
{
  "ConnectorName": "Jane Doe",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "IsEnabled": false,
  "Url": "https://example.com",
  "WebhookEndpointId": "endpoint_9f3a2c"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
DELETE/api/v1/webhooks/{id}

Delete webhook endpoint

Delete a webhook endpoint and all of its event subscriptions.

Path parameters

  • idstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl -X DELETE "https://api.currentclient.com/api/v1/webhooks/cnt_9f3a2c" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • ConnectorNamestringrequired
  • CreatedAtstringrequired
  • IsEnabledbooleanrequired
  • Urlstring | null
  • WebhookEndpointIdstringrequired

    The connector id

Example response
{
  "ConnectorName": "Jane Doe",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "IsEnabled": false,
  "Url": "https://example.com",
  "WebhookEndpointId": "endpoint_9f3a2c"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
GET/api/v1/webhooks/{id}/events

Read webhook endpoint events

List this webhook endpoint's current event subscriptions.

Path parameters

  • idstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl "https://api.currentclient.com/api/v1/webhooks/cnt_9f3a2c/events" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields

Array of WebhookEventSubscription

  • EventNameenumrequired

    Routing event names This enum is copied in the module-routing

    MESSAGE_INCOMINGMESSAGE_UPDATEDCALL_MISSEDNEW_SUBMISSIONCONTACT_VERSIONEDCONTACT_UPDATEDCONTACT_CREATEDSMS_SENTSMS_LOGCALL_LOGCALL_UPDATEDVOICEMAIL_RECEIVEDCALL_RECORDING_COMPLETEDVIDEO_UPLOADEDSMS_UNDELIVEREDCALL_TRANSCRIPT_COMPLETEDTETHER_WIDGET_SUBMISSIONCALL_AI_SUMMARY_COMPLETEDCRMSYNC_BROKENCONVERSATION_REMINDER_DUECOMMENT_MENTIONCONVERSATION_ASSIGNEDINBOX_CREATEDINBOX_DELETEDCHAT_MESSAGECHAT_MENTIONINTERNAL_CHAT_LOGCONTACT_DELETEDMESSAGE_TAKENNEW_LEADMESSAGE_ALL
  • IsEnabledbooleanrequired
Example response
[
  {
    "EventName": "Jane Doe",
    "IsEnabled": false
  }
]
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
PUT/api/v1/webhooks/{id}/events

Update webhook endpoint events

Replace this webhook endpoint's event subscriptions with exactly the set in EventNames: events newly listed are subscribed, events already subscribed but disabled are re-enabled, and subscribed events left off the list are removed. Only the events this API can subscribe to are managed. A webhook endpoint may also carry subscriptions for other events, created elsewhere in the app; those are reported by GET /{id}/events but are never removed by this call, whether or not you list them. Listing one is rejected with a 400, so echo back only the events this endpoint accepts.

Path parameters

  • idstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Request body application/json, required

  • EventNamesenum[]required

    Events to subscribe this webhook endpoint to. Accepts only: MESSAGE_INCOMING, SMS_SENT, SMS_UNDELIVERED, CONVERSATION_REMINDER_DUE, CALL_LOG, CALL_MISSED, VOICEMAIL_RECEIVED, CALL_RECORDING_COMPLETED, CALL_TRANSCRIPT_COMPLETED, CALL_AI_SUMMARY_COMPLETED, NEW_SUBMISSION, TETHER_WIDGET_SUBMISSION, INBOX_CREATED, INBOX_DELETED, CONTACT_CREATED, CONTACT_UPDATED, CONTACT_DELETED. Any other event is rejected with a 400 -- including one this endpoint already has a subscription for, created elsewhere in the app, which GET /{id}/events will report but this call cannot manage.

Example body
{
  "EventNames": [
    "Jane Doe"
  ]
}

Example request

curl -X PUT "https://api.currentclient.com/api/v1/webhooks/cnt_9f3a2c/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "EventNames": [
    "Jane Doe"
  ]
}'

Responses

200Successful Response
Response fields

Array of WebhookEventSubscription

  • EventNameenumrequired

    Routing event names This enum is copied in the module-routing

    MESSAGE_INCOMINGMESSAGE_UPDATEDCALL_MISSEDNEW_SUBMISSIONCONTACT_VERSIONEDCONTACT_UPDATEDCONTACT_CREATEDSMS_SENTSMS_LOGCALL_LOGCALL_UPDATEDVOICEMAIL_RECEIVEDCALL_RECORDING_COMPLETEDVIDEO_UPLOADEDSMS_UNDELIVEREDCALL_TRANSCRIPT_COMPLETEDTETHER_WIDGET_SUBMISSIONCALL_AI_SUMMARY_COMPLETEDCRMSYNC_BROKENCONVERSATION_REMINDER_DUECOMMENT_MENTIONCONVERSATION_ASSIGNEDINBOX_CREATEDINBOX_DELETEDCHAT_MESSAGECHAT_MENTIONINTERNAL_CHAT_LOGCONTACT_DELETEDMESSAGE_TAKENNEW_LEADMESSAGE_ALL
  • IsEnabledbooleanrequired
Example response
[
  {
    "EventName": "Jane Doe",
    "IsEnabled": false
  }
]
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}
POST/api/v1/webhooks/{id}/rotate-secret

Rotate webhook endpoint secret

Rotate this webhook endpoint's signing secret. Returns the new secret exactly once -- save it now. The prior secret stops verifying immediately, including for every existing event subscription.

Path parameters

  • idstringin pathrequired

Query parameters

  • userIdstring | nullAdmin only

    Id for the owner of the user

Example request

curl -X POST "https://api.currentclient.com/api/v1/webhooks/cnt_9f3a2c/rotate-secret" \
  -H "Authorization: Bearer $TOKEN"

Responses

200Successful Response
Response fields
  • ConnectorNamestringrequired
  • CreatedAtstringrequired
  • IsEnabledbooleanrequired
  • Secretstringrequired

    HMAC-SHA256 signing secret; shown only here and on rotate

  • Urlstring | null
  • WebhookEndpointIdstringrequired

    The connector id

Example response
{
  "ConnectorName": "Jane Doe",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "IsEnabled": false,
  "Secret": "string",
  "Url": "https://example.com",
  "WebhookEndpointId": "endpoint_9f3a2c"
}
400Invalid user request
Example response
{
  "detail": "A message for why the request is invalid"
}
401Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
403Unauthorized request
Example response
{
  "detail": "A message for why the request is invalid"
}
422Validation Error
Response fields
Example response
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}
500Server error
Example response
{
  "detail": "A message for why the server failed"
}

Models

The objects the endpoints above send and return. Field names are PascalCase throughout. A field marked nullable can come back as null.

Call

One phone call. Recording, transcript, and AI summary fields are filled in as those jobs finish, so a call fetched moments after it ends may still be missing them.

  • AgentInteractionsmap[] | null

    List of AI agent interactions on this call. Each entry contains agentId, conversationId, dialplanId, nextNodeId, and firmName.

  • AnsweredBystring | null

    Twilio AMD result for outbound calls: 'human', 'machine_start', 'machine_end_silence', 'machine_end_beep', 'machine_end_other', 'fax', or 'unknown'. None when AMD was not run.

  • AnsweredByMemberIdstring | null

    The id of the member that answered a call

  • ArchiverIdsmap | null

    Dictionary to store archiver ids - key is ArchiverId, value is ArchiverType

  • CallAnalysisStatusenum | null

    Ai summary status of the call

    queuedprocessingcompletederror
  • CallAnalysisSummarystring | null

    Analysis generated for the call

  • CallAnalysisSummaryPendingstring | null

    Ai summary held for review; copied to CallAnalysisSummary on approval so no other reader sees unreviewed text

  • CallAnalysisTranscriptstring | null

    Transcript generated for the call

  • CallDurationTimestring | null

    Time in seconds of the call

  • CallEndedTimeinteger | null

    The time the call ended

  • CallIdstringrequired
  • CallSidstring | null

    Specific call sid for the call, useful for twilio api

  • CallSummaryReviewStatusenum | null

    PRO-6946: human review state of the AI call summary

    pendingapproved
  • CallSummaryReviewedAtstring | null

    ISO timestamp the ai summary was approved

  • CallSummaryReviewedBystring | null

    User id that approved the ai summary

  • CallerMemberIdstring | null

    Member id for the caller

  • CallerNamestring | null

    Name of the caller for quick reference

  • CommentsCallComment[] | null

    Comments about the call

  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactMemberIdstring | null

    The called team member on a direct team-member call

  • ContactNamestring | null

    Name of the contact for quick reference

  • ContactNumberstring

    Phone number in E.164 format

  • CreatedTimeinteger | null
  • CrmIdsmap | null

    Dictionary to store CRM ids - key is CrmId, value is CrmType

  • Directionenum

    Direction of the call, whether it was outbound or inbound

    OUTBOUNDINBOUND
  • DispositionIdstring | null

    Workspace disposition assigned to this call (PRO-4164). Null until set; filterable via the calls list endpoint.

  • IsAgentCallboolean | null

    Whether an AI agent handled this call

  • IsForwardedboolean | null

    If the call is forwarded

  • IsMissedCallboolean | null

    Explicitly set to True when the call is confirmed missed by the application layer (is_done=True). Prevents premature missed-call notifications from intermediate DynamoDB stream events during parallel dial.

  • IsOutsideHoursboolean | null

    If the call is outside business hours

  • IsRecordedboolean | null

    If the call is recorded

  • IsSipAnsweredboolean | null

    PRO-7119: set once the <Sip> leg of a VoiceProvider=sip inbound call actually answers, via the sip-answered statusCallback. Positive answer evidence for is_inbound_unattended, the same role IsAgentCall plays for the ElevenLabs agent dial -- a SIP-answered call stamps none of the other answer signals (AnsweredByMemberId is written only from a per-leg <Client> statusCallback, and the cc-sip CDR keys on cc-sip's own call_id, not the Twilio CallSid, so it never reaches this record).

  • IsTeamCallboolean | null

    True for a direct call between two workspace team members

  • IsVoicemailboolean | null

    True when this call was routed to voicemail

  • Metamap | null

    Key values of meta data for this call, will be published as attributes to topic on callbacks

  • Notestring | null

    Note about the call

  • NotetakerIdsmap | null

    Dictionary to store notetaker ids

  • NumberForwardedTostring | null

    If the call is forwarded, this is the number it went to

  • ParticipantsCallParticipant[]

    List of participants currently in the call

  • QualityCallQuality | null

    Audio quality of a cc-sip call (MOS, jitter, round-trip time); null when the call was not measured

  • RecordingDurationTimestring | null

    Time in seconds of the call recording

  • RecordingSidstring | null

    Specific recording sid for the call, useful for twilio api

  • RecordingStatusenum | null

    Recording Status of the call

    in-progresscompletedabsent
  • RecordingUrlstring | null

    Url to the call recording

  • Statusenum

    Status of the call

    createdinitiatedringingin-progresstransferredblockedcompletedfailedbusyno-answercanceled
  • StatusCallSidstring | null

    The Twilio CallSid that produced the current StatusSequence.

  • StatusSequenceinteger | null

    Highest Twilio SequenceNumber processed for status updates. Stored as a DynamoDB N type for correct numeric comparison.

  • StatusWeightinteger | null

    Numeric weight of the current Status, used to prevent cross-CallSid status regressions.

  • Tagsstring[] | null

    Tags for the message

  • TranscriptionStatusstring | null

    Status of the transcription

  • TranscriptionTextstring | null

    Text of the voicemail

  • TransferredAtTimeinteger | null

    Epoch timestamp when the call was transferred

  • TransferredByMemberIdstring | null

    The id of the member that transferred the call away. On the unattended transfer_to_inbox path the transferred record is de-keyed off GSI4 and a NEW destination leg reuses the call id, so the destination's AnsweredByMemberId is the RECIPIENT, not the transferrer. read_call backfills this from the source record's AnsweredByMemberId (PRO-7260). The attended path (CRUDCall.transfer) stamps in place and keeps GSI4, so there AnsweredByMemberId is already the transferrer and this stays unset.

  • TransferredToMemberIdstring | null

    The id of the member that the call was transferred to

  • TransferredToNumberstring | null

    The phone number that the call was transferred to

  • UpdatedTimeinteger | null
  • UserIdstring

    Id of the app user

  • UserNumberstring

    Number with a leading +1, or `member:<id>` on a direct team-member call (PRO-8680)

Example
{
  "AgentInteractions": [
    {}
  ],
  "AnsweredBy": "human",
  "AnsweredByMemberId": "member_9f3a2c",
  "ArchiverIds": {},
  "CallAnalysisStatus": "completed",
  "CallAnalysisSummary": "Jane asked about rolling over her 401(k). Agreed to send the transfer form.",
  "CallAnalysisSummaryPending": "string",
  "CallAnalysisTranscript": "Agent: Thanks for calling. Jane: Hi, I had a question about my 401(k).",
  "CallDurationTime": "184",
  "CallEndedTime": 1725321600,
  "CallId": "call_9f3a2c",
  "CallSid": "CA7f3e2b9c1d4a5e6f",
  "CallSummaryReviewStatus": "pending",
  "CallSummaryReviewedAt": "2026-09-03T14:30:00Z",
  "CallSummaryReviewedBy": "string",
  "CallerMemberId": "member_9f3a2c",
  "CallerName": "Jane Doe",
  "Comments": [
    {
      "CallCommentId": "comment_9f3a2c",
      "Comment": "Client confirmed the meeting time.",
      "CreatedByUserId": "user_9f3a2c",
      "CreatedByUserName": "Jane Doe",
      "CreatedTime": 1725321600,
      "Mentions": [
        "string"
      ],
      "UpdatedAt": "2026-09-03T14:30:00Z"
    }
  ],
  "ContactId": "contact_9f3a2c",
  "ContactMemberId": "member_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+18008675309",
  "CreatedTime": 1725321600,
  "CrmIds": {},
  "Direction": "OUTBOUND",
  "DispositionId": "disposition_9f3a2c",
  "IsAgentCall": false,
  "IsForwarded": false,
  "IsMissedCall": false,
  "IsOutsideHours": false,
  "IsRecorded": true,
  "IsSipAnswered": false,
  "IsTeamCall": false,
  "IsVoicemail": false,
  "Meta": {},
  "Note": "Follow up next week about the rollover.",
  "NotetakerIds": {},
  "NumberForwardedTo": "+14155552671",
  "Participants": [
    {
      "CallSid": "CA7f3e2b9c1d4a5e6f",
      "CallStatus": "connecting",
      "ContactId": "contact_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100",
      "TeamMemberId": "member_9f3a2c",
      "Type": "contact"
    }
  ],
  "Quality": {
    "JitterMsMax": 0,
    "MosAvg": 0,
    "MosMin": 0,
    "RttMsMax": 0
  },
  "RecordingDurationTime": "184",
  "RecordingSid": "RE7f3e2b9c1d4a5e6f",
  "RecordingStatus": "completed",
  "RecordingUrl": "https://recordings.currentclient.com/RE7f3e2b9c1d4a5e6f.mp3",
  "Status": "completed",
  "StatusCallSid": "CA7f3e2b9c1d4a5e6f",
  "StatusSequence": 20,
  "StatusWeight": 0,
  "Tags": [
    "client"
  ],
  "TranscriptionStatus": "string",
  "TranscriptionText": "string",
  "TransferredAtTime": 1725321600,
  "TransferredByMemberId": "member_9f3a2c",
  "TransferredToMemberId": "member_9f3a2c",
  "TransferredToNumber": "string",
  "UpdatedTime": 1725321600,
  "UserId": "1234-abcd-4567-ABCD",
  "UserNumber": "+18008675309"
}

Message

One text message, sent or received, with delivery status and any attached media.

  • ArchiverIdsmap | null

    Dictionary to store archiver ids - key is ArchiverId, value is ArchiverType

  • BestDeliveryStatusstring | null

    For a group-conversation message, the highest-ranked leg success (delivered/read, by MESSAGE_STATUS_WEIGHT) ever recorded on this row, kept independent of the row's own Status. Written on every success receipt via the group-delivery path and never downgraded. Exists because a later failing leg can resolve the row's Status to partiallydelivered -- a single scalar that cannot also encode 'and the best success so far was read' -- so once that happens, prior_status stops being a usable record of it. Without this field, a read receipt followed by a failing leg followed by that leg merely CORRECTING to delivered (rather than read) permanently lost the fact that someone had already read the message (PRO-7413). Populated only via the onDeliveryUpdated group-delivery path (crud.message.update_status resolve_as_group_delivery=True); unset for a 1:1 message.

  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • CommentsMessageComment[] | null

    Comments about the message

  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null

    Name of the contact for quick reference

  • ContactNumberstring | null

    Phone with a leading +1 or a short code

  • ConversationIdstring | null

    A Twilio conversation ID or our number TO number format

  • CreatedTimeinteger | null
  • CrmIdsmap | null

    Dictionary to store CRM ids - key is CrmId, value is CrmType

  • Directionenum | null

    Direction of the message, whether it was sent or received

    SENTRECEIVED
  • ErrorCodestring | null
  • ErrorMessagestring | null
  • HoldUntilinteger | null

    PRO-8559: epoch-seconds when a Status=pending message's undo-send grace period ends and it is actually handed to Twilio. Set only while Status is pending; the frontend renders the remaining hold from this instead of re-deriving its own client-side timer, so the window survives a reload. Never cleared -- it stays on the row, stale, once the message leaves pending -- so consumers must gate on Status==pending, not merely on this field being set.

  • IsIgnoredboolean | null
  • IsSilencedboolean | null
  • LinkedComplianceMessageIdstring | null

    PRO-8589: set on a held real (non-compliance) message whose first-contact compliance sub-message was ALSO held for the same undo-send grace window, pointing at that sub-message's own MessageId. cancel_pending_send follows it to cancel the compliance row in lockstep with this one, so undoing a first-ever send never leaves the contact holding a bare Reply-STOP line with no message attached to it. Unset for every other message -- compliance resends, and automated / admin-or-service / CH sends, which skip the hold entirely.

  • LocalMessageIdstring | null
  • MediaTwilioSidsstring[] | null
  • Messagestring | null

    Field of message to send

  • MessageIdstringrequired
  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap | null

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • SenderMemberIdstring | null

    Member id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • Statusenum | null

    Status of the message

    createdpendingreadycancelledblockednumberunsubscribercannotrouteerrorinvalidnosmspresenderrorsenderrorunsubscribedsessionexpiredaccepteddeliveredfailedqueuedreadsendingsentundeliveredreceivedreceivingpartiallydelivered
  • Tagsstring[] | null

    Tags for the message

  • TwilioNumOfSegmentsstring | null
  • TwilioSidstring | null
  • UndeliveredContactNumberstring | null

    For a group-conversation message, the specific participant number whose relay leg failed, resolved from Twilio's per-recipient onDeliveryUpdated ParticipantSid (PRO-6630/PRO-6632) since the message row's own ContactNumber can't name one recipient out of several. Unset for a 1:1 message, where ContactNumber already identifies the recipient, and unset if the participant lookup failed.

  • UndeliveredContactNumbersstring[] | null

    For a group-conversation message, every participant leg that is CURRENTLY known-failed, by number -- the per-recipient state the PRO-7304 failure alert renders from, since a group send's single Status can only ever describe one aggregate outcome and UndeliveredContactNumber (singular) only ever named the most recently-resolved failure. Index-aligned with UndeliveredParticipantSids (entry i failed as participant i). A NEW failing participant is appended; the SAME participant later correcting to a success (PRO-5002's shape, not a second person's independent failure) removes that entry instead of leaving it stuck forever (PRO-7304 round 3 -- this list is NOT append-only despite an earlier round of this same ticket documenting it that way). Populated only via the onDeliveryUpdated group-delivery path (crud.message.update_status resolve_as_group_delivery=True); unset for a 1:1 message and for a clean group delivery with no failures at all. An ENTRY may be None: the leg is known-failed but Twilio's participant lookup could not resolve its number. The entry is still recorded, because dropping it would leave that leg with no UndeliveredParticipantSids entry either, and its own later correction could then never be matched -- pinning the row at partiallydelivered forever with nothing able to clear it (ironhide, PR #875 round 7). Consumers rendering this list must skip None entries; the count of failed LEGS is the list length, the count of NAMEABLE ones is smaller.

  • UndeliveredParticipantSidsstring[] | null

    Twilio ParticipantSid for each entry in UndeliveredContactNumbers, same index. The identity that lets update_status tell a same-participant DLR correction (PRO-5002: this exact leg corrected itself, remove it) apart from a second, independent participant's receipt (PRO-7304: two different people, two different facts, neither erases the other) -- Status and ContactNumber alone can't distinguish those. Backend-internal: not meant for the frontend to render, only to let this field's sibling list self-correct accurately. An entry can itself be None (a legacy row seeded from the pre-sid-tracking singular UndeliveredContactNumber field, or the Twilio Participant lookup failed) -- update_status's correction matching requires an actual sid on BOTH sides, so a None entry here can never be mistaken for a match against an incoming None sid.

  • UserIdstring

    Id of the app user

  • UserNumberstring | null

    Number with a leading +1

  • WebhookUrlStatusstring | null
  • WhatsAppContentSidstring | null

    Server-resolved Twilio Content SID for a template send. Not client-settable.

  • WhatsAppContentVariablesmap | null

    Server-resolved positional {'1': value, ...} substitutions for a template send. Not client-settable.

  • WhatsAppTemplateIdstring | null

    An approved WhatsAppTemplate to send this message with, bypassing the 24h session window

Example
{
  "ArchiverIds": {},
  "BestDeliveryStatus": "string",
  "ChannelType": "sms",
  "Comments": [
    {
      "Comment": "Client confirmed the meeting time.",
      "CreatedByUserId": "user_9f3a2c",
      "CreatedByUserName": "Jane Doe",
      "CreatedTime": "2026-09-03T14:30:00Z",
      "Mentions": [
        "string"
      ],
      "MessageCommentId": "comment_9f3a2c",
      "UpdatedAt": "2026-09-03T14:30:00Z"
    }
  ],
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": 1725321600,
  "CrmIds": {},
  "Direction": "SENT",
  "ErrorCode": null,
  "ErrorMessage": null,
  "HoldUntil": 0,
  "IsIgnored": false,
  "IsSilenced": false,
  "LinkedComplianceMessageId": "message_9f3a2c",
  "LocalMessageId": "message_9f3a2c",
  "MediaTwilioSids": [
    "CA7f3e2b9c1d4a5e6f"
  ],
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageId": "message_9f3a2c",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "Status": "delivered",
  "Tags": [
    "client"
  ],
  "TwilioNumOfSegments": "string",
  "TwilioSid": "CA7f3e2b9c1d4a5e6f",
  "UndeliveredContactNumber": "+14155552671",
  "UndeliveredContactNumbers": [
    "+14155552671"
  ],
  "UndeliveredParticipantSids": [
    "CA7f3e2b9c1d4a5e6f"
  ],
  "UserId": "user_9f3a2c",
  "UserNumber": "+14155550100",
  "WebhookUrlStatus": "string",
  "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
  "WhatsAppContentVariables": {},
  "WhatsAppTemplateId": "template_9f3a2c"
}

SendMessageRequest

Body for sending a message. Only ContactNumber and UserId are required; UserNumber picks the inbox to send from.

  • ArchiverIdsany
  • ChannelTypeenum | null
    smswhatsapp
  • CommentsComment[] | null
  • ContactIdstring | null
  • ContactNamestring | null
  • ContactNumberstringrequired
  • ConversationIdstring | null
  • CrmIdsany
  • ErrorCodestring | null
  • ErrorMessagestring | null
  • IsIgnoredboolean | null
  • IsSilencedboolean | null
  • LocalMessageIdstring | null
  • Messagestring | null
  • MessageMediaItemsMediaItem[] | null
  • Metaany
  • SenderMemberIdstring | null
  • SenderNamestring | null
  • Tagsstring[] | null
  • UserIdstring

    PRO-10657: optional on the wire. A user token's workspace always overwrites it, so a public API client (Slant) has no reason to send it, and requiring it 422'd every such send. Python's `MessageBase` defaults it to None for the same reason. A system caller must still name the workspace; the handler refuses an empty one.

  • UserNumberstring | null
Example
{
  "ArchiverIds": {},
  "ChannelType": "sms",
  "Comments": [
    {
      "Comment": "Client confirmed the meeting time.",
      "CreatedByUserId": "user_9f3a2c",
      "CreatedByUserName": "Jane Doe",
      "CreatedTime": "2026-09-03T14:30:00Z",
      "Mentions": [
        "string"
      ],
      "MessageCommentId": "comment_9f3a2c",
      "UpdatedAt": "2026-09-03T14:30:00Z"
    }
  ],
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "ConversationId": "conversation_9f3a2c",
  "CrmIds": {},
  "ErrorCode": null,
  "ErrorMessage": null,
  "IsIgnored": false,
  "IsSilenced": false,
  "LocalMessageId": "message_9f3a2c",
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "Tags": [
    "client"
  ],
  "UserId": "user_9f3a2c",
  "UserNumber": "+14155550100"
}

ContactCreate

Fields accepted when creating a contact.

  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • CustomFieldsmap | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestringrequired
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestringrequired
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestringrequired
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UploadIdstring | integer | null
  • Zipstring | null
Example
{
  "Address1": "100 Market St",
  "Address2": "Suite 400",
  "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
  "BirthDate": "1975-04-12",
  "City": "San Francisco",
  "CustomFields": {},
  "Email": "jane@example.com",
  "EnrichCallerName": "Jane Doe",
  "EnrichCallerType": "consumer",
  "EnrichLookupAt": "2026-09-03T14:30:00Z",
  "EnrichMeta": {},
  "FirstName": "Jane",
  "HouseholdId": "household_9f3a2c",
  "HouseholdName": "Jane Doe",
  "HouseholdTitle": "The Doe household",
  "IsArchived": false,
  "LastContactedTime": "2026-09-03T14:30:00Z",
  "LastName": "Doe",
  "LastSubmittedTime": "2026-09-03T14:30:00Z",
  "LastSyncTime": "2026-09-03T14:30:00Z",
  "MiddleName": "Q",
  "Nickname": "Janie",
  "NumberCarrierName": "Jane Doe",
  "NumberCarrierType": "mobile",
  "NumberLookupAt": "2026-09-03T14:30:00Z",
  "NumberMeta": {},
  "Numbers": [
    {
      "IsDoNotContact": false,
      "IsPreferred": true,
      "Label": "Mobile",
      "Meta": {},
      "Phone": "+14155552671"
    }
  ],
  "OwnerId": "owner_9f3a2c",
  "OwnerSourceId": "source_9f3a2c",
  "OwnerSourceName": "Jane Doe",
  "Phone": "+14155552671",
  "SourceId": "source_9f3a2c",
  "SourceMeta": {},
  "SourceSyncFlow": "string",
  "SourceType": "wealthbox",
  "State": "CA",
  "Tags": [
    "client"
  ],
  "UploadId": "upload_9f3a2c",
  "Zip": "94107"
}

ContactUpdate

Fields accepted when updating a contact. All optional.

  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • CustomFieldsmap | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestring | null
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestring | null
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestring | null
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UploadIdstring | integer | null
  • Zipstring | null
Example
{
  "Address1": "100 Market St",
  "Address2": "Suite 400",
  "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
  "BirthDate": "1975-04-12",
  "City": "San Francisco",
  "CustomFields": {},
  "Email": "jane@example.com",
  "EnrichCallerName": "Jane Doe",
  "EnrichCallerType": "consumer",
  "EnrichLookupAt": "2026-09-03T14:30:00Z",
  "EnrichMeta": {},
  "FirstName": "Jane",
  "HouseholdId": "household_9f3a2c",
  "HouseholdName": "Jane Doe",
  "HouseholdTitle": "The Doe household",
  "IsArchived": false,
  "LastContactedTime": "2026-09-03T14:30:00Z",
  "LastName": "Doe",
  "LastSubmittedTime": "2026-09-03T14:30:00Z",
  "LastSyncTime": "2026-09-03T14:30:00Z",
  "MiddleName": "Q",
  "Nickname": "Janie",
  "NumberCarrierName": "Jane Doe",
  "NumberCarrierType": "mobile",
  "NumberLookupAt": "2026-09-03T14:30:00Z",
  "NumberMeta": {},
  "Numbers": [
    {
      "IsDoNotContact": false,
      "IsPreferred": true,
      "Label": "Mobile",
      "Meta": {},
      "Phone": "+14155552671"
    }
  ],
  "OwnerId": "owner_9f3a2c",
  "OwnerSourceId": "source_9f3a2c",
  "OwnerSourceName": "Jane Doe",
  "Phone": "+14155552671",
  "SourceId": "source_9f3a2c",
  "SourceMeta": {},
  "SourceSyncFlow": "string",
  "SourceType": "wealthbox",
  "State": "CA",
  "Tags": [
    "client"
  ],
  "UploadId": "upload_9f3a2c",
  "Zip": "94107"
}

Inbox

A phone number and its settings.

  • BusinessSchedulemap[] | null
  • BusinessTimezonestring | null
  • CallRingDurationstring | null
  • CallRingOrderTypestring | null
  • CallTeamMemberIdsstring[] | null
  • CallflowIdstring | null
  • ComplianceMessagestring | null
  • ComplianceVCardIdstring | null
  • DeletedTimeinteger | null
  • Dialplanstring | null
  • ForwardingTimeoutinteger
  • ForwardingVoicemailModeenum | null

    PRO-6628: which voicemail should win the race when a forwarded call goes unanswered. - DESTINATION (default, `None`/absent behaves identically): the forwarded-to number's own carrier voicemail. `ForwardingTimeout` is floored at `crud.MIN_FORWARD_RING_SEC` so that voicemail has a real chance to answer. - CURRENTCLIENT: CurrentClient's own voicemail. `ForwardingTimeout` is passed through unfloored so a short ring lets it win instead.

    DESTINATIONCURRENTCLIENT
  • GreetingAudioUrlstring | null
  • HiddenForstring[] | null
  • HolidaysInboxHoliday[] | null
  • InboundTypeenum | null

    Determines how incoming calls are handled for this inbox: - RING: Ring the team members in the app - FORWARD: Forward the call to an external number - DIALPLAN: Route through a custom dial plan

    RINGFORWARDDIALPLAN
  • IsComplianceAutoSuppressboolean | null
  • IsComplianceEnabledboolean | null
  • IsDropCallerIdboolean | null
  • IsEnableAutoConferenceNotetakerboolean | null
  • IsEnableAutoIncomingMessageboolean | null
  • IsEnableAutoMissedCallboolean | null
  • IsEnableAutoOutOfOfficeIncomingMessageboolean | null
  • IsEnableAutoOutOfOfficeMissedCallboolean | null
  • IsEnableAutoOutsideHoursIncomingMessageboolean | null
  • IsEnableAutoOutsideHoursMissedCallboolean | null
  • IsEnableAutoRecordCallsboolean | null
  • IsEnableBusinessHoursboolean | null
  • IsEnableCallSummaryboolean | null
  • IsEnableCallTranscriptionboolean | null
  • IsEnableFilterProfanityboolean | null
  • IsEnableForwardCallboolean | null
  • IsEnableGreetingboolean | null
  • IsEnablePhoneMenuboolean | null
  • IsEnableRecordGreetingboolean | null
  • IsEnableRecordingAnnouncementboolean | null
  • IsEnableTranscribeVoicemailboolean | null
  • IsFaxCapableboolean
  • IsRequireCallSummaryReviewboolean | null
  • IsSmsCapableboolean
  • IsSmsHostingboolean | null
  • MutedForstring[] | null
  • Namestring | null
  • NotetakerPhoneNumberstring | null
  • NotetakerProviderenum | null

    PRO-7319: which AI notetaker's dedicated phone number this inbox should auto-conference into a call once it connects. Purely a visual/reference label for the team (which icon/name to show in settings) -- it has no effect on how the dial-in itself works, since that always just dials `NotetakerPhoneNumber`. OTHER covers any notetaker not in this list yet; new named providers get appended here as they're added.

    JUMPZOCKSHAZELWEALTHBOXOTHER
  • Numberstringrequired
  • NumberForwardTostring | null
  • OrgA2pIdstring | null
  • OrgA2pStatusenum | string | null
  • OutOfOfficeEndDatestring | null
  • OutOfOfficeEndTimestring | null
  • OutOfOfficeStartDatestring | null
  • OutOfOfficeStartTimestring | null
  • OutOfOfficeVoicemailAudioUrlstring | null
  • OutsideHoursVoicemailAudioUrlstring | null
  • PermissionsPermissionSettings | null
  • PortOutUnlockedboolean
  • RecordingAnnouncementPromptRefstring | null
  • SkipTeamMemberIdsstring[] | null
  • Symbolstring | null
  • TeamMemberIdstring | null
  • TextAutoAutoOutsideHoursMissedCallstring | null
  • TextAutoIncomingMessagestring | null
  • TextAutoMissedCallstring | null
  • TextAutoOutOfOfficeIncomingMessagestring | null
  • TextAutoOutOfOfficeMissedCallstring | null
  • TextAutoOutsideHoursIncomingMessagestring | null
  • TwilioMessagingServiceSidstring | null
  • Typeenum

    PRO-4150 shipped this as a mutable flip on one row per number -- "an inbox is either REGULAR or WHATSAPP, never both." PRO-7929 corrects that: a number can hold a REGULAR inbox and a WHATSAPP inbox at the same time, as two separate coexisting records (see `Inbox.make_sk`). This enum still names the two channels; it is no longer a toggle on a single record, and outbound channel is still determined by which of the two inbox records you composed from.

    REGULARWHATSAPP
  • UserIdstring | null
  • VoiceProviderenum

    PRO-7115: which voice stack places and receives calls for THIS inbox. Per inbox, deliberately not per workspace: one workspace has to be able to run a Twilio inbox and a CC SIP inbox side by side, both live in the same session. Values are lowercase, unlike the ALL-CAPS `InboundTypeEnum` / `ForwardingVoicemailModeEnum` above. That is not a style slip: cc-app-core passes this string verbatim from `resolveProviderConfig` into `createVoiceDriver`, whose registered driver ids are lowercase (`registerVoiceDriver('twilio', ...)`), and there is no normalization seam between the two. An ALL-CAPS value here would raise UnknownVoiceProviderError in the client.

    twiliosip
  • VoicemailAudioUrlstring | null
  • WabaIdstring | null
  • WhatsappSenderNumberstring | null
Example
{
  "BusinessSchedule": [
    {}
  ],
  "BusinessTimezone": "America/Los_Angeles",
  "CallRingDuration": "15",
  "CallRingOrderType": "string",
  "CallTeamMemberIds": [
    "member_9f3a2c"
  ],
  "CallflowId": "callflow_9f3a2c",
  "ComplianceMessage": "You can call or text us at this number. Primarily, you can expect to receive brief news and updates from us. Msg & data rates may apply. Reply STOP to opt-out anytime. Questions? You are welcome to reply.",
  "ComplianceVCardId": "card_9f3a2c",
  "DeletedTime": 1725321600,
  "Dialplan": "string",
  "ForwardingTimeout": 20,
  "ForwardingVoicemailMode": "DESTINATION",
  "GreetingAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
  "HiddenFor": [
    "string"
  ],
  "Holidays": [
    {
      "CustomDate": "2026-09-03T14:30:00Z",
      "HolidayId": "holiday_9f3a2c",
      "IsEnabled": false,
      "IsRecurringYearly": false,
      "Name": "Jane Doe",
      "TextAutoIncomingMessage": "string",
      "TextAutoMissedCall": "string",
      "VoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3"
    }
  ],
  "InboundType": "RING",
  "IsComplianceAutoSuppress": false,
  "IsComplianceEnabled": false,
  "IsDropCallerId": false,
  "IsEnableAutoConferenceNotetaker": false,
  "IsEnableAutoIncomingMessage": false,
  "IsEnableAutoMissedCall": false,
  "IsEnableAutoOutOfOfficeIncomingMessage": false,
  "IsEnableAutoOutOfOfficeMissedCall": false,
  "IsEnableAutoOutsideHoursIncomingMessage": false,
  "IsEnableAutoOutsideHoursMissedCall": false,
  "IsEnableAutoRecordCalls": true,
  "IsEnableBusinessHours": false,
  "IsEnableCallSummary": true,
  "IsEnableCallTranscription": true,
  "IsEnableFilterProfanity": false,
  "IsEnableForwardCall": false,
  "IsEnableGreeting": false,
  "IsEnablePhoneMenu": false,
  "IsEnableRecordGreeting": false,
  "IsEnableRecordingAnnouncement": false,
  "IsEnableTranscribeVoicemail": false,
  "IsFaxCapable": false,
  "IsRequireCallSummaryReview": false,
  "IsSmsCapable": false,
  "IsSmsHosting": false,
  "MutedFor": [
    "string"
  ],
  "Name": "Jane Doe",
  "NotetakerPhoneNumber": "string",
  "NotetakerProvider": "JUMP",
  "Number": "+14155550100",
  "NumberForwardTo": "+14155550100",
  "OrgA2pId": "p_9f3a2c",
  "OrgA2pStatus": "PORTING_IN",
  "OutOfOfficeEndDate": "2026-09-03T14:30:00Z",
  "OutOfOfficeEndTime": "2026-09-03T14:30:00Z",
  "OutOfOfficeStartDate": "2026-09-03T14:30:00Z",
  "OutOfOfficeStartTime": "2026-09-03T14:30:00Z",
  "OutOfOfficeVoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
  "OutsideHoursVoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
  "Permissions": {
    "Editors": [
      "string"
    ],
    "Viewers": [
      "string"
    ]
  },
  "PortOutUnlocked": false,
  "RecordingAnnouncementPromptRef": "string",
  "SkipTeamMemberIds": [
    "member_9f3a2c"
  ],
  "Symbol": "JD",
  "TeamMemberId": "member_9f3a2c",
  "TextAutoAutoOutsideHoursMissedCall": "string",
  "TextAutoIncomingMessage": "string",
  "TextAutoMissedCall": "string",
  "TextAutoOutOfOfficeIncomingMessage": "string",
  "TextAutoOutOfOfficeMissedCall": "string",
  "TextAutoOutsideHoursIncomingMessage": "string",
  "TwilioMessagingServiceSid": "CA7f3e2b9c1d4a5e6f",
  "Type": "REGULAR",
  "UserId": "user_9f3a2c",
  "VoiceProvider": "twilio",
  "VoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
  "WabaId": "waba_9f3a2c",
  "WhatsappSenderNumber": "string"
}

UserProfile

The account behind the token.

  • AddOnProductIdsstring[] | null
  • Address1string | null
  • Address2string | null
  • AdminBrandImageUrlstring | null
  • AdminEmailstring | null
  • AdminFirstNamestring | null
  • AdminImageUrlstring | null
  • AdminLastNamestring | null
  • BillingBilling | null
  • Biostring | null
  • BrandImageUrlstring | null
  • Citystring | null
  • CompanyNamestring | null
  • CompanyWebsiteUrlstring | null
  • CreatedAtstring | null
  • Crmstring | null
  • DefaultInboxNumberstring | null
  • Emailstring | null
  • ExternalConnectorIdstring | null
  • ExternalDataExternalDataWealthBox | null
  • ExternalIdstring | null
  • ExternalLastUpdatedinteger | null
  • ExternalTypeenum | string | null
  • FirstNamestring | null
  • Industrystring | null
  • IsActiveboolean | null
  • IsAiSummaryFreeboolean | null
  • IsAllowAiContactCreateboolean | null
  • IsDeleteRequestedboolean | null
  • IsFreeboolean | null
  • IsGovernorboolean | null
  • IsHasCrmSyncboolean | null
  • IsManagedBillingboolean | null
  • IsSubscriptionActiveboolean | null
  • IsTeamMemberboolean | null
  • IsUserboolean | null
  • JobTitlestring | null
  • LastNamestring | null
  • LegalDisclosurestring | null
  • MessagingServiceIdstring | null
  • MilestonesMilestones | null
  • NetworkEnrolledAtstring | null
  • NetworkIdstring | null
  • OrganizationIdstring | null
  • Phonestring | null
  • PlanProductIdstring | null
  • RegisteredNumberRegisteredNumber | null
  • SourceAttributionstring | null
  • Statestring | null
  • TeamMemberUserIdstring | null
  • UserIdstringrequired
  • VoiceMeteringSourcestring | null
  • WorkspaceIdstring | null
  • WorkspaceNamestring | null
  • Zipstring | null
Example
{
  "AddOnProductIds": [
    "product_9f3a2c"
  ],
  "Address1": "100 Market St",
  "Address2": "Suite 400",
  "AdminBrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "AdminEmail": "jane@example.com",
  "AdminFirstName": "Jane",
  "AdminImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "AdminLastName": "Doe",
  "Billing": {
    "AddonIds": [
      "addon_9f3a2c"
    ],
    "AddonNames": [
      "Jane Doe"
    ],
    "BillingType": "string",
    "BundleIds": [
      "bundle_9f3a2c"
    ],
    "BundleNames": [
      "Jane Doe"
    ],
    "CancelAtTime": 1725321600,
    "CanceledAtTime": 1725321600,
    "CreatedTime": 1725321600,
    "PriceIds": [
      "price_9f3a2c"
    ],
    "ProductDescription": "string",
    "ProductId": "product_9f3a2c",
    "ProductName": "Jane Doe",
    "StripeCustomerId": "customer_9f3a2c",
    "SubscriptionId": "subscription_9f3a2c",
    "SubscriptionStatus": "active"
  },
  "Bio": "Helping families plan for what is next.",
  "BrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "City": "San Francisco",
  "CompanyName": "Acme Wealth Advisors",
  "CompanyWebsiteUrl": "https://example.com",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "Crm": "string",
  "DefaultInboxNumber": "string",
  "Email": "jane@example.com",
  "ExternalConnectorId": "connector_9f3a2c",
  "ExternalData": {
    "Groups": [
      "string"
    ]
  },
  "ExternalId": "external_9f3a2c",
  "ExternalLastUpdated": 0,
  "ExternalType": "wealthbox",
  "FirstName": "Jane",
  "Industry": "Financial services",
  "IsActive": true,
  "IsAiSummaryFree": false,
  "IsAllowAiContactCreate": false,
  "IsDeleteRequested": false,
  "IsFree": false,
  "IsGovernor": false,
  "IsHasCrmSync": false,
  "IsManagedBilling": false,
  "IsSubscriptionActive": false,
  "IsTeamMember": false,
  "IsUser": true,
  "JobTitle": "Financial Advisor",
  "LastName": "Doe",
  "LegalDisclosure": "string",
  "MessagingServiceId": "service_9f3a2c",
  "Milestones": {
    "IsCompletedOnboarding": false
  },
  "NetworkEnrolledAt": "2026-09-03T14:30:00Z",
  "NetworkId": "network_9f3a2c",
  "OrganizationId": "organization_9f3a2c",
  "Phone": "+14155552671",
  "PlanProductId": "product_9f3a2c",
  "RegisteredNumber": {
    "AddressRequirements": "string",
    "Capabilities": {
      "IsMMSEnabled": false,
      "IsSMSEnabled": false,
      "IsVoiceEnabled": false
    },
    "DateCreated": "string",
    "DateUpdated": "string",
    "FriendlyName": "Jane Doe",
    "Origin": "string",
    "PhoneNumber": "string",
    "Sid": "CA7f3e2b9c1d4a5e6f",
    "SmsFallbackMethod": "string",
    "SmsFallbackUrl": "https://example.com",
    "SmsMethod": "string",
    "SmsUrl": "https://example.com",
    "Status": "string",
    "StatusCallback": "string",
    "StatusCallbackMethod": "string"
  },
  "SourceAttribution": "string",
  "State": "CA",
  "TeamMemberUserId": "user_9f3a2c",
  "UserId": "user_9f3a2c",
  "VoiceMeteringSource": "string",
  "WorkspaceId": "workspace_9f3a2c",
  "WorkspaceName": "Acme Wealth Advisors",
  "Zip": "94107"
}

TeamMemberExtra

A member of the workspace.

  • Biostring | null
  • BrandImageUrlstring | null
  • CognitoUserIdstring | null
  • CreatedAtstringrequired
  • Emailstringrequired
  • ExternalConnectorIdstring | null
  • ExternalDataExternalDataWealthBox | null
  • ExternalIdstring | null
  • ExternalLastUpdatedinteger | null
  • ExternalTypeenum | string | null
  • FirstNamestring | null
  • IsActiveboolean | null
  • IsAdminboolean | null
  • IsAiSummaryFreeboolean | null
  • IsFreeboolean | null
  • IsGovernorboolean | null
  • IsInvitedboolean | null
  • IsJoinedboolean | null
  • IsMemberboolean | null
  • IsXypnMemberboolean | null
  • JobTitlestring | null
  • LastNamestring | null
  • Phonestring | null
  • TeamMemberIdstringrequired
  • UpdatedAtstring | null
  • UserIdstringrequired
Example
{
  "Bio": "Helping families plan for what is next.",
  "BrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "CognitoUserId": "user_9f3a2c",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "Email": "jane@example.com",
  "ExternalConnectorId": "connector_9f3a2c",
  "ExternalData": {
    "Groups": [
      "string"
    ]
  },
  "ExternalId": "external_9f3a2c",
  "ExternalLastUpdated": 0,
  "ExternalType": "wealthbox",
  "FirstName": "Jane",
  "IsActive": true,
  "IsAdmin": false,
  "IsAiSummaryFree": false,
  "IsFree": false,
  "IsGovernor": false,
  "IsInvited": false,
  "IsJoined": true,
  "IsMember": true,
  "IsXypnMember": false,
  "JobTitle": "Financial Advisor",
  "LastName": "Doe",
  "Phone": "+14155552671",
  "TeamMemberId": "member_9f3a2c",
  "UpdatedAt": "2026-09-03T14:30:00Z",
  "UserId": "user_9f3a2c"
}

Billing

Billing provides fields for the billing record. Billing attribute contract (PRO-5119). Comments only; no field is removed or renamed here. SUPPORTED (self-serve gating reads SubscriptionStatus, ProductId and AddonIds in app.core.waffle.get_active_subscription_items; SubscriptionId and StripeCustomerId are the Stripe identifiers used for billing calls): SubscriptionStatus, SubscriptionId, StripeCustomerId, ProductId, AddonIds DISPLAY-ONLY (keep, but never gate on them): ProductName, CreatedTime, CanceledAtTime, CancelAtTime DEPRECATED (write-only, no readers; do not add new readers): BillingType, ProductDescription, BundleIds, BundleNames, AddonNames, PriceIds (and Meta, BundlesLookupIds, AddonsLookupIds on BillingInDB)

  • AddonIdsstring[] | null
  • AddonNamesstring[] | null
  • BillingTypestring | null
  • BundleIdsstring[] | null
  • BundleNamesstring[] | null
  • CancelAtTimeinteger | null
  • CanceledAtTimeinteger | null
  • CreatedTimeinteger | null
  • PriceIdsstring[] | null
  • ProductDescriptionstring | null
  • ProductIdstring | null
  • ProductNamestring | null
  • StripeCustomerIdstring | null
  • SubscriptionIdstring | null
  • SubscriptionStatusenum | null

    Status of the stripe subscription Docs: https://stripe.com/docs/api/subscriptions/object#subscription_object-status

    activepast_dueunpaidcanceledincompleteincomplete_expiredtrialingpausedunknown
Example
{
  "AddonIds": [
    "addon_9f3a2c"
  ],
  "AddonNames": [
    "Jane Doe"
  ],
  "BillingType": "string",
  "BundleIds": [
    "bundle_9f3a2c"
  ],
  "BundleNames": [
    "Jane Doe"
  ],
  "CancelAtTime": 1725321600,
  "CanceledAtTime": 1725321600,
  "CreatedTime": 1725321600,
  "PriceIds": [
    "price_9f3a2c"
  ],
  "ProductDescription": "string",
  "ProductId": "product_9f3a2c",
  "ProductName": "Jane Doe",
  "StripeCustomerId": "customer_9f3a2c",
  "SubscriptionId": "subscription_9f3a2c",
  "SubscriptionStatus": "active"
}
More models (48)

CallComment

  • CallCommentIdstring | integer | null
  • Commentstringrequired
  • CreatedByUserIdstringrequired
  • CreatedByUserNamestringrequired
  • CreatedTimeintegerrequired
  • Mentionsstring[] | null
  • UpdatedAtstring | null
Example
{
  "CallCommentId": "comment_9f3a2c",
  "Comment": "Client confirmed the meeting time.",
  "CreatedByUserId": "user_9f3a2c",
  "CreatedByUserName": "Jane Doe",
  "CreatedTime": 1725321600,
  "Mentions": [
    "string"
  ],
  "UpdatedAt": "2026-09-03T14:30:00Z"
}

CallInDB

InDB Properties properties stored in DB, this is full representation of record

  • AgentInteractionsmap[] | null

    List of AI agent interactions on this call. Each entry contains agentId, conversationId, dialplanId, nextNodeId, and firmName.

  • AnsweredBystring | null

    Twilio AMD result for outbound calls: 'human', 'machine_start', 'machine_end_silence', 'machine_end_beep', 'machine_end_other', 'fax', or 'unknown'. None when AMD was not run.

  • AnsweredByMemberIdstring | null

    The id of the member that answered a call

  • ArchiverIdsmap | null

    Dictionary to store archiver ids - key is ArchiverId, value is ArchiverType

  • CallAnalysisStatusenum | null

    Ai summary status of the call

    queuedprocessingcompletederror
  • CallAnalysisSummarystring | null

    Analysis generated for the call

  • CallAnalysisSummaryPendingstring | null

    Ai summary held for review; copied to CallAnalysisSummary on approval so no other reader sees unreviewed text

  • CallAnalysisTranscriptstring | null

    Transcript generated for the call

  • CallDurationTimestring | null

    Time in seconds of the call

  • CallEndedTimeinteger | null

    The time the call ended

  • CallIdstringrequired
  • CallSidstring | null

    Specific call sid for the call, useful for twilio api

  • CallSummaryReviewStatusenum | null

    PRO-6946: human review state of the AI call summary

    pendingapproved
  • CallSummaryReviewedAtstring | null

    ISO timestamp the ai summary was approved

  • CallSummaryReviewedBystring | null

    User id that approved the ai summary

  • CallerMemberIdstring | null

    Member id for the caller

  • CallerNamestring | null

    Name of the caller for quick reference

  • CommentsCallComment[] | null

    Comments about the call

  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactMemberIdstring | null

    The called team member on a direct team-member call

  • ContactNamestring | null

    Name of the contact for quick reference

  • ContactNumberstring

    Phone number in E.164 format

  • CreatedTimeinteger | null
  • CrmIdsmap | null

    Dictionary to store CRM ids - key is CrmId, value is CrmType

  • Directionenum

    Direction of the call, whether it was outbound or inbound

    OUTBOUNDINBOUND
  • DispositionIdstring | null

    Workspace disposition assigned to this call (PRO-4164). Null until set; filterable via the calls list endpoint.

  • GSI1PKstring | null
  • GSI1SKstring | null
  • GSI2PKstring | null
  • GSI2SKstring | null
  • GSI3PKstring | null
  • GSI3SKstring | null
  • GSI4PKstring | null
  • GSI4SKstring | null
  • IsAgentCallboolean | null

    Whether an AI agent handled this call

  • IsForwardedboolean | null

    If the call is forwarded

  • IsMissedCallboolean | null

    Explicitly set to True when the call is confirmed missed by the application layer (is_done=True). Prevents premature missed-call notifications from intermediate DynamoDB stream events during parallel dial.

  • IsOutsideHoursboolean | null

    If the call is outside business hours

  • IsRecordedboolean | null

    If the call is recorded

  • IsSipAnsweredboolean | null

    PRO-7119: set once the <Sip> leg of a VoiceProvider=sip inbound call actually answers, via the sip-answered statusCallback. Positive answer evidence for is_inbound_unattended, the same role IsAgentCall plays for the ElevenLabs agent dial -- a SIP-answered call stamps none of the other answer signals (AnsweredByMemberId is written only from a per-leg <Client> statusCallback, and the cc-sip CDR keys on cc-sip's own call_id, not the Twilio CallSid, so it never reaches this record).

  • IsTeamCallboolean | null

    True for a direct call between two workspace team members

  • IsVoicemailboolean | null

    True when this call was routed to voicemail

  • Metamap | null

    Key values of meta data for this call, will be published as attributes to topic on callbacks

  • Notestring | null

    Note about the call

  • NotetakerIdsmap | null

    Dictionary to store notetaker ids

  • NumberForwardedTostring | null

    If the call is forwarded, this is the number it went to

  • PKstringrequired
  • ParticipantsCallParticipant[]

    List of participants currently in the call

  • ParticipantsVersioninteger | null

    Monotonic counter bumped by every write of `Participants` this service makes (stamped centrally in CRUDCall.update_call), and pinned by crud_calls.pin_call_to_what_was_read so a read-modify-write of the whole list is refused when ANOTHER roster writer has rewritten it since the read (PRO-8606). `Status`/`CallEndedTime` alone only catch the call's finaliser: two roster writers read the same values for both, so the slower one used to put back a row the faster one removed. Absent on records last written before PRO-8606, which the pin reads as "no version yet". Internal bookkeeping: excluded from the `Call` response model, like `RefusedAddKeys` -- though a `CallInDBBase` response such as `CallSharedResponse` still carries both.

  • QualityCallQuality | null

    Audio quality of a cc-sip call (MOS, jitter, round-trip time); null when the call was not measured

  • RecordingDurationTimestring | null

    Time in seconds of the call recording

  • RecordingSidstring | null

    Specific recording sid for the call, useful for twilio api

  • RecordingStatusenum | null

    Recording Status of the call

    in-progresscompletedabsent
  • RecordingUrlstring | null

    Url to the call recording

  • RefusedAddKeysstring[] | null

    Participant keys (Type|TeamMemberId|Number) whose mid-call add this service staged and then took back because the conference refused it with nothing dialled -- newest last, see crud_calls._refused_add_key. Written beside the removal itself and cleared for a key by every later write this service makes for that identity (a new add staging its row, a cc-sip lifecycle event the roster consumer applies). Read by crud_calls.hide_refused_phantom_rows, which uses it to keep a FINISHED row another service's reconciliation re-materialised out of a reader's copy of the roster (PRO-8264 QA round 20). Internal bookkeeping: excluded from every `Call` response, and cleared off the instance by hide_refused_phantom_rows as it reads it.

  • SKstringrequired
  • Searchablestringrequired
  • SourceCallSKstring | null
  • Statusenum

    Status of the call

    createdinitiatedringingin-progresstransferredblockedcompletedfailedbusyno-answercanceled
  • StatusCallSidstring | null

    The Twilio CallSid that produced the current StatusSequence.

  • StatusSequenceinteger | null

    Highest Twilio SequenceNumber processed for status updates. Stored as a DynamoDB N type for correct numeric comparison.

  • StatusWeightinteger | null

    Numeric weight of the current Status, used to prevent cross-CallSid status regressions.

  • TYPEstringrequired
  • Tagsstring[] | null

    Tags for the message

  • TranscriptionStatusstring | null

    Status of the transcription

  • TranscriptionTextstring | null

    Text of the voicemail

  • TransferredAtTimeinteger | null

    Epoch timestamp when the call was transferred

  • TransferredByMemberIdstring | null

    The id of the member that transferred the call away. On the unattended transfer_to_inbox path the transferred record is de-keyed off GSI4 and a NEW destination leg reuses the call id, so the destination's AnsweredByMemberId is the RECIPIENT, not the transferrer. read_call backfills this from the source record's AnsweredByMemberId (PRO-7260). The attended path (CRUDCall.transfer) stamps in place and keeps GSI4, so there AnsweredByMemberId is already the transferrer and this stays unset.

  • TransferredToMemberIdstring | null

    The id of the member that the call was transferred to

  • TransferredToNumberstring | null

    The phone number that the call was transferred to

  • UpdatedTimeinteger | null
  • UserIdstring

    Id of the app user

  • UserNumberstring

    Number with a leading +1, or `member:<id>` on a direct team-member call (PRO-8680)

Example
{
  "AgentInteractions": [
    {}
  ],
  "AnsweredBy": "human",
  "AnsweredByMemberId": "member_9f3a2c",
  "ArchiverIds": {},
  "CallAnalysisStatus": "completed",
  "CallAnalysisSummary": "Jane asked about rolling over her 401(k). Agreed to send the transfer form.",
  "CallAnalysisSummaryPending": "string",
  "CallAnalysisTranscript": "Agent: Thanks for calling. Jane: Hi, I had a question about my 401(k).",
  "CallDurationTime": "184",
  "CallEndedTime": 1725321600,
  "CallId": "call_9f3a2c",
  "CallSid": "CA7f3e2b9c1d4a5e6f",
  "CallSummaryReviewStatus": "pending",
  "CallSummaryReviewedAt": "2026-09-03T14:30:00Z",
  "CallSummaryReviewedBy": "string",
  "CallerMemberId": "member_9f3a2c",
  "CallerName": "Jane Doe",
  "Comments": [
    {
      "CallCommentId": "comment_9f3a2c",
      "Comment": "Client confirmed the meeting time.",
      "CreatedByUserId": "user_9f3a2c",
      "CreatedByUserName": "Jane Doe",
      "CreatedTime": 1725321600,
      "Mentions": [
        "string"
      ],
      "UpdatedAt": "2026-09-03T14:30:00Z"
    }
  ],
  "ContactId": "contact_9f3a2c",
  "ContactMemberId": "member_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+18008675309",
  "CreatedTime": 1725321600,
  "CrmIds": {},
  "Direction": "OUTBOUND",
  "DispositionId": "disposition_9f3a2c",
  "GSI1PK": "string",
  "GSI1SK": "string",
  "GSI2PK": "string",
  "GSI2SK": "string",
  "GSI3PK": "string",
  "GSI3SK": "string",
  "GSI4PK": "string",
  "GSI4SK": "string",
  "IsAgentCall": false,
  "IsForwarded": false,
  "IsMissedCall": false,
  "IsOutsideHours": false,
  "IsRecorded": true,
  "IsSipAnswered": false,
  "IsTeamCall": false,
  "IsVoicemail": false,
  "Meta": {},
  "Note": "Follow up next week about the rollover.",
  "NotetakerIds": {},
  "NumberForwardedTo": "+14155552671",
  "PK": "string",
  "Participants": [
    {
      "CallSid": "CA7f3e2b9c1d4a5e6f",
      "CallStatus": "connecting",
      "ContactId": "contact_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100",
      "TeamMemberId": "member_9f3a2c",
      "Type": "contact"
    }
  ],
  "ParticipantsVersion": 0,
  "Quality": {
    "JitterMsMax": 0,
    "MosAvg": 0,
    "MosMin": 0,
    "RttMsMax": 0
  },
  "RecordingDurationTime": "184",
  "RecordingSid": "RE7f3e2b9c1d4a5e6f",
  "RecordingStatus": "completed",
  "RecordingUrl": "https://recordings.currentclient.com/RE7f3e2b9c1d4a5e6f.mp3",
  "RefusedAddKeys": [
    "string"
  ],
  "SK": "string",
  "Searchable": "string",
  "SourceCallSK": "string",
  "Status": "completed",
  "StatusCallSid": "CA7f3e2b9c1d4a5e6f",
  "StatusSequence": 20,
  "StatusWeight": 0,
  "TYPE": "string",
  "Tags": [
    "client"
  ],
  "TranscriptionStatus": "string",
  "TranscriptionText": "string",
  "TransferredAtTime": 1725321600,
  "TransferredByMemberId": "member_9f3a2c",
  "TransferredToMemberId": "member_9f3a2c",
  "TransferredToNumber": "string",
  "UpdatedTime": 1725321600,
  "UserId": "1234-abcd-4567-ABCD",
  "UserNumber": "+18008675309"
}

CallParticipant

Model rerpesenting a participant to be added to an existing call

  • CallSidstring | null
  • CallStatusenum

    Enum for the various call states of a call participant

    connectingactiveleftno-answerheld
  • ContactIdstring | null
  • Namestring | null
  • Numberstring | null
  • TeamMemberIdstring | null
  • Typeenumrequired

    Enum for the type of call

    contactteamnotetaker
Example
{
  "CallSid": "CA7f3e2b9c1d4a5e6f",
  "CallStatus": "connecting",
  "ContactId": "contact_9f3a2c",
  "Name": "Jane Doe",
  "Number": "+14155550100",
  "TeamMemberId": "member_9f3a2c",
  "Type": "contact"
}

CallQuality

Per-call audio quality of a cc-sip call (PRO-10625), rolled up across the call's legs by the call-controller and written to the record by the CDR projection in cc-rust-api-outbounds when the call completes. This service only reads it. A figure the media engine never measured (no RTCP from the peer, so no round-trip time) is absent, never zero.

  • JitterMsMaxnumber | null

    Worst inter-arrival jitter any leg reported, in milliseconds

  • MosAvgnumberrequired

    Mean opinion score (1.0-4.5) averaged over the call, each leg weighted by its duration

  • MosMinnumberrequired

    Lowest mean opinion score any leg of the call reported

  • RttMsMaxnumber | null

    Worst round-trip time any leg reported, in milliseconds

Example
{
  "JitterMsMax": 0,
  "MosAvg": 0,
  "MosMin": 0,
  "RttMsMax": 0
}

Comment

  • Commentstring | null
  • CreatedByUserIdstring | null
  • CreatedByUserNamestring | null
  • CreatedTimestring | integer (uint64)required
  • Mentionsstring[] | null

    PRO-9177: Python `MessageCommentCreate.Mentions` (PRO-6909), kept so appending a comment rewrites earlier ones intact.

  • MessageCommentIdstring | integer (uint64) | null
  • UpdatedAtstring | null
Example
{
  "Comment": "Client confirmed the meeting time.",
  "CreatedByUserId": "user_9f3a2c",
  "CreatedByUserName": "Jane Doe",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Mentions": [
    "string"
  ],
  "MessageCommentId": "comment_9f3a2c",
  "UpdatedAt": "2026-09-03T14:30:00Z"
}

Contact

The model to be used for responses. Doesnt include internal PK and SK

  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • ContactIdstringrequired
  • CreatedAtstringrequired
  • CustomFieldsmap | null
  • DeletedAtstring | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestringrequired
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestringrequired
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestringrequired
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UpdatedAtstring | null
  • UploadIdstring | integer | null
  • UserIdstringrequired
  • Versionintegerrequired
  • VersionsContactVersion[] | null
  • Zipstring | null
  • shareExpiresTtlinteger | null
Example
{
  "Address1": "100 Market St",
  "Address2": "Suite 400",
  "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
  "BirthDate": "1975-04-12",
  "City": "San Francisco",
  "ContactId": "contact_9f3a2c",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "CustomFields": {},
  "DeletedAt": "2026-09-03T14:30:00Z",
  "Email": "jane@example.com",
  "EnrichCallerName": "Jane Doe",
  "EnrichCallerType": "consumer",
  "EnrichLookupAt": "2026-09-03T14:30:00Z",
  "EnrichMeta": {},
  "FirstName": "Jane",
  "HouseholdId": "household_9f3a2c",
  "HouseholdName": "Jane Doe",
  "HouseholdTitle": "The Doe household",
  "IsArchived": false,
  "LastContactedTime": "2026-09-03T14:30:00Z",
  "LastName": "Doe",
  "LastSubmittedTime": "2026-09-03T14:30:00Z",
  "LastSyncTime": "2026-09-03T14:30:00Z",
  "MiddleName": "Q",
  "Nickname": "Janie",
  "NumberCarrierName": "Jane Doe",
  "NumberCarrierType": "mobile",
  "NumberLookupAt": "2026-09-03T14:30:00Z",
  "NumberMeta": {},
  "Numbers": [
    {
      "IsDoNotContact": false,
      "IsPreferred": true,
      "Label": "Mobile",
      "Meta": {},
      "Phone": "+14155552671"
    }
  ],
  "OwnerId": "owner_9f3a2c",
  "OwnerSourceId": "source_9f3a2c",
  "OwnerSourceName": "Jane Doe",
  "Phone": "+14155552671",
  "SourceId": "source_9f3a2c",
  "SourceMeta": {},
  "SourceSyncFlow": "string",
  "SourceType": "wealthbox",
  "State": "CA",
  "Tags": [
    "client"
  ],
  "UpdatedAt": "2026-09-03T14:30:00Z",
  "UploadId": "upload_9f3a2c",
  "UserId": "user_9f3a2c",
  "Version": 0,
  "Versions": [
    {
      "Address1": "100 Market St",
      "Address2": "Suite 400",
      "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
      "BirthDate": "1975-04-12",
      "City": "San Francisco",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "CustomFields": {},
      "Email": "jane@example.com",
      "EnrichCallerName": "Jane Doe",
      "EnrichCallerType": "consumer",
      "EnrichLookupAt": "2026-09-03T14:30:00Z",
      "EnrichMeta": {},
      "FirstName": "Jane",
      "HouseholdId": "household_9f3a2c",
      "HouseholdName": "Jane Doe",
      "HouseholdTitle": "The Doe household",
      "IsArchived": false,
      "LastContactedTime": "2026-09-03T14:30:00Z",
      "LastName": "Doe",
      "LastSubmittedTime": "2026-09-03T14:30:00Z",
      "LastSyncTime": "2026-09-03T14:30:00Z",
      "MiddleName": "Q",
      "Nickname": "Janie",
      "NumberCarrierName": "Jane Doe",
      "NumberCarrierType": "mobile",
      "NumberLookupAt": "2026-09-03T14:30:00Z",
      "NumberMeta": {},
      "Numbers": [
        {}
      ],
      "OwnerId": "owner_9f3a2c",
      "OwnerSourceId": "source_9f3a2c",
      "OwnerSourceName": "Jane Doe",
      "Phone": "+14155552671",
      "SourceId": "source_9f3a2c",
      "SourceMeta": {},
      "SourceSyncFlow": "string",
      "SourceType": "wealthbox",
      "State": "CA",
      "Tags": [
        "client"
      ],
      "UpdatedAt": "2026-09-03T14:30:00Z",
      "UploadId": "upload_9f3a2c",
      "Version": 0,
      "Zip": "94107"
    }
  ],
  "Zip": "94107",
  "shareExpiresTtl": 0
}

ContactVersion

Version Properties to share for a Versioned contact

  • Address1string | null
  • Address2string | null
  • AvatarUrlstring | null
  • BirthDatestring | null
  • Citystring | null
  • CreatedAtstring | null
  • CustomFieldsmap | null
  • Emailstring | null
  • EnrichCallerNamestring | null
  • EnrichCallerTypestring | null
  • EnrichLookupAtstring | null
  • EnrichMetaany | null
  • FirstNamestring | null
  • HouseholdIdstring | null
  • HouseholdNamestring | null
  • HouseholdTitlestring | null
  • IsArchivedboolean | null
  • LastContactedTimestring | null
  • LastNamestring | null
  • LastSubmittedTimestring | null
  • LastSyncTimestring | integer | null
  • MiddleNamestring | null
  • Nicknamestring | null
  • NumberCarrierNamestring | null
  • NumberCarrierTypeenum | null

    Twilio carrier types https://www.twilio.com/docs/lookup/tutorials/carrier-and-caller-name

    mobilelandlinevoipinvaliderror
  • NumberLookupAtstring | null
  • NumberMetaany | null
  • NumbersContactNumber[] | null
  • OwnerIdstring | null
  • OwnerSourceIdstring | null
  • OwnerSourceNamestring | null
  • Phonestring | null
  • SourceIdstring | integer | null
  • SourceMetamap | null
  • SourceSyncFlowstring | null
  • SourceTypestring | null
  • Statestring | null
  • Tagsstring[] | null
  • UpdatedAtstring | null
  • UploadIdstring | integer | null
  • Versionintegerrequired
  • Zipstring | null
Example
{
  "Address1": "100 Market St",
  "Address2": "Suite 400",
  "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
  "BirthDate": "1975-04-12",
  "City": "San Francisco",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "CustomFields": {},
  "Email": "jane@example.com",
  "EnrichCallerName": "Jane Doe",
  "EnrichCallerType": "consumer",
  "EnrichLookupAt": "2026-09-03T14:30:00Z",
  "EnrichMeta": {},
  "FirstName": "Jane",
  "HouseholdId": "household_9f3a2c",
  "HouseholdName": "Jane Doe",
  "HouseholdTitle": "The Doe household",
  "IsArchived": false,
  "LastContactedTime": "2026-09-03T14:30:00Z",
  "LastName": "Doe",
  "LastSubmittedTime": "2026-09-03T14:30:00Z",
  "LastSyncTime": "2026-09-03T14:30:00Z",
  "MiddleName": "Q",
  "Nickname": "Janie",
  "NumberCarrierName": "Jane Doe",
  "NumberCarrierType": "mobile",
  "NumberLookupAt": "2026-09-03T14:30:00Z",
  "NumberMeta": {},
  "Numbers": [
    {
      "IsDoNotContact": false,
      "IsPreferred": true,
      "Label": "Mobile",
      "Meta": {},
      "Phone": "+14155552671"
    }
  ],
  "OwnerId": "owner_9f3a2c",
  "OwnerSourceId": "source_9f3a2c",
  "OwnerSourceName": "Jane Doe",
  "Phone": "+14155552671",
  "SourceId": "source_9f3a2c",
  "SourceMeta": {},
  "SourceSyncFlow": "string",
  "SourceType": "wealthbox",
  "State": "CA",
  "Tags": [
    "client"
  ],
  "UpdatedAt": "2026-09-03T14:30:00Z",
  "UploadId": "upload_9f3a2c",
  "Version": 0,
  "Zip": "94107"
}

ContactsPaginated

Pagination Returns pages of records and meta data about pagination

Example
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "Address1": "100 Market St",
      "Address2": "Suite 400",
      "AvatarUrl": "https://static.currentclient.com/avatars/jane.png",
      "BirthDate": "1975-04-12",
      "City": "San Francisco",
      "ContactId": "contact_9f3a2c",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "CustomFields": {},
      "DeletedAt": "2026-09-03T14:30:00Z",
      "Email": "jane@example.com",
      "EnrichCallerName": "Jane Doe",
      "EnrichCallerType": "consumer",
      "EnrichLookupAt": "2026-09-03T14:30:00Z",
      "EnrichMeta": {},
      "FirstName": "Jane",
      "HouseholdId": "household_9f3a2c",
      "HouseholdName": "Jane Doe",
      "HouseholdTitle": "The Doe household",
      "IsArchived": false,
      "LastContactedTime": "2026-09-03T14:30:00Z",
      "LastName": "Doe",
      "LastSubmittedTime": "2026-09-03T14:30:00Z",
      "LastSyncTime": "2026-09-03T14:30:00Z",
      "MiddleName": "Q",
      "Nickname": "Janie",
      "NumberCarrierName": "Jane Doe",
      "NumberCarrierType": "mobile",
      "NumberLookupAt": "2026-09-03T14:30:00Z",
      "NumberMeta": {},
      "Numbers": [
        {}
      ],
      "OwnerId": "owner_9f3a2c",
      "OwnerSourceId": "source_9f3a2c",
      "OwnerSourceName": "Jane Doe",
      "Phone": "+14155552671",
      "SourceId": "source_9f3a2c",
      "SourceMeta": {},
      "SourceSyncFlow": "string",
      "SourceType": "wealthbox",
      "State": "CA",
      "Tags": [
        "client"
      ],
      "UpdatedAt": "2026-09-03T14:30:00Z",
      "UploadId": "upload_9f3a2c",
      "UserId": "user_9f3a2c",
      "Version": 0,
      "Versions": [
        {}
      ],
      "Zip": "94107",
      "shareExpiresTtl": 0
    }
  ]
}

Conversation

The model to be used for responses. Doesnt include internal PK and SK

  • AssignedByUserIdstring | null

    Member ID of the team member who made the assignment

  • AssignedTimestring | null

    ISO-8601 timestamp of when the assignment was made

  • AssignedToUserIdstring | null

    Member ID of the team member this conversation is assigned to

  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • ContactIdstring | null
  • ContactNamestring | null
  • ConversationFolderIdstring | null
  • ConversationIdstringrequired
  • CreatedTimeintegerrequired
  • IsCancelSnoozeOnReplyboolean | null
  • IsReadboolean
  • IsReadByMeboolean | null
  • IsSnoozedboolean | null
  • IsSnoozedAlertboolean | null
  • Labelstring | null
  • LastInboundTimeinteger | null
  • LatestCallCallInDB | null
  • LatestMessageMessageInDB | null
  • Namestring | null
  • NumberReadStatesmap

    Per-inbox read state for group conversations. Maps team phone number to has-read boolean.

  • Ownerstring | null

    Member ID of the first team member to send an outbound message or call in this conversation

  • SnoozedUntilTimestring | null
  • Statusenum

    Status of the conversation

    OPENCLOSED
  • UpdatedTimeinteger | null
  • UserIdstringrequired
  • UserNumbersstring[]

    List of user numbers associated with this conversation

  • Viewersmap | null
  • WhatsAppOptInWhatsAppOptInInfo | null
Example
{
  "AssignedByUserId": "user_9f3a2c",
  "AssignedTime": "2026-09-03T14:30:00Z",
  "AssignedToUserId": "user_9f3a2c",
  "ChannelType": "sms",
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ConversationFolderId": "folder_9f3a2c",
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": 1725321600,
  "IsCancelSnoozeOnReply": false,
  "IsRead": false,
  "IsReadByMe": false,
  "IsSnoozed": false,
  "IsSnoozedAlert": false,
  "Label": "Mobile",
  "LastInboundTime": 1725321600,
  "LatestCall": {
    "AgentInteractions": [
      {}
    ],
    "AnsweredBy": "human",
    "AnsweredByMemberId": "member_9f3a2c",
    "ArchiverIds": {},
    "CallAnalysisStatus": "completed",
    "CallAnalysisSummary": "Jane asked about rolling over her 401(k). Agreed to send the transfer form.",
    "CallAnalysisSummaryPending": "string",
    "CallAnalysisTranscript": "Agent: Thanks for calling. Jane: Hi, I had a question about my 401(k).",
    "CallDurationTime": "184",
    "CallEndedTime": 1725321600,
    "CallId": "call_9f3a2c",
    "CallSid": "CA7f3e2b9c1d4a5e6f",
    "CallSummaryReviewStatus": "pending",
    "CallSummaryReviewedAt": "2026-09-03T14:30:00Z",
    "CallSummaryReviewedBy": "string",
    "CallerMemberId": "member_9f3a2c",
    "CallerName": "Jane Doe",
    "Comments": [
      {
        "CallCommentId": "comment_9f3a2c",
        "Comment": "Client confirmed the meeting time.",
        "CreatedByUserId": "user_9f3a2c",
        "CreatedByUserName": "Jane Doe",
        "CreatedTime": 1725321600,
        "Mentions": [],
        "UpdatedAt": "2026-09-03T14:30:00Z"
      }
    ],
    "ContactId": "contact_9f3a2c",
    "ContactMemberId": "member_9f3a2c",
    "ContactName": "Jane Doe",
    "ContactNumber": "+18008675309",
    "CreatedTime": 1725321600,
    "CrmIds": {},
    "Direction": "OUTBOUND",
    "DispositionId": "disposition_9f3a2c",
    "GSI1PK": "string",
    "GSI1SK": "string",
    "GSI2PK": "string",
    "GSI2SK": "string",
    "GSI3PK": "string",
    "GSI3SK": "string",
    "GSI4PK": "string",
    "GSI4SK": "string",
    "IsAgentCall": false,
    "IsForwarded": false,
    "IsMissedCall": false,
    "IsOutsideHours": false,
    "IsRecorded": true,
    "IsSipAnswered": false,
    "IsTeamCall": false,
    "IsVoicemail": false,
    "Meta": {},
    "Note": "Follow up next week about the rollover.",
    "NotetakerIds": {},
    "NumberForwardedTo": "+14155552671",
    "PK": "string",
    "Participants": [
      {
        "CallSid": "CA7f3e2b9c1d4a5e6f",
        "CallStatus": "connecting",
        "ContactId": "contact_9f3a2c",
        "Name": "Jane Doe",
        "Number": "+14155550100",
        "TeamMemberId": "member_9f3a2c",
        "Type": "contact"
      }
    ],
    "ParticipantsVersion": 0,
    "Quality": {
      "JitterMsMax": 0,
      "MosAvg": 0,
      "MosMin": 0,
      "RttMsMax": 0
    },
    "RecordingDurationTime": "184",
    "RecordingSid": "RE7f3e2b9c1d4a5e6f",
    "RecordingStatus": "completed",
    "RecordingUrl": "https://recordings.currentclient.com/RE7f3e2b9c1d4a5e6f.mp3",
    "RefusedAddKeys": [
      "string"
    ],
    "SK": "string",
    "Searchable": "string",
    "SourceCallSK": "string",
    "Status": "completed",
    "StatusCallSid": "CA7f3e2b9c1d4a5e6f",
    "StatusSequence": 20,
    "StatusWeight": 0,
    "TYPE": "string",
    "Tags": [
      "client"
    ],
    "TranscriptionStatus": "string",
    "TranscriptionText": "string",
    "TransferredAtTime": 1725321600,
    "TransferredByMemberId": "member_9f3a2c",
    "TransferredToMemberId": "member_9f3a2c",
    "TransferredToNumber": "string",
    "UpdatedTime": 1725321600,
    "UserId": "1234-abcd-4567-ABCD",
    "UserNumber": "+18008675309"
  },
  "LatestMessage": {
    "ArchiverIds": {},
    "BestDeliveryStatus": "string",
    "ChannelType": "sms",
    "Comments": [
      {
        "Comment": "Client confirmed the meeting time.",
        "CreatedByUserId": "user_9f3a2c",
        "CreatedByUserName": "Jane Doe",
        "CreatedTime": "2026-09-03T14:30:00Z",
        "Mentions": [],
        "MessageCommentId": "comment_9f3a2c",
        "UpdatedAt": "2026-09-03T14:30:00Z"
      }
    ],
    "ContactId": "contact_9f3a2c",
    "ContactName": "Jane Doe",
    "ContactNumber": "+14155552671",
    "ConversationId": "conversation_9f3a2c",
    "CreatedTime": 1725321600,
    "CrmIds": {},
    "Direction": "SENT",
    "ErrorCode": null,
    "ErrorMessage": null,
    "GSI1PK": "string",
    "GSI1SK": "string",
    "GSI2PK": "string",
    "GSI2SK": "string",
    "GSI3PK": "string",
    "GSI3SK": "string",
    "GSI6PK": "string",
    "GSI6SK": "string",
    "HoldUntil": 0,
    "IsIgnored": false,
    "IsSilenced": false,
    "LinkedComplianceMessageId": "message_9f3a2c",
    "LocalMessageId": "message_9f3a2c",
    "MediaTwilioSids": [
      "CA7f3e2b9c1d4a5e6f"
    ],
    "Message": "Hi Jane, your documents are ready to sign.",
    "MessageId": "message_9f3a2c",
    "MessageMediaItems": [
      {
        "ChatServiceId": "service_9f3a2c",
        "FileName": "statement.jpg",
        "MediaId": "media_9f3a2c",
        "MediaType": "image/jpeg",
        "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
      }
    ],
    "Meta": {},
    "PK": "string",
    "SK": "string",
    "Searchable": "string",
    "SenderMemberId": "member_9f3a2c",
    "SenderName": "Jane Doe",
    "Status": "delivered",
    "TYPE": "string",
    "Tags": [
      "client"
    ],
    "TwilioNumOfSegments": "string",
    "TwilioSid": "CA7f3e2b9c1d4a5e6f",
    "UndeliveredContactNumber": "+14155552671",
    "UndeliveredContactNumbers": [
      "+14155552671"
    ],
    "UndeliveredParticipantSids": [
      "CA7f3e2b9c1d4a5e6f"
    ],
    "UserId": "user_9f3a2c",
    "UserNumber": "+14155550100",
    "WebhookUrlStatus": "string",
    "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
    "WhatsAppContentVariables": {},
    "WhatsAppTemplateId": "template_9f3a2c"
  },
  "Name": "Jane Doe",
  "NumberReadStates": {},
  "Owner": "string",
  "Participants": [
    {
      "ContactId": "contact_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100",
      "Type": "contact"
    }
  ],
  "SnoozedUntilTime": "2026-09-03T14:30:00Z",
  "Status": "OPEN",
  "UpdatedTime": 1725321600,
  "UserId": "user_9f3a2c",
  "UserNumbers": [
    "+14155550100"
  ],
  "Viewers": {},
  "WhatsAppOptIn": {
    "OptedIn": false,
    "Source": "inbound_message",
    "Time": 1725321600
  }
}

ConversationParticipant

Model rerpesenting a participant in a conversation

  • ContactIdstring | null
  • Namestring | null
  • Numberstring | null
  • Typeenumrequired

    Enum for the type of participant

    contactteam
Example
{
  "ContactId": "contact_9f3a2c",
  "Name": "Jane Doe",
  "Number": "+14155550100",
  "Type": "contact"
}

HTTPValidationError

Returned with status 422 when the request does not match the schema.

Example
{
  "detail": [
    {
      "type": "string",
      "ctx": {},
      "input": null,
      "loc": [
        "string"
      ],
      "msg": "string"
    }
  ]
}

InboxHoliday

PRO-811: one holiday an inbox is out of office for. Either a preset (HolidayId in app.core.holidays.HOLIDAYS, date computed per year) or a custom date (HolidayId "CUSTOM_<anything>" plus CustomDate).

  • CustomDatestring | null
  • HolidayIdstringrequired
  • IsEnabledboolean
  • IsRecurringYearlyboolean
  • Namestring | null
  • TextAutoIncomingMessagestring | null
  • TextAutoMissedCallstring | null
  • VoicemailAudioUrlstring | null
Example
{
  "CustomDate": "2026-09-03T14:30:00Z",
  "HolidayId": "holiday_9f3a2c",
  "IsEnabled": false,
  "IsRecurringYearly": false,
  "Name": "Jane Doe",
  "TextAutoIncomingMessage": "string",
  "TextAutoMissedCall": "string",
  "VoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3"
}

InboxPagination

Pagniation Returns pages of records and meta data about pagination

Example
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "BusinessSchedule": [
        {}
      ],
      "BusinessTimezone": "America/Los_Angeles",
      "CallRingDuration": "15",
      "CallRingOrderType": "string",
      "CallTeamMemberIds": [
        "member_9f3a2c"
      ],
      "CallflowId": "callflow_9f3a2c",
      "ComplianceMessage": "You can call or text us at this number. Primarily, you can expect to receive brief news and updates from us. Msg & data rates may apply. Reply STOP to opt-out anytime. Questions? You are welcome to reply.",
      "ComplianceVCardId": "card_9f3a2c",
      "DeletedTime": 1725321600,
      "Dialplan": "string",
      "ForwardingTimeout": 20,
      "ForwardingVoicemailMode": "DESTINATION",
      "GreetingAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
      "HiddenFor": [
        "string"
      ],
      "Holidays": [
        {}
      ],
      "InboundType": "RING",
      "IsComplianceAutoSuppress": false,
      "IsComplianceEnabled": false,
      "IsDropCallerId": false,
      "IsEnableAutoConferenceNotetaker": false,
      "IsEnableAutoIncomingMessage": false,
      "IsEnableAutoMissedCall": false,
      "IsEnableAutoOutOfOfficeIncomingMessage": false,
      "IsEnableAutoOutOfOfficeMissedCall": false,
      "IsEnableAutoOutsideHoursIncomingMessage": false,
      "IsEnableAutoOutsideHoursMissedCall": false,
      "IsEnableAutoRecordCalls": true,
      "IsEnableBusinessHours": false,
      "IsEnableCallSummary": true,
      "IsEnableCallTranscription": true,
      "IsEnableFilterProfanity": false,
      "IsEnableForwardCall": false,
      "IsEnableGreeting": false,
      "IsEnablePhoneMenu": false,
      "IsEnableRecordGreeting": false,
      "IsEnableRecordingAnnouncement": false,
      "IsEnableTranscribeVoicemail": false,
      "IsFaxCapable": false,
      "IsRequireCallSummaryReview": false,
      "IsSmsCapable": false,
      "IsSmsHosting": false,
      "MutedFor": [
        "string"
      ],
      "Name": "Jane Doe",
      "NotetakerPhoneNumber": "string",
      "NotetakerProvider": "JUMP",
      "Number": "+14155550100",
      "NumberForwardTo": "+14155550100",
      "OrgA2pId": "p_9f3a2c",
      "OrgA2pStatus": "PORTING_IN",
      "OutOfOfficeEndDate": "2026-09-03T14:30:00Z",
      "OutOfOfficeEndTime": "2026-09-03T14:30:00Z",
      "OutOfOfficeStartDate": "2026-09-03T14:30:00Z",
      "OutOfOfficeStartTime": "2026-09-03T14:30:00Z",
      "OutOfOfficeVoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
      "OutsideHoursVoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
      "Permissions": {
        "Editors": [],
        "Viewers": []
      },
      "PortOutUnlocked": false,
      "RecordingAnnouncementPromptRef": "string",
      "SkipTeamMemberIds": [
        "member_9f3a2c"
      ],
      "Symbol": "JD",
      "TeamMemberId": "member_9f3a2c",
      "TextAutoAutoOutsideHoursMissedCall": "string",
      "TextAutoIncomingMessage": "string",
      "TextAutoMissedCall": "string",
      "TextAutoOutOfOfficeIncomingMessage": "string",
      "TextAutoOutOfOfficeMissedCall": "string",
      "TextAutoOutsideHoursIncomingMessage": "string",
      "TwilioMessagingServiceSid": "CA7f3e2b9c1d4a5e6f",
      "Type": "REGULAR",
      "UserId": "user_9f3a2c",
      "VoiceProvider": "twilio",
      "VoicemailAudioUrl": "https://static.currentclient.com/audio/greeting.mp3",
      "WabaId": "waba_9f3a2c",
      "WhatsappSenderNumber": "string"
    }
  ]
}

MediaItem

  • ChatServiceIdstring | null
  • FileNamestring | null
  • MediaIdstring | null
  • MediaTypestringrequired
  • MediaUrlstring | null
Example
{
  "ChatServiceId": "service_9f3a2c",
  "FileName": "statement.jpg",
  "MediaId": "media_9f3a2c",
  "MediaType": "image/jpeg",
  "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
}

MessageComment

  • Commentstringrequired
  • CreatedByUserIdstringrequired
  • CreatedByUserNamestringrequired
  • CreatedTimestring | integerrequired
  • Mentionsstring[] | null
  • MessageCommentIdstring | integer | null
  • UpdatedAtstring | null
Example
{
  "Comment": "Client confirmed the meeting time.",
  "CreatedByUserId": "user_9f3a2c",
  "CreatedByUserName": "Jane Doe",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Mentions": [
    "string"
  ],
  "MessageCommentId": "comment_9f3a2c",
  "UpdatedAt": "2026-09-03T14:30:00Z"
}

MessageInDB

InDB Properties properties stored in DB, this is full representation of record

  • ArchiverIdsmap | null

    Dictionary to store archiver ids - key is ArchiverId, value is ArchiverType

  • BestDeliveryStatusstring | null

    For a group-conversation message, the highest-ranked leg success (delivered/read, by MESSAGE_STATUS_WEIGHT) ever recorded on this row, kept independent of the row's own Status. Written on every success receipt via the group-delivery path and never downgraded. Exists because a later failing leg can resolve the row's Status to partiallydelivered -- a single scalar that cannot also encode 'and the best success so far was read' -- so once that happens, prior_status stops being a usable record of it. Without this field, a read receipt followed by a failing leg followed by that leg merely CORRECTING to delivered (rather than read) permanently lost the fact that someone had already read the message (PRO-7413). Populated only via the onDeliveryUpdated group-delivery path (crud.message.update_status resolve_as_group_delivery=True); unset for a 1:1 message.

  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • CommentsMessageComment[] | null

    Comments about the message

  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null

    Name of the contact for quick reference

  • ContactNumberstring | null

    Phone with a leading +1 or a short code

  • ConversationIdstring | null

    A Twilio conversation ID or our number TO number format

  • CreatedTimeinteger | null
  • CrmIdsmap | null

    Dictionary to store CRM ids - key is CrmId, value is CrmType

  • Directionenum | null

    Direction of the message, whether it was sent or received

    SENTRECEIVED
  • ErrorCodestring | null
  • ErrorMessagestring | null
  • GSI1PKstring | null
  • GSI1SKstring | null
  • GSI2PKstring | null
  • GSI2SKstring | null
  • GSI3PKstring | null
  • GSI3SKstring | null
  • GSI6PKstring | null
  • GSI6SKstring | null
  • HoldUntilinteger | null

    PRO-8559: epoch-seconds when a Status=pending message's undo-send grace period ends and it is actually handed to Twilio. Set only while Status is pending; the frontend renders the remaining hold from this instead of re-deriving its own client-side timer, so the window survives a reload. Never cleared -- it stays on the row, stale, once the message leaves pending -- so consumers must gate on Status==pending, not merely on this field being set.

  • IsIgnoredboolean | null
  • IsSilencedboolean | null
  • LinkedComplianceMessageIdstring | null

    PRO-8589: set on a held real (non-compliance) message whose first-contact compliance sub-message was ALSO held for the same undo-send grace window, pointing at that sub-message's own MessageId. cancel_pending_send follows it to cancel the compliance row in lockstep with this one, so undoing a first-ever send never leaves the contact holding a bare Reply-STOP line with no message attached to it. Unset for every other message -- compliance resends, and automated / admin-or-service / CH sends, which skip the hold entirely.

  • LocalMessageIdstring | null
  • MediaTwilioSidsstring[] | null
  • Messagestring | null

    Field of message to send

  • MessageIdstringrequired
  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap | null

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • PKstringrequired
  • SKstringrequired
  • Searchablestringrequired
  • SenderMemberIdstring | null

    Member id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • Statusenum | null

    Status of the message

    createdpendingreadycancelledblockednumberunsubscribercannotrouteerrorinvalidnosmspresenderrorsenderrorunsubscribedsessionexpiredaccepteddeliveredfailedqueuedreadsendingsentundeliveredreceivedreceivingpartiallydelivered
  • TYPEstringrequired
  • Tagsstring[] | null

    Tags for the message

  • TwilioNumOfSegmentsstring | null
  • TwilioSidstring | null
  • UndeliveredContactNumberstring | null

    For a group-conversation message, the specific participant number whose relay leg failed, resolved from Twilio's per-recipient onDeliveryUpdated ParticipantSid (PRO-6630/PRO-6632) since the message row's own ContactNumber can't name one recipient out of several. Unset for a 1:1 message, where ContactNumber already identifies the recipient, and unset if the participant lookup failed.

  • UndeliveredContactNumbersstring[] | null

    For a group-conversation message, every participant leg that is CURRENTLY known-failed, by number -- the per-recipient state the PRO-7304 failure alert renders from, since a group send's single Status can only ever describe one aggregate outcome and UndeliveredContactNumber (singular) only ever named the most recently-resolved failure. Index-aligned with UndeliveredParticipantSids (entry i failed as participant i). A NEW failing participant is appended; the SAME participant later correcting to a success (PRO-5002's shape, not a second person's independent failure) removes that entry instead of leaving it stuck forever (PRO-7304 round 3 -- this list is NOT append-only despite an earlier round of this same ticket documenting it that way). Populated only via the onDeliveryUpdated group-delivery path (crud.message.update_status resolve_as_group_delivery=True); unset for a 1:1 message and for a clean group delivery with no failures at all. An ENTRY may be None: the leg is known-failed but Twilio's participant lookup could not resolve its number. The entry is still recorded, because dropping it would leave that leg with no UndeliveredParticipantSids entry either, and its own later correction could then never be matched -- pinning the row at partiallydelivered forever with nothing able to clear it (ironhide, PR #875 round 7). Consumers rendering this list must skip None entries; the count of failed LEGS is the list length, the count of NAMEABLE ones is smaller.

  • UndeliveredParticipantSidsstring[] | null

    Twilio ParticipantSid for each entry in UndeliveredContactNumbers, same index. The identity that lets update_status tell a same-participant DLR correction (PRO-5002: this exact leg corrected itself, remove it) apart from a second, independent participant's receipt (PRO-7304: two different people, two different facts, neither erases the other) -- Status and ContactNumber alone can't distinguish those. Backend-internal: not meant for the frontend to render, only to let this field's sibling list self-correct accurately. An entry can itself be None (a legacy row seeded from the pre-sid-tracking singular UndeliveredContactNumber field, or the Twilio Participant lookup failed) -- update_status's correction matching requires an actual sid on BOTH sides, so a None entry here can never be mistaken for a match against an incoming None sid.

  • UserIdstring

    Id of the app user

  • UserNumberstring | null

    Number with a leading +1

  • WebhookUrlStatusstring | null
  • WhatsAppContentSidstring | null

    Server-resolved Twilio Content SID for a template send. Not client-settable.

  • WhatsAppContentVariablesmap | null

    Server-resolved positional {'1': value, ...} substitutions for a template send. Not client-settable.

  • WhatsAppTemplateIdstring | null

    An approved WhatsAppTemplate to send this message with, bypassing the 24h session window

Example
{
  "ArchiverIds": {},
  "BestDeliveryStatus": "string",
  "ChannelType": "sms",
  "Comments": [
    {
      "Comment": "Client confirmed the meeting time.",
      "CreatedByUserId": "user_9f3a2c",
      "CreatedByUserName": "Jane Doe",
      "CreatedTime": "2026-09-03T14:30:00Z",
      "Mentions": [
        "string"
      ],
      "MessageCommentId": "comment_9f3a2c",
      "UpdatedAt": "2026-09-03T14:30:00Z"
    }
  ],
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": 1725321600,
  "CrmIds": {},
  "Direction": "SENT",
  "ErrorCode": null,
  "ErrorMessage": null,
  "GSI1PK": "string",
  "GSI1SK": "string",
  "GSI2PK": "string",
  "GSI2SK": "string",
  "GSI3PK": "string",
  "GSI3SK": "string",
  "GSI6PK": "string",
  "GSI6SK": "string",
  "HoldUntil": 0,
  "IsIgnored": false,
  "IsSilenced": false,
  "LinkedComplianceMessageId": "message_9f3a2c",
  "LocalMessageId": "message_9f3a2c",
  "MediaTwilioSids": [
    "CA7f3e2b9c1d4a5e6f"
  ],
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageId": "message_9f3a2c",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "PK": "string",
  "SK": "string",
  "Searchable": "string",
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "Status": "delivered",
  "TYPE": "string",
  "Tags": [
    "client"
  ],
  "TwilioNumOfSegments": "string",
  "TwilioSid": "CA7f3e2b9c1d4a5e6f",
  "UndeliveredContactNumber": "+14155552671",
  "UndeliveredContactNumbers": [
    "+14155552671"
  ],
  "UndeliveredParticipantSids": [
    "CA7f3e2b9c1d4a5e6f"
  ],
  "UserId": "user_9f3a2c",
  "UserNumber": "+14155550100",
  "WebhookUrlStatus": "string",
  "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
  "WhatsAppContentVariables": {},
  "WhatsAppTemplateId": "template_9f3a2c"
}

MessageMediaItem

An attachment on a message. Download it from MediaUrl.

  • ChatServiceIdstring | null
  • FileNamestring | null
  • MediaIdstring | null
  • MediaTypestringrequired
  • MediaUrlstring | null
Example
{
  "ChatServiceId": "service_9f3a2c",
  "FileName": "statement.jpg",
  "MediaId": "media_9f3a2c",
  "MediaType": "image/jpeg",
  "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
}

Milestones

Milestones provides fields for user milestones

  • IsCompletedOnboardingboolean | null
Example
{
  "IsCompletedOnboarding": false
}

Note

The model to be used for responses. Doesnt include internal PK and SK

  • ContactIdstringrequired
  • CreatedTimestring | integerrequired
  • Messagestringrequired
  • NoteIdstring | integerrequired
  • UserIdstringrequired
Example
{
  "ContactId": "contact_9f3a2c",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Message": "Hi Jane, your documents are ready to sign.",
  "NoteId": "note_9f3a2c",
  "UserId": "user_9f3a2c"
}

NoteCreate

Create Properties to receive on note creation

  • Messagestringrequired
Example
{
  "Message": "Hi Jane, your documents are ready to sign."
}

NoteUpdate

Update Properties to receive on note update

  • Messagestring | null
Example
{
  "Message": "Hi Jane, your documents are ready to sign."
}

NotesPaginated

Pagination Returns pages of records and meta data about pagination

Example
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "ContactId": "contact_9f3a2c",
      "CreatedTime": "2026-09-03T14:30:00Z",
      "Message": "Hi Jane, your documents are ready to sign.",
      "NoteId": "note_9f3a2c",
      "UserId": "user_9f3a2c"
    }
  ]
}

Paginated_for_Call

Example
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "AgentInteractions": [
        {}
      ],
      "AnsweredBy": "human",
      "AnsweredByMemberId": "member_9f3a2c",
      "ArchiverIds": {},
      "CallAnalysisStatus": "completed",
      "CallAnalysisSummary": "Jane asked about rolling over her 401(k). Agreed to send the transfer form.",
      "CallAnalysisSummaryPending": "string",
      "CallAnalysisTranscript": "Agent: Thanks for calling. Jane: Hi, I had a question about my 401(k).",
      "CallDurationTime": "184",
      "CallEndedTime": 1725321600,
      "CallId": "call_9f3a2c",
      "CallSid": "CA7f3e2b9c1d4a5e6f",
      "CallSummaryReviewStatus": "pending",
      "CallSummaryReviewedAt": "2026-09-03T14:30:00Z",
      "CallSummaryReviewedBy": "string",
      "CallerMemberId": "member_9f3a2c",
      "CallerName": "Jane Doe",
      "Comments": [
        {}
      ],
      "ContactId": "contact_9f3a2c",
      "ContactMemberId": "member_9f3a2c",
      "ContactName": "Jane Doe",
      "ContactNumber": "+18008675309",
      "CreatedTime": 1725321600,
      "CrmIds": {},
      "Direction": "OUTBOUND",
      "DispositionId": "disposition_9f3a2c",
      "IsAgentCall": false,
      "IsForwarded": false,
      "IsMissedCall": false,
      "IsOutsideHours": false,
      "IsRecorded": true,
      "IsSipAnswered": false,
      "IsTeamCall": false,
      "IsVoicemail": false,
      "Meta": {},
      "Note": "Follow up next week about the rollover.",
      "NotetakerIds": {},
      "NumberForwardedTo": "+14155552671",
      "Participants": [
        {}
      ],
      "Quality": {
        "JitterMsMax": 0,
        "MosAvg": 0,
        "MosMin": 0,
        "RttMsMax": 0
      },
      "RecordingDurationTime": "184",
      "RecordingSid": "RE7f3e2b9c1d4a5e6f",
      "RecordingStatus": "completed",
      "RecordingUrl": "https://recordings.currentclient.com/RE7f3e2b9c1d4a5e6f.mp3",
      "Status": "completed",
      "StatusCallSid": "CA7f3e2b9c1d4a5e6f",
      "StatusSequence": 20,
      "StatusWeight": 0,
      "Tags": [
        "client"
      ],
      "TranscriptionStatus": "string",
      "TranscriptionText": "string",
      "TransferredAtTime": 1725321600,
      "TransferredByMemberId": "member_9f3a2c",
      "TransferredToMemberId": "member_9f3a2c",
      "TransferredToNumber": "string",
      "UpdatedTime": 1725321600,
      "UserId": "1234-abcd-4567-ABCD",
      "UserNumber": "+18008675309"
    }
  ]
}

Paginated_for_Conversation

Example
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "AssignedByUserId": "user_9f3a2c",
      "AssignedTime": "2026-09-03T14:30:00Z",
      "AssignedToUserId": "user_9f3a2c",
      "ChannelType": "sms",
      "ContactId": "contact_9f3a2c",
      "ContactName": "Jane Doe",
      "ConversationFolderId": "folder_9f3a2c",
      "ConversationId": "conversation_9f3a2c",
      "CreatedTime": 1725321600,
      "IsCancelSnoozeOnReply": false,
      "IsRead": false,
      "IsReadByMe": false,
      "IsSnoozed": false,
      "IsSnoozedAlert": false,
      "Label": "Mobile",
      "LastInboundTime": 1725321600,
      "LatestCall": {
        "AgentInteractions": [],
        "AnsweredBy": "human",
        "AnsweredByMemberId": "member_9f3a2c",
        "ArchiverIds": {},
        "CallAnalysisStatus": "completed",
        "CallAnalysisSummary": "Jane asked about rolling over her 401(k). Agreed to send the transfer form.",
        "CallAnalysisSummaryPending": "string",
        "CallAnalysisTranscript": "Agent: Thanks for calling. Jane: Hi, I had a question about my 401(k).",
        "CallDurationTime": "184",
        "CallEndedTime": 1725321600,
        "CallId": "call_9f3a2c",
        "CallSid": "CA7f3e2b9c1d4a5e6f",
        "CallSummaryReviewStatus": "pending",
        "CallSummaryReviewedAt": "2026-09-03T14:30:00Z",
        "CallSummaryReviewedBy": "string",
        "CallerMemberId": "member_9f3a2c",
        "CallerName": "Jane Doe",
        "Comments": [],
        "ContactId": "contact_9f3a2c",
        "ContactMemberId": "member_9f3a2c",
        "ContactName": "Jane Doe",
        "ContactNumber": "+18008675309",
        "CreatedTime": 1725321600,
        "CrmIds": {},
        "Direction": "OUTBOUND",
        "DispositionId": "disposition_9f3a2c",
        "GSI1PK": "string",
        "GSI1SK": "string",
        "GSI2PK": "string",
        "GSI2SK": "string",
        "GSI3PK": "string",
        "GSI3SK": "string",
        "GSI4PK": "string",
        "GSI4SK": "string",
        "IsAgentCall": false,
        "IsForwarded": false,
        "IsMissedCall": false,
        "IsOutsideHours": false,
        "IsRecorded": true,
        "IsSipAnswered": false,
        "IsTeamCall": false,
        "IsVoicemail": false,
        "Meta": {},
        "Note": "Follow up next week about the rollover.",
        "NotetakerIds": {},
        "NumberForwardedTo": "+14155552671",
        "PK": "string",
        "Participants": [],
        "ParticipantsVersion": 0,
        "Quality": {},
        "RecordingDurationTime": "184",
        "RecordingSid": "RE7f3e2b9c1d4a5e6f",
        "RecordingStatus": "completed",
        "RecordingUrl": "https://recordings.currentclient.com/RE7f3e2b9c1d4a5e6f.mp3",
        "RefusedAddKeys": [],
        "SK": "string",
        "Searchable": "string",
        "SourceCallSK": "string",
        "Status": "completed",
        "StatusCallSid": "CA7f3e2b9c1d4a5e6f",
        "StatusSequence": 20,
        "StatusWeight": 0,
        "TYPE": "string",
        "Tags": [],
        "TranscriptionStatus": "string",
        "TranscriptionText": "string",
        "TransferredAtTime": 1725321600,
        "TransferredByMemberId": "member_9f3a2c",
        "TransferredToMemberId": "member_9f3a2c",
        "TransferredToNumber": "string",
        "UpdatedTime": 1725321600,
        "UserId": "1234-abcd-4567-ABCD",
        "UserNumber": "+18008675309"
      },
      "LatestMessage": {
        "ArchiverIds": {},
        "BestDeliveryStatus": "string",
        "ChannelType": "sms",
        "Comments": [],
        "ContactId": "contact_9f3a2c",
        "ContactName": "Jane Doe",
        "ContactNumber": "+14155552671",
        "ConversationId": "conversation_9f3a2c",
        "CreatedTime": 1725321600,
        "CrmIds": {},
        "Direction": "SENT",
        "ErrorCode": null,
        "ErrorMessage": null,
        "GSI1PK": "string",
        "GSI1SK": "string",
        "GSI2PK": "string",
        "GSI2SK": "string",
        "GSI3PK": "string",
        "GSI3SK": "string",
        "GSI6PK": "string",
        "GSI6SK": "string",
        "HoldUntil": 0,
        "IsIgnored": false,
        "IsSilenced": false,
        "LinkedComplianceMessageId": "message_9f3a2c",
        "LocalMessageId": "message_9f3a2c",
        "MediaTwilioSids": [],
        "Message": "Hi Jane, your documents are ready to sign.",
        "MessageId": "message_9f3a2c",
        "MessageMediaItems": [],
        "Meta": {},
        "PK": "string",
        "SK": "string",
        "Searchable": "string",
        "SenderMemberId": "member_9f3a2c",
        "SenderName": "Jane Doe",
        "Status": "delivered",
        "TYPE": "string",
        "Tags": [],
        "TwilioNumOfSegments": "string",
        "TwilioSid": "CA7f3e2b9c1d4a5e6f",
        "UndeliveredContactNumber": "+14155552671",
        "UndeliveredContactNumbers": [],
        "UndeliveredParticipantSids": [],
        "UserId": "user_9f3a2c",
        "UserNumber": "+14155550100",
        "WebhookUrlStatus": "string",
        "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
        "WhatsAppContentVariables": {},
        "WhatsAppTemplateId": "template_9f3a2c"
      },
      "Name": "Jane Doe",
      "NumberReadStates": {},
      "Owner": "string",
      "Participants": [
        {}
      ],
      "SnoozedUntilTime": "2026-09-03T14:30:00Z",
      "Status": "OPEN",
      "UpdatedTime": 1725321600,
      "UserId": "user_9f3a2c",
      "UserNumbers": [
        "+14155550100"
      ],
      "Viewers": {},
      "WhatsAppOptIn": {
        "OptedIn": false,
        "Source": "inbound_message",
        "Time": 1725321600
      }
    }
  ]
}

Paginated_for_Message

Example
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "ArchiverIds": {},
      "BestDeliveryStatus": "string",
      "ChannelType": "sms",
      "Comments": [
        {}
      ],
      "ContactId": "contact_9f3a2c",
      "ContactName": "Jane Doe",
      "ContactNumber": "+14155552671",
      "ConversationId": "conversation_9f3a2c",
      "CreatedTime": 1725321600,
      "CrmIds": {},
      "Direction": "SENT",
      "ErrorCode": null,
      "ErrorMessage": null,
      "HoldUntil": 0,
      "IsIgnored": false,
      "IsSilenced": false,
      "LinkedComplianceMessageId": "message_9f3a2c",
      "LocalMessageId": "message_9f3a2c",
      "MediaTwilioSids": [
        "CA7f3e2b9c1d4a5e6f"
      ],
      "Message": "Hi Jane, your documents are ready to sign.",
      "MessageId": "message_9f3a2c",
      "MessageMediaItems": [
        {}
      ],
      "Meta": {},
      "SenderMemberId": "member_9f3a2c",
      "SenderName": "Jane Doe",
      "Status": "delivered",
      "Tags": [
        "client"
      ],
      "TwilioNumOfSegments": "string",
      "TwilioSid": "CA7f3e2b9c1d4a5e6f",
      "UndeliveredContactNumber": "+14155552671",
      "UndeliveredContactNumbers": [
        "+14155552671"
      ],
      "UndeliveredParticipantSids": [
        "CA7f3e2b9c1d4a5e6f"
      ],
      "UserId": "user_9f3a2c",
      "UserNumber": "+14155550100",
      "WebhookUrlStatus": "string",
      "WhatsAppContentSid": "CA7f3e2b9c1d4a5e6f",
      "WhatsAppContentVariables": {},
      "WhatsAppTemplateId": "template_9f3a2c"
    }
  ]
}

Paginated_for_TeamMemberExtra

Example
{
  "meta": {
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "total": 0
  },
  "records": [
    {
      "Bio": "Helping families plan for what is next.",
      "BrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
      "CognitoUserId": "user_9f3a2c",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "Email": "jane@example.com",
      "ExternalConnectorId": "connector_9f3a2c",
      "ExternalData": {
        "Groups": []
      },
      "ExternalId": "external_9f3a2c",
      "ExternalLastUpdated": 0,
      "ExternalType": "wealthbox",
      "FirstName": "Jane",
      "IsActive": true,
      "IsAdmin": false,
      "IsAiSummaryFree": false,
      "IsFree": false,
      "IsGovernor": false,
      "IsInvited": false,
      "IsJoined": true,
      "IsMember": true,
      "IsXypnMember": false,
      "JobTitle": "Financial Advisor",
      "LastName": "Doe",
      "Phone": "+14155552671",
      "TeamMemberId": "member_9f3a2c",
      "UpdatedAt": "2026-09-03T14:30:00Z",
      "UserId": "user_9f3a2c"
    }
  ]
}

RegisteredNumber

  • AddressRequirementsstring | null
  • CapabilitiesRegisteredNumberCapabilities | null
  • DateCreatedstring | null
  • DateUpdatedstring | null
  • FriendlyNamestring | null
  • Originstring | null
  • PhoneNumberstringrequired
  • Sidstring | null
  • SmsFallbackMethodstring | null
  • SmsFallbackUrlstring | null
  • SmsMethodstring | null
  • SmsUrlstring | null
  • Statusstring | null
  • StatusCallbackstring | null
  • StatusCallbackMethodstring | null
Example
{
  "AddressRequirements": "string",
  "Capabilities": {
    "IsMMSEnabled": false,
    "IsSMSEnabled": false,
    "IsVoiceEnabled": false
  },
  "DateCreated": "string",
  "DateUpdated": "string",
  "FriendlyName": "Jane Doe",
  "Origin": "string",
  "PhoneNumber": "string",
  "Sid": "CA7f3e2b9c1d4a5e6f",
  "SmsFallbackMethod": "string",
  "SmsFallbackUrl": "https://example.com",
  "SmsMethod": "string",
  "SmsUrl": "https://example.com",
  "Status": "string",
  "StatusCallback": "string",
  "StatusCallbackMethod": "string"
}

ScheduledMessage

The model to be used for responses. Doesnt include internal PK and SK

  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • Conditionenum | null

    Enum for condition check

    NOREPLYSINCENONE
  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null
  • ContactNumberstring | null

    Phone with a leading +1

  • ContactsConversationContact[] | null
  • ConversationIdstring | null

    Id of the conversation for outbounds

  • CreatedTimestring | integerrequired
  • Messagestring | null

    Field of message to send

  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • ScheduledMessageIdstringrequired
  • SendAttemptedboolean | null

    PRO-7740: whether the outbounds SMS POST was attempted before the failure this update records. Set only on a FAILED write coming from module-messages' SendScheduledMessage. Once true, the row is terminal regardless of remaining retry budget -- the SMS may already have reached the customer (WithRequests' 5s timeout means a slow-but-accepted POST looks identical to a failed one), so a retry can only send it again, never repair it. False/absent means the failure happened before any send was attempted (e.g. GetUserProfile/CheckCondition), which IS safely retryable.

  • SendAttemptsCountinteger | null
  • SendTimestringrequired
  • SenderMemberIdstring | null

    Memeber id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • SourceTypeenum | null

    Enum for source type

    AUTOMATIONMANUAL
  • Statusenumrequired

    Status of the message

    SCHEDULEDSENTCANCELLEDFAILED
  • UpdatedTimeinteger | null
  • UserIdstringrequired
  • UserNumberstringrequired

    Number with a leading +1

Example
{
  "ChannelType": "sms",
  "Condition": "NOREPLYSINCE",
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "Contacts": [
    {
      "Id": "cnt_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100"
    }
  ],
  "ConversationId": "conversation_9f3a2c",
  "CreatedTime": "2026-09-03T14:30:00Z",
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "ScheduledMessageId": "message_9f3a2c",
  "SendAttempted": false,
  "SendAttemptsCount": 0,
  "SendTime": "2026-09-03T14:30:00Z",
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "SourceType": "wealthbox",
  "Status": "SENT",
  "UpdatedTime": 1725321600,
  "UserId": "user_9f3a2c",
  "UserNumber": "+18008675309"
}

ScheduledMessageCreate

Create Properties to receive on scheduledmessage creation

  • ChannelTypeenum | null

    Type of the communication channel

    smswhatsapp
  • Conditionenum | null

    Enum for condition check

    NOREPLYSINCENONE
  • ContactIdstring | null

    Id of the contact for outbounds

  • ContactNamestring | null
  • ContactNumberstring | null

    Phone with a leading +1

  • ContactsConversationContact[] | null
  • ConversationIdstring | null

    Id of the conversation for outbounds

  • Messagestring | null

    Field of message to send

  • MessageMediaItemsMessageMediaItem[] | null

    Media to include in message

  • Metamap

    Key values of meta data for this message, will be published as attributes to topic on callbacks

  • SendAttemptedboolean | null

    PRO-7740: whether the outbounds SMS POST was attempted before the failure this update records. Set only on a FAILED write coming from module-messages' SendScheduledMessage. Once true, the row is terminal regardless of remaining retry budget -- the SMS may already have reached the customer (WithRequests' 5s timeout means a slow-but-accepted POST looks identical to a failed one), so a retry can only send it again, never repair it. False/absent means the failure happened before any send was attempted (e.g. GetUserProfile/CheckCondition), which IS safely retryable.

  • SendAttemptsCountinteger | null
  • SendTimestringrequired
  • SenderMemberIdstring | null

    Memeber id for the sender

  • SenderNamestring | null

    Name of the Sender for quick reference

  • SourceTypeenum | null

    Enum for source type

    AUTOMATIONMANUAL
  • UserNumberstringrequired

    Number with a leading +1

Example
{
  "ChannelType": "sms",
  "Condition": "NOREPLYSINCE",
  "ContactId": "contact_9f3a2c",
  "ContactName": "Jane Doe",
  "ContactNumber": "+14155552671",
  "Contacts": [
    {
      "Id": "cnt_9f3a2c",
      "Name": "Jane Doe",
      "Number": "+14155550100"
    }
  ],
  "ConversationId": "conversation_9f3a2c",
  "Message": "Hi Jane, your documents are ready to sign.",
  "MessageMediaItems": [
    {
      "ChatServiceId": "service_9f3a2c",
      "FileName": "statement.jpg",
      "MediaId": "media_9f3a2c",
      "MediaType": "image/jpeg",
      "MediaUrl": "https://media.currentclient.com/att_8x2k4m.jpg"
    }
  ],
  "Meta": {},
  "SendAttempted": false,
  "SendAttemptsCount": 0,
  "SendTime": "2026-09-03T14:30:00Z",
  "SenderMemberId": "member_9f3a2c",
  "SenderName": "Jane Doe",
  "SourceType": "wealthbox",
  "UserNumber": "+18008675309"
}

ScheduledMessagesPaginated

Pagination Returns pages of records and meta data about pagination

Example
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "ChannelType": "sms",
      "Condition": "NOREPLYSINCE",
      "ContactId": "contact_9f3a2c",
      "ContactName": "Jane Doe",
      "ContactNumber": "+14155552671",
      "Contacts": [
        {}
      ],
      "ConversationId": "conversation_9f3a2c",
      "CreatedTime": "2026-09-03T14:30:00Z",
      "Message": "Hi Jane, your documents are ready to sign.",
      "MessageMediaItems": [
        {}
      ],
      "Meta": {},
      "ScheduledMessageId": "message_9f3a2c",
      "SendAttempted": false,
      "SendAttemptsCount": 0,
      "SendTime": "2026-09-03T14:30:00Z",
      "SenderMemberId": "member_9f3a2c",
      "SenderName": "Jane Doe",
      "SourceType": "wealthbox",
      "Status": "SENT",
      "UpdatedTime": 1725321600,
      "UserId": "user_9f3a2c",
      "UserNumber": "+18008675309"
    }
  ]
}

Tag

The model to be used for responses. Doesnt include internal PK and SK

  • Colorstring | null
  • CreatedAtstringrequired
  • Descriptionstring | nullrequired
  • IsMutablebooleanrequired
  • IsPinnedboolean | null
  • LastSyncTimestring | integer | null
  • SourceIdstring | integer | null
  • SourceTypestring | null
  • TagIdstringrequired
  • Titlestringrequired
  • UpdatedAtstring | null
  • UserIdstringrequired
Example
{
  "Color": "string",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "Description": "string",
  "IsMutable": false,
  "IsPinned": false,
  "LastSyncTime": "2026-09-03T14:30:00Z",
  "SourceId": "source_9f3a2c",
  "SourceType": "wealthbox",
  "TagId": "tag_9f3a2c",
  "Title": "string",
  "UpdatedAt": "2026-09-03T14:30:00Z",
  "UserId": "user_9f3a2c"
}

TagsPaginated

Pagination Returns pages of records and meta data about pagination

Example
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "Color": "string",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "Description": "string",
      "IsMutable": false,
      "IsPinned": false,
      "LastSyncTime": "2026-09-03T14:30:00Z",
      "SourceId": "source_9f3a2c",
      "SourceType": "wealthbox",
      "TagId": "tag_9f3a2c",
      "Title": "string",
      "UpdatedAt": "2026-09-03T14:30:00Z",
      "UserId": "user_9f3a2c"
    }
  ]
}

TeamMember

The model to be used for responses. Doesnt include internal PK and SK

  • Biostring | null
  • BrandImageUrlstring | null
  • CognitoUserIdstring | null
  • CreatedAtstringrequired
  • Emailstringrequired
  • ExternalConnectorIdstring | null
  • ExternalDataExternalDataWealthBox | null
  • ExternalIdstring | null
  • ExternalLastUpdatedinteger | null
  • ExternalTypeenum | string | null
  • FirstNamestring | null
  • IsActiveboolean | null
  • IsAiSummaryFreeboolean | null
  • IsFreeboolean | null
  • IsInvitedboolean | null
  • IsJoinedboolean | null
  • IsMemberboolean | null
  • IsXypnMemberboolean | null
  • JobTitlestring | null
  • LastNamestring | null
  • Phonestring | null
  • TeamMemberIdstringrequired
  • UpdatedAtstring | null
  • UserIdstringrequired
Example
{
  "Bio": "Helping families plan for what is next.",
  "BrandImageUrl": "https://static.currentclient.com/avatars/jane.png",
  "CognitoUserId": "user_9f3a2c",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "Email": "jane@example.com",
  "ExternalConnectorId": "connector_9f3a2c",
  "ExternalData": {
    "Groups": [
      "string"
    ]
  },
  "ExternalId": "external_9f3a2c",
  "ExternalLastUpdated": 0,
  "ExternalType": "wealthbox",
  "FirstName": "Jane",
  "IsActive": true,
  "IsAiSummaryFree": false,
  "IsFree": false,
  "IsInvited": false,
  "IsJoined": true,
  "IsMember": true,
  "IsXypnMember": false,
  "JobTitle": "Financial Advisor",
  "LastName": "Doe",
  "Phone": "+14155552671",
  "TeamMemberId": "member_9f3a2c",
  "UpdatedAt": "2026-09-03T14:30:00Z",
  "UserId": "user_9f3a2c"
}

ValidationError

  • typestringrequired
  • ctxobject
  • inputany
  • locstring | integer[]required
  • msgstringrequired
Example
{
  "type": "string",
  "ctx": {},
  "input": null,
  "loc": [
    "string"
  ],
  "msg": "string"
}

WebhookEndpoint

A webhook endpoint. Never includes the signing secret -- that's returned only once, by POST /api/v1/webhooks (creation) or POST /{id}/rotate-secret. Save it then; it cannot be retrieved again afterward.

  • ConnectorNamestringrequired
  • CreatedAtstringrequired
  • IsEnabledbooleanrequired
  • Urlstring | null
  • WebhookEndpointIdstringrequired

    The connector id

Example
{
  "ConnectorName": "Jane Doe",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "IsEnabled": false,
  "Url": "https://example.com",
  "WebhookEndpointId": "endpoint_9f3a2c"
}

WebhookEndpointCreate

Properties to receive on POST /api/v1/webhooks

  • ConnectorNamestring | null

    Display name; defaults to a generated name if omitted

  • IsEnabledboolean | null
  • Urlstringrequired

    HTTPS URL deliveries are POSTed to

Example
{
  "ConnectorName": "Jane Doe",
  "IsEnabled": false,
  "Url": "https://example.com"
}

WebhookEndpointUpdate

Properties to receive on PUT /api/v1/webhooks/{id}

  • ConnectorNamestring | null
  • IsEnabledboolean | null
  • Urlstring | null
Example
{
  "ConnectorName": "Jane Doe",
  "IsEnabled": false,
  "Url": "https://example.com"
}

WebhookEndpointWithSecret

Same shape as WebhookEndpoint, plus the signing secret. Only returned by POST /api/v1/webhooks (creation) and POST /api/v1/webhooks/{id}/rotate-secret. Save this value immediately -- it cannot be retrieved again after this response.

  • ConnectorNamestringrequired
  • CreatedAtstringrequired
  • IsEnabledbooleanrequired
  • Secretstringrequired

    HMAC-SHA256 signing secret; shown only here and on rotate

  • Urlstring | null
  • WebhookEndpointIdstringrequired

    The connector id

Example
{
  "ConnectorName": "Jane Doe",
  "CreatedAt": "2026-09-03T14:30:00Z",
  "IsEnabled": false,
  "Secret": "string",
  "Url": "https://example.com",
  "WebhookEndpointId": "endpoint_9f3a2c"
}

WebhookEndpointsPaginated

Pagination wrapper for GET /api/v1/webhooks

Example
{
  "meta": {
    "calls": 0,
    "cursor": "eyJrIjoiMTcyNTMyMTYwMCJ9",
    "limit": 0,
    "stats": [
      {}
    ],
    "total": 0
  },
  "records": [
    {
      "ConnectorName": "Jane Doe",
      "CreatedAt": "2026-09-03T14:30:00Z",
      "IsEnabled": false,
      "Url": "https://example.com",
      "WebhookEndpointId": "endpoint_9f3a2c"
    }
  ]
}

WebhookEventSubscription

One event this webhook endpoint is (or could be) subscribed to. EventName may be an event this API cannot itself subscribe to, if the subscription was created elsewhere in the app; PUT /{id}/events leaves those alone rather than removing them.

  • EventNameenumrequired

    Routing event names This enum is copied in the module-routing

    MESSAGE_INCOMINGMESSAGE_UPDATEDCALL_MISSEDNEW_SUBMISSIONCONTACT_VERSIONEDCONTACT_UPDATEDCONTACT_CREATEDSMS_SENTSMS_LOGCALL_LOGCALL_UPDATEDVOICEMAIL_RECEIVEDCALL_RECORDING_COMPLETEDVIDEO_UPLOADEDSMS_UNDELIVEREDCALL_TRANSCRIPT_COMPLETEDTETHER_WIDGET_SUBMISSIONCALL_AI_SUMMARY_COMPLETEDCRMSYNC_BROKENCONVERSATION_REMINDER_DUECOMMENT_MENTIONCONVERSATION_ASSIGNEDINBOX_CREATEDINBOX_DELETEDCHAT_MESSAGECHAT_MENTIONINTERNAL_CHAT_LOGCONTACT_DELETEDMESSAGE_TAKENNEW_LEADMESSAGE_ALL
  • IsEnabledbooleanrequired
Example
{
  "EventName": "Jane Doe",
  "IsEnabled": false
}

WebhookEventSubscriptionsUpdate

Desired set of subscribed events for PUT /api/v1/webhooks/{id}/events. Replaces the full set of event subscriptions with exactly the events listed here (not a delta): - An event listed here with no existing subscription is subscribed (enabled). - An event listed here that's already subscribed but disabled is re-enabled. - A currently-enabled subscription for an event not listed here is removed. - A currently-disabled subscription for an event not listed here is left untouched. Only the events listed under EventNames below can be subscribed to here. A subscription for any other event -- created elsewhere in the app -- is left untouched by this call, listed or not.

  • EventNamesenum[]required

    Events to subscribe this webhook endpoint to. Accepts only: MESSAGE_INCOMING, SMS_SENT, SMS_UNDELIVERED, CONVERSATION_REMINDER_DUE, CALL_LOG, CALL_MISSED, VOICEMAIL_RECEIVED, CALL_RECORDING_COMPLETED, CALL_TRANSCRIPT_COMPLETED, CALL_AI_SUMMARY_COMPLETED, NEW_SUBMISSION, TETHER_WIDGET_SUBMISSION, INBOX_CREATED, INBOX_DELETED, CONTACT_CREATED, CONTACT_UPDATED, CONTACT_DELETED. Any other event is rejected with a 400 -- including one this endpoint already has a subscription for, created elsewhere in the app, which GET /{id}/events will report but this call cannot manage.

Example
{
  "EventNames": [
    "Jane Doe"
  ]
}

WhatsAppOptInInfo

Records the current state of a contact's consent to receive WhatsApp business-initiated (template) messages, and how/when that state was last set. Distinct from SMS opt-OUT, which is tracked separately via OPT_OUT_KEYWORDS/Unsubscriber (PRO-4154). This must always be written as a persistent record, never removed: an opt-out (STOP) sets OptedIn=False rather than deleting the field, because a merely-absent field is indistinguishable from "never contacted" -- which would let the very next inbound WhatsApp message silently re-enable opt-in via the auto-opt-in path in CRUDConversation._record_inbound_session_signal.

  • OptedInboolean
  • Sourceenumrequired

    How WhatsAppOptIn on a conversation was captured.

    inbound_messagemanualstop_keywordstart_keyword
  • Timeintegerrequired
Example
{
  "OptedIn": false,
  "Source": "inbound_message",
  "Time": 1725321600
}