API reference

Me

The signed-in user

MethodPathSummary
GET/v1/meThe signed-in user, their account, role, groups, vocabulary and permissions
POST/v1/me/accept-inviteAccept a pending invite after signing in from the invite email. Refresh the session afterwards.
GET/v1/me/actionsMy tasks: the action items assigned to me, open and snoozed, due soonest first. Items come from fixed rules, never the model
POST/v1/me/actions/{actionId}/dismissDismiss one of my tasks, with a note for the team saying why
POST/v1/me/actions/{actionId}/doneMark one of my tasks done, with an optional note for the team
POST/v1/me/actions/{actionId}/hand-backGive one of my tasks back: it goes to the booking's assignee, else the community's backup contacts
POST/v1/me/actions/{actionId}/snoozeSnooze one of my tasks until a time, up to 30 days away
GET/v1/me/api-tokensYour personal API tokens
POST/v1/me/api-tokensMake a personal API token, up to your own role. It is shown once and ends in 30, 90 or 365 days
DELETE/v1/me/api-tokens/{tokenId}Revoke one of your tokens. It stops working at once
GET/v1/me/availabilityMy hours: when I take meetings, on calls and on booking pages
POST/v1/me/availabilityAdd a named schedule; the first one becomes my default
GET/v1/me/availability/previewMy open hours over the next seven days: my default hours with busy time on my calendar taken out
PUT/v1/me/availability/{scheduleId}Change one of my schedules
DELETE/v1/me/availability/{scheduleId}Remove a schedule that is not my default
POST/v1/me/availability/{scheduleId}/defaultUse this schedule on calls and by default on pages
PUT/v1/me/booking-linkChange my link name. My old links keep working for 90 days
GET/v1/me/booking-pagesMy booking pages, my link name, and the groups and schedules a page can use
POST/v1/me/booking-pagesMake a booking page; my link name is made from my staff name the first time
PATCH/v1/me/booking-pages/{pageId}Change one of my pages: its settings, link or group. An old link keeps working for 90 days
DELETE/v1/me/booking-pages/{pageId}Remove one of my pages. One with meetings is archived, so they keep their history
POST/v1/me/booking-pages/{pageId}/pauseStop taking bookings on one of my pages; meetings already booked stay
POST/v1/me/booking-pages/{pageId}/resumeTake bookings on one of my pages again, unless an admin paused it
GET/v1/me/calendarMy own calendar, where the tours I am assigned are booked, and how I can connect one
DELETE/v1/me/calendarDisconnect my calendar: no more tours are booked on it
POST/v1/me/calendar/confirmFinish connecting my own calendar, with the token the sign-in callback handed the browser. Only the person who started it can (ADR 0111)
POST/v1/me/calendar/connectStart signing in with Google or Microsoft to connect my own calendar
GET/v1/me/calendar/crmThe CRMs I can use as my calendar, and my CRM user at my primary group
PUT/v1/me/calendar/crmKeep my meetings in the CRM instead of my own calendar (disconnects my own calendar)
POST/v1/me/calendar/testCheck that my calendar still works, and record the result
GET/v1/me/direct-phoneThe phone a transfer to me rings
PUT/v1/me/direct-phoneSet or clear the phone a transfer to me rings
GET/v1/me/handoffsThe calls handed to me: live ones first, then the last 30 days
GET/v1/me/handoffs/{callId}A call handed to me: the caller, why, what the agent learned, the questions and answers, the notes and the words (logs call.view)
POST/v1/me/handoffs/{callId}/doneI am done with the notes: once the call has ended, the CRM log goes now with them (or, after it went, one update)
PATCH/v1/me/handoffs/{callId}/fields/{fieldKey}Set, confirm or clear one answer on a call handed to me. Send the answer's version as read (null when there was none); a stale one is refused with 409
POST/v1/me/handoffs/{callId}/fields/{fieldKey}/suggestionTake the listener's suggestion as the answer, or leave it
POST/v1/me/handoffs/{callId}/heartbeatMy notes page is open: the call's CRM log waits for my Done instead of going as soon as the call ends
PUT/v1/me/handoffs/{callId}/notesSave the notes on a call handed to me (the Markdown subset with checklists). Send the version as read (null for the first save); a stale one is refused with 409
POST/v1/me/handoffs/{callId}/text-linkText the notes link to the rep the call was handed to: the link only, once a minute (logs call.notes.text_link)
GET/v1/me/handoffs/{callId}/turnsThe lines of a call handed to me after the one the page already has, with the signal version they are at least as fresh as
GET/v1/me/meetingsThe meetings assigned to me: upcoming, past or cancelled
GET/v1/me/meetings/{bookingId}One of my meetings: who is coming, how to reach them, and what they told us
GET/v1/me/meetings/{bookingId}/briefThe visit brief for one of my meetings: who is coming, their timeline and interests, objections and answers, open commitments and talking points (logs call.view)
POST/v1/me/meetings/{bookingId}/cancelCancel one of my upcoming meetings, in the calendar and for the caller
POST/v1/me/meetings/{bookingId}/rescheduleMove one of my meetings to another of my free times; the caller is told
GET/v1/me/meetings/{bookingId}/timesTimes I could move one of my meetings to, from my own hours and calendar
GET/v1/me/meetings/{bookingId}/visitA visit I give, or one at a community I can see: its notes, newest first, and what I may do
POST/v1/me/meetings/{bookingId}/visit/actionsAdd a next step to a visit: an item from the community’s list (actionKey), or one typed (label). The same clientKey again returns the first item
POST/v1/me/meetings/{bookingId}/visit/finishSend the visit’s notes and next steps to the CRM now, as one activity. After it went, sends one update with the visit as it now stands
POST/v1/me/meetings/{bookingId}/visit/notesAdd a note to a visit (the Markdown subset with checklists). The same clientKey again returns the first note
PATCH/v1/me/meetings/{bookingId}/visit/notes/{noteId}Change one of my notes on a visit. Send the version as read; a stale one is refused with 409
DELETE/v1/me/meetings/{bookingId}/visit/notes/{noteId}Remove a note from a visit: my own while the visit takes notes, or anyone’s at a community I manage
POST/v1/me/meetings/{bookingId}/visit/photo-consentConfirm the family agreed to have photos taken and shared with them, including on links they forward
POST/v1/me/meetings/{bookingId}/visit/photosStart adding a photo: returns the photo and a one-time link to PUT its bytes to (null when they are already there). The same clientKey again returns the same photo
PUT/v1/me/meetings/{bookingId}/visit/photos/orderPut a visit’s photos in a new order, in one go: every photo the visit shows, each once
PATCH/v1/me/meetings/{bookingId}/visit/photos/{photoId}Change a photo’s caption, whether it is shared with the family, or its place in the order
DELETE/v1/me/meetings/{bookingId}/visit/photos/{photoId}Remove a photo: hidden at once, its files deleted by the daily sweep. My own, or anyone’s at a community I manage
POST/v1/me/meetings/{bookingId}/visit/photos/{photoId}/completeFinish adding a photo once its bytes are sent: checks them, then its copies are made (status processing, then ready)
POST/v1/me/meetings/{bookingId}/visit/publishShow the visit’s shared photos on the family’s page, making an on-demand page if it has none. Returns a fresh link and QR code for an on-demand page (each call: Show the link again), or none for a call’s page
POST/v1/me/meetings/{bookingId}/visit/unpublishTake every photo of the visit off the family’s page at once, without removing any
GET/v1/me/mfaWhich second sign-in steps this login has, and what its account asks for
POST/v1/me/mfa/challengeSend a passcode for one of this login’s methods (an authenticator app sends none)
POST/v1/me/mfa/methodsStart setting a second sign-in step up. Setting the same kind up again replaces it, but only once the new one is confirmed.
DELETE/v1/me/mfa/methods/{factorId}Remove a second sign-in step. Refused when it is the last one and one is required.
POST/v1/me/mfa/methods/{factorId}/confirmFinish setting a second sign-in step up. The first one also returns recovery codes, shown once.
POST/v1/me/mfa/recoverySpend a recovery code to get into this session when no method is to hand. Set a method up again afterwards.
POST/v1/me/mfa/recovery-codesReplace every recovery code with ten new ones. The old ones stop working at once.
POST/v1/me/mfa/verifyConfirm a code for this session. Refresh the Supabase session afterwards to pick up the new claims.
GET/v1/me/oauth-grantsApps you gave access to your account
DELETE/v1/me/oauth-grants/{grantId}Take access away from an app you connected
PUT/v1/me/primary-groupPick the group my defaults come from, among the groups whose staff I am on
PATCH/v1/me/profileChange your own name and the time zone you read times in
GET/v1/me/taking-callsWhether ring groups ring me (Taking calls) or skip me (Away)
PUT/v1/me/taking-callsSwitch myself to Taking calls or Away. Away skips me in every ring group; transfers the agent makes to me still ring
GET/v1/me/token-scopesThe scopes a token can have, in plain words, and which this role may give. Owners and admins may ask for another role (a service identity’s ceiling)
GET/v1/me/visit-actionsMy open next steps from visits, soonest due first, and the ones waiting for a backup contact where I am one
PATCH/v1/me/visit-actions/{actionId}Mark a next step done, dismiss it, reopen it, move it to another day, change its note or hand it on. Send the version as read; a stale one is refused with 409
DELETE/v1/me/visit-actions/{actionId}Take back a next step I added by mistake: within ten minutes, and only while nobody has changed it
POST/v1/me/visit-actions/{actionId}/takeTake a next step that is waiting for one of the community’s backup contacts

The signed-in user, their account, role, groups, vocabulary and permissions#

GET /v1/me

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
aalenumYesOne of: "aal1", "aal2".
accountobject | nullYes—
account.idstring (acct_… ID)YesID (acct_…)
account.namestringYes—
account.recordingPolicyenumYesOne of: "always", "never", "optional".
account.slugstringYes—
account.statusenumYesOne of: "active", "suspended", "deleted".
account.vocabularyobjectYes—
account.vocabulary.contactstringYes1–40 characters. Default: "contact".
account.vocabulary.contactPluralstringYes1–40 characters. Default: "contacts".
account.vocabulary.groupstringYes1–40 characters. Default: "location".
account.vocabulary.groupPluralstringYes1–40 characters. Default: "locations".
account.vocabulary.meetingstringYes1–40 characters. Default: "meeting".
account.vocabulary.meetingPluralstringYes1–40 characters. Default: "meetings".
account.vocabulary.servicestringYes1–40 characters. Default: "service".
account.vocabulary.servicePluralstringYes1–40 characters. Default: "services".
account.vocabulary.specialstringYes1–40 characters. Default: "special".
account.vocabulary.specialPluralstringYes1–40 characters. Default: "specials".
groupIdsarray<string (grp_… ID)>Yes—
groupsarray<object>Yes—
groups[].idstring (grp_… ID)YesID (grp_…)
groups[].namestringYes—
groups[].statusenumYesOne of: "active", "archived".
memberStatusenum | nullYesOne of: "invited", "active", "deactivated".
mfaobjectYes—
mfa.enrolledbooleanYes—
mfa.requiredbooleanYes—
mfa.satisfiedbooleanYes—
permissionsarray<enum>YesItems: "members.manage", "emails.manage", "billing.manage", "playbooks.publish", "playbooks.edit", "playbooks.locks", "groups.manage", "groups.customize", "knowledge.manage", "connections.manage", "numbers.assign", "testcall.run", "calls.read", "analytics.read", "insights.manage", "insights.correct", "insights.topics", "insights.gaps", "experiments.manage", "leads.manage", "insights.actions", "usage.read", "account.read", "pricing.catalog", "pricing.edit", "pricing.approve", "followup.revoke", "widget.manage", "widget.read", "tools.manage", "tools.read", "calendar.own", "calendars.read", "availability.own", "meetings.own", "availability.any", "booking_pages.own", "booking_pages.any", "booking_pages.group", "booking_pages.read", "actions.own", "handoffs.own", "visits.work", "visits.moderate", "brands.read", "brands.manage", "brands.group", "media.read", "media.manage", "media.edit", "media.settings".
platformMfaRequiredbooleanYes—
platformRoleenum | nullYesOne of: "platform_owner", "platform_support".
roleenum | nullYesOne of: "owner", "admin", "editor", "group_manager", "viewer", "sales_rep".
signupPendingbooleanYes—
userobjectYes—
user.emailstring | nullYes—
user.idstring (usr_… ID)YesID (usr_…)
user.namestring | nullYes—
user.timeZonestring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Accept a pending invite after signing in from the invite email. Refresh the session afterwards.#

POST /v1/me/accept-invite

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
accountIdstring (acct_… ID)YesID (acct_…)
statusenumYesOne of: "active".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/accept-invite" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

My tasks: the action items assigned to me, open and snoozed, due soonest first. Items come from fixed rules, never the model#

GET /v1/me/actions

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
tasksarray<MyTask>Yes—
tasks[].commitmentobject | nullYes—
tasks[].commitment.dueAtstring (date-time)Yes—
tasks[].commitment.kindenumYesOne of: "callback", "specialist_confirm", "send_information", "other".
tasks[].dueAtstring (date-time)Yes—
tasks[].firedAtstring (date-time)Yes—
tasks[].groupIdstring (grp_… ID) | nullYes—
tasks[].groupNamestring | nullYes—
tasks[].idstring (iact_… ID)YesID (iact_…)
tasks[].leadobjectYes—
tasks[].lead.emailstring | nullYes—
tasks[].lead.namestring | nullYes—
tasks[].lead.phonestring | nullYes—
tasks[].meetingobject | nullYes—
tasks[].meeting.idstring (bkg_… ID)YesID (bkg_…)
tasks[].meeting.startstring (date-time)Yes—
tasks[].reasonWordsstringYes—
tasks[].ruleenumYesOne of: "hot_target_open", "commitment_due", "urgent_timeline", "operations_miss", "cancelled_no_rebook", "unopened_before_visit", "negative_end", "agent_miss", "no_show_recovery", "anonymous_hot_chat", "recurring_gap", "performance_regression".
tasks[].ruleLabelstringYes—
tasks[].severityenumYesOne of: "high", "medium", "low".
tasks[].snoozedUntilstring (date-time) | nullYes—
tasks[].stateenumYesOne of: "open", "snoozed".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/actions" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Dismiss one of my tasks, with a note for the team saying why#

POST /v1/me/actions/{actionId}/dismiss

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
actionIdstring (iact_… ID)YesID (iact_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringNoUp to 1000 characters.

Response 200

FieldTypeRequiredDescription
taskany | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/actions/{actionId}/dismiss" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

Mark one of my tasks done, with an optional note for the team#

POST /v1/me/actions/{actionId}/done

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
actionIdstring (iact_… ID)YesID (iact_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringNoUp to 1000 characters.

Response 200

FieldTypeRequiredDescription
taskany | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/actions/{actionId}/done" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

Give one of my tasks back: it goes to the booking's assignee, else the community's backup contacts#

POST /v1/me/actions/{actionId}/hand-back

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
actionIdstring (iact_… ID)YesID (iact_…)

Request body

application/json, required.

Type: object

Response 200

FieldTypeRequiredDescription
tasknullYes—
toobjectYes—
to.namestring | nullYes—
to.sourceenumYesOne of: "rep", "booking_assignee", "human_backup", "editors", "staff".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/actions/{actionId}/hand-back" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Snooze one of my tasks until a time, up to 30 days away#

POST /v1/me/actions/{actionId}/snooze

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
actionIdstring (iact_… ID)YesID (iact_…)

Request body

application/json, required.

FieldTypeRequiredDescription
untilanyYes—

Response 200

FieldTypeRequiredDescription
taskany | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/actions/{actionId}/snooze" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "until": {}
}'

Your personal API tokens#

GET /v1/me/api-tokens

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
tokensarray<ApiToken>Yes—
tokens[].createdAtstring (date-time)Yes—
tokens[].expiresAtstring (date-time) | nullYes—
tokens[].groupIdsarray<string (grp_… ID)> | nullYes—
tokens[].idstring (tok_… ID)YesID (tok_…)
tokens[].ipAllowlistarray<string> | nullYes—
tokens[].kindenumYesOne of: "personal", "service".
tokens[].lastFourstringYes—
tokens[].lastUsedAtstring (date-time) | nullYes—
tokens[].lastUsedIpstring | nullYes—
tokens[].namestringYes—
tokens[].prefixstringYes—
tokens[].scopesarray<string>Yes—
tokens[].serviceIdentityIdstring (svc_… ID) | nullYes—
tokens[].serviceIdentityNamestring | nullYes—
tokens[].userEmailstring | nullYes—
tokens[].userIdstring (usr_… ID) | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/api-tokens" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Make a personal API token, up to your own role. It is shown once and ends in 30, 90 or 365 days#

POST /v1/me/api-tokens

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
daysenum | enum | enumYes—
groupIdsarray<string (grp_… ID)> | nullNoUp to 200 items.
namestringYes1–80 characters.
scopesarray<string>YesUp to 30 items.

Response 201

FieldTypeRequiredDescription
apiTokenApiTokenYes—
apiToken.createdAtstring (date-time)Yes—
apiToken.expiresAtstring (date-time) | nullYes—
apiToken.groupIdsarray<string (grp_… ID)> | nullYes—
apiToken.idstring (tok_… ID)YesID (tok_…)
apiToken.ipAllowlistarray<string> | nullYes—
apiToken.kindenumYesOne of: "personal", "service".
apiToken.lastFourstringYes—
apiToken.lastUsedAtstring (date-time) | nullYes—
apiToken.lastUsedIpstring | nullYes—
apiToken.namestringYes—
apiToken.prefixstringYes—
apiToken.scopesarray<string>Yes—
apiToken.serviceIdentityIdstring (svc_… ID) | nullYes—
apiToken.serviceIdentityNamestring | nullYes—
apiToken.userEmailstring | nullYes—
apiToken.userIdstring (usr_… ID) | nullYes—
tokenstringYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/api-tokens" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "scopes": [
    "string"
  ],
  "days": 30
}'

Revoke one of your tokens. It stops working at once#

DELETE /v1/me/api-tokens/{tokenId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
tokenIdstring (tok_… ID)YesID (tok_…)

Response 200

FieldTypeRequiredDescription
revokedenumYesOne of: true.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/api-tokens/{tokenId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

My hours: when I take meetings, on calls and on booking pages#

GET /v1/me/availability

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
groupsarray<object>Yes—
groups[].idstring (grp_… ID)YesID (grp_…)
groups[].namestringYes—
groups[].timeZonestringYes—
matchEmailstring | nullYes—
primaryGroupIdstring (grp_… ID) | nullYes—
schedulesarray<AvailabilitySchedule>Yes—
schedules[].chosenbooleanYes—
schedules[].hoursobjectYes—
schedules[].hours.overridesarray<object>YesUp to 366 items.
schedules[].hours.overrides[].datestring (date)Yes—
schedules[].hours.overrides[].windowsarray<object>YesUp to 12 items.
schedules[].hours.timeZonestringYes—
schedules[].hours.weeklyarray<object>YesUp to 50 items.
schedules[].hours.weekly[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
schedules[].hours.weekly[].endstring | constantYes—
schedules[].hours.weekly[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
schedules[].idstring (avs_… ID)YesID (avs_…)
schedules[].isDefaultbooleanYes—
schedules[].namestringYes—
schedules[].updatedAtstring (date-time)Yes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/availability" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Add a named schedule; the first one becomes my default#

POST /v1/me/availability

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
hoursobjectYes—
hours.overridesarray<object>YesUp to 366 items.
hours.overrides[].datestring (date)Yes—
hours.overrides[].windowsarray<object>YesUp to 12 items.
hours.overrides[].windows[].endstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
hours.overrides[].windows[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
hours.timeZonestringYes—
hours.weeklyarray<object>YesUp to 50 items.
hours.weekly[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
hours.weekly[].endstring | enumYes—
hours.weekly[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
namestringYes1–60 characters.

Response 201

FieldTypeRequiredDescription
scheduleAvailabilityScheduleYes—
schedule.chosenbooleanYes—
schedule.hoursobjectYes—
schedule.hours.overridesarray<object>YesUp to 366 items.
schedule.hours.overrides[].datestring (date)Yes—
schedule.hours.overrides[].windowsarray<object>YesUp to 12 items.
schedule.hours.timeZonestringYes—
schedule.hours.weeklyarray<object>YesUp to 50 items.
schedule.hours.weekly[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
schedule.hours.weekly[].endstring | constantYes—
schedule.hours.weekly[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
schedule.idstring (avs_… ID)YesID (avs_…)
schedule.isDefaultbooleanYes—
schedule.namestringYes—
schedule.updatedAtstring (date-time)Yes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/availability" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "hours": {
    "timeZone": "string",
    "weekly": [
      {
        "days": [
          "mon"
        ],
        "start": "string",
        "end": "string"
      }
    ],
    "overrides": [
      {
        "date": "2026-01-15",
        "windows": [
          {
            "start": "string",
            "end": "string"
          }
        ]
      }
    ]
  }
}'

My open hours over the next seven days: my default hours with busy time on my calendar taken out#

GET /v1/me/availability/preview

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
calendarenumYesOne of: "checked", "not_connected", "unavailable".
daysarray<object>Yes—
days[].datestringYes—
days[].stretchesarray<object>Yes—
days[].stretches[].endstringYes—
days[].stretches[].startstringYes—
timeZonestring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/availability/preview" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Change one of my schedules#

PUT /v1/me/availability/{scheduleId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
scheduleIdstring (avs_… ID)YesID (avs_…)

Request body

application/json, required.

FieldTypeRequiredDescription
hoursobjectYes—
hours.overridesarray<object>YesUp to 366 items.
hours.overrides[].datestring (date)Yes—
hours.overrides[].windowsarray<object>YesUp to 12 items.
hours.overrides[].windows[].endstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
hours.overrides[].windows[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
hours.timeZonestringYes—
hours.weeklyarray<object>YesUp to 50 items.
hours.weekly[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
hours.weekly[].endstring | enumYes—
hours.weekly[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
namestringYes1–60 characters.

Response 200

FieldTypeRequiredDescription
scheduleAvailabilityScheduleYes—
schedule.chosenbooleanYes—
schedule.hoursobjectYes—
schedule.hours.overridesarray<object>YesUp to 366 items.
schedule.hours.overrides[].datestring (date)Yes—
schedule.hours.overrides[].windowsarray<object>YesUp to 12 items.
schedule.hours.timeZonestringYes—
schedule.hours.weeklyarray<object>YesUp to 50 items.
schedule.hours.weekly[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
schedule.hours.weekly[].endstring | constantYes—
schedule.hours.weekly[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
schedule.idstring (avs_… ID)YesID (avs_…)
schedule.isDefaultbooleanYes—
schedule.namestringYes—
schedule.updatedAtstring (date-time)Yes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/me/availability/{scheduleId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "hours": {
    "timeZone": "string",
    "weekly": [
      {
        "days": [
          "mon"
        ],
        "start": "string",
        "end": "string"
      }
    ],
    "overrides": [
      {
        "date": "2026-01-15",
        "windows": [
          {
            "start": "string",
            "end": "string"
          }
        ]
      }
    ]
  }
}'

Remove a schedule that is not my default#

DELETE /v1/me/availability/{scheduleId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
scheduleIdstring (avs_… ID)YesID (avs_…)

Response 200

FieldTypeRequiredDescription
deletedenumYesOne of: true.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/availability/{scheduleId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Use this schedule on calls and by default on pages#

POST /v1/me/availability/{scheduleId}/default

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
scheduleIdstring (avs_… ID)YesID (avs_…)

Response 200

FieldTypeRequiredDescription
scheduleAvailabilityScheduleYes—
schedule.chosenbooleanYes—
schedule.hoursobjectYes—
schedule.hours.overridesarray<object>YesUp to 366 items.
schedule.hours.overrides[].datestring (date)Yes—
schedule.hours.overrides[].windowsarray<object>YesUp to 12 items.
schedule.hours.timeZonestringYes—
schedule.hours.weeklyarray<object>YesUp to 50 items.
schedule.hours.weekly[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
schedule.hours.weekly[].endstring | constantYes—
schedule.hours.weekly[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
schedule.idstring (avs_… ID)YesID (avs_…)
schedule.isDefaultbooleanYes—
schedule.namestringYes—
schedule.updatedAtstring (date-time)Yes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/availability/{scheduleId}/default" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

PUT /v1/me/booking-link

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

application/json, required.

FieldTypeRequiredDescription
slugstringYes2–60 characters. Pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$.
FieldTypeRequiredDescription
accountSlugstringYes—
bookingAppUrlstringYes—
groupPagesarray<object>Yes—
groupPages[].groupNamestringYes—
groupPages[].idstring (bpg_… ID)YesID (bpg_…)
groupPages[].statusenumYesOne of: "active", "paused", "archived".
groupPages[].titlestringYes—
groupPages[].urlstring | nullYes—
groupsarray<object>Yes—
groups[].idstring (grp_… ID)YesID (grp_…)
groups[].namestringYes—
matchEmailstring | nullYes—
pagesarray<BookingPageSummary>Yes—
pages[].bookingsThisMonthintegerYes—
pages[].groupIdstring (grp_… ID)YesID (grp_…)
pages[].groupNamestringYes—
pages[].idstring (bpg_… ID)YesID (bpg_…)
pages[].pausedByenum | nullYesOne of: "owner", "admin".
pages[].settingsBookingPageSettingsYes—
pages[].settings.assignmentobject | objectYesDefault: \{"mode":"round_robin","strategy":"equal"\}.
pages[].settings.assignment.modeconstantYes(variant 1) Always "round_robin".
pages[].settings.assignment.strategyenumYes(variant 1) One of: "equal", "most_available". Default: "equal".
pages[].settings.assignment.modeconstantYes(variant 2) Always "invitee_chooses".
pages[].settings.brandIdstring (brd_… ID) | nullYes—
pages[].settings.bufferAfterMinutesintegerYesBetween 0 and 120. Default: 0.
pages[].settings.bufferBeforeMinutesintegerYesBetween 0 and 120. Default: 0.
pages[].settings.colorstring | nullYesPattern: ^#[0-9a-f]\{6\}$.
pages[].settings.coverPhotostring (uri) | string (uri) | nullYes—
pages[].settings.dailyLimitinteger | nullYesBetween 1 and 50.
pages[].settings.descriptionstringYesUp to 1000 characters. Default: "".
pages[].settings.durationsarray<constant | constant | constant | constant>YesUp to 4 items. Default: [30].
pages[].settings.incrementconstant | constant | constant | constantYesDefault: 30.
pages[].settings.locationobject | object | object | object | objectYesDefault: \{"kind":"in_person"\}.
pages[].settings.location.kindconstantYes(variant 1) Always "in_person".
pages[].settings.location.kindconstantYes(variant 2) Always "phone_invitee".
pages[].settings.location.kindconstantYes(variant 3) Always "phone_rep".
pages[].settings.location.phonestringYes(variant 3) 7–32 characters.
pages[].settings.location.kindconstantYes(variant 4) Always "video".
pages[].settings.location.urlstring (uri)Yes(variant 4) A https:// link Up to 2000 characters.
pages[].settings.location.kindconstantYes(variant 5) Always "custom".
pages[].settings.location.textstringYes(variant 5) 1–200 characters.
pages[].settings.meetingTypestring | nullYesUp to 64 characters.
pages[].settings.minNoticeMinutesintegerYesBetween 0 and 43200. Default: 240.
pages[].settings.pageHoursarray<object> | nullYesUp to 50 items.
pages[].settings.pageHours[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
pages[].settings.pageHours[].endstring | constantYes—
pages[].settings.pageHours[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
pages[].settings.preferLeadRepbooleanYesDefault: true.
pages[].settings.questionsarray<object>YesUp to 10 items. Default: [].
pages[].settings.questions[].fieldKeystringNo1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
pages[].settings.questions[].idstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
pages[].settings.questions[].kindenumYesOne of: "short_text", "long_text", "single_choice", "multiple_choice", "yes_no", "date".
pages[].settings.questions[].labelstringYes1–200 characters.
pages[].settings.questions[].optionsarray<string>NoUp to 20 items.
pages[].settings.questions[].requiredbooleanYesDefault: false.
pages[].settings.redirectUrlstring (uri) | nullYesUp to 2000 characters.
pages[].settings.reminderDayBeforebooleanYesDefault: true.
pages[].settings.reminderTwoHoursbooleanYesDefault: true.
pages[].settings.requireEmailbooleanYesDefault: true.
pages[].settings.requirePhonebooleanYesDefault: true.
pages[].settings.scheduleIdstring | nullYesUp to 40 characters.
pages[].settings.serviceobject | object | objectYesDefault: \{"kind":"none"\}.
pages[].settings.service.kindconstantYes(variant 1) Always "none".
pages[].settings.service.kindconstantYes(variant 2) Always "fixed".
pages[].settings.service.serviceIdstring (srv_… ID)Yes(variant 2) ID (srv_…)
pages[].settings.service.kindconstantYes(variant 3) Always "ask".
pages[].settings.serviceCoverPhotobooleanYesDefault: false.
pages[].settings.titlestringYes1–80 characters.
pages[].settings.windowobject | objectYesDefault: \{"days":30,"kind":"rolling"\}.
pages[].settings.window.daysintegerYes(variant 1) Between 1 and 365.
pages[].settings.window.kindconstantYes(variant 1) Always "rolling".
pages[].settings.window.fromstring (date)Yes(variant 2)
pages[].settings.window.kindconstantYes(variant 2) Always "range".
pages[].settings.window.tostring (date)Yes(variant 2)
pages[].slugstringYes—
pages[].statusenumYesOne of: "active", "paused", "archived".
pages[].updatedAtstring (date-time)Yes—
pages[].urlstring | nullYes—
primaryGroupIdstring (grp_… ID) | nullYes—
repSlugstring | nullYes—
schedulesarray<object>Yes—
schedules[].idstring (avs_… ID)YesID (avs_…)
schedules[].isDefaultbooleanYes—
schedules[].namestringYes—

Errors: 400, 401, 402, 403, 404, 409, 429, 500, with an ErrorBody body.

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/me/booking-link" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "slug": "string"
}'

My booking pages, my link name, and the groups and schedules a page can use#

GET /v1/me/booking-pages

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
accountSlugstringYes—
bookingAppUrlstringYes—
groupPagesarray<object>Yes—
groupPages[].groupNamestringYes—
groupPages[].idstring (bpg_… ID)YesID (bpg_…)
groupPages[].statusenumYesOne of: "active", "paused", "archived".
groupPages[].titlestringYes—
groupPages[].urlstring | nullYes—
groupsarray<object>Yes—
groups[].idstring (grp_… ID)YesID (grp_…)
groups[].namestringYes—
matchEmailstring | nullYes—
pagesarray<BookingPageSummary>Yes—
pages[].bookingsThisMonthintegerYes—
pages[].groupIdstring (grp_… ID)YesID (grp_…)
pages[].groupNamestringYes—
pages[].idstring (bpg_… ID)YesID (bpg_…)
pages[].pausedByenum | nullYesOne of: "owner", "admin".
pages[].settingsBookingPageSettingsYes—
pages[].settings.assignmentobject | objectYesDefault: \{"mode":"round_robin","strategy":"equal"\}.
pages[].settings.assignment.modeconstantYes(variant 1) Always "round_robin".
pages[].settings.assignment.strategyenumYes(variant 1) One of: "equal", "most_available". Default: "equal".
pages[].settings.assignment.modeconstantYes(variant 2) Always "invitee_chooses".
pages[].settings.brandIdstring (brd_… ID) | nullYes—
pages[].settings.bufferAfterMinutesintegerYesBetween 0 and 120. Default: 0.
pages[].settings.bufferBeforeMinutesintegerYesBetween 0 and 120. Default: 0.
pages[].settings.colorstring | nullYesPattern: ^#[0-9a-f]\{6\}$.
pages[].settings.coverPhotostring (uri) | string (uri) | nullYes—
pages[].settings.dailyLimitinteger | nullYesBetween 1 and 50.
pages[].settings.descriptionstringYesUp to 1000 characters. Default: "".
pages[].settings.durationsarray<constant | constant | constant | constant>YesUp to 4 items. Default: [30].
pages[].settings.incrementconstant | constant | constant | constantYesDefault: 30.
pages[].settings.locationobject | object | object | object | objectYesDefault: \{"kind":"in_person"\}.
pages[].settings.location.kindconstantYes(variant 1) Always "in_person".
pages[].settings.location.kindconstantYes(variant 2) Always "phone_invitee".
pages[].settings.location.kindconstantYes(variant 3) Always "phone_rep".
pages[].settings.location.phonestringYes(variant 3) 7–32 characters.
pages[].settings.location.kindconstantYes(variant 4) Always "video".
pages[].settings.location.urlstring (uri)Yes(variant 4) A https:// link Up to 2000 characters.
pages[].settings.location.kindconstantYes(variant 5) Always "custom".
pages[].settings.location.textstringYes(variant 5) 1–200 characters.
pages[].settings.meetingTypestring | nullYesUp to 64 characters.
pages[].settings.minNoticeMinutesintegerYesBetween 0 and 43200. Default: 240.
pages[].settings.pageHoursarray<object> | nullYesUp to 50 items.
pages[].settings.pageHours[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
pages[].settings.pageHours[].endstring | constantYes—
pages[].settings.pageHours[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
pages[].settings.preferLeadRepbooleanYesDefault: true.
pages[].settings.questionsarray<object>YesUp to 10 items. Default: [].
pages[].settings.questions[].fieldKeystringNo1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
pages[].settings.questions[].idstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
pages[].settings.questions[].kindenumYesOne of: "short_text", "long_text", "single_choice", "multiple_choice", "yes_no", "date".
pages[].settings.questions[].labelstringYes1–200 characters.
pages[].settings.questions[].optionsarray<string>NoUp to 20 items.
pages[].settings.questions[].requiredbooleanYesDefault: false.
pages[].settings.redirectUrlstring (uri) | nullYesUp to 2000 characters.
pages[].settings.reminderDayBeforebooleanYesDefault: true.
pages[].settings.reminderTwoHoursbooleanYesDefault: true.
pages[].settings.requireEmailbooleanYesDefault: true.
pages[].settings.requirePhonebooleanYesDefault: true.
pages[].settings.scheduleIdstring | nullYesUp to 40 characters.
pages[].settings.serviceobject | object | objectYesDefault: \{"kind":"none"\}.
pages[].settings.service.kindconstantYes(variant 1) Always "none".
pages[].settings.service.kindconstantYes(variant 2) Always "fixed".
pages[].settings.service.serviceIdstring (srv_… ID)Yes(variant 2) ID (srv_…)
pages[].settings.service.kindconstantYes(variant 3) Always "ask".
pages[].settings.serviceCoverPhotobooleanYesDefault: false.
pages[].settings.titlestringYes1–80 characters.
pages[].settings.windowobject | objectYesDefault: \{"days":30,"kind":"rolling"\}.
pages[].settings.window.daysintegerYes(variant 1) Between 1 and 365.
pages[].settings.window.kindconstantYes(variant 1) Always "rolling".
pages[].settings.window.fromstring (date)Yes(variant 2)
pages[].settings.window.kindconstantYes(variant 2) Always "range".
pages[].settings.window.tostring (date)Yes(variant 2)
pages[].slugstringYes—
pages[].statusenumYesOne of: "active", "paused", "archived".
pages[].updatedAtstring (date-time)Yes—
pages[].urlstring | nullYes—
primaryGroupIdstring (grp_… ID) | nullYes—
repSlugstring | nullYes—
schedulesarray<object>Yes—
schedules[].idstring (avs_… ID)YesID (avs_…)
schedules[].isDefaultbooleanYes—
schedules[].namestringYes—

Errors: 400, 401, 402, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/booking-pages" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Make a booking page; my link name is made from my staff name the first time#

POST /v1/me/booking-pages

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
groupIdstring (grp_… ID)NoID (grp_…)
settingsBookingPageSettingsInputYes—
settings.assignmentobject | objectNoDefault: \{"mode":"round_robin","strategy":"equal"\}.
settings.assignment.modeconstantYes(variant 1) Always "round_robin".
settings.assignment.strategyenumNo(variant 1) One of: "equal", "most_available". Default: "equal".
settings.assignment.modeconstantYes(variant 2) Always "invitee_chooses".
settings.brandIdstring (brd_… ID) | nullNo—
settings.bufferAfterMinutesintegerNoBetween 0 and 120. Default: 0.
settings.bufferBeforeMinutesintegerNoBetween 0 and 120. Default: 0.
settings.colorstring | nullNoPattern: ^#[0-9a-f]\{6\}$.
settings.coverPhotostring (uri) | string (uri) | nullNo—
settings.dailyLimitinteger | nullNoBetween 1 and 50.
settings.descriptionstringNoUp to 1000 characters. Default: "".
settings.durationsarray<constant | constant | constant | constant>NoUp to 4 items. Default: [30].
settings.incrementconstant | constant | constant | constantNoDefault: 30.
settings.locationobject | object | object | object | objectNoDefault: \{"kind":"in_person"\}.
settings.location.kindconstantYes(variant 1) Always "in_person".
settings.location.kindconstantYes(variant 2) Always "phone_invitee".
settings.location.kindconstantYes(variant 3) Always "phone_rep".
settings.location.phonestringYes(variant 3) 7–32 characters.
settings.location.kindconstantYes(variant 4) Always "video".
settings.location.urlstring (uri)Yes(variant 4) A https:// link Up to 2000 characters.
settings.location.kindconstantYes(variant 5) Always "custom".
settings.location.textstringYes(variant 5) 1–200 characters.
settings.meetingTypestring | nullNoUp to 64 characters.
settings.minNoticeMinutesintegerNoBetween 0 and 43200. Default: 240.
settings.pageHoursarray<object> | nullNoUp to 50 items.
settings.pageHours[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
settings.pageHours[].endstring | constantYes—
settings.pageHours[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
settings.preferLeadRepbooleanNoDefault: true.
settings.questionsarray<object>NoUp to 10 items. Default: [].
settings.questions[].fieldKeystringNo1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
settings.questions[].idstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
settings.questions[].kindenumYesOne of: "short_text", "long_text", "single_choice", "multiple_choice", "yes_no", "date".
settings.questions[].labelstringYes1–200 characters.
settings.questions[].optionsarray<string>NoUp to 20 items.
settings.questions[].requiredbooleanNoDefault: false.
settings.redirectUrlstring (uri) | nullNoUp to 2000 characters.
settings.reminderDayBeforebooleanNoDefault: true.
settings.reminderTwoHoursbooleanNoDefault: true.
settings.requireEmailbooleanNoDefault: true.
settings.requirePhonebooleanNoDefault: true.
settings.scheduleIdstring | nullNoUp to 40 characters.
settings.serviceobject | object | objectNoDefault: \{"kind":"none"\}.
settings.service.kindconstantYes(variant 1) Always "none".
settings.service.kindconstantYes(variant 2) Always "fixed".
settings.service.serviceIdstring (srv_… ID)Yes(variant 2) ID (srv_…)
settings.service.kindconstantYes(variant 3) Always "ask".
settings.serviceCoverPhotobooleanNoDefault: false.
settings.titlestringYes1–80 characters.
settings.windowobject | objectNoDefault: \{"days":30,"kind":"rolling"\}.
settings.window.daysintegerYes(variant 1) Between 1 and 365.
settings.window.kindconstantYes(variant 1) Always "rolling".
settings.window.fromstring (date)Yes(variant 2)
settings.window.kindconstantYes(variant 2) Always "range".
settings.window.tostring (date)Yes(variant 2)
slugstringNo2–60 characters. Pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$.

Response 201

FieldTypeRequiredDescription
pageBookingPageSummaryYes—
page.bookingsThisMonthintegerYes—
page.groupIdstring (grp_… ID)YesID (grp_…)
page.groupNamestringYes—
page.idstring (bpg_… ID)YesID (bpg_…)
page.pausedByenum | nullYesOne of: "owner", "admin".
page.settingsBookingPageSettingsYes—
page.settings.assignmentobject | objectYesDefault: \{"mode":"round_robin","strategy":"equal"\}.
page.settings.assignment.modeconstantYes(variant 1) Always "round_robin".
page.settings.assignment.strategyenumYes(variant 1) One of: "equal", "most_available". Default: "equal".
page.settings.assignment.modeconstantYes(variant 2) Always "invitee_chooses".
page.settings.brandIdstring (brd_… ID) | nullYes—
page.settings.bufferAfterMinutesintegerYesBetween 0 and 120. Default: 0.
page.settings.bufferBeforeMinutesintegerYesBetween 0 and 120. Default: 0.
page.settings.colorstring | nullYesPattern: ^#[0-9a-f]\{6\}$.
page.settings.coverPhotostring (uri) | string (uri) | nullYes—
page.settings.dailyLimitinteger | nullYesBetween 1 and 50.
page.settings.descriptionstringYesUp to 1000 characters. Default: "".
page.settings.durationsarray<constant | constant | constant | constant>YesUp to 4 items. Default: [30].
page.settings.incrementconstant | constant | constant | constantYesDefault: 30.
page.settings.locationobject | object | object | object | objectYesDefault: \{"kind":"in_person"\}.
page.settings.location.kindconstantYes(variant 1) Always "in_person".
page.settings.location.kindconstantYes(variant 2) Always "phone_invitee".
page.settings.location.kindconstantYes(variant 3) Always "phone_rep".
page.settings.location.phonestringYes(variant 3) 7–32 characters.
page.settings.location.kindconstantYes(variant 4) Always "video".
page.settings.location.urlstring (uri)Yes(variant 4) A https:// link Up to 2000 characters.
page.settings.location.kindconstantYes(variant 5) Always "custom".
page.settings.location.textstringYes(variant 5) 1–200 characters.
page.settings.meetingTypestring | nullYesUp to 64 characters.
page.settings.minNoticeMinutesintegerYesBetween 0 and 43200. Default: 240.
page.settings.pageHoursarray<object> | nullYesUp to 50 items.
page.settings.pageHours[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
page.settings.pageHours[].endstring | constantYes—
page.settings.pageHours[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
page.settings.preferLeadRepbooleanYesDefault: true.
page.settings.questionsarray<object>YesUp to 10 items. Default: [].
page.settings.questions[].fieldKeystringNo1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
page.settings.questions[].idstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
page.settings.questions[].kindenumYesOne of: "short_text", "long_text", "single_choice", "multiple_choice", "yes_no", "date".
page.settings.questions[].labelstringYes1–200 characters.
page.settings.questions[].optionsarray<string>NoUp to 20 items.
page.settings.questions[].requiredbooleanYesDefault: false.
page.settings.redirectUrlstring (uri) | nullYesUp to 2000 characters.
page.settings.reminderDayBeforebooleanYesDefault: true.
page.settings.reminderTwoHoursbooleanYesDefault: true.
page.settings.requireEmailbooleanYesDefault: true.
page.settings.requirePhonebooleanYesDefault: true.
page.settings.scheduleIdstring | nullYesUp to 40 characters.
page.settings.serviceobject | object | objectYesDefault: \{"kind":"none"\}.
page.settings.service.kindconstantYes(variant 1) Always "none".
page.settings.service.kindconstantYes(variant 2) Always "fixed".
page.settings.service.serviceIdstring (srv_… ID)Yes(variant 2) ID (srv_…)
page.settings.service.kindconstantYes(variant 3) Always "ask".
page.settings.serviceCoverPhotobooleanYesDefault: false.
page.settings.titlestringYes1–80 characters.
page.settings.windowobject | objectYesDefault: \{"days":30,"kind":"rolling"\}.
page.settings.window.daysintegerYes(variant 1) Between 1 and 365.
page.settings.window.kindconstantYes(variant 1) Always "rolling".
page.settings.window.fromstring (date)Yes(variant 2)
page.settings.window.kindconstantYes(variant 2) Always "range".
page.settings.window.tostring (date)Yes(variant 2)
page.slugstringYes—
page.statusenumYesOne of: "active", "paused", "archived".
page.updatedAtstring (date-time)Yes—
page.urlstring | nullYes—

Errors: 400, 401, 402, 403, 404, 409, 422, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/booking-pages" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "settings": {
    "title": "string"
  }
}'

Change one of my pages: its settings, link or group. An old link keeps working for 90 days#

PATCH /v1/me/booking-pages/{pageId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
pageIdstring (bpg_… ID)YesID (bpg_…)

Request body

application/json, required.

FieldTypeRequiredDescription
groupIdstring (grp_… ID)NoID (grp_…)
settingsBookingPageSettingsInputNo—
settings.assignmentobject | objectNoDefault: \{"mode":"round_robin","strategy":"equal"\}.
settings.assignment.modeconstantYes(variant 1) Always "round_robin".
settings.assignment.strategyenumNo(variant 1) One of: "equal", "most_available". Default: "equal".
settings.assignment.modeconstantYes(variant 2) Always "invitee_chooses".
settings.brandIdstring (brd_… ID) | nullNo—
settings.bufferAfterMinutesintegerNoBetween 0 and 120. Default: 0.
settings.bufferBeforeMinutesintegerNoBetween 0 and 120. Default: 0.
settings.colorstring | nullNoPattern: ^#[0-9a-f]\{6\}$.
settings.coverPhotostring (uri) | string (uri) | nullNo—
settings.dailyLimitinteger | nullNoBetween 1 and 50.
settings.descriptionstringNoUp to 1000 characters. Default: "".
settings.durationsarray<constant | constant | constant | constant>NoUp to 4 items. Default: [30].
settings.incrementconstant | constant | constant | constantNoDefault: 30.
settings.locationobject | object | object | object | objectNoDefault: \{"kind":"in_person"\}.
settings.location.kindconstantYes(variant 1) Always "in_person".
settings.location.kindconstantYes(variant 2) Always "phone_invitee".
settings.location.kindconstantYes(variant 3) Always "phone_rep".
settings.location.phonestringYes(variant 3) 7–32 characters.
settings.location.kindconstantYes(variant 4) Always "video".
settings.location.urlstring (uri)Yes(variant 4) A https:// link Up to 2000 characters.
settings.location.kindconstantYes(variant 5) Always "custom".
settings.location.textstringYes(variant 5) 1–200 characters.
settings.meetingTypestring | nullNoUp to 64 characters.
settings.minNoticeMinutesintegerNoBetween 0 and 43200. Default: 240.
settings.pageHoursarray<object> | nullNoUp to 50 items.
settings.pageHours[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
settings.pageHours[].endstring | constantYes—
settings.pageHours[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
settings.preferLeadRepbooleanNoDefault: true.
settings.questionsarray<object>NoUp to 10 items. Default: [].
settings.questions[].fieldKeystringNo1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
settings.questions[].idstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
settings.questions[].kindenumYesOne of: "short_text", "long_text", "single_choice", "multiple_choice", "yes_no", "date".
settings.questions[].labelstringYes1–200 characters.
settings.questions[].optionsarray<string>NoUp to 20 items.
settings.questions[].requiredbooleanNoDefault: false.
settings.redirectUrlstring (uri) | nullNoUp to 2000 characters.
settings.reminderDayBeforebooleanNoDefault: true.
settings.reminderTwoHoursbooleanNoDefault: true.
settings.requireEmailbooleanNoDefault: true.
settings.requirePhonebooleanNoDefault: true.
settings.scheduleIdstring | nullNoUp to 40 characters.
settings.serviceobject | object | objectNoDefault: \{"kind":"none"\}.
settings.service.kindconstantYes(variant 1) Always "none".
settings.service.kindconstantYes(variant 2) Always "fixed".
settings.service.serviceIdstring (srv_… ID)Yes(variant 2) ID (srv_…)
settings.service.kindconstantYes(variant 3) Always "ask".
settings.serviceCoverPhotobooleanNoDefault: false.
settings.titlestringYes1–80 characters.
settings.windowobject | objectNoDefault: \{"days":30,"kind":"rolling"\}.
settings.window.daysintegerYes(variant 1) Between 1 and 365.
settings.window.kindconstantYes(variant 1) Always "rolling".
settings.window.fromstring (date)Yes(variant 2)
settings.window.kindconstantYes(variant 2) Always "range".
settings.window.tostring (date)Yes(variant 2)
slugstringNo2–60 characters. Pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$.

Response 200

FieldTypeRequiredDescription
pageBookingPageSummaryYes—
page.bookingsThisMonthintegerYes—
page.groupIdstring (grp_… ID)YesID (grp_…)
page.groupNamestringYes—
page.idstring (bpg_… ID)YesID (bpg_…)
page.pausedByenum | nullYesOne of: "owner", "admin".
page.settingsBookingPageSettingsYes—
page.settings.assignmentobject | objectYesDefault: \{"mode":"round_robin","strategy":"equal"\}.
page.settings.assignment.modeconstantYes(variant 1) Always "round_robin".
page.settings.assignment.strategyenumYes(variant 1) One of: "equal", "most_available". Default: "equal".
page.settings.assignment.modeconstantYes(variant 2) Always "invitee_chooses".
page.settings.brandIdstring (brd_… ID) | nullYes—
page.settings.bufferAfterMinutesintegerYesBetween 0 and 120. Default: 0.
page.settings.bufferBeforeMinutesintegerYesBetween 0 and 120. Default: 0.
page.settings.colorstring | nullYesPattern: ^#[0-9a-f]\{6\}$.
page.settings.coverPhotostring (uri) | string (uri) | nullYes—
page.settings.dailyLimitinteger | nullYesBetween 1 and 50.
page.settings.descriptionstringYesUp to 1000 characters. Default: "".
page.settings.durationsarray<constant | constant | constant | constant>YesUp to 4 items. Default: [30].
page.settings.incrementconstant | constant | constant | constantYesDefault: 30.
page.settings.locationobject | object | object | object | objectYesDefault: \{"kind":"in_person"\}.
page.settings.location.kindconstantYes(variant 1) Always "in_person".
page.settings.location.kindconstantYes(variant 2) Always "phone_invitee".
page.settings.location.kindconstantYes(variant 3) Always "phone_rep".
page.settings.location.phonestringYes(variant 3) 7–32 characters.
page.settings.location.kindconstantYes(variant 4) Always "video".
page.settings.location.urlstring (uri)Yes(variant 4) A https:// link Up to 2000 characters.
page.settings.location.kindconstantYes(variant 5) Always "custom".
page.settings.location.textstringYes(variant 5) 1–200 characters.
page.settings.meetingTypestring | nullYesUp to 64 characters.
page.settings.minNoticeMinutesintegerYesBetween 0 and 43200. Default: 240.
page.settings.pageHoursarray<object> | nullYesUp to 50 items.
page.settings.pageHours[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
page.settings.pageHours[].endstring | constantYes—
page.settings.pageHours[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
page.settings.preferLeadRepbooleanYesDefault: true.
page.settings.questionsarray<object>YesUp to 10 items. Default: [].
page.settings.questions[].fieldKeystringNo1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
page.settings.questions[].idstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
page.settings.questions[].kindenumYesOne of: "short_text", "long_text", "single_choice", "multiple_choice", "yes_no", "date".
page.settings.questions[].labelstringYes1–200 characters.
page.settings.questions[].optionsarray<string>NoUp to 20 items.
page.settings.questions[].requiredbooleanYesDefault: false.
page.settings.redirectUrlstring (uri) | nullYesUp to 2000 characters.
page.settings.reminderDayBeforebooleanYesDefault: true.
page.settings.reminderTwoHoursbooleanYesDefault: true.
page.settings.requireEmailbooleanYesDefault: true.
page.settings.requirePhonebooleanYesDefault: true.
page.settings.scheduleIdstring | nullYesUp to 40 characters.
page.settings.serviceobject | object | objectYesDefault: \{"kind":"none"\}.
page.settings.service.kindconstantYes(variant 1) Always "none".
page.settings.service.kindconstantYes(variant 2) Always "fixed".
page.settings.service.serviceIdstring (srv_… ID)Yes(variant 2) ID (srv_…)
page.settings.service.kindconstantYes(variant 3) Always "ask".
page.settings.serviceCoverPhotobooleanYesDefault: false.
page.settings.titlestringYes1–80 characters.
page.settings.windowobject | objectYesDefault: \{"days":30,"kind":"rolling"\}.
page.settings.window.daysintegerYes(variant 1) Between 1 and 365.
page.settings.window.kindconstantYes(variant 1) Always "rolling".
page.settings.window.fromstring (date)Yes(variant 2)
page.settings.window.kindconstantYes(variant 2) Always "range".
page.settings.window.tostring (date)Yes(variant 2)
page.slugstringYes—
page.statusenumYesOne of: "active", "paused", "archived".
page.updatedAtstring (date-time)Yes—
page.urlstring | nullYes—

Errors: 400, 401, 402, 403, 404, 409, 422, 429, 500, with an ErrorBody body.

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/me/booking-pages/{pageId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "groupId": "grp_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE",
  "settings": {
    "title": "string"
  },
  "slug": "string"
}'

Remove one of my pages. One with meetings is archived, so they keep their history#

DELETE /v1/me/booking-pages/{pageId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
pageIdstring (bpg_… ID)YesID (bpg_…)

Response 204

No content.

Errors: 400, 401, 402, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/booking-pages/{pageId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Stop taking bookings on one of my pages; meetings already booked stay#

POST /v1/me/booking-pages/{pageId}/pause

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
pageIdstring (bpg_… ID)YesID (bpg_…)

Response 200

FieldTypeRequiredDescription
pageBookingPageSummaryYes—
page.bookingsThisMonthintegerYes—
page.groupIdstring (grp_… ID)YesID (grp_…)
page.groupNamestringYes—
page.idstring (bpg_… ID)YesID (bpg_…)
page.pausedByenum | nullYesOne of: "owner", "admin".
page.settingsBookingPageSettingsYes—
page.settings.assignmentobject | objectYesDefault: \{"mode":"round_robin","strategy":"equal"\}.
page.settings.assignment.modeconstantYes(variant 1) Always "round_robin".
page.settings.assignment.strategyenumYes(variant 1) One of: "equal", "most_available". Default: "equal".
page.settings.assignment.modeconstantYes(variant 2) Always "invitee_chooses".
page.settings.brandIdstring (brd_… ID) | nullYes—
page.settings.bufferAfterMinutesintegerYesBetween 0 and 120. Default: 0.
page.settings.bufferBeforeMinutesintegerYesBetween 0 and 120. Default: 0.
page.settings.colorstring | nullYesPattern: ^#[0-9a-f]\{6\}$.
page.settings.coverPhotostring (uri) | string (uri) | nullYes—
page.settings.dailyLimitinteger | nullYesBetween 1 and 50.
page.settings.descriptionstringYesUp to 1000 characters. Default: "".
page.settings.durationsarray<constant | constant | constant | constant>YesUp to 4 items. Default: [30].
page.settings.incrementconstant | constant | constant | constantYesDefault: 30.
page.settings.locationobject | object | object | object | objectYesDefault: \{"kind":"in_person"\}.
page.settings.location.kindconstantYes(variant 1) Always "in_person".
page.settings.location.kindconstantYes(variant 2) Always "phone_invitee".
page.settings.location.kindconstantYes(variant 3) Always "phone_rep".
page.settings.location.phonestringYes(variant 3) 7–32 characters.
page.settings.location.kindconstantYes(variant 4) Always "video".
page.settings.location.urlstring (uri)Yes(variant 4) A https:// link Up to 2000 characters.
page.settings.location.kindconstantYes(variant 5) Always "custom".
page.settings.location.textstringYes(variant 5) 1–200 characters.
page.settings.meetingTypestring | nullYesUp to 64 characters.
page.settings.minNoticeMinutesintegerYesBetween 0 and 43200. Default: 240.
page.settings.pageHoursarray<object> | nullYesUp to 50 items.
page.settings.pageHours[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
page.settings.pageHours[].endstring | constantYes—
page.settings.pageHours[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
page.settings.preferLeadRepbooleanYesDefault: true.
page.settings.questionsarray<object>YesUp to 10 items. Default: [].
page.settings.questions[].fieldKeystringNo1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
page.settings.questions[].idstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
page.settings.questions[].kindenumYesOne of: "short_text", "long_text", "single_choice", "multiple_choice", "yes_no", "date".
page.settings.questions[].labelstringYes1–200 characters.
page.settings.questions[].optionsarray<string>NoUp to 20 items.
page.settings.questions[].requiredbooleanYesDefault: false.
page.settings.redirectUrlstring (uri) | nullYesUp to 2000 characters.
page.settings.reminderDayBeforebooleanYesDefault: true.
page.settings.reminderTwoHoursbooleanYesDefault: true.
page.settings.requireEmailbooleanYesDefault: true.
page.settings.requirePhonebooleanYesDefault: true.
page.settings.scheduleIdstring | nullYesUp to 40 characters.
page.settings.serviceobject | object | objectYesDefault: \{"kind":"none"\}.
page.settings.service.kindconstantYes(variant 1) Always "none".
page.settings.service.kindconstantYes(variant 2) Always "fixed".
page.settings.service.serviceIdstring (srv_… ID)Yes(variant 2) ID (srv_…)
page.settings.service.kindconstantYes(variant 3) Always "ask".
page.settings.serviceCoverPhotobooleanYesDefault: false.
page.settings.titlestringYes1–80 characters.
page.settings.windowobject | objectYesDefault: \{"days":30,"kind":"rolling"\}.
page.settings.window.daysintegerYes(variant 1) Between 1 and 365.
page.settings.window.kindconstantYes(variant 1) Always "rolling".
page.settings.window.fromstring (date)Yes(variant 2)
page.settings.window.kindconstantYes(variant 2) Always "range".
page.settings.window.tostring (date)Yes(variant 2)
page.slugstringYes—
page.statusenumYesOne of: "active", "paused", "archived".
page.updatedAtstring (date-time)Yes—
page.urlstring | nullYes—

Errors: 400, 401, 402, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/booking-pages/{pageId}/pause" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Take bookings on one of my pages again, unless an admin paused it#

POST /v1/me/booking-pages/{pageId}/resume

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
pageIdstring (bpg_… ID)YesID (bpg_…)

Response 200

FieldTypeRequiredDescription
pageBookingPageSummaryYes—
page.bookingsThisMonthintegerYes—
page.groupIdstring (grp_… ID)YesID (grp_…)
page.groupNamestringYes—
page.idstring (bpg_… ID)YesID (bpg_…)
page.pausedByenum | nullYesOne of: "owner", "admin".
page.settingsBookingPageSettingsYes—
page.settings.assignmentobject | objectYesDefault: \{"mode":"round_robin","strategy":"equal"\}.
page.settings.assignment.modeconstantYes(variant 1) Always "round_robin".
page.settings.assignment.strategyenumYes(variant 1) One of: "equal", "most_available". Default: "equal".
page.settings.assignment.modeconstantYes(variant 2) Always "invitee_chooses".
page.settings.brandIdstring (brd_… ID) | nullYes—
page.settings.bufferAfterMinutesintegerYesBetween 0 and 120. Default: 0.
page.settings.bufferBeforeMinutesintegerYesBetween 0 and 120. Default: 0.
page.settings.colorstring | nullYesPattern: ^#[0-9a-f]\{6\}$.
page.settings.coverPhotostring (uri) | string (uri) | nullYes—
page.settings.dailyLimitinteger | nullYesBetween 1 and 50.
page.settings.descriptionstringYesUp to 1000 characters. Default: "".
page.settings.durationsarray<constant | constant | constant | constant>YesUp to 4 items. Default: [30].
page.settings.incrementconstant | constant | constant | constantYesDefault: 30.
page.settings.locationobject | object | object | object | objectYesDefault: \{"kind":"in_person"\}.
page.settings.location.kindconstantYes(variant 1) Always "in_person".
page.settings.location.kindconstantYes(variant 2) Always "phone_invitee".
page.settings.location.kindconstantYes(variant 3) Always "phone_rep".
page.settings.location.phonestringYes(variant 3) 7–32 characters.
page.settings.location.kindconstantYes(variant 4) Always "video".
page.settings.location.urlstring (uri)Yes(variant 4) A https:// link Up to 2000 characters.
page.settings.location.kindconstantYes(variant 5) Always "custom".
page.settings.location.textstringYes(variant 5) 1–200 characters.
page.settings.meetingTypestring | nullYesUp to 64 characters.
page.settings.minNoticeMinutesintegerYesBetween 0 and 43200. Default: 240.
page.settings.pageHoursarray<object> | nullYesUp to 50 items.
page.settings.pageHours[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
page.settings.pageHours[].endstring | constantYes—
page.settings.pageHours[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
page.settings.preferLeadRepbooleanYesDefault: true.
page.settings.questionsarray<object>YesUp to 10 items. Default: [].
page.settings.questions[].fieldKeystringNo1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
page.settings.questions[].idstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
page.settings.questions[].kindenumYesOne of: "short_text", "long_text", "single_choice", "multiple_choice", "yes_no", "date".
page.settings.questions[].labelstringYes1–200 characters.
page.settings.questions[].optionsarray<string>NoUp to 20 items.
page.settings.questions[].requiredbooleanYesDefault: false.
page.settings.redirectUrlstring (uri) | nullYesUp to 2000 characters.
page.settings.reminderDayBeforebooleanYesDefault: true.
page.settings.reminderTwoHoursbooleanYesDefault: true.
page.settings.requireEmailbooleanYesDefault: true.
page.settings.requirePhonebooleanYesDefault: true.
page.settings.scheduleIdstring | nullYesUp to 40 characters.
page.settings.serviceobject | object | objectYesDefault: \{"kind":"none"\}.
page.settings.service.kindconstantYes(variant 1) Always "none".
page.settings.service.kindconstantYes(variant 2) Always "fixed".
page.settings.service.serviceIdstring (srv_… ID)Yes(variant 2) ID (srv_…)
page.settings.service.kindconstantYes(variant 3) Always "ask".
page.settings.serviceCoverPhotobooleanYesDefault: false.
page.settings.titlestringYes1–80 characters.
page.settings.windowobject | objectYesDefault: \{"days":30,"kind":"rolling"\}.
page.settings.window.daysintegerYes(variant 1) Between 1 and 365.
page.settings.window.kindconstantYes(variant 1) Always "rolling".
page.settings.window.fromstring (date)Yes(variant 2)
page.settings.window.kindconstantYes(variant 2) Always "range".
page.settings.window.tostring (date)Yes(variant 2)
page.slugstringYes—
page.statusenumYesOne of: "active", "paused", "archived".
page.updatedAtstring (date-time)Yes—
page.urlstring | nullYes—

Errors: 400, 401, 402, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/booking-pages/{pageId}/resume" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

My own calendar, where the tours I am assigned are booked, and how I can connect one#

GET /v1/me/calendar

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
calendarany | nullYes—
matchEmailstring | nullYes—
providersarray<object>Yes—
providers[].displayNamestringYes—
providers[].keystringYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/calendar" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Disconnect my calendar: no more tours are booked on it#

DELETE /v1/me/calendar

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
disconnectedenumYesOne of: true.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/calendar" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Finish connecting my own calendar, with the token the sign-in callback handed the browser. Only the person who started it can (ADR 0111)#

POST /v1/me/calendar/confirm

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
confirmstringYes20–200 characters.

Response 200

FieldTypeRequiredDescription
connectionstringNo—
reasonenumNoOne of: "unauthorized", "forbidden", "not_found", "rate_limited", "unavailable", "timeout", "misconfigured", "missing_permissions", "calendar_not_found", "calendar_read_only", "personal_account", "mailbox_access_denied", "failed".
resultenumYesOne of: "ok", "denied", "expired", "missing_scopes", "failed", "error", "wrong_user".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/calendar/confirm" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "confirm": "string"
}'

Start signing in with Google or Microsoft to connect my own calendar#

POST /v1/me/calendar/connect

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
providerstringYesPattern: ^[a-z][a-z0-9_]\{1,40\}$.

Response 200

FieldTypeRequiredDescription
authorizationUrlstringYes—
expiresInSecondsintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/calendar/connect" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "provider": "string"
}'

The CRMs I can use as my calendar, and my CRM user at my primary group#

GET /v1/me/calendar/crm

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
crmUserIdstring | nullYes—
optionsarray<object>Yes—
options[].connectionIdstring (conn_… ID)YesID (conn_…)
options[].namestringYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/calendar/crm" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Keep my meetings in the CRM instead of my own calendar (disconnects my own calendar)#

PUT /v1/me/calendar/crm

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
connectionIdstring (conn_… ID)YesID (conn_…)

Response 200

FieldTypeRequiredDescription
providerenumYesOne of: "crm".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/me/calendar/crm" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "connectionId": "conn_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
}'

Check that my calendar still works, and record the result#

POST /v1/me/calendar/test

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
calendarMyCalendarYes—
calendar.accountEmailstring | nullYes—
calendar.connectedAtstring (date-time)Yes—
calendar.lastCheckedAtstring (date-time) | nullYes—
calendar.lastErrorstring | nullYes—
calendar.providerstringYes—
calendar.statusenumYesOne of: "connected", "error", "pending".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/calendar/test" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

The phone a transfer to me rings#

GET /v1/me/direct-phone

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
directPhonestring | nullYesPattern: ^\+[1-9]\d\{6,14\}$.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/direct-phone" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Set or clear the phone a transfer to me rings#

PUT /v1/me/direct-phone

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
directPhonestring | nullYesPattern: ^\+[1-9]\d\{6,14\}$.

Response 200

FieldTypeRequiredDescription
directPhonestring | nullYesPattern: ^\+[1-9]\d\{6,14\}$.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/me/direct-phone" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "directPhone": "string"
}'

The calls handed to me: live ones first, then the last 30 days#

GET /v1/me/handoffs

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Query parameters

NameTypeRequiredDescription
limitintegerNoBetween 1 and 100. Default: 50.

Response 200

FieldTypeRequiredDescription
handoffsarray<HandoffSummary>Yes—
handoffs[].callIdstring (call_… ID)YesID (call_…)
handoffs[].callerNamestring | nullYes—
handoffs[].callerNumberstring | nullYes—
handoffs[].endedAtstring (date-time) | nullYes—
handoffs[].fromRingStepbooleanYes—
handoffs[].groupIdstring (grp_… ID)YesID (grp_…)
handoffs[].groupNamestringYes—
handoffs[].handoffReasonenum | nullYesOne of: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency".
handoffs[].isTestbooleanYes—
handoffs[].startedAtstring (date-time)Yes—
handoffs[].stateenumYesOne of: "live", "ended".
handoffs[].transferredAtstring (date-time) | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/handoffs" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

A call handed to me: the caller, why, what the agent learned, the questions and answers, the notes and the words (logs call.view)#

GET /v1/me/handoffs/{callId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token). Bearer token: Authorization: Bearer <token> (An API token (ans_pat_ or ans_svc_). Only routes that list a scope here accept one, and only with that scope.).

Path parameters

NameTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)

Query parameters

NameTypeRequiredDescription
turnsenumNoOne of: "all", "none". Default: "all".

Response 200

FieldTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)
callerNamestring | nullYes—
callerNumberstring | nullYes—
endedAtstring (date-time) | nullYes—
fromRingStepbooleanYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
handoffReasonenum | nullYesOne of: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency".
isTestbooleanYes—
linesarray<HandoffLine>Yes—
lines[].idstringYes—
lines[].namestringYes—
lines[].questionsarray<HandoffQuestion>Yes—
lines[].questions[].keystringYes—
lines[].questions[].labelstringYes—
lines[].questions[].optionsarray<object>Yes—
lines[].questions[].options[].labelstringYes—
lines[].questions[].options[].valuestringYes—
lines[].questions[].requiredbooleanYes—
lines[].questions[].sensitivityenumYesOne of: "standard", "sensitive".
lines[].questions[].sourceenum | nullYesOne of: "agent", "heard", "rep".
lines[].questions[].statusenum | nullYesOne of: "confirmed", "provisional".
lines[].questions[].suggestedany | nullYes—
lines[].questions[].typeenumYesOne of: "text", "number", "enum", "boolean", "date", "phone", "email".
lines[].questions[].valueany | nullYes—
lines[].questions[].versioninteger | nullYes—
lines[].questions[].withheldbooleanYes—
lines[].usedbooleanYes—
liveHandoffLiveYes—
live.canEditbooleanYes—
live.crmobjectYes—
live.crm.heldbooleanYes—
live.crm.sentbooleanYes—
live.crm.updatesintegerYes—
live.minebooleanYes—
live.notesobject | nullYes—
live.notes.bodystringYes—
live.notes.versionintegerYes—
live.openbooleanYes—
live.stateenum | nullYesOne of: "connected", "ended", "done".
live.textobjectYes—
live.text.availablebooleanYes—
live.text.sentAtstring (date-time) | nullYes—
live.versionintegerYes—
notetakerHandoffNotetakerYes—
notetaker.offReasonstring | nullYes—
notetaker.statusenum | nullYesOne of: "listening", "finished", "unavailable".
otherAnswersarray<object>Yes—
otherAnswers[].keystringYes—
otherAnswers[].valueany | nullYes—
startedAtstring (date-time)Yes—
stateenumYesOne of: "live", "ended".
summarystring | nullYes—
transcriptStoredbooleanYes—
transferredAtstring (date-time) | nullYes—
turnsarray<HandoffTurn>Yes—
turns[].atstring (date-time) | nullYes—
turns[].seqintegerYes—
turns[].speakerenumYesOne of: "agent", "caller", "rep".
turns[].textstringYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/handoffs/{callId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

I am done with the notes: once the call has ended, the CRM log goes now with them (or, after it went, one update)#

POST /v1/me/handoffs/{callId}/done

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)

Response 200

FieldTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)
callerNamestring | nullYes—
callerNumberstring | nullYes—
endedAtstring (date-time) | nullYes—
fromRingStepbooleanYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
handoffReasonenum | nullYesOne of: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency".
isTestbooleanYes—
linesarray<HandoffLine>Yes—
lines[].idstringYes—
lines[].namestringYes—
lines[].questionsarray<HandoffQuestion>Yes—
lines[].questions[].keystringYes—
lines[].questions[].labelstringYes—
lines[].questions[].optionsarray<object>Yes—
lines[].questions[].options[].labelstringYes—
lines[].questions[].options[].valuestringYes—
lines[].questions[].requiredbooleanYes—
lines[].questions[].sensitivityenumYesOne of: "standard", "sensitive".
lines[].questions[].sourceenum | nullYesOne of: "agent", "heard", "rep".
lines[].questions[].statusenum | nullYesOne of: "confirmed", "provisional".
lines[].questions[].suggestedany | nullYes—
lines[].questions[].typeenumYesOne of: "text", "number", "enum", "boolean", "date", "phone", "email".
lines[].questions[].valueany | nullYes—
lines[].questions[].versioninteger | nullYes—
lines[].questions[].withheldbooleanYes—
lines[].usedbooleanYes—
liveHandoffLiveYes—
live.canEditbooleanYes—
live.crmobjectYes—
live.crm.heldbooleanYes—
live.crm.sentbooleanYes—
live.crm.updatesintegerYes—
live.minebooleanYes—
live.notesobject | nullYes—
live.notes.bodystringYes—
live.notes.versionintegerYes—
live.openbooleanYes—
live.stateenum | nullYesOne of: "connected", "ended", "done".
live.textobjectYes—
live.text.availablebooleanYes—
live.text.sentAtstring (date-time) | nullYes—
live.versionintegerYes—
notetakerHandoffNotetakerYes—
notetaker.offReasonstring | nullYes—
notetaker.statusenum | nullYesOne of: "listening", "finished", "unavailable".
otherAnswersarray<object>Yes—
otherAnswers[].keystringYes—
otherAnswers[].valueany | nullYes—
startedAtstring (date-time)Yes—
stateenumYesOne of: "live", "ended".
summarystring | nullYes—
transcriptStoredbooleanYes—
transferredAtstring (date-time) | nullYes—
turnsarray<HandoffTurn>Yes—
turns[].atstring (date-time) | nullYes—
turns[].seqintegerYes—
turns[].speakerenumYesOne of: "agent", "caller", "rep".
turns[].textstringYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/handoffs/{callId}/done" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Set, confirm or clear one answer on a call handed to me. Send the answer's version as read (null when there was none); a stale one is refused with 409#

PATCH /v1/me/handoffs/{callId}/fields/{fieldKey}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)
fieldKeystringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.

Request body

application/json, required.

FieldTypeRequiredDescription
valuestring | number | boolean | nullYes—
versioninteger | nullYesMinimum 1.

Response 200

FieldTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)
callerNamestring | nullYes—
callerNumberstring | nullYes—
endedAtstring (date-time) | nullYes—
fromRingStepbooleanYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
handoffReasonenum | nullYesOne of: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency".
isTestbooleanYes—
linesarray<HandoffLine>Yes—
lines[].idstringYes—
lines[].namestringYes—
lines[].questionsarray<HandoffQuestion>Yes—
lines[].questions[].keystringYes—
lines[].questions[].labelstringYes—
lines[].questions[].optionsarray<object>Yes—
lines[].questions[].options[].labelstringYes—
lines[].questions[].options[].valuestringYes—
lines[].questions[].requiredbooleanYes—
lines[].questions[].sensitivityenumYesOne of: "standard", "sensitive".
lines[].questions[].sourceenum | nullYesOne of: "agent", "heard", "rep".
lines[].questions[].statusenum | nullYesOne of: "confirmed", "provisional".
lines[].questions[].suggestedany | nullYes—
lines[].questions[].typeenumYesOne of: "text", "number", "enum", "boolean", "date", "phone", "email".
lines[].questions[].valueany | nullYes—
lines[].questions[].versioninteger | nullYes—
lines[].questions[].withheldbooleanYes—
lines[].usedbooleanYes—
liveHandoffLiveYes—
live.canEditbooleanYes—
live.crmobjectYes—
live.crm.heldbooleanYes—
live.crm.sentbooleanYes—
live.crm.updatesintegerYes—
live.minebooleanYes—
live.notesobject | nullYes—
live.notes.bodystringYes—
live.notes.versionintegerYes—
live.openbooleanYes—
live.stateenum | nullYesOne of: "connected", "ended", "done".
live.textobjectYes—
live.text.availablebooleanYes—
live.text.sentAtstring (date-time) | nullYes—
live.versionintegerYes—
notetakerHandoffNotetakerYes—
notetaker.offReasonstring | nullYes—
notetaker.statusenum | nullYesOne of: "listening", "finished", "unavailable".
otherAnswersarray<object>Yes—
otherAnswers[].keystringYes—
otherAnswers[].valueany | nullYes—
startedAtstring (date-time)Yes—
stateenumYesOne of: "live", "ended".
summarystring | nullYes—
transcriptStoredbooleanYes—
transferredAtstring (date-time) | nullYes—
turnsarray<HandoffTurn>Yes—
turns[].atstring (date-time) | nullYes—
turns[].seqintegerYes—
turns[].speakerenumYesOne of: "agent", "caller", "rep".
turns[].textstringYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/me/handoffs/{callId}/fields/{fieldKey}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "value": "string",
  "version": 1
}'

Take the listener's suggestion as the answer, or leave it#

POST /v1/me/handoffs/{callId}/fields/{fieldKey}/suggestion

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)
fieldKeystringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.

Request body

application/json, required.

FieldTypeRequiredDescription
actionenumYesOne of: "accept", "dismiss".
versionintegerYesMinimum 1.

Response 200

FieldTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)
callerNamestring | nullYes—
callerNumberstring | nullYes—
endedAtstring (date-time) | nullYes—
fromRingStepbooleanYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
handoffReasonenum | nullYesOne of: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency".
isTestbooleanYes—
linesarray<HandoffLine>Yes—
lines[].idstringYes—
lines[].namestringYes—
lines[].questionsarray<HandoffQuestion>Yes—
lines[].questions[].keystringYes—
lines[].questions[].labelstringYes—
lines[].questions[].optionsarray<object>Yes—
lines[].questions[].options[].labelstringYes—
lines[].questions[].options[].valuestringYes—
lines[].questions[].requiredbooleanYes—
lines[].questions[].sensitivityenumYesOne of: "standard", "sensitive".
lines[].questions[].sourceenum | nullYesOne of: "agent", "heard", "rep".
lines[].questions[].statusenum | nullYesOne of: "confirmed", "provisional".
lines[].questions[].suggestedany | nullYes—
lines[].questions[].typeenumYesOne of: "text", "number", "enum", "boolean", "date", "phone", "email".
lines[].questions[].valueany | nullYes—
lines[].questions[].versioninteger | nullYes—
lines[].questions[].withheldbooleanYes—
lines[].usedbooleanYes—
liveHandoffLiveYes—
live.canEditbooleanYes—
live.crmobjectYes—
live.crm.heldbooleanYes—
live.crm.sentbooleanYes—
live.crm.updatesintegerYes—
live.minebooleanYes—
live.notesobject | nullYes—
live.notes.bodystringYes—
live.notes.versionintegerYes—
live.openbooleanYes—
live.stateenum | nullYesOne of: "connected", "ended", "done".
live.textobjectYes—
live.text.availablebooleanYes—
live.text.sentAtstring (date-time) | nullYes—
live.versionintegerYes—
notetakerHandoffNotetakerYes—
notetaker.offReasonstring | nullYes—
notetaker.statusenum | nullYesOne of: "listening", "finished", "unavailable".
otherAnswersarray<object>Yes—
otherAnswers[].keystringYes—
otherAnswers[].valueany | nullYes—
startedAtstring (date-time)Yes—
stateenumYesOne of: "live", "ended".
summarystring | nullYes—
transcriptStoredbooleanYes—
transferredAtstring (date-time) | nullYes—
turnsarray<HandoffTurn>Yes—
turns[].atstring (date-time) | nullYes—
turns[].seqintegerYes—
turns[].speakerenumYesOne of: "agent", "caller", "rep".
turns[].textstringYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/handoffs/{callId}/fields/{fieldKey}/suggestion" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "action": "accept",
  "version": 1
}'

My notes page is open: the call's CRM log waits for my Done instead of going as soon as the call ends#

POST /v1/me/handoffs/{callId}/heartbeat

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)

Response 204

No content.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/handoffs/{callId}/heartbeat" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Save the notes on a call handed to me (the Markdown subset with checklists). Send the version as read (null for the first save); a stale one is refused with 409#

PUT /v1/me/handoffs/{callId}/notes

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)

Request body

application/json, required.

FieldTypeRequiredDescription
bodystringYesUp to 40000 characters.
versioninteger | nullYesMinimum 1.

Response 200

FieldTypeRequiredDescription
bodystringYes—
versionintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/me/handoffs/{callId}/notes" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "body": "string",
  "version": 1
}'

POST /v1/me/handoffs/{callId}/text-link

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

NameTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)

application/json, required.

Type: object

FieldTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)
callerNamestring | nullYes—
callerNumberstring | nullYes—
endedAtstring (date-time) | nullYes—
fromRingStepbooleanYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
handoffReasonenum | nullYesOne of: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency".
isTestbooleanYes—
linesarray<HandoffLine>Yes—
lines[].idstringYes—
lines[].namestringYes—
lines[].questionsarray<HandoffQuestion>Yes—
lines[].questions[].keystringYes—
lines[].questions[].labelstringYes—
lines[].questions[].optionsarray<object>Yes—
lines[].questions[].options[].labelstringYes—
lines[].questions[].options[].valuestringYes—
lines[].questions[].requiredbooleanYes—
lines[].questions[].sensitivityenumYesOne of: "standard", "sensitive".
lines[].questions[].sourceenum | nullYesOne of: "agent", "heard", "rep".
lines[].questions[].statusenum | nullYesOne of: "confirmed", "provisional".
lines[].questions[].suggestedany | nullYes—
lines[].questions[].typeenumYesOne of: "text", "number", "enum", "boolean", "date", "phone", "email".
lines[].questions[].valueany | nullYes—
lines[].questions[].versioninteger | nullYes—
lines[].questions[].withheldbooleanYes—
lines[].usedbooleanYes—
liveHandoffLiveYes—
live.canEditbooleanYes—
live.crmobjectYes—
live.crm.heldbooleanYes—
live.crm.sentbooleanYes—
live.crm.updatesintegerYes—
live.minebooleanYes—
live.notesobject | nullYes—
live.notes.bodystringYes—
live.notes.versionintegerYes—
live.openbooleanYes—
live.stateenum | nullYesOne of: "connected", "ended", "done".
live.textobjectYes—
live.text.availablebooleanYes—
live.text.sentAtstring (date-time) | nullYes—
live.versionintegerYes—
notetakerHandoffNotetakerYes—
notetaker.offReasonstring | nullYes—
notetaker.statusenum | nullYesOne of: "listening", "finished", "unavailable".
otherAnswersarray<object>Yes—
otherAnswers[].keystringYes—
otherAnswers[].valueany | nullYes—
startedAtstring (date-time)Yes—
stateenumYesOne of: "live", "ended".
summarystring | nullYes—
transcriptStoredbooleanYes—
transferredAtstring (date-time) | nullYes—
turnsarray<HandoffTurn>Yes—
turns[].atstring (date-time) | nullYes—
turns[].seqintegerYes—
turns[].speakerenumYesOne of: "agent", "caller", "rep".
turns[].textstringYes—

Errors: 400, 401, 403, 404, 409, 422, 429, 500, 502, with an ErrorBody body.

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/handoffs/{callId}/text-link" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

The lines of a call handed to me after the one the page already has, with the signal version they are at least as fresh as#

GET /v1/me/handoffs/{callId}/turns

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token). Bearer token: Authorization: Bearer <token> (An API token (ans_pat_ or ans_svc_). Only routes that list a scope here accept one, and only with that scope.).

Path parameters

NameTypeRequiredDescription
callIdstring (call_… ID)YesID (call_…)

Query parameters

NameTypeRequiredDescription
afterintegerNoMinimum -1. Default: -1.
limitintegerNoBetween 1 and 500. Default: 200.

Response 200

FieldTypeRequiredDescription
turnsarray<HandoffTurn>Yes—
turns[].atstring (date-time) | nullYes—
turns[].seqintegerYes—
turns[].speakerenumYesOne of: "agent", "caller", "rep".
turns[].textstringYes—
versionintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/handoffs/{callId}/turns" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

The meetings assigned to me: upcoming, past or cancelled#

GET /v1/me/meetings

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Query parameters

NameTypeRequiredDescription
statusenumNoOne of: "upcoming", "past", "cancelled". Default: "upcoming".
limitintegerNoBetween 1 and 200. Default: 100.

Response 200

FieldTypeRequiredDescription
meetingsarray<Meeting>Yes—
meetings[].cancelNotestring | nullYes—
meetings[].cancelledAtstring (date-time) | nullYes—
meetings[].cancelledByenum | nullYesOne of: "caller", "rep", "admin", "calendar".
meetings[].endstring (date-time) | nullYes—
meetings[].groupIdstring (grp_… ID)YesID (grp_…)
meetings[].groupNamestringYes—
meetings[].idstring (bkg_… ID)YesID (bkg_…)
meetings[].inviteeNamestring | nullYes—
meetings[].meetingTypestring | nullYes—
meetings[].outcomeenum | nullYesOne of: "attended", "no_show".
meetings[].pageTitlestring | nullYes—
meetings[].sourceenumYesOne of: "phone", "web_chat", "web_voice", "booking_page", "other".
meetings[].startstring (date-time)Yes—
meetings[].statusenumYesOne of: "upcoming", "past", "cancelled".
meetings[].timeZonestring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/meetings" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

One of my meetings: who is coming, how to reach them, and what they told us#

GET /v1/me/meetings/{bookingId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Response 200

FieldTypeRequiredDescription
meetingMeetingDetailYes—
meeting.answersmapYes—
meeting.answers.{key}anyNoAny key.
meeting.cancelNotestring | nullYes—
meeting.cancelledAtstring (date-time) | nullYes—
meeting.cancelledByenum | nullYesOne of: "caller", "rep", "admin", "calendar".
meeting.emailstring | nullYes—
meeting.endstring (date-time) | nullYes—
meeting.groupIdstring (grp_… ID)YesID (grp_…)
meeting.groupNamestringYes—
meeting.idstring (bkg_… ID)YesID (bkg_…)
meeting.inviteeNamestring | nullYes—
meeting.maskedFieldsarray<string>Yes—
meeting.meetingTypestring | nullYes—
meeting.outcomeenum | nullYesOne of: "attended", "no_show".
meeting.pageTitlestring | nullYes—
meeting.phonestring | nullYes—
meeting.sourceenumYesOne of: "phone", "web_chat", "web_voice", "booking_page", "other".
meeting.startstring (date-time)Yes—
meeting.statusenumYesOne of: "upcoming", "past", "cancelled".
meeting.summarystring | nullYes—
meeting.timeZonestring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

The visit brief for one of my meetings: who is coming, their timeline and interests, objections and answers, open commitments and talking points (logs call.view)#

GET /v1/me/meetings/{bookingId}/brief

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Response 200

FieldTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)
contentany | nullYes—
crmLoggedbooleanYes—
generatedAtstring (date-time) | nullYes—
notifiedAtstring (date-time) | nullYes—
recipientobject | nullYes—
recipient.namestring | nullYes—
recipient.sourceenumYesOne of: "rep", "booking_assignee", "human_backup", "editors", "staff".
recipient.userIdstring (usr_… ID) | nullYes—
stageenum | nullYesOne of: "booked", "day_before", "two_hours".
stateenumYesOne of: "ready", "pending", "cleared".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/brief" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Cancel one of my upcoming meetings, in the calendar and for the caller#

POST /v1/me/meetings/{bookingId}/cancel

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
meetingMeetingYes—
meeting.cancelNotestring | nullYes—
meeting.cancelledAtstring (date-time) | nullYes—
meeting.cancelledByenum | nullYesOne of: "caller", "rep", "admin", "calendar".
meeting.endstring (date-time) | nullYes—
meeting.groupIdstring (grp_… ID)YesID (grp_…)
meeting.groupNamestringYes—
meeting.idstring (bkg_… ID)YesID (bkg_…)
meeting.inviteeNamestring | nullYes—
meeting.meetingTypestring | nullYes—
meeting.outcomeenum | nullYesOne of: "attended", "no_show".
meeting.pageTitlestring | nullYes—
meeting.sourceenumYesOne of: "phone", "web_chat", "web_voice", "booking_page", "other".
meeting.startstring (date-time)Yes—
meeting.statusenumYesOne of: "upcoming", "past", "cancelled".
meeting.timeZonestring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, 502, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/cancel" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

Move one of my meetings to another of my free times; the caller is told#

POST /v1/me/meetings/{bookingId}/reschedule

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Request body

application/json, required.

FieldTypeRequiredDescription
startAtstring (date-time)Yes—

Response 200

FieldTypeRequiredDescription
meetingMeetingYes—
meeting.cancelNotestring | nullYes—
meeting.cancelledAtstring (date-time) | nullYes—
meeting.cancelledByenum | nullYesOne of: "caller", "rep", "admin", "calendar".
meeting.endstring (date-time) | nullYes—
meeting.groupIdstring (grp_… ID)YesID (grp_…)
meeting.groupNamestringYes—
meeting.idstring (bkg_… ID)YesID (bkg_…)
meeting.inviteeNamestring | nullYes—
meeting.meetingTypestring | nullYes—
meeting.outcomeenum | nullYesOne of: "attended", "no_show".
meeting.pageTitlestring | nullYes—
meeting.sourceenumYesOne of: "phone", "web_chat", "web_voice", "booking_page", "other".
meeting.startstring (date-time)Yes—
meeting.statusenumYesOne of: "upcoming", "past", "cancelled".
meeting.timeZonestring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, 502, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/reschedule" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "startAt": "2026-01-15T15:30:00Z"
}'

Times I could move one of my meetings to, from my own hours and calendar#

GET /v1/me/meetings/{bookingId}/times

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Response 200

FieldTypeRequiredDescription
timesarray<object>Yes—
times[].endstringYes—
times[].startstringYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/times" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

A visit I give, or one at a community I can see: its notes, newest first, and what I may do#

GET /v1/me/meetings/{bookingId}/visit

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Response 200

FieldTypeRequiredDescription
actionsarray<VisitAction>Yes—
actions[].actionKeystring | nullYes—
actions[].bookingIdstring (bkg_… ID)YesID (bkg_…)
actions[].canTakebooleanYes—
actions[].canUndobooleanYes—
actions[].canWorkbooleanYes—
actions[].closedAtstring (date-time) | nullYes—
actions[].closedInCrmbooleanYes—
actions[].createdAtstring (date-time)Yes—
actions[].crmTaskbooleanYes—
actions[].dismissReasonstring | nullYes—
actions[].dueAtstring (date-time)Yes—
actions[].idstring (vac_… ID)YesID (vac_…)
actions[].labelstringYes—
actions[].notestring | nullYes—
actions[].ownerobject | nullYes—
actions[].owner.namestringYes—
actions[].owner.userIdstring (usr_… ID)YesID (usr_…)
actions[].ownerSourceenumYesOne of: "rep", "backup", "member".
actions[].statusenumYesOne of: "open", "done", "dismissed".
actions[].versionintegerYes—
bookingIdstring (bkg_… ID)YesID (bkg_…)
canWritebooleanYes—
catalogVisitActionCatalogYes—
catalog.allowCustombooleanYes—
catalog.itemsarray<object>Yes—
catalog.items[].dueDaysintegerYes—
catalog.items[].keystringYes—
catalog.items[].labelstringYes—
catalog.items[].ownerenumYesOne of: "rep", "backup".
closesAtstring (date-time)Yes—
crmVisitCrmYes—
crm.blockedenum | nullYesOne of: "no_contact", "no_crm".
crm.changedSincebooleanYes—
crm.finishedAtstring (date-time) | nullYes—
crm.hasContentbooleanYes—
crm.sentAtstring (date-time) | nullYes—
crm.startedbooleanYes—
crm.updatesintegerYes—
movedTostring (bkg_… ID) | nullYes—
notesarray<VisitNote>Yes—
notes[].authorobjectYes—
notes[].author.namestringYes—
notes[].author.userIdstring (usr_… ID)YesID (usr_…)
notes[].bodystringYes—
notes[].canDeletebooleanYes—
notes[].canEditbooleanYes—
notes[].createdAtstring (date-time)Yes—
notes[].idstring (vnt_… ID)YesID (vnt_…)
notes[].minebooleanYes—
notes[].updatedAtstring (date-time)Yes—
notes[].versionintegerYes—
openbooleanYes—
pageVisitPageYes—
page.originenum | nullYesOne of: "call", "visit".
page.publishedAtstring (date-time) | nullYes—
page.showsPhotosbooleanYes—
page.stateenumYesOne of: "none", "live", "closed".
photoStateVisitPhotoStateYes—
photoState.blockedenum | nullYesOne of: "not_writer", "moved", "cancelled", "compliance", "too_early", "closed".
photoState.consentAtstring (date-time) | nullYes—
photoState.opensAtstring (date-time)Yes—
photosarray<VisitPhoto>Yes—
photos[].canDeletebooleanYes—
photos[].canEditbooleanYes—
photos[].captionstring | nullYes—
photos[].createdAtstring (date-time)Yes—
photos[].heightinteger | nullYes—
photos[].idstring (vph_… ID)YesID (vph_…)
photos[].largeUrlstring | nullYes—
photos[].minebooleanYes—
photos[].sharedbooleanYes—
photos[].sortintegerYes—
photos[].statusenumYesOne of: "uploading", "processing", "ready", "failed".
photos[].thumbUrlstring | nullYes—
photos[].uploadedByobjectYes—
photos[].uploadedBy.namestringYes—
photos[].uploadedBy.userIdstring (usr_… ID)YesID (usr_…)
photos[].widthinteger | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Add a next step to a visit: an item from the community’s list (actionKey), or one typed (label). The same clientKey again returns the first item#

POST /v1/me/meetings/{bookingId}/visit/actions

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Request body

application/json, required.

FieldTypeRequiredDescription
actionKeystringNoUp to 64 characters.
clientKeystringYesPattern: ^[A-Za-z0-9_-]\{16,64\}$.
dueDaystringNoPattern: ^\d\{4\}-\d\{2\}-\d\{2\}$.
labelstringNo1–80 characters.
notestringNoUp to 500 characters.
ownerUserIdstring (usr_… ID)NoID (usr_…)

Response 200

FieldTypeRequiredDescription
actionKeystring | nullYes—
bookingIdstring (bkg_… ID)YesID (bkg_…)
canTakebooleanYes—
canUndobooleanYes—
canWorkbooleanYes—
closedAtstring (date-time) | nullYes—
closedInCrmbooleanYes—
createdAtstring (date-time)Yes—
crmTaskbooleanYes—
dismissReasonstring | nullYes—
dueAtstring (date-time)Yes—
idstring (vac_… ID)YesID (vac_…)
labelstringYes—
notestring | nullYes—
ownerobject | nullYes—
owner.namestringYes—
owner.userIdstring (usr_… ID)YesID (usr_…)
ownerSourceenumYesOne of: "rep", "backup", "member".
statusenumYesOne of: "open", "done", "dismissed".
versionintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/actions" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "clientKey": "string"
}'

Send the visit’s notes and next steps to the CRM now, as one activity. After it went, sends one update with the visit as it now stands#

POST /v1/me/meetings/{bookingId}/visit/finish

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Response 200

FieldTypeRequiredDescription
blockedenum | nullYesOne of: "no_contact", "no_crm".
changedSincebooleanYes—
finishedAtstring (date-time) | nullYes—
hasContentbooleanYes—
sentAtstring (date-time) | nullYes—
startedbooleanYes—
updatesintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/finish" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Add a note to a visit (the Markdown subset with checklists). The same clientKey again returns the first note#

POST /v1/me/meetings/{bookingId}/visit/notes

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Request body

application/json, required.

FieldTypeRequiredDescription
bodystringYesUp to 20000 characters.
clientKeystringYesPattern: ^[A-Za-z0-9_-]\{16,64\}$.

Response 200

FieldTypeRequiredDescription
authorobjectYes—
author.namestringYes—
author.userIdstring (usr_… ID)YesID (usr_…)
bodystringYes—
canDeletebooleanYes—
canEditbooleanYes—
createdAtstring (date-time)Yes—
idstring (vnt_… ID)YesID (vnt_…)
minebooleanYes—
updatedAtstring (date-time)Yes—
versionintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/notes" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "clientKey": "string",
  "body": "string"
}'

Change one of my notes on a visit. Send the version as read; a stale one is refused with 409#

PATCH /v1/me/meetings/{bookingId}/visit/notes/{noteId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)
noteIdstring (vnt_… ID)YesID (vnt_…)

Request body

application/json, required.

FieldTypeRequiredDescription
bodystringYesUp to 20000 characters.
versionintegerYesMinimum 1.

Response 200

FieldTypeRequiredDescription
authorobjectYes—
author.namestringYes—
author.userIdstring (usr_… ID)YesID (usr_…)
bodystringYes—
canDeletebooleanYes—
canEditbooleanYes—
createdAtstring (date-time)Yes—
idstring (vnt_… ID)YesID (vnt_…)
minebooleanYes—
updatedAtstring (date-time)Yes—
versionintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/notes/{noteId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "body": "string",
  "version": 1
}'

Remove a note from a visit: my own while the visit takes notes, or anyone’s at a community I manage#

DELETE /v1/me/meetings/{bookingId}/visit/notes/{noteId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)
noteIdstring (vnt_… ID)YesID (vnt_…)

Response 204

No content.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/notes/{noteId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Confirm the family agreed to have photos taken and shared with them, including on links they forward#

POST /v1/me/meetings/{bookingId}/visit/photo-consent

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Response 200

FieldTypeRequiredDescription
consentAtstring (date-time)Yes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/photo-consent" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Start adding a photo: returns the photo and a one-time link to PUT its bytes to (null when they are already there). The same clientKey again returns the same photo#

POST /v1/me/meetings/{bookingId}/visit/photos

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Request body

application/json, required.

FieldTypeRequiredDescription
bytesintegerYesBetween 1 and 15728640.
clientKeystringYesPattern: ^[A-Za-z0-9_-]\{16,64\}$.
contentTypeenumYesOne of: "image/jpeg", "image/png", "image/webp".

Response 200

FieldTypeRequiredDescription
photoVisitPhotoYes—
photo.canDeletebooleanYes—
photo.canEditbooleanYes—
photo.captionstring | nullYes—
photo.createdAtstring (date-time)Yes—
photo.heightinteger | nullYes—
photo.idstring (vph_… ID)YesID (vph_…)
photo.largeUrlstring | nullYes—
photo.minebooleanYes—
photo.sharedbooleanYes—
photo.sortintegerYes—
photo.statusenumYesOne of: "uploading", "processing", "ready", "failed".
photo.thumbUrlstring | nullYes—
photo.uploadedByobjectYes—
photo.uploadedBy.namestringYes—
photo.uploadedBy.userIdstring (usr_… ID)YesID (usr_…)
photo.widthinteger | nullYes—
uploadUrlstring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/photos" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "clientKey": "string",
  "contentType": "image/jpeg",
  "bytes": 1
}'

Put a visit’s photos in a new order, in one go: every photo the visit shows, each once#

PUT /v1/me/meetings/{bookingId}/visit/photos/order

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Request body

application/json, required.

FieldTypeRequiredDescription
photoIdsarray<string (vph_… ID)>YesUp to 2000 items.

Response 204

No content.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/photos/order" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "photoIds": [
    "vph_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
  ]
}'

Change a photo’s caption, whether it is shared with the family, or its place in the order#

PATCH /v1/me/meetings/{bookingId}/visit/photos/{photoId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)
photoIdstring (vph_… ID)YesID (vph_…)

Request body

application/json, required.

FieldTypeRequiredDescription
captionstring | nullNoUp to 200 characters.
sharedbooleanNo—
sortintegerNoBetween 0 and 10000.

Response 200

FieldTypeRequiredDescription
canDeletebooleanYes—
canEditbooleanYes—
captionstring | nullYes—
createdAtstring (date-time)Yes—
heightinteger | nullYes—
idstring (vph_… ID)YesID (vph_…)
largeUrlstring | nullYes—
minebooleanYes—
sharedbooleanYes—
sortintegerYes—
statusenumYesOne of: "uploading", "processing", "ready", "failed".
thumbUrlstring | nullYes—
uploadedByobjectYes—
uploadedBy.namestringYes—
uploadedBy.userIdstring (usr_… ID)YesID (usr_…)
widthinteger | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/photos/{photoId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "string",
  "shared": true,
  "sort": 0
}'

Remove a photo: hidden at once, its files deleted by the daily sweep. My own, or anyone’s at a community I manage#

DELETE /v1/me/meetings/{bookingId}/visit/photos/{photoId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)
photoIdstring (vph_… ID)YesID (vph_…)

Response 204

No content.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/photos/{photoId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Finish adding a photo once its bytes are sent: checks them, then its copies are made (status processing, then ready)#

POST /v1/me/meetings/{bookingId}/visit/photos/{photoId}/complete

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)
photoIdstring (vph_… ID)YesID (vph_…)

Response 200

FieldTypeRequiredDescription
canDeletebooleanYes—
canEditbooleanYes—
captionstring | nullYes—
createdAtstring (date-time)Yes—
heightinteger | nullYes—
idstring (vph_… ID)YesID (vph_…)
largeUrlstring | nullYes—
minebooleanYes—
sharedbooleanYes—
sortintegerYes—
statusenumYesOne of: "uploading", "processing", "ready", "failed".
thumbUrlstring | nullYes—
uploadedByobjectYes—
uploadedBy.namestringYes—
uploadedBy.userIdstring (usr_… ID)YesID (usr_…)
widthinteger | nullYes—

Errors: 400, 401, 403, 404, 409, 413, 415, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/photos/{photoId}/complete" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Show the visit’s shared photos on the family’s page, making an on-demand page if it has none. Returns a fresh link and QR code for an on-demand page (each call: Show the link again), or none for a call’s page#

POST /v1/me/meetings/{bookingId}/visit/publish

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Response 200

FieldTypeRequiredDescription
linkany | nullYes—
pageVisitPageYes—
page.originenum | nullYesOne of: "call", "visit".
page.publishedAtstring (date-time) | nullYes—
page.showsPhotosbooleanYes—
page.stateenumYesOne of: "none", "live", "closed".
shownintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/publish" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Take every photo of the visit off the family’s page at once, without removing any#

POST /v1/me/meetings/{bookingId}/visit/unpublish

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
bookingIdstring (bkg_… ID)YesID (bkg_…)

Response 200

FieldTypeRequiredDescription
originenum | nullYesOne of: "call", "visit".
publishedAtstring (date-time) | nullYes—
showsPhotosbooleanYes—
stateenumYesOne of: "none", "live", "closed".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/meetings/{bookingId}/visit/unpublish" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Which second sign-in steps this login has, and what its account asks for#

GET /v1/me/mfa

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
accountPolicyany | nullYes—
enrolledbooleanYes—
factorsarray<MfaFactor>Yes—
factors[].backedUpboolean | nullYes—
factors[].createdAtstring (date-time)Yes—
factors[].hintstring | nullYes—
factors[].idstring (mfa_… ID)YesID (mfa_…)
factors[].kindenumYesOne of: "email", "sms", "totp", "passkey".
factors[].labelstring | nullYes—
factors[].lastUsedAtstring (date-time) | nullYes—
factors[].statusenumYesOne of: "pending", "active".
methodsarray<enum>YesItems: "email", "sms", "totp", "passkey".
reasonenum | nullYesOne of: "platform", "account".
recoveryCodesLeftintegerYes—
requiredbooleanYes—
satisfiedbooleanYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/mfa" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Send a passcode for one of this login’s methods (an authenticator app sends none)#

POST /v1/me/mfa/challenge

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
factorIdstring (mfa_… ID)YesID (mfa_…)

Response 200

FieldTypeRequiredDescription
challengeIdstring (mfch_… ID)NoID (mfch_…)
devCodestringNo—
kindenumYesOne of: "email", "sms", "totp", "passkey".
publicKeyOptionsmapNo—
publicKeyOptions.{key}anyNoAny key.
sentToHintstringNo—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/mfa/challenge" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "factorId": "mfa_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
}'

Start setting a second sign-in step up. Setting the same kind up again replaces it, but only once the new one is confirmed.#

POST /v1/me/mfa/methods

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
kindenumYesOne of: "email", "sms", "totp", "passkey".
labelstringNoUp to 60 characters.
phonestringNoUp to 20 characters.

Response 201

FieldTypeRequiredDescription
challengeIdstring (mfch_… ID)NoID (mfch_…)
devCodestringNo—
factorIdstring (mfa_… ID)YesID (mfa_…)
kindenumYesOne of: "email", "sms", "totp", "passkey".
publicKeyOptionsmapNo—
publicKeyOptions.{key}anyNoAny key.
qrDataUrlstringNo—
secretstringNo—
sentToHintstringNo—
uristringNo—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/mfa/methods" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "kind": "email"
}'

Remove a second sign-in step. Refused when it is the last one and one is required.#

DELETE /v1/me/mfa/methods/{factorId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
factorIdstring (mfa_… ID)YesID (mfa_…)

Response 204

No content.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/mfa/methods/{factorId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Finish setting a second sign-in step up. The first one also returns recovery codes, shown once.#

POST /v1/me/mfa/methods/{factorId}/confirm

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
factorIdstring (mfa_… ID)YesID (mfa_…)

Request body

application/json, required.

FieldTypeRequiredDescription
challengeIdstring (mfch_… ID)NoID (mfch_…)
codestringNo4–32 characters.
credentialmapNo—
credential.{key}anyNoAny key.

Response 200

FieldTypeRequiredDescription
factorMfaFactorYes—
factor.backedUpboolean | nullYes—
factor.createdAtstring (date-time)Yes—
factor.hintstring | nullYes—
factor.idstring (mfa_… ID)YesID (mfa_…)
factor.kindenumYesOne of: "email", "sms", "totp", "passkey".
factor.labelstring | nullYes—
factor.lastUsedAtstring (date-time) | nullYes—
factor.statusenumYesOne of: "pending", "active".
recoveryCodesarray<string> | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/mfa/methods/{factorId}/confirm" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "challengeId": "mfch_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE",
  "code": "string",
  "credential": {}
}'

Spend a recovery code to get into this session when no method is to hand. Set a method up again afterwards.#

POST /v1/me/mfa/recovery

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
codestringYes4–32 characters.

Response 200

FieldTypeRequiredDescription
recoveryCodesLeftintegerYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/mfa/recovery" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "code": "string"
}'

Replace every recovery code with ten new ones. The old ones stop working at once.#

POST /v1/me/mfa/recovery-codes

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
codesarray<string>Yes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/mfa/recovery-codes" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Confirm a code for this session. Refresh the Supabase session afterwards to pick up the new claims.#

POST /v1/me/mfa/verify

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
challengeIdstring (mfch_… ID)NoID (mfch_…)
codestringNo4–32 characters.
credentialmapNo—
credential.{key}anyNoAny key.
factorIdstring (mfa_… ID)YesID (mfa_…)

Response 200

FieldTypeRequiredDescription
methodenumYesOne of: "email", "sms", "totp", "passkey".

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/mfa/verify" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "factorId": "mfa_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
}'

Apps you gave access to your account#

GET /v1/me/oauth-grants

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
grantsarray<OAuthGrant>Yes—
grants[].clientIdstringYes—
grants[].clientNamestring | nullYes—
grants[].createdAtstring (date-time)Yes—
grants[].expiresAtstring (date-time) | nullYes—
grants[].groupIdsarray<string (grp_… ID)> | nullYes—
grants[].idstring (ogr_… ID)YesID (ogr_…)
grants[].lastUsedAtstring (date-time) | nullYes—
grants[].redirectHoststring | nullYes—
grants[].scopesarray<string>Yes—
grants[].userEmailstring | nullYes—
grants[].userIdstring (usr_… ID)YesID (usr_…)

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/oauth-grants" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Take access away from an app you connected#

DELETE /v1/me/oauth-grants/{grantId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
grantIdstring (ogr_… ID)YesID (ogr_…)

Response 200

FieldTypeRequiredDescription
revokedenumYesOne of: true.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/oauth-grants/{grantId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Pick the group my defaults come from, among the groups whose staff I am on#

PUT /v1/me/primary-group

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)

Response 200

FieldTypeRequiredDescription
groupsarray<object>Yes—
groups[].idstring (grp_… ID)YesID (grp_…)
groups[].namestringYes—
groups[].timeZonestringYes—
matchEmailstring | nullYes—
primaryGroupIdstring (grp_… ID) | nullYes—
schedulesarray<AvailabilitySchedule>Yes—
schedules[].chosenbooleanYes—
schedules[].hoursobjectYes—
schedules[].hours.overridesarray<object>YesUp to 366 items.
schedules[].hours.overrides[].datestring (date)Yes—
schedules[].hours.overrides[].windowsarray<object>YesUp to 12 items.
schedules[].hours.timeZonestringYes—
schedules[].hours.weeklyarray<object>YesUp to 50 items.
schedules[].hours.weekly[].daysarray<enum>YesItems: "mon", "tue", "wed", "thu", "fri", "sat", "sun".
schedules[].hours.weekly[].endstring | constantYes—
schedules[].hours.weekly[].startstringYesPattern: ^([01]\d|2[0-3]):[0-5]\d$.
schedules[].idstring (avs_… ID)YesID (avs_…)
schedules[].isDefaultbooleanYes—
schedules[].namestringYes—
schedules[].updatedAtstring (date-time)Yes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/me/primary-group" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "groupId": "grp_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
}'

Change your own name and the time zone you read times in#

PATCH /v1/me/profile

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
namestringNoUp to 120 characters.
timeZonestring | nullNo1–64 characters.

Response 200

FieldTypeRequiredDescription
namestring | nullYes—
timeZonestring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/me/profile" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "timeZone": "string"
}'

Whether ring groups ring me (Taking calls) or skip me (Away)#

GET /v1/me/taking-calls

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
takingCallsbooleanYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/taking-calls" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Switch myself to Taking calls or Away. Away skips me in every ring group; transfers the agent makes to me still ring#

PUT /v1/me/taking-calls

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Request body

application/json, required.

FieldTypeRequiredDescription
takingCallsbooleanYes—

Response 200

FieldTypeRequiredDescription
takingCallsbooleanYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/me/taking-calls" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "takingCalls": true
}'

The scopes a token can have, in plain words, and which this role may give. Owners and admins may ask for another role (a service identity’s ceiling)#

GET /v1/me/token-scopes

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Query parameters

NameTypeRequiredDescription
roleenumNoOne of: "owner", "admin", "editor", "group_manager", "viewer", "sales_rep".

Response 200

FieldTypeRequiredDescription
scopesarray<object>Yes—
scopes[].grantablebooleanYes—
scopes[].labelstringYes—
scopes[].scopestringYes—
scopes[].writebooleanYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/token-scopes" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

My open next steps from visits, soonest due first, and the ones waiting for a backup contact where I am one#

GET /v1/me/visit-actions

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Response 200

FieldTypeRequiredDescription
itemsarray<MyVisitAction>Yes—
items[].actionKeystring | nullYes—
items[].bookingIdstring (bkg_… ID)YesID (bkg_…)
items[].canTakebooleanYes—
items[].canUndobooleanYes—
items[].canWorkbooleanYes—
items[].closedAtstring (date-time) | nullYes—
items[].closedInCrmbooleanYes—
items[].createdAtstring (date-time)Yes—
items[].crmTaskbooleanYes—
items[].dismissReasonstring | nullYes—
items[].dueAtstring (date-time)Yes—
items[].idstring (vac_… ID)YesID (vac_…)
items[].labelstringYes—
items[].notestring | nullYes—
items[].ownerobject | nullYes—
items[].owner.namestringYes—
items[].owner.userIdstring (usr_… ID)YesID (usr_…)
items[].ownerSourceenumYesOne of: "rep", "backup", "member".
items[].statusenumYesOne of: "open", "done", "dismissed".
items[].versionintegerYes—
items[].visitVisitActionVisitYes—
items[].visit.groupIdstring (grp_… ID)YesID (grp_…)
items[].visit.groupNamestringYes—
items[].visit.openobject | object | objectYes—
items[].visit.open.bookingIdstring (bkg_… ID)Yes(variant 1) ID (bkg_…)
items[].visit.open.kindconstantYes(variant 1) Always "meeting".
items[].visit.open.callIdstring (call_… ID)Yes(variant 2) ID (call_…)
items[].visit.open.kindconstantYes(variant 2) Always "call".
items[].visit.open.kindconstantYes(variant 3) Always "none".
items[].visit.startstring (date-time)Yes—
items[].visit.timeZonestring | nullYes—
items[].visit.whostring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/me/visit-actions" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Mark a next step done, dismiss it, reopen it, move it to another day, change its note or hand it on. Send the version as read; a stale one is refused with 409#

PATCH /v1/me/visit-actions/{actionId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
actionIdstring (vac_… ID)YesID (vac_…)

Request body

application/json, required.

FieldTypeRequiredDescription
dismissReasonstringNoUp to 200 characters.
dueDaystringNoPattern: ^\d\{4\}-\d\{2\}-\d\{2\}$.
notestring | nullNoUp to 500 characters.
ownerstring (usr_… ID) | enumNo—
statusenumNoOne of: "open", "done", "dismissed".
versionintegerYesMinimum 1.

Response 200

FieldTypeRequiredDescription
actionKeystring | nullYes—
bookingIdstring (bkg_… ID)YesID (bkg_…)
canTakebooleanYes—
canUndobooleanYes—
canWorkbooleanYes—
closedAtstring (date-time) | nullYes—
closedInCrmbooleanYes—
createdAtstring (date-time)Yes—
crmTaskbooleanYes—
dismissReasonstring | nullYes—
dueAtstring (date-time)Yes—
idstring (vac_… ID)YesID (vac_…)
labelstringYes—
notestring | nullYes—
ownerobject | nullYes—
owner.namestringYes—
owner.userIdstring (usr_… ID)YesID (usr_…)
ownerSourceenumYesOne of: "rep", "backup", "member".
statusenumYesOne of: "open", "done", "dismissed".
versionintegerYes—
visitVisitActionVisitYes—
visit.groupIdstring (grp_… ID)YesID (grp_…)
visit.groupNamestringYes—
visit.openobject | object | objectYes—
visit.open.bookingIdstring (bkg_… ID)Yes(variant 1) ID (bkg_…)
visit.open.kindconstantYes(variant 1) Always "meeting".
visit.open.callIdstring (call_… ID)Yes(variant 2) ID (call_…)
visit.open.kindconstantYes(variant 2) Always "call".
visit.open.kindconstantYes(variant 3) Always "none".
visit.startstring (date-time)Yes—
visit.timeZonestring | nullYes—
visit.whostring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/me/visit-actions/{actionId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "version": 1
}'

Take back a next step I added by mistake: within ten minutes, and only while nobody has changed it#

DELETE /v1/me/visit-actions/{actionId}

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
actionIdstring (vac_… ID)YesID (vac_…)

Response 204

No content.

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/me/visit-actions/{actionId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Take a next step that is waiting for one of the community’s backup contacts#

POST /v1/me/visit-actions/{actionId}/take

Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).

Path parameters

NameTypeRequiredDescription
actionIdstring (vac_… ID)YesID (vac_…)

Response 200

FieldTypeRequiredDescription
actionKeystring | nullYes—
bookingIdstring (bkg_… ID)YesID (bkg_…)
canTakebooleanYes—
canUndobooleanYes—
canWorkbooleanYes—
closedAtstring (date-time) | nullYes—
closedInCrmbooleanYes—
createdAtstring (date-time)Yes—
crmTaskbooleanYes—
dismissReasonstring | nullYes—
dueAtstring (date-time)Yes—
idstring (vac_… ID)YesID (vac_…)
labelstringYes—
notestring | nullYes—
ownerobject | nullYes—
owner.namestringYes—
owner.userIdstring (usr_… ID)YesID (usr_…)
ownerSourceenumYesOne of: "rep", "backup", "member".
statusenumYesOne of: "open", "done", "dismissed".
versionintegerYes—
visitVisitActionVisitYes—
visit.groupIdstring (grp_… ID)YesID (grp_…)
visit.groupNamestringYes—
visit.openobject | object | objectYes—
visit.open.bookingIdstring (bkg_… ID)Yes(variant 1) ID (bkg_…)
visit.open.kindconstantYes(variant 1) Always "meeting".
visit.open.callIdstring (call_… ID)Yes(variant 2) ID (call_…)
visit.open.kindconstantYes(variant 2) Always "call".
visit.open.kindconstantYes(variant 3) Always "none".
visit.startstring (date-time)Yes—
visit.timeZonestring | nullYes—
visit.whostring | nullYes—

Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/me/visit-actions/{actionId}/take" \
  -H "Authorization: Bearer $ACCESS_TOKEN"