API reference

Playbooks

Playbooks, drafts, versions and publishing

MethodPathSummary
GET/v1/account/ai-modelsThe language and speech recognition models a playbook can choose, and the recommended one of each
GET/v1/account/playbooksAccount playbooks
POST/v1/account/playbooksCreate a playbook from the defaults or by cloning a version
GET/v1/account/playbooks/{playbookId}A playbook with its latest published version and its draft
PATCH/v1/account/playbooks/{playbookId}Rename a playbook or change its description
POST/v1/account/playbooks/{playbookId}/archiveArchive or restore a playbook (refused while numbers or groups use it)
GET/v1/account/playbooks/{playbookId}/changesChange history: who changed what and when, newest first
GET/v1/account/playbooks/{playbookId}/diffWhat changed between two versions, in words (defaults: latest published to draft)
GET/v1/account/playbooks/{playbookId}/draftThe draft, or the latest published content to start one from
PUT/v1/account/playbooks/{playbookId}/draftAutosave the draft; records the change in words
DELETE/v1/account/playbooks/{playbookId}/draftDiscard the draft (only when a published version exists). A draft that ran test calls is kept, hidden, so those calls still show what ran
PUT/v1/account/playbooks/{playbookId}/kill-switchRoute this playbook's calls to a person or voicemail at once, without a deploy
POST/v1/account/playbooks/{playbookId}/publishPublish the draft as the next version and update every group that follows it
GET/v1/account/playbooks/{playbookId}/question-map/layoutHow the question map is arranged: the account's arrangement, and a group's own when groupId is given
PUT/v1/account/playbooks/{playbookId}/question-map/layoutSave where the cards sit on the question map (the account’s, or a group’s own)
DELETE/v1/account/playbooks/{playbookId}/question-map/layoutTidy up: drop the saved arrangement so the map arranges itself again
GET/v1/account/playbooks/{playbookId}/question-map/trafficHow many calls took each arrow of the question map in the last days days (test calls left out)
POST/v1/account/playbooks/{playbookId}/rollbackRestore an old version by publishing it again as a new version (history is never rewritten)
POST/v1/account/playbooks/{playbookId}/validateRun the publish checklist on the draft: rules, voice and connection health
GET/v1/account/playbooks/{playbookId}/versionsVersion history, newest first
GET/v1/account/playbooks/{playbookId}/versions/{version}One version with its content
GET/v1/account/voicesThe stock voices a playbook can use, all of them or one voice company

The language and speech recognition models a playbook can choose, and the recommended one of each#

GET /v1/account/ai-models

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

Response 200

FieldTypeRequiredDescription
{key}objectNoAny key.
{key}.modelsarray<AiModelOption>Yes—
{key}.models[].descriptionstring | nullYes—
{key}.models[].labelstringYes—
{key}.models[].modelstringYes—
{key}.recommendedany | nullYes—

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

Example

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

Account playbooks#

GET /v1/account/playbooks

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.).

Query parameters

NameTypeRequiredDescription
includeArchivedenumNoOne of: "true", "false".

Response 200

FieldTypeRequiredDescription
playbooksarray<PlaybookSummary>Yes—
playbooks[].archivedbooleanYes—
playbooks[].createdAtstring (date-time)Yes—
playbooks[].descriptionstring | nullYes—
playbooks[].draftobject | nullYes—
playbooks[].draft.updatedAtstring (date-time)Yes—
playbooks[].draft.versionintegerYes—
playbooks[].draft.versionIdstring (pbv_… ID)YesID (pbv_…)
playbooks[].idstring (pb_… ID)YesID (pb_…)
playbooks[].isSamplebooleanYes—
playbooks[].killSwitchbooleanYes—
playbooks[].killSwitchModeenumYesOne of: "human", "voicemail".
playbooks[].latestPublishedVersioninteger | nullYes—
playbooks[].namestringYes—
playbooks[].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/account/playbooks" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Create a playbook from the defaults or by cloning a version#

POST /v1/account/playbooks

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

Request body

application/json, required.

FieldTypeRequiredDescription
descriptionstringNoUp to 1000 characters.
fromVersionIdstring (pbv_… ID)NoID (pbv_…)
namestringYes1–120 characters.

Response 201

FieldTypeRequiredDescription
archivedbooleanYes—
createdAtstring (date-time)Yes—
descriptionstring | nullYes—
draftobject | nullYes—
draft.updatedAtstring (date-time)Yes—
draft.versionintegerYes—
draft.versionIdstring (pbv_… ID)YesID (pbv_…)
draftVersionany | nullYes—
idstring (pb_… ID)YesID (pb_…)
isSamplebooleanYes—
killSwitchbooleanYes—
killSwitchModeenumYesOne of: "human", "voicemail".
latestany | nullYes—
latestPublishedVersioninteger | nullYes—
namestringYes—
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/account/playbooks" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'

A playbook with its latest published version and its draft#

GET /v1/account/playbooks/{playbookId}

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Response 200

FieldTypeRequiredDescription
archivedbooleanYes—
createdAtstring (date-time)Yes—
descriptionstring | nullYes—
draftobject | nullYes—
draft.updatedAtstring (date-time)Yes—
draft.versionintegerYes—
draft.versionIdstring (pbv_… ID)YesID (pbv_…)
draftVersionany | nullYes—
idstring (pb_… ID)YesID (pb_…)
isSamplebooleanYes—
killSwitchbooleanYes—
killSwitchModeenumYesOne of: "human", "voicemail".
latestany | nullYes—
latestPublishedVersioninteger | nullYes—
namestringYes—
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/account/playbooks/{playbookId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Rename a playbook or change its description#

PATCH /v1/account/playbooks/{playbookId}

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Request body

application/json, required.

FieldTypeRequiredDescription
descriptionstring | nullNoUp to 1000 characters.
namestringNo1–120 characters.

Response 200

FieldTypeRequiredDescription
archivedbooleanYes—
createdAtstring (date-time)Yes—
descriptionstring | nullYes—
draftobject | nullYes—
draft.updatedAtstring (date-time)Yes—
draft.versionintegerYes—
draft.versionIdstring (pbv_… ID)YesID (pbv_…)
idstring (pb_… ID)YesID (pb_…)
isSamplebooleanYes—
killSwitchbooleanYes—
killSwitchModeenumYesOne of: "human", "voicemail".
latestPublishedVersioninteger | nullYes—
namestringYes—
updatedAtstring (date-time)Yes—

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

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "description": "string",
  "name": "string"
}'

Archive or restore a playbook (refused while numbers or groups use it)#

POST /v1/account/playbooks/{playbookId}/archive

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Request body

application/json, required.

FieldTypeRequiredDescription
archivedbooleanYes—

Response 200

FieldTypeRequiredDescription
archivedbooleanYes—
createdAtstring (date-time)Yes—
descriptionstring | nullYes—
draftobject | nullYes—
draft.updatedAtstring (date-time)Yes—
draft.versionintegerYes—
draft.versionIdstring (pbv_… ID)YesID (pbv_…)
idstring (pb_… ID)YesID (pb_…)
isSamplebooleanYes—
killSwitchbooleanYes—
killSwitchModeenumYesOne of: "human", "voicemail".
latestPublishedVersioninteger | nullYes—
namestringYes—
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/account/playbooks/{playbookId}/archive" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "archived": true
}'

Change history: who changed what and when, newest first#

GET /v1/account/playbooks/{playbookId}/changes

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Query parameters

NameTypeRequiredDescription
limitintegerNoBetween 1 and 100. Default: 50.
cursorstringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
changesarray<object>Yes—
changes[].changesarray<PlaybookChange>Yes—
changes[].changes[].afteranyNo—
changes[].changes[].beforeanyNo—
changes[].changes[].kindenumYesOne of: "added", "removed", "changed".
changes[].changes[].pathstringYes—
changes[].changes[].summarystringYes—
changes[].createdAtstring (date-time)Yes—
changes[].idstring (pbc_… ID)YesID (pbc_…)
changes[].notestring | nullYes—
changes[].publishedVersioninteger | nullYes—
changes[].userIdstring (usr_… ID) | string (svc_… ID) | nullYes—
changes[].versionIdstring (pbv_… ID) | nullYes—
nextCursorstring | nullYes—

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

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/changes" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

What changed between two versions, in words (defaults: latest published to draft)#

GET /v1/account/playbooks/{playbookId}/diff

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
playbookIdstring (pb_… ID)YesID (pb_…)

Query parameters

NameTypeRequiredDescription
frominteger | enumNoDefault: "latest".
tointeger | enumNoDefault: "draft".

Response 200

FieldTypeRequiredDescription
changesarray<PlaybookChange>Yes—
changes[].afteranyNo—
changes[].beforeanyNo—
changes[].kindenumYesOne of: "added", "removed", "changed".
changes[].pathstringYes—
changes[].summarystringYes—
fromintegerYes—
tointegerYes—

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

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/diff" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

The draft, or the latest published content to start one from#

GET /v1/account/playbooks/{playbookId}/draft

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
playbookIdstring (pb_… ID)YesID (pb_…)

Response 200

FieldTypeRequiredDescription
baseVersioninteger | nullYes—
contentPlaybookContentYes—
content.bookingobjectYes—
content.booking.allowUnqualifiedbooleanNoDefault: false.
content.booking.maxBookingsPerCallintegerNoBetween 1 and 2. Default: 2.
content.booking.minNoticeMinutesintegerNoBetween 0 and 10080. Default: 60.
content.booking.offerSlotsintegerNoBetween 1 and 4. Default: 2.
content.booking.rulesarray<object>Yes—
content.booking.rules[].enabledbooleanNoDefault: true.
content.booking.rules[].namestringNoUp to 120 characters.
content.booking.rules[].thenobject | object | object | object | object | object | objectYes—
content.booking.rules[].whenobject | object | object | object | object | object | object | object | object | objectYes—
content.briefstringYes1–12000 characters.
content.defaultFlowIdstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.escalationobjectYes—
content.escalation.afterFailedAnswersintegerNoBetween 1 and 5. Default: 2.
content.escalation.onFrustrationbooleanNoDefault: true.
content.escalation.onGuardrailHitbooleanNoDefault: true.
content.escalation.transferLinestringYes1–300 characters.
content.escalation.transferModeenumNoOne of: "cold", "warm". Default: "cold".
content.escalation.unavailableLinestringYes1–300 characters.
content.flowsarray<object>Yes—
content.flows[].brancharray<object>NoDefault: [].
content.flows[].branch[].gotostringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.flows[].branch[].ifobject | object | object | object | object | object | object | object | object | objectYes—
content.flows[].disqualifyarray<object>NoDefault: [].
content.flows[].disqualify[].actionenumYesOne of: "offer_nurture", "offer_referral", "end_politely".
content.flows[].disqualify[].ifobject | object | object | object | object | object | object | object | object | objectYes—
content.flows[].disqualify[].linestringNoUp to 500 characters.
content.flows[].enterWhenstringYes1–500 characters.
content.flows[].fieldsarray<object>Yes—
content.flows[].fields[].alwaysConfirmbooleanNo—
content.flows[].fields[].askstringYes1–500 characters.
content.flows[].fields[].askWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.flows[].fields[].hearAsarray<string>NoUp to 20 items.
content.flows[].fields[].hintstringNoUp to 500 characters.
content.flows[].fields[].keystringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.flows[].fields[].labelstringNo1–120 characters.
content.flows[].fields[].optionsarray<object>No—
content.flows[].fields[].optionsFromenum | string (oset_… ID)No—
content.flows[].fields[].requiredbooleanNoDefault: false.
content.flows[].fields[].sensitivityenumNoOne of: "standard", "sensitive". Default: "standard".
content.flows[].fields[].typeenumYesOne of: "text", "number", "enum", "boolean", "date", "phone", "email".
content.flows[].goalstringYes1–500 characters.
content.flows[].maxQuestionsBeforeValueintegerNoBetween 1 and 10. Default: 2.
content.flows[].namestringYes1–120 characters.
content.flows[].talkingPointsarray<object | object>NoDefault: [].
content.flows[].talkingPoints[].saystringYes(variant 1) 1–500 characters.
content.flows[].talkingPoints[].whenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.flows[].talkingPoints[].talkAboutstringYes(variant 2) 1–500 characters.
content.flows[].talkingPoints[].whenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.followUpobjectNo—
content.followUp.blocksarray<object>NoUp to 20 items. Default: [].
content.followUp.blocks[].bodystringNoUp to 2000 characters.
content.followUp.blocks[].buttonobjectNo—
content.followUp.blocks[].headingstringNoUp to 120 characters.
content.followUp.blocks[].imagestring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.blocks[].videoobjectNo—
content.followUp.cardsarray<object>NoUp to 30 items. Default: [].
content.followUp.cards[].bodystringYes1–2000 characters.
content.followUp.cards[].buttonobjectNo—
content.followUp.cards[].enabledbooleanNoDefault: true.
content.followUp.cards[].imagestring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.cards[].showWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.cards[].titlestringYes1–120 characters.
content.followUp.chatobjectNoDefault: \{"callContext":true,"enabled":false\}.
content.followUp.chat.callContextbooleanNoDefault: true.
content.followUp.chat.enabledbooleanNoDefault: false.
content.followUp.consentQuestionstringNo1–480 characters. Default: "Can I text you a link with your \{\{vocab.meeting\}\} details and a recap of our call? Message and data rates may apply, and you can reply STOP anytime.".
content.followUp.emailsobjectNo—
content.followUp.emails.after_visitobject | nullNo—
content.followUp.emails.cancel_confirmationobject | nullNo—
content.followUp.emails.initial_linkobject | nullNo—
content.followUp.emails.reminderobject | nullNo—
content.followUp.emails.reschedule_confirmationobject | nullNo—
content.followUp.enabledbooleanNoDefault: false.
content.followUp.formobjectNoDefault: \{"fields":[]\}.
content.followUp.form.fieldsarray<object>NoUp to 8 items. Default: [].
content.followUp.form.introstringNoUp to 480 characters.
content.followUp.leadsobjectNoDefault: \{\}.
content.followUp.leads.afterVisitstringNoUp to 480 characters.
content.followUp.leads.cancelledstringNoUp to 480 characters.
content.followUp.leads.noBookingstringNoUp to 480 characters.
content.followUp.linkExpiryDaysintegerNoBetween 7 and 365. Default: 60.
content.followUp.messagesobjectNoDefault: \{"afterVisit":\{"enabled":false\},"initialSms":"Hi \{\{caller.firstName\}\}, it's \{\{group.name\}\}. Here are your \{\{vocab.meeting\}\} details and a recap of our call: \{\{link\}\} Reply STOP to opt out.","reminders":[\{"before":"24h"\},\{"before":"2h"\}]\}.
content.followUp.messages.afterVisitobjectNoDefault: \{"enabled":false\}.
content.followUp.messages.initialSmsstringYes1–480 characters.
content.followUp.messages.remindersarray<object>NoUp to 4 items. Default: [\{"before":"24h"\},\{"before":"2h"\}].
content.followUp.modulesarray<object>NoDefault: [\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\}].
content.followUp.modules[].blockIdstringNo1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.followUp.modules[].headingstringNoUp to 120 characters.
content.followUp.modules[].showWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.modules[].statesarray<enum>NoItems: "upcoming", "day_of", "after_visit", "no_booking", "cancelled", "expired", "revoked".
content.followUp.prepobjectNoDefault: \{"checklist":[]\}.
content.followUp.prep.bodystringNoUp to 2000 characters.
content.followUp.prep.checklistarray<object>NoUp to 12 items. Default: [].
content.followUp.resourcesarray<object>NoUp to 20 items. Default: [].
content.followUp.resources[].descriptionstringNoUp to 300 characters.
content.followUp.resources[].labelstringYes1–120 characters.
content.followUp.resources[].urlstring (uri)YesA https:// link Up to 2000 characters.
content.followUp.reviewsarray<object>NoUp to 12 items. Default: [].
content.followUp.reviews[].attributionstringNoUp to 120 characters.
content.followUp.reviews[].quotestringYes1–600 characters.
content.followUp.sendWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.sendWhen.allarray<object | object | object | object | object | object | object | object | object | object>Yes(variant 1)
content.followUp.sendWhen.anyarray<object | object | object | object | object | object | object | object | object | object>Yes(variant 2)
content.followUp.sendWhen.notobject | object | object | object | object | object | object | object | object | objectYes(variant 3)
content.followUp.sendWhen.alwaysenumYes(variant 4) One of: true.
content.followUp.sendWhen.factstringYes(variant 5) (variant 1) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.isstring | number | booleanYes(variant 5) (variant 1)
content.followUp.sendWhen.factstringYes(variant 5) (variant 2) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.inarray<string | number | boolean>Yes(variant 5) (variant 2)
content.followUp.sendWhen.factstringYes(variant 5) (variant 3) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.gtnumberYes(variant 5) (variant 3)
content.followUp.sendWhen.factstringYes(variant 5) (variant 4) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.ltnumberYes(variant 5) (variant 4)
content.followUp.sendWhen.betweenarrayYes(variant 5) (variant 5) Up to 2 items.
content.followUp.sendWhen.factstringYes(variant 5) (variant 5) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.factstringYes(variant 5) (variant 6) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.missingbooleanYes(variant 5) (variant 6)
content.followUp.themeobjectNoDefault: \{"accent":"#B4512E","background":"#F7F3EC","font":"system","primary":"#24473D"\}.
content.followUp.theme.accentstringYesPattern: ^#[0-9a-f]\{6\}$.
content.followUp.theme.backgroundstringNoPattern: ^#[0-9a-f]\{6\}$. Default: "#F7F3EC".
content.followUp.theme.fontenumNoOne of: "system", "serif_warm", "sans_modern". Default: "system".
content.followUp.theme.logostring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.theme.primarystringYesPattern: ^#[0-9a-f]\{6\}$.
content.guardrailsobjectYes—
content.guardrails.allowPriceDiscussionbooleanNoDefault: true.
content.guardrails.declineTopicsarray<object>NoDefault: [].
content.guardrails.declineTopics[].textstringYes1–1000 characters.
content.guardrails.emergencyLinestringYes1–300 characters.
content.guardrails.fallbackLinestringYes1–300 characters.
content.guardrails.neverSayarray<object>NoDefault: [].
content.guardrails.neverSay[].textstringYes1–1000 characters.
content.guardrails.prohibitedClaimsarray<object>NoDefault: [].
content.guardrails.prohibitedClaims[].textstringYes1–1000 characters.
content.guardrails.redirectLinesobjectYes—
content.guardrails.redirectLines.existing_customerstringYes1–500 characters.
content.guardrails.redirectLines.job_seekerstringYes1–500 characters.
content.guardrails.redirectLines.resident_familystringYes1–500 characters.
content.guardrails.redirectLines.vendorstringYes1–500 characters.
content.guardrails.redirectLines.wrong_numberstringYes1–500 characters.
content.guardrails.requiredDisclosuresarray<object>NoDefault: [].
content.guardrails.requiredDisclosures[].textstringYes1–1000 characters.
content.integrationsobjectNoDefault: \{\}.
content.integrations.crmobjectNo—
content.integrations.crm.connectionIdstring (conn_… ID)YesID (conn_…)
content.integrations.crm.connectorstringYes1–64 characters.
content.integrations.crm.createContactsbooleanNoDefault: true.
content.integrations.crm.fieldMapmapNoDefault: \{\}.
content.integrations.crm.historyLookbackDaysintegerNoBetween 0 and 3650. Default: 180.
content.integrations.crm.logCallsbooleanNoDefault: true.
content.integrations.crm.optionsmapNoDefault: \{\}.
content.integrations.schedulerobjectNo—
content.integrations.scheduler.activityTypestringYes1–64 characters.
content.integrations.scheduler.connectionIdstring (conn_… ID)YesID (conn_…)
content.integrations.scheduler.connectorstringYes1–64 characters.
content.integrations.scheduler.optionsmapNoDefault: \{\}.
content.knowledgeobjectNoDefault: \{"documents":[],"faq":[]\}.
content.knowledge.documentsarray<object>NoDefault: [].
content.knowledge.documents[].titlestringYes1–200 characters.
content.knowledge.faqarray<object>NoDefault: [].
content.knowledge.faq[].answerstringYes1–2000 characters.
content.knowledge.faq[].questionstringYes1–300 characters.
content.lexiconobjectNoDefault: \{"account":[],"packs":[],"platform":1\}.
content.lexicon.accountarray<object>NoUp to 200 items. Default: [].
content.lexicon.account[].conceptstringYesUp to 80 characters. Pattern: ^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+$.
content.lexicon.account[].neverarray<string>NoUp to 50 items. Default: [].
content.lexicon.account[].phrasesarray<string>NoUp to 50 items. Default: [].
content.lexicon.packsarray<object>NoUp to 10 items. Default: [].
content.lexicon.packs[].versionintegerYesMinimum 1.
content.lexicon.platformintegerNoMinimum 1. Default: 1.
content.locksarray<string>No—
content.modelsobjectNoDefault: \{"keyterms":[]\}.
content.models.keytermsarray<string>NoDefault: [].
content.models.llmstringNoUp to 200 characters.
content.models.sttstringNoUp to 200 characters.
content.objectionsarray<object>NoDefault: [].
content.objections[].guidancestringYes1–1000 characters.
content.objections[].triggerstringYes1–200 characters.
content.objectivesobjectNoDefault: \{"channels":\{\},"fallbacks":[],"primary":\{"label":"Book a meeting","meetingTypes":[],"qualifiedOnly":false,"type":"book_meeting"\},"secondary":[]\}.
content.objectives.channelsobjectNoDefault: \{\}.
content.objectives.channels.page_chatobjectNo—
content.objectives.channels.site_chatobjectNo—
content.objectives.fallbacksarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 3 items. Default: [].
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.fallbacks[].labelstringYes(variant 1) 1–80 characters.
content.objectives.fallbacks[].meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.fallbacks[].qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.fallbacks[].typeenumYes(variant 1) One of: "book_meeting".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.fallbacks[].labelstringYes(variant 2) 1–80 characters.
content.objectives.fallbacks[].reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.fallbacks[].typeenumYes(variant 2) One of: "live_transfer".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.fallbacks[].labelstringYes(variant 3) 1–80 characters.
content.objectives.fallbacks[].requireReasonbooleanNo(variant 3) Default: false.
content.objectives.fallbacks[].typeenumYes(variant 3) One of: "capture_callback".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.fallbacks[].fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.fallbacks[].labelstringYes(variant 4) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 4) One of: "capture_contact".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.fallbacks[].fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.fallbacks[].flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.fallbacks[].labelstringYes(variant 5) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 5) One of: "qualify".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.fallbacks[].labelstringYes(variant 6) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.fallbacks[].labelstringYes(variant 7) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 7) One of: "manage_booking".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.fallbacks[].kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.fallbacks[].labelstringYes(variant 8) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 8) One of: "route_correctly".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.fallbacks[].labelstringYes(variant 9) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 9) One of: "nurture".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.fallbacks[].bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.fallbacks[].labelstringYes(variant 10) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 10) One of: "run_tool".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.fallbacks[].labelstringYes(variant 11) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 11) One of: "answer_questions".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.fallbacks[].labelstringYes(variant 12) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 12) One of: "custom_condition".
content.objectives.fallbacks[].whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.fallbacks[].labelstringYes(variant 13) 1–80 characters.
content.objectives.fallbacks[].rubricstringYes(variant 13) 1–500 characters.
content.objectives.fallbacks[].typeenumYes(variant 13) One of: "custom_judged".
content.objectives.primaryobject | object | object | object | object | object | object | object | object | object | object | object | objectYes—
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.primary.labelstringYes(variant 1) 1–80 characters.
content.objectives.primary.meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.primary.qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.primary.typeenumYes(variant 1) One of: "book_meeting".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.primary.labelstringYes(variant 2) 1–80 characters.
content.objectives.primary.reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.primary.typeenumYes(variant 2) One of: "live_transfer".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.primary.labelstringYes(variant 3) 1–80 characters.
content.objectives.primary.requireReasonbooleanNo(variant 3) Default: false.
content.objectives.primary.typeenumYes(variant 3) One of: "capture_callback".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.primary.fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.primary.labelstringYes(variant 4) 1–80 characters.
content.objectives.primary.typeenumYes(variant 4) One of: "capture_contact".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.primary.fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.primary.flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.primary.labelstringYes(variant 5) 1–80 characters.
content.objectives.primary.typeenumYes(variant 5) One of: "qualify".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.primary.labelstringYes(variant 6) 1–80 characters.
content.objectives.primary.typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.primary.labelstringYes(variant 7) 1–80 characters.
content.objectives.primary.typeenumYes(variant 7) One of: "manage_booking".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.primary.kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.primary.labelstringYes(variant 8) 1–80 characters.
content.objectives.primary.typeenumYes(variant 8) One of: "route_correctly".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.primary.labelstringYes(variant 9) 1–80 characters.
content.objectives.primary.typeenumYes(variant 9) One of: "nurture".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.primary.bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.primary.labelstringYes(variant 10) 1–80 characters.
content.objectives.primary.typeenumYes(variant 10) One of: "run_tool".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.primary.labelstringYes(variant 11) 1–80 characters.
content.objectives.primary.typeenumYes(variant 11) One of: "answer_questions".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.primary.labelstringYes(variant 12) 1–80 characters.
content.objectives.primary.typeenumYes(variant 12) One of: "custom_condition".
content.objectives.primary.whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.primary.labelstringYes(variant 13) 1–80 characters.
content.objectives.primary.rubricstringYes(variant 13) 1–500 characters.
content.objectives.primary.typeenumYes(variant 13) One of: "custom_judged".
content.objectives.secondaryarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 5 items. Default: [].
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.secondary[].labelstringYes(variant 1) 1–80 characters.
content.objectives.secondary[].meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.secondary[].qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.secondary[].typeenumYes(variant 1) One of: "book_meeting".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.secondary[].labelstringYes(variant 2) 1–80 characters.
content.objectives.secondary[].reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.secondary[].typeenumYes(variant 2) One of: "live_transfer".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.secondary[].labelstringYes(variant 3) 1–80 characters.
content.objectives.secondary[].requireReasonbooleanNo(variant 3) Default: false.
content.objectives.secondary[].typeenumYes(variant 3) One of: "capture_callback".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.secondary[].fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.secondary[].labelstringYes(variant 4) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 4) One of: "capture_contact".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.secondary[].fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.secondary[].flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.secondary[].labelstringYes(variant 5) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 5) One of: "qualify".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.secondary[].labelstringYes(variant 6) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.secondary[].labelstringYes(variant 7) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 7) One of: "manage_booking".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.secondary[].kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.secondary[].labelstringYes(variant 8) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 8) One of: "route_correctly".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.secondary[].labelstringYes(variant 9) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 9) One of: "nurture".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.secondary[].bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.secondary[].labelstringYes(variant 10) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 10) One of: "run_tool".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.secondary[].labelstringYes(variant 11) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 11) One of: "answer_questions".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.secondary[].labelstringYes(variant 12) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 12) One of: "custom_condition".
content.objectives.secondary[].whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.secondary[].labelstringYes(variant 13) 1–80 characters.
content.objectives.secondary[].rubricstringYes(variant 13) 1–500 characters.
content.objectives.secondary[].typeenumYes(variant 13) One of: "custom_judged".
content.personaobjectYes—
content.persona.agentNamestringYes1–60 characters.
content.persona.companyNamestringYes1–120 characters.
content.persona.exampleExchangesarray<object>NoDefault: [].
content.persona.exampleExchanges[].agentstringYes1–500 characters.
content.persona.exampleExchanges[].callerstringYes1–500 characters.
content.persona.openingstringYes1–600 characters.
content.persona.openingAfterRingstringNo1–600 characters.
content.persona.openingNotRecordedstringNo1–600 characters.
content.persona.openingQuestionstringYes1–300 characters.
content.persona.preRingNoticestringNo1–300 characters.
content.persona.returningCallerLinestringNoUp to 300 characters.
content.persona.tonestringYes1–300 characters.
content.persona.voiceobjectYes—
content.persona.voice.ambiencebooleanNoDefault: false.
content.persona.voice.expressivebooleanNoDefault: false.
content.persona.voice.modeenumNoOne of: "cascaded". Default: "cascaded".
content.persona.voice.modelstringNoUp to 200 characters.
content.persona.voice.pronunciationsarray<object>NoDefault: [].
content.persona.voice.providerenumYesOne of: "cartesia", "elevenlabs", "deepgram", "fishaudio", "gradium", "inworld", "rime", "xai", "openai", "google".
content.persona.voice.thinkingSoundsbooleanNoDefault: true.
content.persona.voice.tuningmapNoDefault: \{\}.
content.persona.voice.voiceIdstringYes1–200 characters.
content.pricingobjectNoDefault: \{"feeLine":"The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.","floorPlanLine":"\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.","mentionSpecials":"when_price_comes_up","notOfferedLine":"\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.","onRequestLine":"Our team will go over pricing for \{\{price.service\}\} with you.","otherLocations":"off","otherLocationsLine":"\{\{price.service\}\} is offered at \{\{price.locations\}\}.","specialLine":"\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.","specialLineOpenEnded":"\{\{price.specialWording\}\}.","startingAtLine":"\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.","startingAtWithOptions":"\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}."\}.
content.pricing.feeLinestringNo1–300 characters. Default: "The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.".
content.pricing.floorPlanLinestringNo1–300 characters. Default: "\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.".
content.pricing.mentionSpecialsenumNoOne of: "when_price_comes_up", "once_after_discovery", "only_when_asked". Default: "when_price_comes_up".
content.pricing.notOfferedLinestringNo1–300 characters. Default: "\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.".
content.pricing.onRequestLinestringNo1–300 characters. Default: "Our team will go over pricing for \{\{price.service\}\} with you.".
content.pricing.otherLocationsenumNoOne of: "off", "mention", "mention_and_connect". Default: "off".
content.pricing.otherLocationsLinestringNo1–300 characters. Default: "\{\{price.service\}\} is offered at \{\{price.locations\}\}.".
content.pricing.specialLinestringNo1–300 characters. Default: "\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.".
content.pricing.specialLineOpenEndedstringNo1–300 characters. Default: "\{\{price.specialWording\}\}.".
content.pricing.startingAtLinestringNo1–300 characters. Default: "\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.".
content.pricing.startingAtWithOptionsstringNo1–300 characters. Default: "\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}.".
content.recordingobjectNoDefault: \{"enabled":true\}.
content.recording.enabledbooleanNoDefault: true.
content.retentionobjectNoDefault: \{"recordingDays":90,"transcriptDays":90\}.
content.retention.recordingDaysintegerNoBetween 1 and 3650. Default: 90.
content.retention.transcriptDaysintegerNoBetween 1 and 3650. Default: 90.
content.schemaVersionenumNoOne of: 1. Default: 1.
content.toolsobjectNoDefault: \{"bindings":[]\}.
content.tools.bindingsarray<object>NoUp to 20 items. Default: [].
content.tools.bindings[].allowCallerInputbooleanNoDefault: true.
content.tools.bindings[].argsmapNoDefault: \{\}.
content.tools.bindings[].asstringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.tools.bindings[].channelsarray<enum>NoItems: "phone", "web_voice", "web_chat". Default: ["phone","web_voice","web_chat"].
content.tools.bindings[].confirmWithCallerbooleanNoDefault: false.
content.tools.bindings[].enabledbooleanNoDefault: true.
content.tools.bindings[].holdingLinestringNo1–200 characters.
content.tools.bindings[].inputsmapNoDefault: \{\}.
content.tools.bindings[].labelstringYes1–80 characters.
content.tools.bindings[].maxCallsintegerNoBetween 1 and 3. Default: 3.
content.tools.bindings[].onFailureenumNoOne of: "say_will_follow_up", "continue_silently", "offer_callback", "transfer". Default: "say_will_follow_up".
content.tools.bindings[].resultobjectYes—
content.tools.bindings[].toolobjectYes—
content.tools.bindings[].triggerobject | objectYes—
content.tools.bindings[].whenobject | object | object | object | object | object | object | object | object | objectNo—
content.visitActionsobjectNo—
content.visitActions.allowCustombooleanNoDefault: true.
content.visitActions.itemsarray<object>NoUp to 30 items.
content.visitActions.items[].crmTaskbooleanNoDefault: false.
content.visitActions.items[].dueDaysintegerNoBetween 0 and 30. Default: 1.
content.visitActions.items[].keystringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.visitActions.items[].labelstringYes1–240 characters.
content.visitActions.items[].ownerenumNoOne of: "rep", "backup". Default: "rep".
content.visitActions.typedCrmTaskbooleanNoDefault: false.
content.webWidgetobjectNoDefault: \{"continuationDisclosure":"Hi again — this is the AI assistant you spoke with on the phone.","continuationGreeting":"I have the notes from your call, so we can pick up right where we left off. What else can I help with?","copy":\{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\},"disclosure":"Hi — I am an AI assistant, and I can answer questions or book you a time to visit.","enabled":false,"greeting":"What would you like to know?","launcher":\{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\},"limits":\{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\},"panel":\{"height":620,"presentation":"panel","width":400\},"showMedia":false,"surfaces":\{"chat":true,"voice":false\},"theme":\{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}\}.
content.webWidget.continuationDisclosurestringNo1–320 characters. Default: "Hi again — this is the AI assistant you spoke with on the phone.".
content.webWidget.continuationGreetingstringNo1–320 characters. Default: "I have the notes from your call, so we can pick up right where we left off. What else can I help with?".
content.webWidget.copyobjectNoDefault: \{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\}.
content.webWidget.copy.agentLabelstringNo1–80 characters. Default: "AI assistant".
content.webWidget.copy.choicesLabelstringNo1–80 characters. Default: "Tap an answer, or type your own".
content.webWidget.copy.closeLabelstringNo1–80 characters. Default: "Close the chat".
content.webWidget.copy.composerDisabledNotestringNo1–320 characters. Default: "Messaging is not switched on here yet.".
content.webWidget.copy.continuingNotestringNo1–80 characters. Default: "Continuing from your call on \{date\}".
content.webWidget.copy.endedNotestringNo1–320 characters. Default: "This conversation has ended.".
content.webWidget.copy.errorBodystringNo1–320 characters. Default: "Please try again in a moment, or call us and we will help.".
content.webWidget.copy.errorTitlestringNo1–80 characters. Default: "We could not load the chat".
content.webWidget.copy.inputPlaceholderstringNo1–80 characters. Default: "Type your question".
content.webWidget.copy.loadingLabelstringNo1–80 characters. Default: "Loading the chat".
content.webWidget.copy.newChatLabelstringNo1–80 characters. Default: "Start a new chat".
content.webWidget.copy.notAllowedBodystringNo1–320 characters. Default: "If you run this website, add it to the allowed list in your admin settings.".
content.webWidget.copy.notAllowedTitlestringNo1–80 characters. Default: "This chat is not available on this site".
content.webWidget.copy.openLabelstringNo1–80 characters. Default: "Open the chat".
content.webWidget.copy.retryLabelstringNo1–80 characters. Default: "Try again".
content.webWidget.copy.sendFailedstringNo1–320 characters. Default: "That message did not send. Please try again.".
content.webWidget.copy.sendLabelstringNo1–80 characters. Default: "Send".
content.webWidget.copy.subtitlestringNo1–80 characters. Default: "Answers in a moment".
content.webWidget.copy.typingLabelstringNo1–80 characters. Default: "Writing a reply".
content.webWidget.copy.visitorLabelstringNo1–80 characters. Default: "You".
content.webWidget.disclosurestringNo1–320 characters. Default: "Hi — I am an AI assistant, and I can answer questions or book you a time to visit.".
content.webWidget.enabledbooleanNoDefault: false.
content.webWidget.greetingstringNo1–320 characters. Default: "What would you like to know?".
content.webWidget.launcherobjectNoDefault: \{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\}.
content.webWidget.launcher.iconenumNoOne of: "chat", "message", "question", "sparkle", "phone", "headset". Default: "chat".
content.webWidget.launcher.iconUrlstring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.launcher.labelstringNo1–80 characters. Default: "Chat with us".
content.webWidget.launcher.offsetobjectNoDefault: \{"x":20,"y":20\}.
content.webWidget.launcher.positionenumNoOne of: "bottom-right", "bottom-left". Default: "bottom-right".
content.webWidget.launcher.shapeenumNoOne of: "circle", "rounded". Default: "circle".
content.webWidget.launcher.showLabelbooleanNoDefault: false.
content.webWidget.launcher.sizeenumNoOne of: "medium", "large". Default: "medium".
content.webWidget.limitsobjectNoDefault: \{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\}.
content.webWidget.limits.charactersPerMessageintegerNoBetween 200 and 8000. Default: 2000.
content.webWidget.limits.messagesPerConversationintegerNoBetween 1 and 2000. Default: 200.
content.webWidget.limits.messagesPerHourintegerNoBetween 1 and 500. Default: 30.
content.webWidget.panelobjectNoDefault: \{"height":620,"presentation":"panel","width":400\}.
content.webWidget.panel.headingstringNo1–80 characters.
content.webWidget.panel.heightintegerNoBetween 420 and 800. Default: 620.
content.webWidget.panel.presentationenumNoOne of: "panel", "sheet", "fullscreen". Default: "panel".
content.webWidget.panel.widthintegerNoBetween 320 and 560. Default: 400.
content.webWidget.showMediabooleanNoDefault: false.
content.webWidget.surfacesobjectNoDefault: \{"chat":true,"voice":false\}.
content.webWidget.surfaces.chatbooleanNoDefault: true.
content.webWidget.surfaces.voicebooleanNoDefault: false.
content.webWidget.themeobjectNoDefault: \{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}.
content.webWidget.theme.avatarstring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.theme.darkobjectNoDefault: \{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\}.
content.webWidget.theme.fontenumNoOne of: "system", "serif_warm", "sans_modern". Default: "system".
content.webWidget.theme.lightobjectNoDefault: \{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\}.
content.webWidget.theme.logostring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.theme.radiusobjectNoDefault: \{"bubble":14,"launcher":28,"panel":16\}.
content.webWidget.theme.schemeenumNoOne of: "auto", "light", "dark". Default: "auto".
contentHashstringYes—
draftany | nullYes—

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

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/draft" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Autosave the draft; records the change in words#

PUT /v1/account/playbooks/{playbookId}/draft

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
playbookIdstring (pb_… ID)YesID (pb_…)

Request body

application/json, required.

FieldTypeRequiredDescription
baseHashstringNoExactly 64 characters.
contentPlaybookContentYes—
content.bookingobjectYes—
content.booking.allowUnqualifiedbooleanNoDefault: false.
content.booking.maxBookingsPerCallintegerNoBetween 1 and 2. Default: 2.
content.booking.minNoticeMinutesintegerNoBetween 0 and 10080. Default: 60.
content.booking.offerSlotsintegerNoBetween 1 and 4. Default: 2.
content.booking.rulesarray<object>Yes—
content.booking.rules[].enabledbooleanNoDefault: true.
content.booking.rules[].namestringNoUp to 120 characters.
content.booking.rules[].thenobject | object | object | object | object | object | objectYes—
content.booking.rules[].whenobject | object | object | object | object | object | object | object | object | objectYes—
content.briefstringYes1–12000 characters.
content.defaultFlowIdstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.escalationobjectYes—
content.escalation.afterFailedAnswersintegerNoBetween 1 and 5. Default: 2.
content.escalation.onFrustrationbooleanNoDefault: true.
content.escalation.onGuardrailHitbooleanNoDefault: true.
content.escalation.transferLinestringYes1–300 characters.
content.escalation.transferModeenumNoOne of: "cold", "warm". Default: "cold".
content.escalation.unavailableLinestringYes1–300 characters.
content.flowsarray<object>Yes—
content.flows[].brancharray<object>NoDefault: [].
content.flows[].branch[].gotostringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.flows[].branch[].ifobject | object | object | object | object | object | object | object | object | objectYes—
content.flows[].disqualifyarray<object>NoDefault: [].
content.flows[].disqualify[].actionenumYesOne of: "offer_nurture", "offer_referral", "end_politely".
content.flows[].disqualify[].ifobject | object | object | object | object | object | object | object | object | objectYes—
content.flows[].disqualify[].linestringNoUp to 500 characters.
content.flows[].enterWhenstringYes1–500 characters.
content.flows[].fieldsarray<object>Yes—
content.flows[].fields[].alwaysConfirmbooleanNo—
content.flows[].fields[].askstringYes1–500 characters.
content.flows[].fields[].askWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.flows[].fields[].hearAsarray<string>NoUp to 20 items.
content.flows[].fields[].hintstringNoUp to 500 characters.
content.flows[].fields[].keystringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.flows[].fields[].labelstringNo1–120 characters.
content.flows[].fields[].optionsarray<object>No—
content.flows[].fields[].optionsFromenum | string (oset_… ID)No—
content.flows[].fields[].requiredbooleanNoDefault: false.
content.flows[].fields[].sensitivityenumNoOne of: "standard", "sensitive". Default: "standard".
content.flows[].fields[].typeenumYesOne of: "text", "number", "enum", "boolean", "date", "phone", "email".
content.flows[].goalstringYes1–500 characters.
content.flows[].maxQuestionsBeforeValueintegerNoBetween 1 and 10. Default: 2.
content.flows[].namestringYes1–120 characters.
content.flows[].talkingPointsarray<object | object>NoDefault: [].
content.flows[].talkingPoints[].saystringYes(variant 1) 1–500 characters.
content.flows[].talkingPoints[].whenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.flows[].talkingPoints[].talkAboutstringYes(variant 2) 1–500 characters.
content.flows[].talkingPoints[].whenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.followUpobjectNo—
content.followUp.blocksarray<object>NoUp to 20 items. Default: [].
content.followUp.blocks[].bodystringNoUp to 2000 characters.
content.followUp.blocks[].buttonobjectNo—
content.followUp.blocks[].headingstringNoUp to 120 characters.
content.followUp.blocks[].imagestring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.blocks[].videoobjectNo—
content.followUp.cardsarray<object>NoUp to 30 items. Default: [].
content.followUp.cards[].bodystringYes1–2000 characters.
content.followUp.cards[].buttonobjectNo—
content.followUp.cards[].enabledbooleanNoDefault: true.
content.followUp.cards[].imagestring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.cards[].showWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.cards[].titlestringYes1–120 characters.
content.followUp.chatobjectNoDefault: \{"callContext":true,"enabled":false\}.
content.followUp.chat.callContextbooleanNoDefault: true.
content.followUp.chat.enabledbooleanNoDefault: false.
content.followUp.consentQuestionstringNo1–480 characters. Default: "Can I text you a link with your \{\{vocab.meeting\}\} details and a recap of our call? Message and data rates may apply, and you can reply STOP anytime.".
content.followUp.emailsobjectNo—
content.followUp.emails.after_visitobject | nullNo—
content.followUp.emails.cancel_confirmationobject | nullNo—
content.followUp.emails.initial_linkobject | nullNo—
content.followUp.emails.reminderobject | nullNo—
content.followUp.emails.reschedule_confirmationobject | nullNo—
content.followUp.enabledbooleanNoDefault: false.
content.followUp.formobjectNoDefault: \{"fields":[]\}.
content.followUp.form.fieldsarray<object>NoUp to 8 items. Default: [].
content.followUp.form.introstringNoUp to 480 characters.
content.followUp.leadsobjectNoDefault: \{\}.
content.followUp.leads.afterVisitstringNoUp to 480 characters.
content.followUp.leads.cancelledstringNoUp to 480 characters.
content.followUp.leads.noBookingstringNoUp to 480 characters.
content.followUp.linkExpiryDaysintegerNoBetween 7 and 365. Default: 60.
content.followUp.messagesobjectNoDefault: \{"afterVisit":\{"enabled":false\},"initialSms":"Hi \{\{caller.firstName\}\}, it's \{\{group.name\}\}. Here are your \{\{vocab.meeting\}\} details and a recap of our call: \{\{link\}\} Reply STOP to opt out.","reminders":[\{"before":"24h"\},\{"before":"2h"\}]\}.
content.followUp.messages.afterVisitobjectNoDefault: \{"enabled":false\}.
content.followUp.messages.initialSmsstringYes1–480 characters.
content.followUp.messages.remindersarray<object>NoUp to 4 items. Default: [\{"before":"24h"\},\{"before":"2h"\}].
content.followUp.modulesarray<object>NoDefault: [\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\}].
content.followUp.modules[].blockIdstringNo1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.followUp.modules[].headingstringNoUp to 120 characters.
content.followUp.modules[].showWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.modules[].statesarray<enum>NoItems: "upcoming", "day_of", "after_visit", "no_booking", "cancelled", "expired", "revoked".
content.followUp.prepobjectNoDefault: \{"checklist":[]\}.
content.followUp.prep.bodystringNoUp to 2000 characters.
content.followUp.prep.checklistarray<object>NoUp to 12 items. Default: [].
content.followUp.resourcesarray<object>NoUp to 20 items. Default: [].
content.followUp.resources[].descriptionstringNoUp to 300 characters.
content.followUp.resources[].labelstringYes1–120 characters.
content.followUp.resources[].urlstring (uri)YesA https:// link Up to 2000 characters.
content.followUp.reviewsarray<object>NoUp to 12 items. Default: [].
content.followUp.reviews[].attributionstringNoUp to 120 characters.
content.followUp.reviews[].quotestringYes1–600 characters.
content.followUp.sendWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.sendWhen.allarray<object | object | object | object | object | object | object | object | object | object>Yes(variant 1)
content.followUp.sendWhen.anyarray<object | object | object | object | object | object | object | object | object | object>Yes(variant 2)
content.followUp.sendWhen.notobject | object | object | object | object | object | object | object | object | objectYes(variant 3)
content.followUp.sendWhen.alwaysenumYes(variant 4) One of: true.
content.followUp.sendWhen.factstringYes(variant 5) (variant 1) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.isstring | number | booleanYes(variant 5) (variant 1)
content.followUp.sendWhen.factstringYes(variant 5) (variant 2) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.inarray<string | number | boolean>Yes(variant 5) (variant 2)
content.followUp.sendWhen.factstringYes(variant 5) (variant 3) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.gtnumberYes(variant 5) (variant 3)
content.followUp.sendWhen.factstringYes(variant 5) (variant 4) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.ltnumberYes(variant 5) (variant 4)
content.followUp.sendWhen.betweenarrayYes(variant 5) (variant 5) Up to 2 items.
content.followUp.sendWhen.factstringYes(variant 5) (variant 5) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.factstringYes(variant 5) (variant 6) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.missingbooleanYes(variant 5) (variant 6)
content.followUp.themeobjectNoDefault: \{"accent":"#B4512E","background":"#F7F3EC","font":"system","primary":"#24473D"\}.
content.followUp.theme.accentstringYesPattern: ^#[0-9a-f]\{6\}$.
content.followUp.theme.backgroundstringNoPattern: ^#[0-9a-f]\{6\}$. Default: "#F7F3EC".
content.followUp.theme.fontenumNoOne of: "system", "serif_warm", "sans_modern". Default: "system".
content.followUp.theme.logostring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.theme.primarystringYesPattern: ^#[0-9a-f]\{6\}$.
content.guardrailsobjectYes—
content.guardrails.allowPriceDiscussionbooleanNoDefault: true.
content.guardrails.declineTopicsarray<object>NoDefault: [].
content.guardrails.declineTopics[].textstringYes1–1000 characters.
content.guardrails.emergencyLinestringYes1–300 characters.
content.guardrails.fallbackLinestringYes1–300 characters.
content.guardrails.neverSayarray<object>NoDefault: [].
content.guardrails.neverSay[].textstringYes1–1000 characters.
content.guardrails.prohibitedClaimsarray<object>NoDefault: [].
content.guardrails.prohibitedClaims[].textstringYes1–1000 characters.
content.guardrails.redirectLinesobjectYes—
content.guardrails.redirectLines.existing_customerstringYes1–500 characters.
content.guardrails.redirectLines.job_seekerstringYes1–500 characters.
content.guardrails.redirectLines.resident_familystringYes1–500 characters.
content.guardrails.redirectLines.vendorstringYes1–500 characters.
content.guardrails.redirectLines.wrong_numberstringYes1–500 characters.
content.guardrails.requiredDisclosuresarray<object>NoDefault: [].
content.guardrails.requiredDisclosures[].textstringYes1–1000 characters.
content.integrationsobjectNoDefault: \{\}.
content.integrations.crmobjectNo—
content.integrations.crm.connectionIdstring (conn_… ID)YesID (conn_…)
content.integrations.crm.connectorstringYes1–64 characters.
content.integrations.crm.createContactsbooleanNoDefault: true.
content.integrations.crm.fieldMapmapNoDefault: \{\}.
content.integrations.crm.historyLookbackDaysintegerNoBetween 0 and 3650. Default: 180.
content.integrations.crm.logCallsbooleanNoDefault: true.
content.integrations.crm.optionsmapNoDefault: \{\}.
content.integrations.schedulerobjectNo—
content.integrations.scheduler.activityTypestringYes1–64 characters.
content.integrations.scheduler.connectionIdstring (conn_… ID)YesID (conn_…)
content.integrations.scheduler.connectorstringYes1–64 characters.
content.integrations.scheduler.optionsmapNoDefault: \{\}.
content.knowledgeobjectNoDefault: \{"documents":[],"faq":[]\}.
content.knowledge.documentsarray<object>NoDefault: [].
content.knowledge.documents[].titlestringYes1–200 characters.
content.knowledge.faqarray<object>NoDefault: [].
content.knowledge.faq[].answerstringYes1–2000 characters.
content.knowledge.faq[].questionstringYes1–300 characters.
content.lexiconobjectNoDefault: \{"account":[],"packs":[],"platform":1\}.
content.lexicon.accountarray<object>NoUp to 200 items. Default: [].
content.lexicon.account[].conceptstringYesUp to 80 characters. Pattern: ^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+$.
content.lexicon.account[].neverarray<string>NoUp to 50 items. Default: [].
content.lexicon.account[].phrasesarray<string>NoUp to 50 items. Default: [].
content.lexicon.packsarray<object>NoUp to 10 items. Default: [].
content.lexicon.packs[].versionintegerYesMinimum 1.
content.lexicon.platformintegerNoMinimum 1. Default: 1.
content.locksarray<string>No—
content.modelsobjectNoDefault: \{"keyterms":[]\}.
content.models.keytermsarray<string>NoDefault: [].
content.models.llmstringNoUp to 200 characters.
content.models.sttstringNoUp to 200 characters.
content.objectionsarray<object>NoDefault: [].
content.objections[].guidancestringYes1–1000 characters.
content.objections[].triggerstringYes1–200 characters.
content.objectivesobjectNoDefault: \{"channels":\{\},"fallbacks":[],"primary":\{"label":"Book a meeting","meetingTypes":[],"qualifiedOnly":false,"type":"book_meeting"\},"secondary":[]\}.
content.objectives.channelsobjectNoDefault: \{\}.
content.objectives.channels.page_chatobjectNo—
content.objectives.channels.site_chatobjectNo—
content.objectives.fallbacksarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 3 items. Default: [].
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.fallbacks[].labelstringYes(variant 1) 1–80 characters.
content.objectives.fallbacks[].meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.fallbacks[].qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.fallbacks[].typeenumYes(variant 1) One of: "book_meeting".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.fallbacks[].labelstringYes(variant 2) 1–80 characters.
content.objectives.fallbacks[].reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.fallbacks[].typeenumYes(variant 2) One of: "live_transfer".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.fallbacks[].labelstringYes(variant 3) 1–80 characters.
content.objectives.fallbacks[].requireReasonbooleanNo(variant 3) Default: false.
content.objectives.fallbacks[].typeenumYes(variant 3) One of: "capture_callback".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.fallbacks[].fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.fallbacks[].labelstringYes(variant 4) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 4) One of: "capture_contact".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.fallbacks[].fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.fallbacks[].flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.fallbacks[].labelstringYes(variant 5) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 5) One of: "qualify".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.fallbacks[].labelstringYes(variant 6) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.fallbacks[].labelstringYes(variant 7) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 7) One of: "manage_booking".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.fallbacks[].kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.fallbacks[].labelstringYes(variant 8) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 8) One of: "route_correctly".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.fallbacks[].labelstringYes(variant 9) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 9) One of: "nurture".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.fallbacks[].bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.fallbacks[].labelstringYes(variant 10) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 10) One of: "run_tool".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.fallbacks[].labelstringYes(variant 11) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 11) One of: "answer_questions".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.fallbacks[].labelstringYes(variant 12) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 12) One of: "custom_condition".
content.objectives.fallbacks[].whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.fallbacks[].labelstringYes(variant 13) 1–80 characters.
content.objectives.fallbacks[].rubricstringYes(variant 13) 1–500 characters.
content.objectives.fallbacks[].typeenumYes(variant 13) One of: "custom_judged".
content.objectives.primaryobject | object | object | object | object | object | object | object | object | object | object | object | objectYes—
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.primary.labelstringYes(variant 1) 1–80 characters.
content.objectives.primary.meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.primary.qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.primary.typeenumYes(variant 1) One of: "book_meeting".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.primary.labelstringYes(variant 2) 1–80 characters.
content.objectives.primary.reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.primary.typeenumYes(variant 2) One of: "live_transfer".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.primary.labelstringYes(variant 3) 1–80 characters.
content.objectives.primary.requireReasonbooleanNo(variant 3) Default: false.
content.objectives.primary.typeenumYes(variant 3) One of: "capture_callback".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.primary.fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.primary.labelstringYes(variant 4) 1–80 characters.
content.objectives.primary.typeenumYes(variant 4) One of: "capture_contact".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.primary.fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.primary.flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.primary.labelstringYes(variant 5) 1–80 characters.
content.objectives.primary.typeenumYes(variant 5) One of: "qualify".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.primary.labelstringYes(variant 6) 1–80 characters.
content.objectives.primary.typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.primary.labelstringYes(variant 7) 1–80 characters.
content.objectives.primary.typeenumYes(variant 7) One of: "manage_booking".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.primary.kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.primary.labelstringYes(variant 8) 1–80 characters.
content.objectives.primary.typeenumYes(variant 8) One of: "route_correctly".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.primary.labelstringYes(variant 9) 1–80 characters.
content.objectives.primary.typeenumYes(variant 9) One of: "nurture".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.primary.bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.primary.labelstringYes(variant 10) 1–80 characters.
content.objectives.primary.typeenumYes(variant 10) One of: "run_tool".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.primary.labelstringYes(variant 11) 1–80 characters.
content.objectives.primary.typeenumYes(variant 11) One of: "answer_questions".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.primary.labelstringYes(variant 12) 1–80 characters.
content.objectives.primary.typeenumYes(variant 12) One of: "custom_condition".
content.objectives.primary.whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.primary.labelstringYes(variant 13) 1–80 characters.
content.objectives.primary.rubricstringYes(variant 13) 1–500 characters.
content.objectives.primary.typeenumYes(variant 13) One of: "custom_judged".
content.objectives.secondaryarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 5 items. Default: [].
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.secondary[].labelstringYes(variant 1) 1–80 characters.
content.objectives.secondary[].meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.secondary[].qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.secondary[].typeenumYes(variant 1) One of: "book_meeting".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.secondary[].labelstringYes(variant 2) 1–80 characters.
content.objectives.secondary[].reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.secondary[].typeenumYes(variant 2) One of: "live_transfer".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.secondary[].labelstringYes(variant 3) 1–80 characters.
content.objectives.secondary[].requireReasonbooleanNo(variant 3) Default: false.
content.objectives.secondary[].typeenumYes(variant 3) One of: "capture_callback".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.secondary[].fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.secondary[].labelstringYes(variant 4) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 4) One of: "capture_contact".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.secondary[].fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.secondary[].flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.secondary[].labelstringYes(variant 5) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 5) One of: "qualify".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.secondary[].labelstringYes(variant 6) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.secondary[].labelstringYes(variant 7) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 7) One of: "manage_booking".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.secondary[].kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.secondary[].labelstringYes(variant 8) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 8) One of: "route_correctly".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.secondary[].labelstringYes(variant 9) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 9) One of: "nurture".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.secondary[].bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.secondary[].labelstringYes(variant 10) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 10) One of: "run_tool".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.secondary[].labelstringYes(variant 11) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 11) One of: "answer_questions".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.secondary[].labelstringYes(variant 12) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 12) One of: "custom_condition".
content.objectives.secondary[].whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.secondary[].labelstringYes(variant 13) 1–80 characters.
content.objectives.secondary[].rubricstringYes(variant 13) 1–500 characters.
content.objectives.secondary[].typeenumYes(variant 13) One of: "custom_judged".
content.personaobjectYes—
content.persona.agentNamestringYes1–60 characters.
content.persona.companyNamestringYes1–120 characters.
content.persona.exampleExchangesarray<object>NoDefault: [].
content.persona.exampleExchanges[].agentstringYes1–500 characters.
content.persona.exampleExchanges[].callerstringYes1–500 characters.
content.persona.openingstringYes1–600 characters.
content.persona.openingAfterRingstringNo1–600 characters.
content.persona.openingNotRecordedstringNo1–600 characters.
content.persona.openingQuestionstringYes1–300 characters.
content.persona.preRingNoticestringNo1–300 characters.
content.persona.returningCallerLinestringNoUp to 300 characters.
content.persona.tonestringYes1–300 characters.
content.persona.voiceobjectYes—
content.persona.voice.ambiencebooleanNoDefault: false.
content.persona.voice.expressivebooleanNoDefault: false.
content.persona.voice.modeenumNoOne of: "cascaded". Default: "cascaded".
content.persona.voice.modelstringNoUp to 200 characters.
content.persona.voice.pronunciationsarray<object>NoDefault: [].
content.persona.voice.providerenumYesOne of: "cartesia", "elevenlabs", "deepgram", "fishaudio", "gradium", "inworld", "rime", "xai", "openai", "google".
content.persona.voice.thinkingSoundsbooleanNoDefault: true.
content.persona.voice.tuningmapNoDefault: \{\}.
content.persona.voice.voiceIdstringYes1–200 characters.
content.pricingobjectNoDefault: \{"feeLine":"The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.","floorPlanLine":"\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.","mentionSpecials":"when_price_comes_up","notOfferedLine":"\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.","onRequestLine":"Our team will go over pricing for \{\{price.service\}\} with you.","otherLocations":"off","otherLocationsLine":"\{\{price.service\}\} is offered at \{\{price.locations\}\}.","specialLine":"\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.","specialLineOpenEnded":"\{\{price.specialWording\}\}.","startingAtLine":"\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.","startingAtWithOptions":"\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}."\}.
content.pricing.feeLinestringNo1–300 characters. Default: "The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.".
content.pricing.floorPlanLinestringNo1–300 characters. Default: "\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.".
content.pricing.mentionSpecialsenumNoOne of: "when_price_comes_up", "once_after_discovery", "only_when_asked". Default: "when_price_comes_up".
content.pricing.notOfferedLinestringNo1–300 characters. Default: "\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.".
content.pricing.onRequestLinestringNo1–300 characters. Default: "Our team will go over pricing for \{\{price.service\}\} with you.".
content.pricing.otherLocationsenumNoOne of: "off", "mention", "mention_and_connect". Default: "off".
content.pricing.otherLocationsLinestringNo1–300 characters. Default: "\{\{price.service\}\} is offered at \{\{price.locations\}\}.".
content.pricing.specialLinestringNo1–300 characters. Default: "\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.".
content.pricing.specialLineOpenEndedstringNo1–300 characters. Default: "\{\{price.specialWording\}\}.".
content.pricing.startingAtLinestringNo1–300 characters. Default: "\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.".
content.pricing.startingAtWithOptionsstringNo1–300 characters. Default: "\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}.".
content.recordingobjectNoDefault: \{"enabled":true\}.
content.recording.enabledbooleanNoDefault: true.
content.retentionobjectNoDefault: \{"recordingDays":90,"transcriptDays":90\}.
content.retention.recordingDaysintegerNoBetween 1 and 3650. Default: 90.
content.retention.transcriptDaysintegerNoBetween 1 and 3650. Default: 90.
content.schemaVersionenumNoOne of: 1. Default: 1.
content.toolsobjectNoDefault: \{"bindings":[]\}.
content.tools.bindingsarray<object>NoUp to 20 items. Default: [].
content.tools.bindings[].allowCallerInputbooleanNoDefault: true.
content.tools.bindings[].argsmapNoDefault: \{\}.
content.tools.bindings[].asstringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.tools.bindings[].channelsarray<enum>NoItems: "phone", "web_voice", "web_chat". Default: ["phone","web_voice","web_chat"].
content.tools.bindings[].confirmWithCallerbooleanNoDefault: false.
content.tools.bindings[].enabledbooleanNoDefault: true.
content.tools.bindings[].holdingLinestringNo1–200 characters.
content.tools.bindings[].inputsmapNoDefault: \{\}.
content.tools.bindings[].labelstringYes1–80 characters.
content.tools.bindings[].maxCallsintegerNoBetween 1 and 3. Default: 3.
content.tools.bindings[].onFailureenumNoOne of: "say_will_follow_up", "continue_silently", "offer_callback", "transfer". Default: "say_will_follow_up".
content.tools.bindings[].resultobjectYes—
content.tools.bindings[].toolobjectYes—
content.tools.bindings[].triggerobject | objectYes—
content.tools.bindings[].whenobject | object | object | object | object | object | object | object | object | objectNo—
content.visitActionsobjectNo—
content.visitActions.allowCustombooleanNoDefault: true.
content.visitActions.itemsarray<object>NoUp to 30 items.
content.visitActions.items[].crmTaskbooleanNoDefault: false.
content.visitActions.items[].dueDaysintegerNoBetween 0 and 30. Default: 1.
content.visitActions.items[].keystringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.visitActions.items[].labelstringYes1–240 characters.
content.visitActions.items[].ownerenumNoOne of: "rep", "backup". Default: "rep".
content.visitActions.typedCrmTaskbooleanNoDefault: false.
content.webWidgetobjectNoDefault: \{"continuationDisclosure":"Hi again — this is the AI assistant you spoke with on the phone.","continuationGreeting":"I have the notes from your call, so we can pick up right where we left off. What else can I help with?","copy":\{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\},"disclosure":"Hi — I am an AI assistant, and I can answer questions or book you a time to visit.","enabled":false,"greeting":"What would you like to know?","launcher":\{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\},"limits":\{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\},"panel":\{"height":620,"presentation":"panel","width":400\},"showMedia":false,"surfaces":\{"chat":true,"voice":false\},"theme":\{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}\}.
content.webWidget.continuationDisclosurestringNo1–320 characters. Default: "Hi again — this is the AI assistant you spoke with on the phone.".
content.webWidget.continuationGreetingstringNo1–320 characters. Default: "I have the notes from your call, so we can pick up right where we left off. What else can I help with?".
content.webWidget.copyobjectNoDefault: \{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\}.
content.webWidget.copy.agentLabelstringNo1–80 characters. Default: "AI assistant".
content.webWidget.copy.choicesLabelstringNo1–80 characters. Default: "Tap an answer, or type your own".
content.webWidget.copy.closeLabelstringNo1–80 characters. Default: "Close the chat".
content.webWidget.copy.composerDisabledNotestringNo1–320 characters. Default: "Messaging is not switched on here yet.".
content.webWidget.copy.continuingNotestringNo1–80 characters. Default: "Continuing from your call on \{date\}".
content.webWidget.copy.endedNotestringNo1–320 characters. Default: "This conversation has ended.".
content.webWidget.copy.errorBodystringNo1–320 characters. Default: "Please try again in a moment, or call us and we will help.".
content.webWidget.copy.errorTitlestringNo1–80 characters. Default: "We could not load the chat".
content.webWidget.copy.inputPlaceholderstringNo1–80 characters. Default: "Type your question".
content.webWidget.copy.loadingLabelstringNo1–80 characters. Default: "Loading the chat".
content.webWidget.copy.newChatLabelstringNo1–80 characters. Default: "Start a new chat".
content.webWidget.copy.notAllowedBodystringNo1–320 characters. Default: "If you run this website, add it to the allowed list in your admin settings.".
content.webWidget.copy.notAllowedTitlestringNo1–80 characters. Default: "This chat is not available on this site".
content.webWidget.copy.openLabelstringNo1–80 characters. Default: "Open the chat".
content.webWidget.copy.retryLabelstringNo1–80 characters. Default: "Try again".
content.webWidget.copy.sendFailedstringNo1–320 characters. Default: "That message did not send. Please try again.".
content.webWidget.copy.sendLabelstringNo1–80 characters. Default: "Send".
content.webWidget.copy.subtitlestringNo1–80 characters. Default: "Answers in a moment".
content.webWidget.copy.typingLabelstringNo1–80 characters. Default: "Writing a reply".
content.webWidget.copy.visitorLabelstringNo1–80 characters. Default: "You".
content.webWidget.disclosurestringNo1–320 characters. Default: "Hi — I am an AI assistant, and I can answer questions or book you a time to visit.".
content.webWidget.enabledbooleanNoDefault: false.
content.webWidget.greetingstringNo1–320 characters. Default: "What would you like to know?".
content.webWidget.launcherobjectNoDefault: \{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\}.
content.webWidget.launcher.iconenumNoOne of: "chat", "message", "question", "sparkle", "phone", "headset". Default: "chat".
content.webWidget.launcher.iconUrlstring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.launcher.labelstringNo1–80 characters. Default: "Chat with us".
content.webWidget.launcher.offsetobjectNoDefault: \{"x":20,"y":20\}.
content.webWidget.launcher.positionenumNoOne of: "bottom-right", "bottom-left". Default: "bottom-right".
content.webWidget.launcher.shapeenumNoOne of: "circle", "rounded". Default: "circle".
content.webWidget.launcher.showLabelbooleanNoDefault: false.
content.webWidget.launcher.sizeenumNoOne of: "medium", "large". Default: "medium".
content.webWidget.limitsobjectNoDefault: \{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\}.
content.webWidget.limits.charactersPerMessageintegerNoBetween 200 and 8000. Default: 2000.
content.webWidget.limits.messagesPerConversationintegerNoBetween 1 and 2000. Default: 200.
content.webWidget.limits.messagesPerHourintegerNoBetween 1 and 500. Default: 30.
content.webWidget.panelobjectNoDefault: \{"height":620,"presentation":"panel","width":400\}.
content.webWidget.panel.headingstringNo1–80 characters.
content.webWidget.panel.heightintegerNoBetween 420 and 800. Default: 620.
content.webWidget.panel.presentationenumNoOne of: "panel", "sheet", "fullscreen". Default: "panel".
content.webWidget.panel.widthintegerNoBetween 320 and 560. Default: 400.
content.webWidget.showMediabooleanNoDefault: false.
content.webWidget.surfacesobjectNoDefault: \{"chat":true,"voice":false\}.
content.webWidget.surfaces.chatbooleanNoDefault: true.
content.webWidget.surfaces.voicebooleanNoDefault: false.
content.webWidget.themeobjectNoDefault: \{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}.
content.webWidget.theme.avatarstring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.theme.darkobjectNoDefault: \{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\}.
content.webWidget.theme.fontenumNoOne of: "system", "serif_warm", "sans_modern". Default: "system".
content.webWidget.theme.lightobjectNoDefault: \{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\}.
content.webWidget.theme.logostring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.theme.radiusobjectNoDefault: \{"bubble":14,"launcher":28,"panel":16\}.
content.webWidget.theme.schemeenumNoOne of: "auto", "light", "dark". Default: "auto".
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
changesarray<PlaybookChange>Yes—
changes[].afteranyNo—
changes[].beforeanyNo—
changes[].kindenumYesOne of: "added", "removed", "changed".
changes[].pathstringYes—
changes[].summarystringYes—
checklistarray<ValidationMessage>Yes—
checklist[].messagestringYes—
checklist[].pathstringYes—
checklist[].severityenumYesOne of: "error", "warning".
draftPlaybookVersionYes—
draft.authorIdstring (usr_… ID) | string (svc_… ID) | nullYes—
draft.changeNotestring | nullYes—
draft.contentPlaybookContentYesThe full playbook content.
draft.content.bookingobjectYes—
draft.content.booking.allowUnqualifiedbooleanNoDefault: false.
draft.content.booking.maxBookingsPerCallintegerNoBetween 1 and 2. Default: 2.
draft.content.booking.minNoticeMinutesintegerNoBetween 0 and 10080. Default: 60.
draft.content.booking.offerSlotsintegerNoBetween 1 and 4. Default: 2.
draft.content.booking.rulesarray<object>Yes—
draft.content.briefstringYes1–12000 characters.
draft.content.defaultFlowIdstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
draft.content.escalationobjectYes—
draft.content.escalation.afterFailedAnswersintegerNoBetween 1 and 5. Default: 2.
draft.content.escalation.onFrustrationbooleanNoDefault: true.
draft.content.escalation.onGuardrailHitbooleanNoDefault: true.
draft.content.escalation.transferLinestringYes1–300 characters.
draft.content.escalation.transferModeenumNoOne of: "cold", "warm". Default: "cold".
draft.content.escalation.unavailableLinestringYes1–300 characters.
draft.content.flowsarray<object>Yes—
draft.content.flows[].brancharray<object>NoDefault: [].
draft.content.flows[].disqualifyarray<object>NoDefault: [].
draft.content.flows[].enterWhenstringYes1–500 characters.
draft.content.flows[].fieldsarray<object>Yes—
draft.content.flows[].goalstringYes1–500 characters.
draft.content.flows[].maxQuestionsBeforeValueintegerNoBetween 1 and 10. Default: 2.
draft.content.flows[].namestringYes1–120 characters.
draft.content.flows[].talkingPointsarray<object | object>NoDefault: [].
draft.content.followUpobjectNo—
draft.content.followUp.blocksarray<object>NoUp to 20 items. Default: [].
draft.content.followUp.cardsarray<object>NoUp to 30 items. Default: [].
draft.content.followUp.chatobjectNoDefault: \{"callContext":true,"enabled":false\}.
draft.content.followUp.consentQuestionstringNo1–480 characters. Default: "Can I text you a link with your \{\{vocab.meeting\}\} details and a recap of our call? Message and data rates may apply, and you can reply STOP anytime.".
draft.content.followUp.emailsobjectNo—
draft.content.followUp.enabledbooleanNoDefault: false.
draft.content.followUp.formobjectNoDefault: \{"fields":[]\}.
draft.content.followUp.leadsobjectNoDefault: \{\}.
draft.content.followUp.linkExpiryDaysintegerNoBetween 7 and 365. Default: 60.
draft.content.followUp.messagesobjectNoDefault: \{"afterVisit":\{"enabled":false\},"initialSms":"Hi \{\{caller.firstName\}\}, it's \{\{group.name\}\}. Here are your \{\{vocab.meeting\}\} details and a recap of our call: \{\{link\}\} Reply STOP to opt out.","reminders":[\{"before":"24h"\},\{"before":"2h"\}]\}.
draft.content.followUp.modulesarray<object>NoDefault: [\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\}].
draft.content.followUp.prepobjectNoDefault: \{"checklist":[]\}.
draft.content.followUp.resourcesarray<object>NoUp to 20 items. Default: [].
draft.content.followUp.reviewsarray<object>NoUp to 12 items. Default: [].
draft.content.followUp.sendWhenobject | object | object | object | object | object | object | object | object | objectNo—
draft.content.followUp.themeobjectNoDefault: \{"accent":"#B4512E","background":"#F7F3EC","font":"system","primary":"#24473D"\}.
draft.content.guardrailsobjectYes—
draft.content.guardrails.allowPriceDiscussionbooleanNoDefault: true.
draft.content.guardrails.declineTopicsarray<object>NoDefault: [].
draft.content.guardrails.emergencyLinestringYes1–300 characters.
draft.content.guardrails.fallbackLinestringYes1–300 characters.
draft.content.guardrails.neverSayarray<object>NoDefault: [].
draft.content.guardrails.prohibitedClaimsarray<object>NoDefault: [].
draft.content.guardrails.redirectLinesobjectYes—
draft.content.guardrails.requiredDisclosuresarray<object>NoDefault: [].
draft.content.integrationsobjectNoDefault: \{\}.
draft.content.integrations.crmobjectNo—
draft.content.integrations.schedulerobjectNo—
draft.content.knowledgeobjectNoDefault: \{"documents":[],"faq":[]\}.
draft.content.knowledge.documentsarray<object>NoDefault: [].
draft.content.knowledge.faqarray<object>NoDefault: [].
draft.content.lexiconobjectNoDefault: \{"account":[],"packs":[],"platform":1\}.
draft.content.lexicon.accountarray<object>NoUp to 200 items. Default: [].
draft.content.lexicon.packsarray<object>NoUp to 10 items. Default: [].
draft.content.lexicon.platformintegerNoMinimum 1. Default: 1.
draft.content.locksarray<string>No—
draft.content.modelsobjectNoDefault: \{"keyterms":[]\}.
draft.content.models.keytermsarray<string>NoDefault: [].
draft.content.models.llmstringNoUp to 200 characters.
draft.content.models.sttstringNoUp to 200 characters.
draft.content.objectionsarray<object>NoDefault: [].
draft.content.objections[].guidancestringYes1–1000 characters.
draft.content.objections[].triggerstringYes1–200 characters.
draft.content.objectivesobjectNoDefault: \{"channels":\{\},"fallbacks":[],"primary":\{"label":"Book a meeting","meetingTypes":[],"qualifiedOnly":false,"type":"book_meeting"\},"secondary":[]\}.
draft.content.objectives.channelsobjectNoDefault: \{\}.
draft.content.objectives.fallbacksarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 3 items. Default: [].
draft.content.objectives.primaryobject | object | object | object | object | object | object | object | object | object | object | object | objectYes—
draft.content.objectives.secondaryarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 5 items. Default: [].
draft.content.personaobjectYes—
draft.content.persona.agentNamestringYes1–60 characters.
draft.content.persona.companyNamestringYes1–120 characters.
draft.content.persona.exampleExchangesarray<object>NoDefault: [].
draft.content.persona.openingstringYes1–600 characters.
draft.content.persona.openingAfterRingstringNo1–600 characters.
draft.content.persona.openingNotRecordedstringNo1–600 characters.
draft.content.persona.openingQuestionstringYes1–300 characters.
draft.content.persona.preRingNoticestringNo1–300 characters.
draft.content.persona.returningCallerLinestringNoUp to 300 characters.
draft.content.persona.tonestringYes1–300 characters.
draft.content.persona.voiceobjectYes—
draft.content.pricingobjectNoDefault: \{"feeLine":"The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.","floorPlanLine":"\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.","mentionSpecials":"when_price_comes_up","notOfferedLine":"\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.","onRequestLine":"Our team will go over pricing for \{\{price.service\}\} with you.","otherLocations":"off","otherLocationsLine":"\{\{price.service\}\} is offered at \{\{price.locations\}\}.","specialLine":"\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.","specialLineOpenEnded":"\{\{price.specialWording\}\}.","startingAtLine":"\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.","startingAtWithOptions":"\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}."\}.
draft.content.pricing.feeLinestringNo1–300 characters. Default: "The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.".
draft.content.pricing.floorPlanLinestringNo1–300 characters. Default: "\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.".
draft.content.pricing.mentionSpecialsenumNoOne of: "when_price_comes_up", "once_after_discovery", "only_when_asked". Default: "when_price_comes_up".
draft.content.pricing.notOfferedLinestringNo1–300 characters. Default: "\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.".
draft.content.pricing.onRequestLinestringNo1–300 characters. Default: "Our team will go over pricing for \{\{price.service\}\} with you.".
draft.content.pricing.otherLocationsenumNoOne of: "off", "mention", "mention_and_connect". Default: "off".
draft.content.pricing.otherLocationsLinestringNo1–300 characters. Default: "\{\{price.service\}\} is offered at \{\{price.locations\}\}.".
draft.content.pricing.specialLinestringNo1–300 characters. Default: "\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.".
draft.content.pricing.specialLineOpenEndedstringNo1–300 characters. Default: "\{\{price.specialWording\}\}.".
draft.content.pricing.startingAtLinestringNo1–300 characters. Default: "\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.".
draft.content.pricing.startingAtWithOptionsstringNo1–300 characters. Default: "\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}.".
draft.content.recordingobjectNoDefault: \{"enabled":true\}.
draft.content.recording.enabledbooleanNoDefault: true.
draft.content.retentionobjectNoDefault: \{"recordingDays":90,"transcriptDays":90\}.
draft.content.retention.recordingDaysintegerNoBetween 1 and 3650. Default: 90.
draft.content.retention.transcriptDaysintegerNoBetween 1 and 3650. Default: 90.
draft.content.schemaVersionenumNoOne of: 1. Default: 1.
draft.content.toolsobjectNoDefault: \{"bindings":[]\}.
draft.content.tools.bindingsarray<object>NoUp to 20 items. Default: [].
draft.content.visitActionsobjectNo—
draft.content.visitActions.allowCustombooleanNoDefault: true.
draft.content.visitActions.itemsarray<object>NoUp to 30 items.
draft.content.visitActions.typedCrmTaskbooleanNoDefault: false.
draft.content.webWidgetobjectNoDefault: \{"continuationDisclosure":"Hi again — this is the AI assistant you spoke with on the phone.","continuationGreeting":"I have the notes from your call, so we can pick up right where we left off. What else can I help with?","copy":\{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\},"disclosure":"Hi — I am an AI assistant, and I can answer questions or book you a time to visit.","enabled":false,"greeting":"What would you like to know?","launcher":\{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\},"limits":\{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\},"panel":\{"height":620,"presentation":"panel","width":400\},"showMedia":false,"surfaces":\{"chat":true,"voice":false\},"theme":\{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}\}.
draft.content.webWidget.continuationDisclosurestringNo1–320 characters. Default: "Hi again — this is the AI assistant you spoke with on the phone.".
draft.content.webWidget.continuationGreetingstringNo1–320 characters. Default: "I have the notes from your call, so we can pick up right where we left off. What else can I help with?".
draft.content.webWidget.copyobjectNoDefault: \{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\}.
draft.content.webWidget.disclosurestringNo1–320 characters. Default: "Hi — I am an AI assistant, and I can answer questions or book you a time to visit.".
draft.content.webWidget.enabledbooleanNoDefault: false.
draft.content.webWidget.greetingstringNo1–320 characters. Default: "What would you like to know?".
draft.content.webWidget.launcherobjectNoDefault: \{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\}.
draft.content.webWidget.limitsobjectNoDefault: \{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\}.
draft.content.webWidget.panelobjectNoDefault: \{"height":620,"presentation":"panel","width":400\}.
draft.content.webWidget.showMediabooleanNoDefault: false.
draft.content.webWidget.surfacesobjectNoDefault: \{"chat":true,"voice":false\}.
draft.content.webWidget.themeobjectNoDefault: \{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}.
draft.contentHashstringYes—
draft.createdAtstring (date-time)Yes—
draft.idstring (pbv_… ID)YesID (pbv_…)
draft.publishedAtstring (date-time) | nullYes—
draft.publishedBystring (usr_… ID) | string (svc_… ID) | nullYes—
draft.statusenumYesOne of: "draft", "published", "archived", "discarded".
draft.updatedAtstring (date-time)Yes—
draft.versionintegerYes—

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

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/draft" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "content": {
    "persona": {
      "agentName": "string",
      "companyName": "string",
      "tone": "string",
      "opening": "string",
      "openingQuestion": "string",
      "voice": {
        "provider": "cartesia",
        "voiceId": "string"
      }
    },
    "brief": "string",
    "flows": [
      {
        "name": "string",
        "goal": "string",
        "enterWhen": "string",
        "fields": [
          {
            "key": "string",
            "ask": "string",
            "type": "text"
          }
        ]
      }
    ],
    "defaultFlowId": "string",
    "booking": {
      "rules": [
        {
          "when": {},
          "then": {}
        }
      ]
    },
    "escalation": {
      "transferLine": "string",
      "unavailableLine": "string"
    },
    "guardrails": {
      "fallbackLine": "string",
      "emergencyLine": "string",
      "redirectLines": {
        "wrong_number": "string",
        "existing_customer": "string",
        "vendor": "string",
        "job_seeker": "string",
        "resident_family": "string"
      }
    }
  }
}'

Discard the draft (only when a published version exists). A draft that ran test calls is kept, hidden, so those calls still show what ran#

DELETE /v1/account/playbooks/{playbookId}/draft

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Response 200

FieldTypeRequiredDescription
discardedbooleanYes—

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

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/draft" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Route this playbook's calls to a person or voicemail at once, without a deploy#

PUT /v1/account/playbooks/{playbookId}/kill-switch

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Request body

application/json, required.

FieldTypeRequiredDescription
enabledbooleanYes—
modeenumNoOne of: "human", "voicemail".

Response 200

FieldTypeRequiredDescription
archivedbooleanYes—
createdAtstring (date-time)Yes—
descriptionstring | nullYes—
draftobject | nullYes—
draft.updatedAtstring (date-time)Yes—
draft.versionintegerYes—
draft.versionIdstring (pbv_… ID)YesID (pbv_…)
idstring (pb_… ID)YesID (pb_…)
isSamplebooleanYes—
killSwitchbooleanYes—
killSwitchModeenumYesOne of: "human", "voicemail".
latestPublishedVersioninteger | nullYes—
namestringYes—
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/account/playbooks/{playbookId}/kill-switch" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "enabled": true
}'

Publish the draft as the next version and update every group that follows it#

POST /v1/account/playbooks/{playbookId}/publish

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Request body

application/json, required.

FieldTypeRequiredDescription
expectedHashstringNoExactly 64 characters.
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
changesarray<PlaybookChange>Yes—
changes[].afteranyNo—
changes[].beforeanyNo—
changes[].kindenumYesOne of: "added", "removed", "changed".
changes[].pathstringYes—
changes[].summarystringYes—
groupsarray<object>Yes—
groups[].groupIdstring (grp_… ID)YesID (grp_…)
groups[].groupNamestringYes—
groups[].issuesarray<string>Yes—
groups[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
versionPlaybookVersionYes—
version.authorIdstring (usr_… ID) | string (svc_… ID) | nullYes—
version.changeNotestring | nullYes—
version.contentPlaybookContentYesThe full playbook content.
version.content.bookingobjectYes—
version.content.booking.allowUnqualifiedbooleanNoDefault: false.
version.content.booking.maxBookingsPerCallintegerNoBetween 1 and 2. Default: 2.
version.content.booking.minNoticeMinutesintegerNoBetween 0 and 10080. Default: 60.
version.content.booking.offerSlotsintegerNoBetween 1 and 4. Default: 2.
version.content.booking.rulesarray<object>Yes—
version.content.briefstringYes1–12000 characters.
version.content.defaultFlowIdstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
version.content.escalationobjectYes—
version.content.escalation.afterFailedAnswersintegerNoBetween 1 and 5. Default: 2.
version.content.escalation.onFrustrationbooleanNoDefault: true.
version.content.escalation.onGuardrailHitbooleanNoDefault: true.
version.content.escalation.transferLinestringYes1–300 characters.
version.content.escalation.transferModeenumNoOne of: "cold", "warm". Default: "cold".
version.content.escalation.unavailableLinestringYes1–300 characters.
version.content.flowsarray<object>Yes—
version.content.flows[].brancharray<object>NoDefault: [].
version.content.flows[].disqualifyarray<object>NoDefault: [].
version.content.flows[].enterWhenstringYes1–500 characters.
version.content.flows[].fieldsarray<object>Yes—
version.content.flows[].goalstringYes1–500 characters.
version.content.flows[].maxQuestionsBeforeValueintegerNoBetween 1 and 10. Default: 2.
version.content.flows[].namestringYes1–120 characters.
version.content.flows[].talkingPointsarray<object | object>NoDefault: [].
version.content.followUpobjectNo—
version.content.followUp.blocksarray<object>NoUp to 20 items. Default: [].
version.content.followUp.cardsarray<object>NoUp to 30 items. Default: [].
version.content.followUp.chatobjectNoDefault: \{"callContext":true,"enabled":false\}.
version.content.followUp.consentQuestionstringNo1–480 characters. Default: "Can I text you a link with your \{\{vocab.meeting\}\} details and a recap of our call? Message and data rates may apply, and you can reply STOP anytime.".
version.content.followUp.emailsobjectNo—
version.content.followUp.enabledbooleanNoDefault: false.
version.content.followUp.formobjectNoDefault: \{"fields":[]\}.
version.content.followUp.leadsobjectNoDefault: \{\}.
version.content.followUp.linkExpiryDaysintegerNoBetween 7 and 365. Default: 60.
version.content.followUp.messagesobjectNoDefault: \{"afterVisit":\{"enabled":false\},"initialSms":"Hi \{\{caller.firstName\}\}, it's \{\{group.name\}\}. Here are your \{\{vocab.meeting\}\} details and a recap of our call: \{\{link\}\} Reply STOP to opt out.","reminders":[\{"before":"24h"\},\{"before":"2h"\}]\}.
version.content.followUp.modulesarray<object>NoDefault: [\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\}].
version.content.followUp.prepobjectNoDefault: \{"checklist":[]\}.
version.content.followUp.resourcesarray<object>NoUp to 20 items. Default: [].
version.content.followUp.reviewsarray<object>NoUp to 12 items. Default: [].
version.content.followUp.sendWhenobject | object | object | object | object | object | object | object | object | objectNo—
version.content.followUp.themeobjectNoDefault: \{"accent":"#B4512E","background":"#F7F3EC","font":"system","primary":"#24473D"\}.
version.content.guardrailsobjectYes—
version.content.guardrails.allowPriceDiscussionbooleanNoDefault: true.
version.content.guardrails.declineTopicsarray<object>NoDefault: [].
version.content.guardrails.emergencyLinestringYes1–300 characters.
version.content.guardrails.fallbackLinestringYes1–300 characters.
version.content.guardrails.neverSayarray<object>NoDefault: [].
version.content.guardrails.prohibitedClaimsarray<object>NoDefault: [].
version.content.guardrails.redirectLinesobjectYes—
version.content.guardrails.requiredDisclosuresarray<object>NoDefault: [].
version.content.integrationsobjectNoDefault: \{\}.
version.content.integrations.crmobjectNo—
version.content.integrations.schedulerobjectNo—
version.content.knowledgeobjectNoDefault: \{"documents":[],"faq":[]\}.
version.content.knowledge.documentsarray<object>NoDefault: [].
version.content.knowledge.faqarray<object>NoDefault: [].
version.content.lexiconobjectNoDefault: \{"account":[],"packs":[],"platform":1\}.
version.content.lexicon.accountarray<object>NoUp to 200 items. Default: [].
version.content.lexicon.packsarray<object>NoUp to 10 items. Default: [].
version.content.lexicon.platformintegerNoMinimum 1. Default: 1.
version.content.locksarray<string>No—
version.content.modelsobjectNoDefault: \{"keyterms":[]\}.
version.content.models.keytermsarray<string>NoDefault: [].
version.content.models.llmstringNoUp to 200 characters.
version.content.models.sttstringNoUp to 200 characters.
version.content.objectionsarray<object>NoDefault: [].
version.content.objections[].guidancestringYes1–1000 characters.
version.content.objections[].triggerstringYes1–200 characters.
version.content.objectivesobjectNoDefault: \{"channels":\{\},"fallbacks":[],"primary":\{"label":"Book a meeting","meetingTypes":[],"qualifiedOnly":false,"type":"book_meeting"\},"secondary":[]\}.
version.content.objectives.channelsobjectNoDefault: \{\}.
version.content.objectives.fallbacksarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 3 items. Default: [].
version.content.objectives.primaryobject | object | object | object | object | object | object | object | object | object | object | object | objectYes—
version.content.objectives.secondaryarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 5 items. Default: [].
version.content.personaobjectYes—
version.content.persona.agentNamestringYes1–60 characters.
version.content.persona.companyNamestringYes1–120 characters.
version.content.persona.exampleExchangesarray<object>NoDefault: [].
version.content.persona.openingstringYes1–600 characters.
version.content.persona.openingAfterRingstringNo1–600 characters.
version.content.persona.openingNotRecordedstringNo1–600 characters.
version.content.persona.openingQuestionstringYes1–300 characters.
version.content.persona.preRingNoticestringNo1–300 characters.
version.content.persona.returningCallerLinestringNoUp to 300 characters.
version.content.persona.tonestringYes1–300 characters.
version.content.persona.voiceobjectYes—
version.content.pricingobjectNoDefault: \{"feeLine":"The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.","floorPlanLine":"\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.","mentionSpecials":"when_price_comes_up","notOfferedLine":"\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.","onRequestLine":"Our team will go over pricing for \{\{price.service\}\} with you.","otherLocations":"off","otherLocationsLine":"\{\{price.service\}\} is offered at \{\{price.locations\}\}.","specialLine":"\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.","specialLineOpenEnded":"\{\{price.specialWording\}\}.","startingAtLine":"\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.","startingAtWithOptions":"\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}."\}.
version.content.pricing.feeLinestringNo1–300 characters. Default: "The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.".
version.content.pricing.floorPlanLinestringNo1–300 characters. Default: "\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.".
version.content.pricing.mentionSpecialsenumNoOne of: "when_price_comes_up", "once_after_discovery", "only_when_asked". Default: "when_price_comes_up".
version.content.pricing.notOfferedLinestringNo1–300 characters. Default: "\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.".
version.content.pricing.onRequestLinestringNo1–300 characters. Default: "Our team will go over pricing for \{\{price.service\}\} with you.".
version.content.pricing.otherLocationsenumNoOne of: "off", "mention", "mention_and_connect". Default: "off".
version.content.pricing.otherLocationsLinestringNo1–300 characters. Default: "\{\{price.service\}\} is offered at \{\{price.locations\}\}.".
version.content.pricing.specialLinestringNo1–300 characters. Default: "\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.".
version.content.pricing.specialLineOpenEndedstringNo1–300 characters. Default: "\{\{price.specialWording\}\}.".
version.content.pricing.startingAtLinestringNo1–300 characters. Default: "\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.".
version.content.pricing.startingAtWithOptionsstringNo1–300 characters. Default: "\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}.".
version.content.recordingobjectNoDefault: \{"enabled":true\}.
version.content.recording.enabledbooleanNoDefault: true.
version.content.retentionobjectNoDefault: \{"recordingDays":90,"transcriptDays":90\}.
version.content.retention.recordingDaysintegerNoBetween 1 and 3650. Default: 90.
version.content.retention.transcriptDaysintegerNoBetween 1 and 3650. Default: 90.
version.content.schemaVersionenumNoOne of: 1. Default: 1.
version.content.toolsobjectNoDefault: \{"bindings":[]\}.
version.content.tools.bindingsarray<object>NoUp to 20 items. Default: [].
version.content.visitActionsobjectNo—
version.content.visitActions.allowCustombooleanNoDefault: true.
version.content.visitActions.itemsarray<object>NoUp to 30 items.
version.content.visitActions.typedCrmTaskbooleanNoDefault: false.
version.content.webWidgetobjectNoDefault: \{"continuationDisclosure":"Hi again — this is the AI assistant you spoke with on the phone.","continuationGreeting":"I have the notes from your call, so we can pick up right where we left off. What else can I help with?","copy":\{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\},"disclosure":"Hi — I am an AI assistant, and I can answer questions or book you a time to visit.","enabled":false,"greeting":"What would you like to know?","launcher":\{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\},"limits":\{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\},"panel":\{"height":620,"presentation":"panel","width":400\},"showMedia":false,"surfaces":\{"chat":true,"voice":false\},"theme":\{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}\}.
version.content.webWidget.continuationDisclosurestringNo1–320 characters. Default: "Hi again — this is the AI assistant you spoke with on the phone.".
version.content.webWidget.continuationGreetingstringNo1–320 characters. Default: "I have the notes from your call, so we can pick up right where we left off. What else can I help with?".
version.content.webWidget.copyobjectNoDefault: \{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\}.
version.content.webWidget.disclosurestringNo1–320 characters. Default: "Hi — I am an AI assistant, and I can answer questions or book you a time to visit.".
version.content.webWidget.enabledbooleanNoDefault: false.
version.content.webWidget.greetingstringNo1–320 characters. Default: "What would you like to know?".
version.content.webWidget.launcherobjectNoDefault: \{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\}.
version.content.webWidget.limitsobjectNoDefault: \{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\}.
version.content.webWidget.panelobjectNoDefault: \{"height":620,"presentation":"panel","width":400\}.
version.content.webWidget.showMediabooleanNoDefault: false.
version.content.webWidget.surfacesobjectNoDefault: \{"chat":true,"voice":false\}.
version.content.webWidget.themeobjectNoDefault: \{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}.
version.contentHashstringYes—
version.createdAtstring (date-time)Yes—
version.idstring (pbv_… ID)YesID (pbv_…)
version.publishedAtstring (date-time) | nullYes—
version.publishedBystring (usr_… ID) | string (svc_… ID) | nullYes—
version.statusenumYesOne of: "draft", "published", "archived", "discarded".
version.updatedAtstring (date-time)Yes—
version.versionintegerYes—
warningsarray<ValidationMessage>Yes—
warnings[].messagestringYes—
warnings[].pathstringYes—
warnings[].severityenumYesOne of: "error", "warning".

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/publish" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "expectedHash": "string",
  "note": "string"
}'

How the question map is arranged: the account's arrangement, and a group's own when groupId is given#

GET /v1/account/playbooks/{playbookId}/question-map/layout

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Query parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)NoID (grp_…)

Response 200

FieldTypeRequiredDescription
accountany | nullYes—
groupany | nullYes—

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

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/question-map/layout" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Save where the cards sit on the question map (the account’s, or a group’s own)#

PUT /v1/account/playbooks/{playbookId}/question-map/layout

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Request body

application/json, required.

FieldTypeRequiredDescription
groupIdstring (grp_… ID)NoID (grp_…)
positionsmapYes—
positions.{key}objectNoAny key.
positions.{key}.xnumberYes—
positions.{key}.ynumberYes—

Response 200

FieldTypeRequiredDescription
groupIdstring (grp_… ID) | nullYes—
positionsmapYes—
positions.{key}objectNoAny key.
positions.{key}.xnumberYes—
positions.{key}.ynumberYes—
updatedAtstring (date-time)Yes—
updatedBystring (usr_… ID) | string (svc_… ID) | nullYes—

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

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/question-map/layout" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "positions": {}
}'

Tidy up: drop the saved arrangement so the map arranges itself again#

DELETE /v1/account/playbooks/{playbookId}/question-map/layout

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Query parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)NoID (grp_…)

Response 200

FieldTypeRequiredDescription
resetbooleanYes—

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

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/question-map/layout" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

How many calls took each arrow of the question map in the last days days (test calls left out)#

GET /v1/account/playbooks/{playbookId}/question-map/traffic

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Query parameters

NameTypeRequiredDescription
daysintegerNoBetween 1 and 365. Default: 30.
groupIdstring (grp_… ID)NoID (grp_…)

Response 200

FieldTypeRequiredDescription
arrowsmapYes—
arrows.{key}integerNoAny key.
callsintegerYes—
daysintegerYes—
stoppedOnarray<object>Yes—
stoppedOn[].callsinteger | nullYes—
stoppedOn[].flowIdstringYes—
stoppedOn[].questionstring | nullYes—

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

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/question-map/traffic" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Restore an old version by publishing it again as a new version (history is never rewritten)#

POST /v1/account/playbooks/{playbookId}/rollback

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Request body

application/json, required.

FieldTypeRequiredDescription
discardDraftbooleanNoDefault: false.
notestringNoUp to 500 characters.
versionintegerYesMinimum 1.

Response 200

FieldTypeRequiredDescription
changesarray<PlaybookChange>Yes—
changes[].afteranyNo—
changes[].beforeanyNo—
changes[].kindenumYesOne of: "added", "removed", "changed".
changes[].pathstringYes—
changes[].summarystringYes—
groupsarray<object>Yes—
groups[].groupIdstring (grp_… ID)YesID (grp_…)
groups[].groupNamestringYes—
groups[].issuesarray<string>Yes—
groups[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
versionPlaybookVersionYes—
version.authorIdstring (usr_… ID) | string (svc_… ID) | nullYes—
version.changeNotestring | nullYes—
version.contentPlaybookContentYesThe full playbook content.
version.content.bookingobjectYes—
version.content.booking.allowUnqualifiedbooleanNoDefault: false.
version.content.booking.maxBookingsPerCallintegerNoBetween 1 and 2. Default: 2.
version.content.booking.minNoticeMinutesintegerNoBetween 0 and 10080. Default: 60.
version.content.booking.offerSlotsintegerNoBetween 1 and 4. Default: 2.
version.content.booking.rulesarray<object>Yes—
version.content.briefstringYes1–12000 characters.
version.content.defaultFlowIdstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
version.content.escalationobjectYes—
version.content.escalation.afterFailedAnswersintegerNoBetween 1 and 5. Default: 2.
version.content.escalation.onFrustrationbooleanNoDefault: true.
version.content.escalation.onGuardrailHitbooleanNoDefault: true.
version.content.escalation.transferLinestringYes1–300 characters.
version.content.escalation.transferModeenumNoOne of: "cold", "warm". Default: "cold".
version.content.escalation.unavailableLinestringYes1–300 characters.
version.content.flowsarray<object>Yes—
version.content.flows[].brancharray<object>NoDefault: [].
version.content.flows[].disqualifyarray<object>NoDefault: [].
version.content.flows[].enterWhenstringYes1–500 characters.
version.content.flows[].fieldsarray<object>Yes—
version.content.flows[].goalstringYes1–500 characters.
version.content.flows[].maxQuestionsBeforeValueintegerNoBetween 1 and 10. Default: 2.
version.content.flows[].namestringYes1–120 characters.
version.content.flows[].talkingPointsarray<object | object>NoDefault: [].
version.content.followUpobjectNo—
version.content.followUp.blocksarray<object>NoUp to 20 items. Default: [].
version.content.followUp.cardsarray<object>NoUp to 30 items. Default: [].
version.content.followUp.chatobjectNoDefault: \{"callContext":true,"enabled":false\}.
version.content.followUp.consentQuestionstringNo1–480 characters. Default: "Can I text you a link with your \{\{vocab.meeting\}\} details and a recap of our call? Message and data rates may apply, and you can reply STOP anytime.".
version.content.followUp.emailsobjectNo—
version.content.followUp.enabledbooleanNoDefault: false.
version.content.followUp.formobjectNoDefault: \{"fields":[]\}.
version.content.followUp.leadsobjectNoDefault: \{\}.
version.content.followUp.linkExpiryDaysintegerNoBetween 7 and 365. Default: 60.
version.content.followUp.messagesobjectNoDefault: \{"afterVisit":\{"enabled":false\},"initialSms":"Hi \{\{caller.firstName\}\}, it's \{\{group.name\}\}. Here are your \{\{vocab.meeting\}\} details and a recap of our call: \{\{link\}\} Reply STOP to opt out.","reminders":[\{"before":"24h"\},\{"before":"2h"\}]\}.
version.content.followUp.modulesarray<object>NoDefault: [\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\}].
version.content.followUp.prepobjectNoDefault: \{"checklist":[]\}.
version.content.followUp.resourcesarray<object>NoUp to 20 items. Default: [].
version.content.followUp.reviewsarray<object>NoUp to 12 items. Default: [].
version.content.followUp.sendWhenobject | object | object | object | object | object | object | object | object | objectNo—
version.content.followUp.themeobjectNoDefault: \{"accent":"#B4512E","background":"#F7F3EC","font":"system","primary":"#24473D"\}.
version.content.guardrailsobjectYes—
version.content.guardrails.allowPriceDiscussionbooleanNoDefault: true.
version.content.guardrails.declineTopicsarray<object>NoDefault: [].
version.content.guardrails.emergencyLinestringYes1–300 characters.
version.content.guardrails.fallbackLinestringYes1–300 characters.
version.content.guardrails.neverSayarray<object>NoDefault: [].
version.content.guardrails.prohibitedClaimsarray<object>NoDefault: [].
version.content.guardrails.redirectLinesobjectYes—
version.content.guardrails.requiredDisclosuresarray<object>NoDefault: [].
version.content.integrationsobjectNoDefault: \{\}.
version.content.integrations.crmobjectNo—
version.content.integrations.schedulerobjectNo—
version.content.knowledgeobjectNoDefault: \{"documents":[],"faq":[]\}.
version.content.knowledge.documentsarray<object>NoDefault: [].
version.content.knowledge.faqarray<object>NoDefault: [].
version.content.lexiconobjectNoDefault: \{"account":[],"packs":[],"platform":1\}.
version.content.lexicon.accountarray<object>NoUp to 200 items. Default: [].
version.content.lexicon.packsarray<object>NoUp to 10 items. Default: [].
version.content.lexicon.platformintegerNoMinimum 1. Default: 1.
version.content.locksarray<string>No—
version.content.modelsobjectNoDefault: \{"keyterms":[]\}.
version.content.models.keytermsarray<string>NoDefault: [].
version.content.models.llmstringNoUp to 200 characters.
version.content.models.sttstringNoUp to 200 characters.
version.content.objectionsarray<object>NoDefault: [].
version.content.objections[].guidancestringYes1–1000 characters.
version.content.objections[].triggerstringYes1–200 characters.
version.content.objectivesobjectNoDefault: \{"channels":\{\},"fallbacks":[],"primary":\{"label":"Book a meeting","meetingTypes":[],"qualifiedOnly":false,"type":"book_meeting"\},"secondary":[]\}.
version.content.objectives.channelsobjectNoDefault: \{\}.
version.content.objectives.fallbacksarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 3 items. Default: [].
version.content.objectives.primaryobject | object | object | object | object | object | object | object | object | object | object | object | objectYes—
version.content.objectives.secondaryarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 5 items. Default: [].
version.content.personaobjectYes—
version.content.persona.agentNamestringYes1–60 characters.
version.content.persona.companyNamestringYes1–120 characters.
version.content.persona.exampleExchangesarray<object>NoDefault: [].
version.content.persona.openingstringYes1–600 characters.
version.content.persona.openingAfterRingstringNo1–600 characters.
version.content.persona.openingNotRecordedstringNo1–600 characters.
version.content.persona.openingQuestionstringYes1–300 characters.
version.content.persona.preRingNoticestringNo1–300 characters.
version.content.persona.returningCallerLinestringNoUp to 300 characters.
version.content.persona.tonestringYes1–300 characters.
version.content.persona.voiceobjectYes—
version.content.pricingobjectNoDefault: \{"feeLine":"The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.","floorPlanLine":"\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.","mentionSpecials":"when_price_comes_up","notOfferedLine":"\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.","onRequestLine":"Our team will go over pricing for \{\{price.service\}\} with you.","otherLocations":"off","otherLocationsLine":"\{\{price.service\}\} is offered at \{\{price.locations\}\}.","specialLine":"\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.","specialLineOpenEnded":"\{\{price.specialWording\}\}.","startingAtLine":"\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.","startingAtWithOptions":"\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}."\}.
version.content.pricing.feeLinestringNo1–300 characters. Default: "The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.".
version.content.pricing.floorPlanLinestringNo1–300 characters. Default: "\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.".
version.content.pricing.mentionSpecialsenumNoOne of: "when_price_comes_up", "once_after_discovery", "only_when_asked". Default: "when_price_comes_up".
version.content.pricing.notOfferedLinestringNo1–300 characters. Default: "\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.".
version.content.pricing.onRequestLinestringNo1–300 characters. Default: "Our team will go over pricing for \{\{price.service\}\} with you.".
version.content.pricing.otherLocationsenumNoOne of: "off", "mention", "mention_and_connect". Default: "off".
version.content.pricing.otherLocationsLinestringNo1–300 characters. Default: "\{\{price.service\}\} is offered at \{\{price.locations\}\}.".
version.content.pricing.specialLinestringNo1–300 characters. Default: "\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.".
version.content.pricing.specialLineOpenEndedstringNo1–300 characters. Default: "\{\{price.specialWording\}\}.".
version.content.pricing.startingAtLinestringNo1–300 characters. Default: "\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.".
version.content.pricing.startingAtWithOptionsstringNo1–300 characters. Default: "\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}.".
version.content.recordingobjectNoDefault: \{"enabled":true\}.
version.content.recording.enabledbooleanNoDefault: true.
version.content.retentionobjectNoDefault: \{"recordingDays":90,"transcriptDays":90\}.
version.content.retention.recordingDaysintegerNoBetween 1 and 3650. Default: 90.
version.content.retention.transcriptDaysintegerNoBetween 1 and 3650. Default: 90.
version.content.schemaVersionenumNoOne of: 1. Default: 1.
version.content.toolsobjectNoDefault: \{"bindings":[]\}.
version.content.tools.bindingsarray<object>NoUp to 20 items. Default: [].
version.content.visitActionsobjectNo—
version.content.visitActions.allowCustombooleanNoDefault: true.
version.content.visitActions.itemsarray<object>NoUp to 30 items.
version.content.visitActions.typedCrmTaskbooleanNoDefault: false.
version.content.webWidgetobjectNoDefault: \{"continuationDisclosure":"Hi again — this is the AI assistant you spoke with on the phone.","continuationGreeting":"I have the notes from your call, so we can pick up right where we left off. What else can I help with?","copy":\{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\},"disclosure":"Hi — I am an AI assistant, and I can answer questions or book you a time to visit.","enabled":false,"greeting":"What would you like to know?","launcher":\{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\},"limits":\{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\},"panel":\{"height":620,"presentation":"panel","width":400\},"showMedia":false,"surfaces":\{"chat":true,"voice":false\},"theme":\{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}\}.
version.content.webWidget.continuationDisclosurestringNo1–320 characters. Default: "Hi again — this is the AI assistant you spoke with on the phone.".
version.content.webWidget.continuationGreetingstringNo1–320 characters. Default: "I have the notes from your call, so we can pick up right where we left off. What else can I help with?".
version.content.webWidget.copyobjectNoDefault: \{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\}.
version.content.webWidget.disclosurestringNo1–320 characters. Default: "Hi — I am an AI assistant, and I can answer questions or book you a time to visit.".
version.content.webWidget.enabledbooleanNoDefault: false.
version.content.webWidget.greetingstringNo1–320 characters. Default: "What would you like to know?".
version.content.webWidget.launcherobjectNoDefault: \{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\}.
version.content.webWidget.limitsobjectNoDefault: \{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\}.
version.content.webWidget.panelobjectNoDefault: \{"height":620,"presentation":"panel","width":400\}.
version.content.webWidget.showMediabooleanNoDefault: false.
version.content.webWidget.surfacesobjectNoDefault: \{"chat":true,"voice":false\}.
version.content.webWidget.themeobjectNoDefault: \{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}.
version.contentHashstringYes—
version.createdAtstring (date-time)Yes—
version.idstring (pbv_… ID)YesID (pbv_…)
version.publishedAtstring (date-time) | nullYes—
version.publishedBystring (usr_… ID) | string (svc_… ID) | nullYes—
version.statusenumYesOne of: "draft", "published", "archived", "discarded".
version.updatedAtstring (date-time)Yes—
version.versionintegerYes—
warningsarray<ValidationMessage>Yes—
warnings[].messagestringYes—
warnings[].pathstringYes—
warnings[].severityenumYesOne of: "error", "warning".

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/rollback" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "version": 1
}'

Run the publish checklist on the draft: rules, voice and connection health#

POST /v1/account/playbooks/{playbookId}/validate

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

Path parameters

NameTypeRequiredDescription
playbookIdstring (pb_… ID)YesID (pb_…)

Response 200

FieldTypeRequiredDescription
errorsarray<ValidationMessage>Yes—
errors[].messagestringYes—
errors[].pathstringYes—
errors[].severityenumYesOne of: "error", "warning".
okbooleanYes—
warningsarray<ValidationMessage>Yes—
warnings[].messagestringYes—
warnings[].pathstringYes—
warnings[].severityenumYesOne of: "error", "warning".

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/validate" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Version history, newest first#

GET /v1/account/playbooks/{playbookId}/versions

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
playbookIdstring (pb_… ID)YesID (pb_…)

Response 200

FieldTypeRequiredDescription
versionsarray<PlaybookVersionSummary>Yes—
versions[].authorIdstring (usr_… ID) | string (svc_… ID) | nullYes—
versions[].changeNotestring | nullYes—
versions[].contentHashstringYes—
versions[].createdAtstring (date-time)Yes—
versions[].idstring (pbv_… ID)YesID (pbv_…)
versions[].publishedAtstring (date-time) | nullYes—
versions[].publishedBystring (usr_… ID) | string (svc_… ID) | nullYes—
versions[].statusenumYesOne of: "draft", "published", "archived", "discarded".
versions[].updatedAtstring (date-time)Yes—
versions[].versionintegerYes—

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

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/versions" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

One version with its content#

GET /v1/account/playbooks/{playbookId}/versions/{version}

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
playbookIdstring (pb_… ID)YesID (pb_…)
versionintegerYesMinimum 1.

Response 200

FieldTypeRequiredDescription
authorIdstring (usr_… ID) | string (svc_… ID) | nullYes—
changeNotestring | nullYes—
contentPlaybookContentYesThe full playbook content.
content.bookingobjectYes—
content.booking.allowUnqualifiedbooleanNoDefault: false.
content.booking.maxBookingsPerCallintegerNoBetween 1 and 2. Default: 2.
content.booking.minNoticeMinutesintegerNoBetween 0 and 10080. Default: 60.
content.booking.offerSlotsintegerNoBetween 1 and 4. Default: 2.
content.booking.rulesarray<object>Yes—
content.booking.rules[].enabledbooleanNoDefault: true.
content.booking.rules[].namestringNoUp to 120 characters.
content.booking.rules[].thenobject | object | object | object | object | object | objectYes—
content.booking.rules[].whenobject | object | object | object | object | object | object | object | object | objectYes—
content.briefstringYes1–12000 characters.
content.defaultFlowIdstringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.escalationobjectYes—
content.escalation.afterFailedAnswersintegerNoBetween 1 and 5. Default: 2.
content.escalation.onFrustrationbooleanNoDefault: true.
content.escalation.onGuardrailHitbooleanNoDefault: true.
content.escalation.transferLinestringYes1–300 characters.
content.escalation.transferModeenumNoOne of: "cold", "warm". Default: "cold".
content.escalation.unavailableLinestringYes1–300 characters.
content.flowsarray<object>Yes—
content.flows[].brancharray<object>NoDefault: [].
content.flows[].branch[].gotostringYes1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.flows[].branch[].ifobject | object | object | object | object | object | object | object | object | objectYes—
content.flows[].disqualifyarray<object>NoDefault: [].
content.flows[].disqualify[].actionenumYesOne of: "offer_nurture", "offer_referral", "end_politely".
content.flows[].disqualify[].ifobject | object | object | object | object | object | object | object | object | objectYes—
content.flows[].disqualify[].linestringNoUp to 500 characters.
content.flows[].enterWhenstringYes1–500 characters.
content.flows[].fieldsarray<object>Yes—
content.flows[].fields[].alwaysConfirmbooleanNo—
content.flows[].fields[].askstringYes1–500 characters.
content.flows[].fields[].askWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.flows[].fields[].hearAsarray<string>NoUp to 20 items.
content.flows[].fields[].hintstringNoUp to 500 characters.
content.flows[].fields[].keystringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.flows[].fields[].labelstringNo1–120 characters.
content.flows[].fields[].optionsarray<object>No—
content.flows[].fields[].optionsFromenum | string (oset_… ID)No—
content.flows[].fields[].requiredbooleanNoDefault: false.
content.flows[].fields[].sensitivityenumNoOne of: "standard", "sensitive". Default: "standard".
content.flows[].fields[].typeenumYesOne of: "text", "number", "enum", "boolean", "date", "phone", "email".
content.flows[].goalstringYes1–500 characters.
content.flows[].maxQuestionsBeforeValueintegerNoBetween 1 and 10. Default: 2.
content.flows[].namestringYes1–120 characters.
content.flows[].talkingPointsarray<object | object>NoDefault: [].
content.flows[].talkingPoints[].saystringYes(variant 1) 1–500 characters.
content.flows[].talkingPoints[].whenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.flows[].talkingPoints[].talkAboutstringYes(variant 2) 1–500 characters.
content.flows[].talkingPoints[].whenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.followUpobjectNo—
content.followUp.blocksarray<object>NoUp to 20 items. Default: [].
content.followUp.blocks[].bodystringNoUp to 2000 characters.
content.followUp.blocks[].buttonobjectNo—
content.followUp.blocks[].headingstringNoUp to 120 characters.
content.followUp.blocks[].imagestring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.blocks[].videoobjectNo—
content.followUp.cardsarray<object>NoUp to 30 items. Default: [].
content.followUp.cards[].bodystringYes1–2000 characters.
content.followUp.cards[].buttonobjectNo—
content.followUp.cards[].enabledbooleanNoDefault: true.
content.followUp.cards[].imagestring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.cards[].showWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.cards[].titlestringYes1–120 characters.
content.followUp.chatobjectNoDefault: \{"callContext":true,"enabled":false\}.
content.followUp.chat.callContextbooleanNoDefault: true.
content.followUp.chat.enabledbooleanNoDefault: false.
content.followUp.consentQuestionstringNo1–480 characters. Default: "Can I text you a link with your \{\{vocab.meeting\}\} details and a recap of our call? Message and data rates may apply, and you can reply STOP anytime.".
content.followUp.emailsobjectNo—
content.followUp.emails.after_visitobject | nullNo—
content.followUp.emails.cancel_confirmationobject | nullNo—
content.followUp.emails.initial_linkobject | nullNo—
content.followUp.emails.reminderobject | nullNo—
content.followUp.emails.reschedule_confirmationobject | nullNo—
content.followUp.enabledbooleanNoDefault: false.
content.followUp.formobjectNoDefault: \{"fields":[]\}.
content.followUp.form.fieldsarray<object>NoUp to 8 items. Default: [].
content.followUp.form.introstringNoUp to 480 characters.
content.followUp.leadsobjectNoDefault: \{\}.
content.followUp.leads.afterVisitstringNoUp to 480 characters.
content.followUp.leads.cancelledstringNoUp to 480 characters.
content.followUp.leads.noBookingstringNoUp to 480 characters.
content.followUp.linkExpiryDaysintegerNoBetween 7 and 365. Default: 60.
content.followUp.messagesobjectNoDefault: \{"afterVisit":\{"enabled":false\},"initialSms":"Hi \{\{caller.firstName\}\}, it's \{\{group.name\}\}. Here are your \{\{vocab.meeting\}\} details and a recap of our call: \{\{link\}\} Reply STOP to opt out.","reminders":[\{"before":"24h"\},\{"before":"2h"\}]\}.
content.followUp.messages.afterVisitobjectNoDefault: \{"enabled":false\}.
content.followUp.messages.initialSmsstringYes1–480 characters.
content.followUp.messages.remindersarray<object>NoUp to 4 items. Default: [\{"before":"24h"\},\{"before":"2h"\}].
content.followUp.modulesarray<object>NoDefault: [\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\},\{\}].
content.followUp.modules[].blockIdstringNo1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.followUp.modules[].headingstringNoUp to 120 characters.
content.followUp.modules[].showWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.modules[].statesarray<enum>NoItems: "upcoming", "day_of", "after_visit", "no_booking", "cancelled", "expired", "revoked".
content.followUp.prepobjectNoDefault: \{"checklist":[]\}.
content.followUp.prep.bodystringNoUp to 2000 characters.
content.followUp.prep.checklistarray<object>NoUp to 12 items. Default: [].
content.followUp.resourcesarray<object>NoUp to 20 items. Default: [].
content.followUp.resources[].descriptionstringNoUp to 300 characters.
content.followUp.resources[].labelstringYes1–120 characters.
content.followUp.resources[].urlstring (uri)YesA https:// link Up to 2000 characters.
content.followUp.reviewsarray<object>NoUp to 12 items. Default: [].
content.followUp.reviews[].attributionstringNoUp to 120 characters.
content.followUp.reviews[].quotestringYes1–600 characters.
content.followUp.sendWhenobject | object | object | object | object | object | object | object | object | objectNo—
content.followUp.sendWhen.allarray<object | object | object | object | object | object | object | object | object | object>Yes(variant 1)
content.followUp.sendWhen.anyarray<object | object | object | object | object | object | object | object | object | object>Yes(variant 2)
content.followUp.sendWhen.notobject | object | object | object | object | object | object | object | object | objectYes(variant 3)
content.followUp.sendWhen.alwaysenumYes(variant 4) One of: true.
content.followUp.sendWhen.factstringYes(variant 5) (variant 1) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.isstring | number | booleanYes(variant 5) (variant 1)
content.followUp.sendWhen.factstringYes(variant 5) (variant 2) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.inarray<string | number | boolean>Yes(variant 5) (variant 2)
content.followUp.sendWhen.factstringYes(variant 5) (variant 3) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.gtnumberYes(variant 5) (variant 3)
content.followUp.sendWhen.factstringYes(variant 5) (variant 4) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.ltnumberYes(variant 5) (variant 4)
content.followUp.sendWhen.betweenarrayYes(variant 5) (variant 5) Up to 2 items.
content.followUp.sendWhen.factstringYes(variant 5) (variant 5) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.factstringYes(variant 5) (variant 6) 1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.followUp.sendWhen.missingbooleanYes(variant 5) (variant 6)
content.followUp.themeobjectNoDefault: \{"accent":"#B4512E","background":"#F7F3EC","font":"system","primary":"#24473D"\}.
content.followUp.theme.accentstringYesPattern: ^#[0-9a-f]\{6\}$.
content.followUp.theme.backgroundstringNoPattern: ^#[0-9a-f]\{6\}$. Default: "#F7F3EC".
content.followUp.theme.fontenumNoOne of: "system", "serif_warm", "sans_modern". Default: "system".
content.followUp.theme.logostring (uri) | string (uri)NoA https:// link to an uploaded file
content.followUp.theme.primarystringYesPattern: ^#[0-9a-f]\{6\}$.
content.guardrailsobjectYes—
content.guardrails.allowPriceDiscussionbooleanNoDefault: true.
content.guardrails.declineTopicsarray<object>NoDefault: [].
content.guardrails.declineTopics[].textstringYes1–1000 characters.
content.guardrails.emergencyLinestringYes1–300 characters.
content.guardrails.fallbackLinestringYes1–300 characters.
content.guardrails.neverSayarray<object>NoDefault: [].
content.guardrails.neverSay[].textstringYes1–1000 characters.
content.guardrails.prohibitedClaimsarray<object>NoDefault: [].
content.guardrails.prohibitedClaims[].textstringYes1–1000 characters.
content.guardrails.redirectLinesobjectYes—
content.guardrails.redirectLines.existing_customerstringYes1–500 characters.
content.guardrails.redirectLines.job_seekerstringYes1–500 characters.
content.guardrails.redirectLines.resident_familystringYes1–500 characters.
content.guardrails.redirectLines.vendorstringYes1–500 characters.
content.guardrails.redirectLines.wrong_numberstringYes1–500 characters.
content.guardrails.requiredDisclosuresarray<object>NoDefault: [].
content.guardrails.requiredDisclosures[].textstringYes1–1000 characters.
content.integrationsobjectNoDefault: \{\}.
content.integrations.crmobjectNo—
content.integrations.crm.connectionIdstring (conn_… ID)YesID (conn_…)
content.integrations.crm.connectorstringYes1–64 characters.
content.integrations.crm.createContactsbooleanNoDefault: true.
content.integrations.crm.fieldMapmapNoDefault: \{\}.
content.integrations.crm.historyLookbackDaysintegerNoBetween 0 and 3650. Default: 180.
content.integrations.crm.logCallsbooleanNoDefault: true.
content.integrations.crm.optionsmapNoDefault: \{\}.
content.integrations.schedulerobjectNo—
content.integrations.scheduler.activityTypestringYes1–64 characters.
content.integrations.scheduler.connectionIdstring (conn_… ID)YesID (conn_…)
content.integrations.scheduler.connectorstringYes1–64 characters.
content.integrations.scheduler.optionsmapNoDefault: \{\}.
content.knowledgeobjectNoDefault: \{"documents":[],"faq":[]\}.
content.knowledge.documentsarray<object>NoDefault: [].
content.knowledge.documents[].titlestringYes1–200 characters.
content.knowledge.faqarray<object>NoDefault: [].
content.knowledge.faq[].answerstringYes1–2000 characters.
content.knowledge.faq[].questionstringYes1–300 characters.
content.lexiconobjectNoDefault: \{"account":[],"packs":[],"platform":1\}.
content.lexicon.accountarray<object>NoUp to 200 items. Default: [].
content.lexicon.account[].conceptstringYesUp to 80 characters. Pattern: ^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+$.
content.lexicon.account[].neverarray<string>NoUp to 50 items. Default: [].
content.lexicon.account[].phrasesarray<string>NoUp to 50 items. Default: [].
content.lexicon.packsarray<object>NoUp to 10 items. Default: [].
content.lexicon.packs[].versionintegerYesMinimum 1.
content.lexicon.platformintegerNoMinimum 1. Default: 1.
content.locksarray<string>No—
content.modelsobjectNoDefault: \{"keyterms":[]\}.
content.models.keytermsarray<string>NoDefault: [].
content.models.llmstringNoUp to 200 characters.
content.models.sttstringNoUp to 200 characters.
content.objectionsarray<object>NoDefault: [].
content.objections[].guidancestringYes1–1000 characters.
content.objections[].triggerstringYes1–200 characters.
content.objectivesobjectNoDefault: \{"channels":\{\},"fallbacks":[],"primary":\{"label":"Book a meeting","meetingTypes":[],"qualifiedOnly":false,"type":"book_meeting"\},"secondary":[]\}.
content.objectives.channelsobjectNoDefault: \{\}.
content.objectives.channels.page_chatobjectNo—
content.objectives.channels.site_chatobjectNo—
content.objectives.fallbacksarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 3 items. Default: [].
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.fallbacks[].labelstringYes(variant 1) 1–80 characters.
content.objectives.fallbacks[].meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.fallbacks[].qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.fallbacks[].typeenumYes(variant 1) One of: "book_meeting".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.fallbacks[].labelstringYes(variant 2) 1–80 characters.
content.objectives.fallbacks[].reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.fallbacks[].typeenumYes(variant 2) One of: "live_transfer".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.fallbacks[].labelstringYes(variant 3) 1–80 characters.
content.objectives.fallbacks[].requireReasonbooleanNo(variant 3) Default: false.
content.objectives.fallbacks[].typeenumYes(variant 3) One of: "capture_callback".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.fallbacks[].fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.fallbacks[].labelstringYes(variant 4) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 4) One of: "capture_contact".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.fallbacks[].fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.fallbacks[].flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.fallbacks[].labelstringYes(variant 5) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 5) One of: "qualify".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.fallbacks[].labelstringYes(variant 6) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.fallbacks[].labelstringYes(variant 7) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 7) One of: "manage_booking".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.fallbacks[].kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.fallbacks[].labelstringYes(variant 8) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 8) One of: "route_correctly".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.fallbacks[].labelstringYes(variant 9) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 9) One of: "nurture".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.fallbacks[].bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.fallbacks[].labelstringYes(variant 10) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 10) One of: "run_tool".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.fallbacks[].labelstringYes(variant 11) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 11) One of: "answer_questions".
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.fallbacks[].labelstringYes(variant 12) 1–80 characters.
content.objectives.fallbacks[].typeenumYes(variant 12) One of: "custom_condition".
content.objectives.fallbacks[].whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.fallbacks[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.fallbacks[].labelstringYes(variant 13) 1–80 characters.
content.objectives.fallbacks[].rubricstringYes(variant 13) 1–500 characters.
content.objectives.fallbacks[].typeenumYes(variant 13) One of: "custom_judged".
content.objectives.primaryobject | object | object | object | object | object | object | object | object | object | object | object | objectYes—
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.primary.labelstringYes(variant 1) 1–80 characters.
content.objectives.primary.meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.primary.qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.primary.typeenumYes(variant 1) One of: "book_meeting".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.primary.labelstringYes(variant 2) 1–80 characters.
content.objectives.primary.reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.primary.typeenumYes(variant 2) One of: "live_transfer".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.primary.labelstringYes(variant 3) 1–80 characters.
content.objectives.primary.requireReasonbooleanNo(variant 3) Default: false.
content.objectives.primary.typeenumYes(variant 3) One of: "capture_callback".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.primary.fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.primary.labelstringYes(variant 4) 1–80 characters.
content.objectives.primary.typeenumYes(variant 4) One of: "capture_contact".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.primary.fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.primary.flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.primary.labelstringYes(variant 5) 1–80 characters.
content.objectives.primary.typeenumYes(variant 5) One of: "qualify".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.primary.labelstringYes(variant 6) 1–80 characters.
content.objectives.primary.typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.primary.labelstringYes(variant 7) 1–80 characters.
content.objectives.primary.typeenumYes(variant 7) One of: "manage_booking".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.primary.kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.primary.labelstringYes(variant 8) 1–80 characters.
content.objectives.primary.typeenumYes(variant 8) One of: "route_correctly".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.primary.labelstringYes(variant 9) 1–80 characters.
content.objectives.primary.typeenumYes(variant 9) One of: "nurture".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.primary.bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.primary.labelstringYes(variant 10) 1–80 characters.
content.objectives.primary.typeenumYes(variant 10) One of: "run_tool".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.primary.labelstringYes(variant 11) 1–80 characters.
content.objectives.primary.typeenumYes(variant 11) One of: "answer_questions".
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.primary.labelstringYes(variant 12) 1–80 characters.
content.objectives.primary.typeenumYes(variant 12) One of: "custom_condition".
content.objectives.primary.whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.primary.appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.primary.labelstringYes(variant 13) 1–80 characters.
content.objectives.primary.rubricstringYes(variant 13) 1–500 characters.
content.objectives.primary.typeenumYes(variant 13) One of: "custom_judged".
content.objectives.secondaryarray<object | object | object | object | object | object | object | object | object | object | object | object | object>NoUp to 5 items. Default: [].
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 1)
content.objectives.secondary[].labelstringYes(variant 1) 1–80 characters.
content.objectives.secondary[].meetingTypesarray<string>No(variant 1) Up to 10 items. Default: [].
content.objectives.secondary[].qualifiedOnlybooleanNo(variant 1) Default: false.
content.objectives.secondary[].typeenumYes(variant 1) One of: "book_meeting".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 2)
content.objectives.secondary[].labelstringYes(variant 2) 1–80 characters.
content.objectives.secondary[].reasonsarray<enum>No(variant 2) Items: "caller_request", "rule_transfer", "unanswered", "frustration", "guardrail", "system_failure", "emergency". Up to 10 items. Default: [].
content.objectives.secondary[].typeenumYes(variant 2) One of: "live_transfer".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 3)
content.objectives.secondary[].labelstringYes(variant 3) 1–80 characters.
content.objectives.secondary[].requireReasonbooleanNo(variant 3) Default: false.
content.objectives.secondary[].typeenumYes(variant 3) One of: "capture_callback".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 4)
content.objectives.secondary[].fieldsarray<string>Yes(variant 4) Up to 10 items.
content.objectives.secondary[].labelstringYes(variant 4) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 4) One of: "capture_contact".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 5)
content.objectives.secondary[].fieldsarray<string>No(variant 5) Up to 30 items. Default: [].
content.objectives.secondary[].flowIdstringNo(variant 5) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.secondary[].labelstringYes(variant 5) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 5) One of: "qualify".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 6)
content.objectives.secondary[].labelstringYes(variant 6) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 6) One of: "text_follow_up".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 7)
content.objectives.secondary[].labelstringYes(variant 7) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 7) One of: "manage_booking".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 8)
content.objectives.secondary[].kindsarray<enum>No(variant 8) Items: "wrong_number", "existing_customer", "vendor", "job_seeker", "resident_family". Up to 10 items. Default: [].
content.objectives.secondary[].labelstringYes(variant 8) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 8) One of: "route_correctly".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 9)
content.objectives.secondary[].labelstringYes(variant 9) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 9) One of: "nurture".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 10)
content.objectives.secondary[].bindingIdstringYes(variant 10) 1–64 characters. Pattern: ^[a-z0-9][a-z0-9_-]*$.
content.objectives.secondary[].labelstringYes(variant 10) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 10) One of: "run_tool".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 11)
content.objectives.secondary[].labelstringYes(variant 11) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 11) One of: "answer_questions".
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 12)
content.objectives.secondary[].labelstringYes(variant 12) 1–80 characters.
content.objectives.secondary[].typeenumYes(variant 12) One of: "custom_condition".
content.objectives.secondary[].whenobject | object | object | object | object | object | object | object | object | objectYes(variant 12)
content.objectives.secondary[].appliesWhenobject | object | object | object | object | object | object | object | object | objectNo(variant 13)
content.objectives.secondary[].labelstringYes(variant 13) 1–80 characters.
content.objectives.secondary[].rubricstringYes(variant 13) 1–500 characters.
content.objectives.secondary[].typeenumYes(variant 13) One of: "custom_judged".
content.personaobjectYes—
content.persona.agentNamestringYes1–60 characters.
content.persona.companyNamestringYes1–120 characters.
content.persona.exampleExchangesarray<object>NoDefault: [].
content.persona.exampleExchanges[].agentstringYes1–500 characters.
content.persona.exampleExchanges[].callerstringYes1–500 characters.
content.persona.openingstringYes1–600 characters.
content.persona.openingAfterRingstringNo1–600 characters.
content.persona.openingNotRecordedstringNo1–600 characters.
content.persona.openingQuestionstringYes1–300 characters.
content.persona.preRingNoticestringNo1–300 characters.
content.persona.returningCallerLinestringNoUp to 300 characters.
content.persona.tonestringYes1–300 characters.
content.persona.voiceobjectYes—
content.persona.voice.ambiencebooleanNoDefault: false.
content.persona.voice.expressivebooleanNoDefault: false.
content.persona.voice.modeenumNoOne of: "cascaded". Default: "cascaded".
content.persona.voice.modelstringNoUp to 200 characters.
content.persona.voice.pronunciationsarray<object>NoDefault: [].
content.persona.voice.providerenumYesOne of: "cartesia", "elevenlabs", "deepgram", "fishaudio", "gradium", "inworld", "rime", "xai", "openai", "google".
content.persona.voice.thinkingSoundsbooleanNoDefault: true.
content.persona.voice.tuningmapNoDefault: \{\}.
content.persona.voice.voiceIdstringYes1–200 characters.
content.pricingobjectNoDefault: \{"feeLine":"The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.","floorPlanLine":"\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.","mentionSpecials":"when_price_comes_up","notOfferedLine":"\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.","onRequestLine":"Our team will go over pricing for \{\{price.service\}\} with you.","otherLocations":"off","otherLocationsLine":"\{\{price.service\}\} is offered at \{\{price.locations\}\}.","specialLine":"\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.","specialLineOpenEnded":"\{\{price.specialWording\}\}.","startingAtLine":"\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.","startingAtWithOptions":"\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}."\}.
content.pricing.feeLinestringNo1–300 characters. Default: "The \{\{price.service\}\} is \{\{price.amount\}\} \{\{price.per\}\}.".
content.pricing.floorPlanLinestringNo1–300 characters. Default: "\{\{floorPlan.name\}\} is \{\{floorPlan.details\}\}.".
content.pricing.mentionSpecialsenumNoOne of: "when_price_comes_up", "once_after_discovery", "only_when_asked". Default: "when_price_comes_up".
content.pricing.notOfferedLinestringNo1–300 characters. Default: "\{\{group.displayName\}\} doesn't offer \{\{price.service\}\}.".
content.pricing.onRequestLinestringNo1–300 characters. Default: "Our team will go over pricing for \{\{price.service\}\} with you.".
content.pricing.otherLocationsenumNoOne of: "off", "mention", "mention_and_connect". Default: "off".
content.pricing.otherLocationsLinestringNo1–300 characters. Default: "\{\{price.service\}\} is offered at \{\{price.locations\}\}.".
content.pricing.specialLinestringNo1–300 characters. Default: "\{\{price.specialWording\}\}. It ends \{\{price.specialEnds\}\}.".
content.pricing.specialLineOpenEndedstringNo1–300 characters. Default: "\{\{price.specialWording\}\}.".
content.pricing.startingAtLinestringNo1–300 characters. Default: "\{\{price.service\}\} starts at \{\{price.amount\}\} \{\{price.per\}\}.".
content.pricing.startingAtWithOptionsstringNo1–300 characters. Default: "\{\{price.service\}\}, \{\{price.options\}\}, starts at \{\{price.amount\}\} \{\{price.per\}\}.".
content.recordingobjectNoDefault: \{"enabled":true\}.
content.recording.enabledbooleanNoDefault: true.
content.retentionobjectNoDefault: \{"recordingDays":90,"transcriptDays":90\}.
content.retention.recordingDaysintegerNoBetween 1 and 3650. Default: 90.
content.retention.transcriptDaysintegerNoBetween 1 and 3650. Default: 90.
content.schemaVersionenumNoOne of: 1. Default: 1.
content.toolsobjectNoDefault: \{"bindings":[]\}.
content.tools.bindingsarray<object>NoUp to 20 items. Default: [].
content.tools.bindings[].allowCallerInputbooleanNoDefault: true.
content.tools.bindings[].argsmapNoDefault: \{\}.
content.tools.bindings[].asstringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.tools.bindings[].channelsarray<enum>NoItems: "phone", "web_voice", "web_chat". Default: ["phone","web_voice","web_chat"].
content.tools.bindings[].confirmWithCallerbooleanNoDefault: false.
content.tools.bindings[].enabledbooleanNoDefault: true.
content.tools.bindings[].holdingLinestringNo1–200 characters.
content.tools.bindings[].inputsmapNoDefault: \{\}.
content.tools.bindings[].labelstringYes1–80 characters.
content.tools.bindings[].maxCallsintegerNoBetween 1 and 3. Default: 3.
content.tools.bindings[].onFailureenumNoOne of: "say_will_follow_up", "continue_silently", "offer_callback", "transfer". Default: "say_will_follow_up".
content.tools.bindings[].resultobjectYes—
content.tools.bindings[].toolobjectYes—
content.tools.bindings[].triggerobject | objectYes—
content.tools.bindings[].whenobject | object | object | object | object | object | object | object | object | objectNo—
content.visitActionsobjectNo—
content.visitActions.allowCustombooleanNoDefault: true.
content.visitActions.itemsarray<object>NoUp to 30 items.
content.visitActions.items[].crmTaskbooleanNoDefault: false.
content.visitActions.items[].dueDaysintegerNoBetween 0 and 30. Default: 1.
content.visitActions.items[].keystringYes1–64 characters. Pattern: ^[a-z][a-z0-9_]*$.
content.visitActions.items[].labelstringYes1–240 characters.
content.visitActions.items[].ownerenumNoOne of: "rep", "backup". Default: "rep".
content.visitActions.typedCrmTaskbooleanNoDefault: false.
content.webWidgetobjectNoDefault: \{"continuationDisclosure":"Hi again — this is the AI assistant you spoke with on the phone.","continuationGreeting":"I have the notes from your call, so we can pick up right where we left off. What else can I help with?","copy":\{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\},"disclosure":"Hi — I am an AI assistant, and I can answer questions or book you a time to visit.","enabled":false,"greeting":"What would you like to know?","launcher":\{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\},"limits":\{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\},"panel":\{"height":620,"presentation":"panel","width":400\},"showMedia":false,"surfaces":\{"chat":true,"voice":false\},"theme":\{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}\}.
content.webWidget.continuationDisclosurestringNo1–320 characters. Default: "Hi again — this is the AI assistant you spoke with on the phone.".
content.webWidget.continuationGreetingstringNo1–320 characters. Default: "I have the notes from your call, so we can pick up right where we left off. What else can I help with?".
content.webWidget.copyobjectNoDefault: \{"agentLabel":"AI assistant","choicesLabel":"Tap an answer, or type your own","closeLabel":"Close the chat","composerDisabledNote":"Messaging is not switched on here yet.","continuingNote":"Continuing from your call on \{date\}","endedNote":"This conversation has ended.","errorBody":"Please try again in a moment, or call us and we will help.","errorTitle":"We could not load the chat","inputPlaceholder":"Type your question","loadingLabel":"Loading the chat","newChatLabel":"Start a new chat","notAllowedBody":"If you run this website, add it to the allowed list in your admin settings.","notAllowedTitle":"This chat is not available on this site","openLabel":"Open the chat","retryLabel":"Try again","sendFailed":"That message did not send. Please try again.","sendLabel":"Send","subtitle":"Answers in a moment","typingLabel":"Writing a reply","visitorLabel":"You"\}.
content.webWidget.copy.agentLabelstringNo1–80 characters. Default: "AI assistant".
content.webWidget.copy.choicesLabelstringNo1–80 characters. Default: "Tap an answer, or type your own".
content.webWidget.copy.closeLabelstringNo1–80 characters. Default: "Close the chat".
content.webWidget.copy.composerDisabledNotestringNo1–320 characters. Default: "Messaging is not switched on here yet.".
content.webWidget.copy.continuingNotestringNo1–80 characters. Default: "Continuing from your call on \{date\}".
content.webWidget.copy.endedNotestringNo1–320 characters. Default: "This conversation has ended.".
content.webWidget.copy.errorBodystringNo1–320 characters. Default: "Please try again in a moment, or call us and we will help.".
content.webWidget.copy.errorTitlestringNo1–80 characters. Default: "We could not load the chat".
content.webWidget.copy.inputPlaceholderstringNo1–80 characters. Default: "Type your question".
content.webWidget.copy.loadingLabelstringNo1–80 characters. Default: "Loading the chat".
content.webWidget.copy.newChatLabelstringNo1–80 characters. Default: "Start a new chat".
content.webWidget.copy.notAllowedBodystringNo1–320 characters. Default: "If you run this website, add it to the allowed list in your admin settings.".
content.webWidget.copy.notAllowedTitlestringNo1–80 characters. Default: "This chat is not available on this site".
content.webWidget.copy.openLabelstringNo1–80 characters. Default: "Open the chat".
content.webWidget.copy.retryLabelstringNo1–80 characters. Default: "Try again".
content.webWidget.copy.sendFailedstringNo1–320 characters. Default: "That message did not send. Please try again.".
content.webWidget.copy.sendLabelstringNo1–80 characters. Default: "Send".
content.webWidget.copy.subtitlestringNo1–80 characters. Default: "Answers in a moment".
content.webWidget.copy.typingLabelstringNo1–80 characters. Default: "Writing a reply".
content.webWidget.copy.visitorLabelstringNo1–80 characters. Default: "You".
content.webWidget.disclosurestringNo1–320 characters. Default: "Hi — I am an AI assistant, and I can answer questions or book you a time to visit.".
content.webWidget.enabledbooleanNoDefault: false.
content.webWidget.greetingstringNo1–320 characters. Default: "What would you like to know?".
content.webWidget.launcherobjectNoDefault: \{"icon":"chat","label":"Chat with us","offset":\{"x":20,"y":20\},"position":"bottom-right","shape":"circle","showLabel":false,"size":"medium"\}.
content.webWidget.launcher.iconenumNoOne of: "chat", "message", "question", "sparkle", "phone", "headset". Default: "chat".
content.webWidget.launcher.iconUrlstring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.launcher.labelstringNo1–80 characters. Default: "Chat with us".
content.webWidget.launcher.offsetobjectNoDefault: \{"x":20,"y":20\}.
content.webWidget.launcher.positionenumNoOne of: "bottom-right", "bottom-left". Default: "bottom-right".
content.webWidget.launcher.shapeenumNoOne of: "circle", "rounded". Default: "circle".
content.webWidget.launcher.showLabelbooleanNoDefault: false.
content.webWidget.launcher.sizeenumNoOne of: "medium", "large". Default: "medium".
content.webWidget.limitsobjectNoDefault: \{"charactersPerMessage":2000,"messagesPerConversation":200,"messagesPerHour":30\}.
content.webWidget.limits.charactersPerMessageintegerNoBetween 200 and 8000. Default: 2000.
content.webWidget.limits.messagesPerConversationintegerNoBetween 1 and 2000. Default: 200.
content.webWidget.limits.messagesPerHourintegerNoBetween 1 and 500. Default: 30.
content.webWidget.panelobjectNoDefault: \{"height":620,"presentation":"panel","width":400\}.
content.webWidget.panel.headingstringNo1–80 characters.
content.webWidget.panel.heightintegerNoBetween 420 and 800. Default: 620.
content.webWidget.panel.presentationenumNoOne of: "panel", "sheet", "fullscreen". Default: "panel".
content.webWidget.panel.widthintegerNoBetween 320 and 560. Default: 400.
content.webWidget.showMediabooleanNoDefault: false.
content.webWidget.surfacesobjectNoDefault: \{"chat":true,"voice":false\}.
content.webWidget.surfaces.chatbooleanNoDefault: true.
content.webWidget.surfaces.voicebooleanNoDefault: false.
content.webWidget.themeobjectNoDefault: \{"dark":\{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\},"font":"system","light":\{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\},"radius":\{"bubble":14,"launcher":28,"panel":16\},"scheme":"auto"\}.
content.webWidget.theme.avatarstring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.theme.darkobjectNoDefault: \{"agentBubble":"#1E2724","agentBubbleText":"#ECF1EF","border":"#7E8C87","brand":"#8FC9B5","brandContrast":"#10201B","danger":"#F2A7A1","focusRing":"#8FBEF5","surface":"#141A18","surfaceMuted":"#1E2724","text":"#ECF1EF","textMuted":"#A7B3AF","visitorBubble":"#2C544A","visitorBubbleText":"#F4F9F7"\}.
content.webWidget.theme.fontenumNoOne of: "system", "serif_warm", "sans_modern". Default: "system".
content.webWidget.theme.lightobjectNoDefault: \{"agentBubble":"#F1EFEA","agentBubbleText":"#1E2A26","border":"#77837E","brand":"#24473D","brandContrast":"#FFFFFF","danger":"#A3241C","focusRing":"#0B5FA5","surface":"#FFFFFF","surfaceMuted":"#F1EFEA","text":"#1E2A26","textMuted":"#5A6763","visitorBubble":"#24473D","visitorBubbleText":"#FFFFFF"\}.
content.webWidget.theme.logostring (uri) | string (uri)NoA https:// link to an uploaded file
content.webWidget.theme.radiusobjectNoDefault: \{"bubble":14,"launcher":28,"panel":16\}.
content.webWidget.theme.schemeenumNoOne of: "auto", "light", "dark". Default: "auto".
contentHashstringYes—
createdAtstring (date-time)Yes—
idstring (pbv_… ID)YesID (pbv_…)
publishedAtstring (date-time) | nullYes—
publishedBystring (usr_… ID) | string (svc_… ID) | nullYes—
statusenumYesOne of: "draft", "published", "archived", "discarded".
updatedAtstring (date-time)Yes—
versionintegerYes—

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

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/account/playbooks/{playbookId}/versions/{version}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

The stock voices a playbook can use, all of them or one voice company#

GET /v1/account/voices

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

Query parameters

NameTypeRequiredDescription
providerstringNoUp to 40 characters.

Response 200

FieldTypeRequiredDescription
voicesarray<Voice>Yes—
voices[].accentstringNo—
voices[].descriptionstringNo—
voices[].genderenumNoOne of: "female", "male", "neutral".
voices[].modelsarray<string>No—
voices[].namestringYes—
voices[].previewUrlstringNo—
voices[].providerstringYes—
voices[].voiceIdstringYes—

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

Example

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