API reference

Pricing

Pricing endpoints.

MethodPathSummary
GET/v1/account/groups/{groupId}/price-bookA location's current prices, its unpublished changes, and what blocks publishing
POST/v1/account/groups/{groupId}/price-book/approveApprove a location's price changes: they are published, on their date if one was asked
POST/v1/account/groups/{groupId}/price-book/cancel-scheduledCancel a scheduled price change before its date: it becomes the draft again
PUT/v1/account/groups/{groupId}/price-book/draftSave a location's unpublished price changes
DELETE/v1/account/groups/{groupId}/price-book/draftDiscard a location's unpublished price changes
POST/v1/account/groups/{groupId}/price-book/publishPublish a location's price changes, now or on a date. Sent for approval instead when your changes need it
POST/v1/account/groups/{groupId}/price-book/returnSend price changes waiting for approval back to draft, with a note saying why
GET/v1/account/groups/{groupId}/price-book/versionsA location's published price books, newest first
POST/v1/account/groups/{groupId}/price-book/versions/{version}/rollbackPublish a copy of an earlier price book as the newest version (sent for approval when your changes need it)
POST/v1/account/groups/{groupId}/price-book/withdrawTake back price changes you sent for approval, to change them
GET/v1/account/price-matrixEvery location you can see against every service: current prices and drafts, or the prices in effect at a past moment
POST/v1/account/price-matrix/approveApprove the price changes waiting at several locations
POST/v1/account/price-matrix/discardDiscard the unpublished price changes of several locations
PUT/v1/account/price-matrix/draftsSave unpublished price changes for several locations at once
POST/v1/account/price-matrix/publishPublish the price changes of several locations with one note, now or on a date (sent for approval when your changes need it)
GET/v1/account/pricing/catalogThe services, option sets and options you sell, and the pricing settings
POST/v1/account/pricing/option-setsAdd an option set: a list of choices that changes a price
PATCH/v1/account/pricing/option-sets/{optionSetId}Rename, reorder or archive an option set
POST/v1/account/pricing/option-sets/{optionSetId}/optionsAdd an option to a set: the account's, or a location's own
PATCH/v1/account/pricing/options/{optionId}Rename, reorder or archive an option
POST/v1/account/pricing/servicesAdd a service to the account's catalog, or a location's own
PATCH/v1/account/pricing/services/{serviceId}Change or archive a service. Every location that offers it is recomputed
GET/v1/account/pricing/specialsYour specials: drafts, those waiting for approval, and approved ones
POST/v1/account/pricing/specialsAdd a special. It is approved at once, or sent for approval when your changes need it, or kept as a draft
PATCH/v1/account/pricing/specials/{specialId}Change a special. Changing an approved one sends it back for approval when your changes need it
DELETE/v1/account/pricing/specials/{specialId}Delete a draft special (approved ones are ended, never deleted)
POST/v1/account/pricing/specials/{specialId}/approveApprove a special waiting for approval
POST/v1/account/pricing/specials/{specialId}/endEnd an approved special now: the agent stops mentioning it
POST/v1/account/pricing/specials/{specialId}/returnSend a special waiting for approval back to draft, with a note saying why
POST/v1/account/pricing/specials/{specialId}/submitSend a draft special for approval (approved at once when your changes do not need it)
POST/v1/account/pricing/specials/{specialId}/withdrawTake back a special you sent for approval

A location's current prices, its unpublished changes, and what blocks publishing#

GET /v1/account/groups/{groupId}/price-book

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
groupIdstring (grp_… ID)YesID (grp_…)

Response 200

FieldTypeRequiredDescription
currentany | nullYes—
draftany | nullYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
issuesarray<object>Yes—
issues[].messagestringYes—
issues[].pathstringYes—
scheduledany | nullYes—

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

Example

bash
curl -X GET "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Approve a location's price changes: they are published, on their date if one was asked#

POST /v1/account/groups/{groupId}/price-book/approve

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

Path parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
outcomeenumYesOne of: "published", "scheduled", "pending_approval".
priceBookPriceBookYes—
priceBook.currentany | nullYes—
priceBook.draftany | nullYes—
priceBook.groupIdstring (grp_… ID)YesID (grp_…)
priceBook.groupNamestringYes—
priceBook.issuesarray<object>Yes—
priceBook.issues[].messagestringYes—
priceBook.issues[].pathstringYes—
priceBook.scheduledany | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book/approve" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

Cancel a scheduled price change before its date: it becomes the draft again#

POST /v1/account/groups/{groupId}/price-book/cancel-scheduled

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

Path parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)

Response 200

FieldTypeRequiredDescription
currentany | nullYes—
draftany | nullYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
issuesarray<object>Yes—
issues[].messagestringYes—
issues[].pathstringYes—
scheduledany | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book/cancel-scheduled" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Save a location's unpublished price changes#

PUT /v1/account/groups/{groupId}/price-book/draft

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

Path parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)

Request body

application/json, required.

FieldTypeRequiredDescription
contentobjectYes—
content.entriesarray<object>NoDefault: [].
content.entries[].cellsarray<object>NoDefault: [].
content.entries[].cells[].confirmedAtstring (date-time)No—
content.entries[].cells[].crmobjectNo—
content.entries[].cells[].hiddenbooleanNoDefault: false.
content.entries[].cells[].internalNotestringNoUp to 500 characters.
content.entries[].cells[].offeredbooleanNoDefault: true.
content.entries[].cells[].optionsarray<string (sopt_… ID)>NoUp to 2 items. Default: [].
content.entries[].cells[].priceobject | objectYes—
content.entries[].cells[].wordingstringNoUp to 200 characters.
content.entries[].offeredbooleanNoDefault: true.
content.entries[].pricedByarray<string (oset_… ID)>NoUp to 2 items. Default: [].
content.entries[].serviceIdstring (srv_… ID)YesID (srv_…)
expectedHashstring | nullNoUp to 100 characters.

Response 200

FieldTypeRequiredDescription
currentany | nullYes—
draftany | nullYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
issuesarray<object>Yes—
issues[].messagestringYes—
issues[].pathstringYes—
scheduledany | nullYes—

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

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book/draft" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "content": {
    "entries": []
  }
}'

Discard a location's unpublished price changes#

DELETE /v1/account/groups/{groupId}/price-book/draft

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

Path parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)

Response 200

FieldTypeRequiredDescription
currentany | nullYes—
draftany | nullYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
issuesarray<object>Yes—
issues[].messagestringYes—
issues[].pathstringYes—
scheduledany | nullYes—

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

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book/draft" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Publish a location's price changes, now or on a date. Sent for approval instead when your changes need it#

POST /v1/account/groups/{groupId}/price-book/publish

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

Path parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)

Request body

application/json, required.

FieldTypeRequiredDescription
effectiveFromstring (date-time)No—
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
outcomeenumYesOne of: "published", "scheduled", "pending_approval".
priceBookPriceBookYes—
priceBook.currentany | nullYes—
priceBook.draftany | nullYes—
priceBook.groupIdstring (grp_… ID)YesID (grp_…)
priceBook.groupNamestringYes—
priceBook.issuesarray<object>Yes—
priceBook.issues[].messagestringYes—
priceBook.issues[].pathstringYes—
priceBook.scheduledany | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book/publish" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "effectiveFrom": "2026-01-15T15:30:00Z",
  "note": "string"
}'

Send price changes waiting for approval back to draft, with a note saying why#

POST /v1/account/groups/{groupId}/price-book/return

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

Path parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringYes1–500 characters.

Response 200

FieldTypeRequiredDescription
currentany | nullYes—
draftany | nullYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
issuesarray<object>Yes—
issues[].messagestringYes—
issues[].pathstringYes—
scheduledany | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book/return" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

A location's published price books, newest first#

GET /v1/account/groups/{groupId}/price-book/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
groupIdstring (grp_… ID)YesID (grp_…)

Response 200

FieldTypeRequiredDescription
versionsarray<PriceBookVersion>Yes—
versions[].authorIdstring | nullYes—
versions[].changeNotestring | nullYes—
versions[].contentobjectYes—
versions[].content.entriesarray<object>YesDefault: [].
versions[].content.entries[].cellsarray<object>YesDefault: [].
versions[].content.entries[].offeredbooleanYesDefault: true.
versions[].content.entries[].pricedByarray<string (oset_… ID)>YesUp to 2 items. Default: [].
versions[].content.entries[].serviceIdstring (srv_… ID)YesID (srv_…)
versions[].contentHashstringYes—
versions[].decidedBystring | nullYes—
versions[].decisionNotestring | nullYes—
versions[].effectiveFromstring (date-time) | nullYes—
versions[].publishedAtstring (date-time) | nullYes—
versions[].publishedBystring | nullYes—
versions[].statusenumYesOne of: "draft", "pending_approval", "published".
versions[].submittedAtstring (date-time) | nullYes—
versions[].submittedBystring | nullYes—
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/groups/{groupId}/price-book/versions" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Publish a copy of an earlier price book as the newest version (sent for approval when your changes need it)#

POST /v1/account/groups/{groupId}/price-book/versions/{version}/rollback

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

Path parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)
versionintegerYesMinimum 1.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
outcomeenumYesOne of: "published", "scheduled", "pending_approval".
priceBookPriceBookYes—
priceBook.currentany | nullYes—
priceBook.draftany | nullYes—
priceBook.groupIdstring (grp_… ID)YesID (grp_…)
priceBook.groupNamestringYes—
priceBook.issuesarray<object>Yes—
priceBook.issues[].messagestringYes—
priceBook.issues[].pathstringYes—
priceBook.scheduledany | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book/versions/{version}/rollback" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Take back price changes you sent for approval, to change them#

POST /v1/account/groups/{groupId}/price-book/withdraw

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

Path parameters

NameTypeRequiredDescription
groupIdstring (grp_… ID)YesID (grp_…)

Request body

application/json, required.

Type: object

Response 200

FieldTypeRequiredDescription
currentany | nullYes—
draftany | nullYes—
groupIdstring (grp_… ID)YesID (grp_…)
groupNamestringYes—
issuesarray<object>Yes—
issues[].messagestringYes—
issues[].pathstringYes—
scheduledany | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/groups/{groupId}/price-book/withdraw" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Every location you can see against every service: current prices and drafts, or the prices in effect at a past moment#

GET /v1/account/price-matrix

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
atstring (date-time)No—

Response 200

FieldTypeRequiredDescription
catalogPriceCatalogYes—
catalog.optionSetsarray<object>Yes—
catalog.optionSets[].archivedbooleanYesDefault: false.
catalog.optionSets[].idstring (oset_… ID)YesID (oset_…)
catalog.optionSets[].namestringYes1–80 characters.
catalog.optionSets[].sortintegerYesBetween 0 and 100000. Default: 0.
catalog.optionsarray<object>Yes—
catalog.options[].archivedbooleanYesDefault: false.
catalog.options[].groupIdstring (grp_… ID) | nullYes—
catalog.options[].idstring (sopt_… ID)YesID (sopt_…)
catalog.options[].namestringYes1–80 characters.
catalog.options[].optionSetIdstring (oset_… ID)YesID (oset_…)
catalog.options[].sortintegerYesBetween 0 and 100000. Default: 0.
catalog.options[].spokenNamestringNo1–80 characters.
catalog.options[].synonymsarray<string>YesUp to 20 items. Default: [].
catalog.servicesarray<object>Yes—
catalog.services[].archivedbooleanYesDefault: false.
catalog.services[].descriptionstringYesUp to 600 characters. Default: "".
catalog.services[].groupIdstring (grp_… ID) | nullYes—
catalog.services[].idstring (srv_… ID)YesID (srv_…)
catalog.services[].kindenumYesOne of: "service", "add_on", "fee". Default: "service".
catalog.services[].namestringYes1–80 characters.
catalog.services[].optionSetIdsarray<string (oset_… ID)>YesUp to 2 items. Default: [].
catalog.services[].perPersonenumYesOne of: "single", "second_person". Default: "single".
catalog.services[].sortintegerYesBetween 0 and 100000. Default: 0.
catalog.services[].spokenNamestringNo1–80 characters.
catalog.services[].synonymsarray<string>YesUp to 20 items. Default: [].
catalog.services[].unitenumYesOne of: "month", "day", "night", "week", "visit", "hour", "one_time". Default: "month".
catalog.settingsobjectYes—
catalog.settings.allowLocationServicesbooleanYesDefault: true.
catalog.settings.priceApprovalenumYesOne of: "off", "group_managers", "everyone". Default: "off".
catalog.settings.priceApprovalIncludesCrmbooleanYesDefault: false.
catalog.settings.priceReviewDaysintegerYesBetween 0 and 3650. Default: 90.
priceBooksarray<PriceBook>Yes—
priceBooks[].currentany | nullYes—
priceBooks[].draftany | nullYes—
priceBooks[].groupIdstring (grp_… ID)YesID (grp_…)
priceBooks[].groupNamestringYes—
priceBooks[].issuesarray<object>Yes—
priceBooks[].issues[].messagestringYes—
priceBooks[].issues[].pathstringYes—
priceBooks[].scheduledany | nullYes—

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

Example

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

Approve the price changes waiting at several locations#

POST /v1/account/price-matrix/approve

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

Request body

application/json, required.

FieldTypeRequiredDescription
groupIdsarray<string (grp_… ID)>YesUp to 500 items.
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
outcomeenumYesOne of: "published", "scheduled", "pending_approval".
priceBooksarray<PriceBook>Yes—
priceBooks[].currentany | nullYes—
priceBooks[].draftany | nullYes—
priceBooks[].groupIdstring (grp_… ID)YesID (grp_…)
priceBooks[].groupNamestringYes—
priceBooks[].issuesarray<object>Yes—
priceBooks[].issues[].messagestringYes—
priceBooks[].issues[].pathstringYes—
priceBooks[].scheduledany | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/price-matrix/approve" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "groupIds": [
    "grp_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
  ]
}'

Discard the unpublished price changes of several locations#

POST /v1/account/price-matrix/discard

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

Request body

application/json, required.

FieldTypeRequiredDescription
groupIdsarray<string (grp_… ID)>YesUp to 500 items.

Response 200

FieldTypeRequiredDescription
discardedintegerYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/price-matrix/discard" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "groupIds": [
    "grp_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
  ]
}'

Save unpublished price changes for several locations at once#

PUT /v1/account/price-matrix/drafts

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

Request body

application/json, required.

FieldTypeRequiredDescription
draftsarray<object>YesUp to 500 items.
drafts[].contentobjectYes—
drafts[].content.entriesarray<object>NoDefault: [].
drafts[].content.entries[].cellsarray<object>NoDefault: [].
drafts[].content.entries[].offeredbooleanNoDefault: true.
drafts[].content.entries[].pricedByarray<string (oset_… ID)>NoUp to 2 items. Default: [].
drafts[].content.entries[].serviceIdstring (srv_… ID)YesID (srv_…)
drafts[].expectedHashstring | nullNoUp to 100 characters.
drafts[].groupIdstring (grp_… ID)YesID (grp_…)

Response 200

FieldTypeRequiredDescription
priceBooksarray<PriceBook>Yes—
priceBooks[].currentany | nullYes—
priceBooks[].draftany | nullYes—
priceBooks[].groupIdstring (grp_… ID)YesID (grp_…)
priceBooks[].groupNamestringYes—
priceBooks[].issuesarray<object>Yes—
priceBooks[].issues[].messagestringYes—
priceBooks[].issues[].pathstringYes—
priceBooks[].scheduledany | nullYes—

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

Example

bash
curl -X PUT "$ANSWERSTACK_API_URL/v1/account/price-matrix/drafts" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "drafts": [
    {
      "groupId": "grp_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE",
      "content": {
        "entries": []
      }
    }
  ]
}'

Publish the price changes of several locations with one note, now or on a date (sent for approval when your changes need it)#

POST /v1/account/price-matrix/publish

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

Request body

application/json, required.

FieldTypeRequiredDescription
effectiveFromstring (date-time)No—
groupIdsarray<string (grp_… ID)>YesUp to 500 items.
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
outcomeenumYesOne of: "published", "scheduled", "pending_approval".
priceBooksarray<PriceBook>Yes—
priceBooks[].currentany | nullYes—
priceBooks[].draftany | nullYes—
priceBooks[].groupIdstring (grp_… ID)YesID (grp_…)
priceBooks[].groupNamestringYes—
priceBooks[].issuesarray<object>Yes—
priceBooks[].issues[].messagestringYes—
priceBooks[].issues[].pathstringYes—
priceBooks[].scheduledany | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/price-matrix/publish" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "groupIds": [
    "grp_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
  ]
}'

The services, option sets and options you sell, and the pricing settings#

GET /v1/account/pricing/catalog

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

Response 200

FieldTypeRequiredDescription
optionSetsarray<object>Yes—
optionSets[].archivedbooleanYesDefault: false.
optionSets[].idstring (oset_… ID)YesID (oset_…)
optionSets[].namestringYes1–80 characters.
optionSets[].sortintegerYesBetween 0 and 100000. Default: 0.
optionsarray<object>Yes—
options[].archivedbooleanYesDefault: false.
options[].groupIdstring (grp_… ID) | nullYes—
options[].idstring (sopt_… ID)YesID (sopt_…)
options[].namestringYes1–80 characters.
options[].optionSetIdstring (oset_… ID)YesID (oset_…)
options[].sortintegerYesBetween 0 and 100000. Default: 0.
options[].spokenNamestringNo1–80 characters.
options[].synonymsarray<string>YesUp to 20 items. Default: [].
servicesarray<object>Yes—
services[].archivedbooleanYesDefault: false.
services[].descriptionstringYesUp to 600 characters. Default: "".
services[].groupIdstring (grp_… ID) | nullYes—
services[].idstring (srv_… ID)YesID (srv_…)
services[].kindenumYesOne of: "service", "add_on", "fee". Default: "service".
services[].namestringYes1–80 characters.
services[].optionSetIdsarray<string (oset_… ID)>YesUp to 2 items. Default: [].
services[].perPersonenumYesOne of: "single", "second_person". Default: "single".
services[].sortintegerYesBetween 0 and 100000. Default: 0.
services[].spokenNamestringNo1–80 characters.
services[].synonymsarray<string>YesUp to 20 items. Default: [].
services[].unitenumYesOne of: "month", "day", "night", "week", "visit", "hour", "one_time". Default: "month".
settingsobjectYes—
settings.allowLocationServicesbooleanYesDefault: true.
settings.priceApprovalenumYesOne of: "off", "group_managers", "everyone". Default: "off".
settings.priceApprovalIncludesCrmbooleanYesDefault: false.
settings.priceReviewDaysintegerYesBetween 0 and 3650. Default: 90.

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

Example

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

Add an option set: a list of choices that changes a price#

POST /v1/account/pricing/option-sets

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

Request body

application/json, required.

FieldTypeRequiredDescription
namestringYes1–80 characters.
sortintegerNoBetween 0 and 100000. Default: 0.

Response 201

FieldTypeRequiredDescription
archivedbooleanYesDefault: false.
idstring (oset_… ID)YesID (oset_…)
namestringYes1–80 characters.
sortintegerYesBetween 0 and 100000. Default: 0.

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/option-sets" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'

Rename, reorder or archive an option set#

PATCH /v1/account/pricing/option-sets/{optionSetId}

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

Path parameters

NameTypeRequiredDescription
optionSetIdstring (oset_… ID)YesID (oset_…)

Request body

application/json, required.

FieldTypeRequiredDescription
archivedbooleanNo—
namestringNo1–80 characters.
sortintegerNoBetween 0 and 100000.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
optionSetobjectYes—
optionSet.archivedbooleanYesDefault: false.
optionSet.idstring (oset_… ID)YesID (oset_…)
optionSet.namestringYes1–80 characters.
optionSet.sortintegerYesBetween 0 and 100000. Default: 0.

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

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/account/pricing/option-sets/{optionSetId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "archived": true,
  "name": "string",
  "sort": 0
}'

Add an option to a set: the account's, or a location's own#

POST /v1/account/pricing/option-sets/{optionSetId}/options

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

Path parameters

NameTypeRequiredDescription
optionSetIdstring (oset_… ID)YesID (oset_…)

Request body

application/json, required.

FieldTypeRequiredDescription
groupIdstring (grp_… ID) | nullNo—
namestringYes1–80 characters.
sortintegerNoBetween 0 and 100000. Default: 0.
spokenNamestringNo1–80 characters.
synonymsarray<string>NoUp to 20 items. Default: [].

Response 201

FieldTypeRequiredDescription
archivedbooleanYesDefault: false.
groupIdstring (grp_… ID) | nullYes—
idstring (sopt_… ID)YesID (sopt_…)
namestringYes1–80 characters.
optionSetIdstring (oset_… ID)YesID (oset_…)
sortintegerYesBetween 0 and 100000. Default: 0.
spokenNamestringNo1–80 characters.
synonymsarray<string>YesUp to 20 items. Default: [].

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/option-sets/{optionSetId}/options" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'

Rename, reorder or archive an option#

PATCH /v1/account/pricing/options/{optionId}

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

Path parameters

NameTypeRequiredDescription
optionIdstring (sopt_… ID)YesID (sopt_…)

Request body

application/json, required.

FieldTypeRequiredDescription
archivedbooleanNo—
namestringNo1–80 characters.
sortintegerNoBetween 0 and 100000.
spokenNamestring | nullNo1–80 characters.
synonymsarray<string>NoUp to 20 items.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
optionobjectYes—
option.archivedbooleanYesDefault: false.
option.groupIdstring (grp_… ID) | nullYes—
option.idstring (sopt_… ID)YesID (sopt_…)
option.namestringYes1–80 characters.
option.optionSetIdstring (oset_… ID)YesID (oset_…)
option.sortintegerYesBetween 0 and 100000. Default: 0.
option.spokenNamestringNo1–80 characters.
option.synonymsarray<string>YesUp to 20 items. Default: [].

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

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/account/pricing/options/{optionId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "archived": true,
  "name": "string",
  "sort": 0,
  "spokenName": "string",
  "synonyms": [
    "string"
  ]
}'

Add a service to the account's catalog, or a location's own#

POST /v1/account/pricing/services

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

Request body

application/json, required.

FieldTypeRequiredDescription
descriptionstringNoUp to 600 characters. Default: "".
groupIdstring (grp_… ID) | nullNo—
kindenumNoOne of: "service", "add_on", "fee". Default: "service".
namestringYes1–80 characters.
optionSetIdsarray<string (oset_… ID)>NoUp to 2 items. Default: [].
perPersonenumNoOne of: "single", "second_person". Default: "single".
sortintegerNoBetween 0 and 100000. Default: 0.
spokenNamestringNo1–80 characters.
synonymsarray<string>NoUp to 20 items. Default: [].
unitenumNoOne of: "month", "day", "night", "week", "visit", "hour", "one_time". Default: "month".

Response 201

FieldTypeRequiredDescription
archivedbooleanYesDefault: false.
descriptionstringYesUp to 600 characters. Default: "".
groupIdstring (grp_… ID) | nullYes—
idstring (srv_… ID)YesID (srv_…)
kindenumYesOne of: "service", "add_on", "fee". Default: "service".
namestringYes1–80 characters.
optionSetIdsarray<string (oset_… ID)>YesUp to 2 items. Default: [].
perPersonenumYesOne of: "single", "second_person". Default: "single".
sortintegerYesBetween 0 and 100000. Default: 0.
spokenNamestringNo1–80 characters.
synonymsarray<string>YesUp to 20 items. Default: [].
unitenumYesOne of: "month", "day", "night", "week", "visit", "hour", "one_time". Default: "month".

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/services" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'

Change or archive a service. Every location that offers it is recomputed#

PATCH /v1/account/pricing/services/{serviceId}

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

Path parameters

NameTypeRequiredDescription
serviceIdstring (srv_… ID)YesID (srv_…)

Request body

application/json, required.

FieldTypeRequiredDescription
archivedbooleanNo—
descriptionstringNoUp to 600 characters.
kindenumNoOne of: "service", "add_on", "fee".
namestringNo1–80 characters.
optionSetIdsarray<string (oset_… ID)>NoUp to 2 items.
perPersonenumNoOne of: "single", "second_person".
sortintegerNoBetween 0 and 100000.
spokenNamestring | nullNo1–80 characters.
synonymsarray<string>NoUp to 20 items.
unitenumNoOne of: "month", "day", "night", "week", "visit", "hour", "one_time".

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
serviceobjectYes—
service.archivedbooleanYesDefault: false.
service.descriptionstringYesUp to 600 characters. Default: "".
service.groupIdstring (grp_… ID) | nullYes—
service.idstring (srv_… ID)YesID (srv_…)
service.kindenumYesOne of: "service", "add_on", "fee". Default: "service".
service.namestringYes1–80 characters.
service.optionSetIdsarray<string (oset_… ID)>YesUp to 2 items. Default: [].
service.perPersonenumYesOne of: "single", "second_person". Default: "single".
service.sortintegerYesBetween 0 and 100000. Default: 0.
service.spokenNamestringNo1–80 characters.
service.synonymsarray<string>YesUp to 20 items. Default: [].
service.unitenumYesOne of: "month", "day", "night", "week", "visit", "hour", "one_time". Default: "month".

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

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/account/pricing/services/{serviceId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "archived": true,
  "description": "string",
  "kind": "service",
  "name": "string",
  "optionSetIds": [
    "oset_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
  ],
  "perPerson": "single",
  "sort": 0,
  "spokenName": "string",
  "synonyms": [
    "string"
  ],
  "unit": "month"
}'

Your specials: drafts, those waiting for approval, and approved ones#

GET /v1/account/pricing/specials

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

Response 200

FieldTypeRequiredDescription
specialsarray<SpecialListItem>Yes—
specials[].createdBystring | nullYes—
specials[].decidedBystring | nullYes—
specials[].decisionNotestring | nullYes—
specials[].endsOnstring | nullYes—
specials[].groupIdsarray<string>Yes—
specials[].idstring (spcl_… ID)YesID (spcl_…)
specials[].reacharray<object>Yes—
specials[].reach[].groupIdstringYes—
specials[].reach[].groupNamestringYes—
specials[].reach[].reasonenum | nullYesOne of: "no_published_prices".
specials[].reach[].saidbooleanYes—
specials[].serviceIdsarray<string>Yes—
specials[].spokenWordingstringYes—
specials[].startsOnstringYes—
specials[].statusenumYesOne of: "draft", "pending_approval", "approved".
specials[].submittedBystring | nullYes—
specials[].titlestringYes—
specials[].updatedAtstring (date-time)Yes—
specials[].writtenWordingstring | nullYes—

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

Example

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

Add a special. It is approved at once, or sent for approval when your changes need it, or kept as a draft#

POST /v1/account/pricing/specials

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

Request body

application/json, required.

FieldTypeRequiredDescription
draftbooleanNo—
endsOnstring (date) | nullNo—
groupIdsarray<string (grp_… ID)>NoUp to 500 items. Default: [].
serviceIdsarray<string (srv_… ID)>NoUp to 50 items. Default: [].
spokenWordingstringYes1–300 characters.
startsOnstring (date)Yes—
titlestringYes1–80 characters.
writtenWordingstringNo1–300 characters.

Response 201

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
specialSpecialYes—
special.createdBystring | nullYes—
special.decidedBystring | nullYes—
special.decisionNotestring | nullYes—
special.endsOnstring | nullYes—
special.groupIdsarray<string>Yes—
special.idstring (spcl_… ID)YesID (spcl_…)
special.serviceIdsarray<string>Yes—
special.spokenWordingstringYes—
special.startsOnstringYes—
special.statusenumYesOne of: "draft", "pending_approval", "approved".
special.submittedBystring | nullYes—
special.titlestringYes—
special.updatedAtstring (date-time)Yes—
special.writtenWordingstring | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/specials" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "string",
  "spokenWording": "string",
  "startsOn": "2026-01-15"
}'

Change a special. Changing an approved one sends it back for approval when your changes need it#

PATCH /v1/account/pricing/specials/{specialId}

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

Path parameters

NameTypeRequiredDescription
specialIdstring (spcl_… ID)YesID (spcl_…)

Request body

application/json, required.

FieldTypeRequiredDescription
endsOnstring (date) | nullNo—
groupIdsarray<string (grp_… ID)>NoUp to 500 items.
serviceIdsarray<string (srv_… ID)>NoUp to 50 items.
spokenWordingstringNo1–300 characters.
startsOnstring (date)No—
titlestringNo1–80 characters.
writtenWordingstring | nullNo1–300 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
specialSpecialYes—
special.createdBystring | nullYes—
special.decidedBystring | nullYes—
special.decisionNotestring | nullYes—
special.endsOnstring | nullYes—
special.groupIdsarray<string>Yes—
special.idstring (spcl_… ID)YesID (spcl_…)
special.serviceIdsarray<string>Yes—
special.spokenWordingstringYes—
special.startsOnstringYes—
special.statusenumYesOne of: "draft", "pending_approval", "approved".
special.submittedBystring | nullYes—
special.titlestringYes—
special.updatedAtstring (date-time)Yes—
special.writtenWordingstring | nullYes—

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

Example

bash
curl -X PATCH "$ANSWERSTACK_API_URL/v1/account/pricing/specials/{specialId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "endsOn": "2026-01-15",
  "groupIds": [
    "grp_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
  ],
  "serviceIds": [
    "srv_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE"
  ],
  "spokenWording": "string",
  "startsOn": "2026-01-15",
  "title": "string",
  "writtenWording": "string"
}'

Delete a draft special (approved ones are ended, never deleted)#

DELETE /v1/account/pricing/specials/{specialId}

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

Path parameters

NameTypeRequiredDescription
specialIdstring (spcl_… ID)YesID (spcl_…)

Response 204

No content.

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

Example

bash
curl -X DELETE "$ANSWERSTACK_API_URL/v1/account/pricing/specials/{specialId}" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Approve a special waiting for approval#

POST /v1/account/pricing/specials/{specialId}/approve

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

Path parameters

NameTypeRequiredDescription
specialIdstring (spcl_… ID)YesID (spcl_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
specialSpecialYes—
special.createdBystring | nullYes—
special.decidedBystring | nullYes—
special.decisionNotestring | nullYes—
special.endsOnstring | nullYes—
special.groupIdsarray<string>Yes—
special.idstring (spcl_… ID)YesID (spcl_…)
special.serviceIdsarray<string>Yes—
special.spokenWordingstringYes—
special.startsOnstringYes—
special.statusenumYesOne of: "draft", "pending_approval", "approved".
special.submittedBystring | nullYes—
special.titlestringYes—
special.updatedAtstring (date-time)Yes—
special.writtenWordingstring | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/specials/{specialId}/approve" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

End an approved special now: the agent stops mentioning it#

POST /v1/account/pricing/specials/{specialId}/end

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

Path parameters

NameTypeRequiredDescription
specialIdstring (spcl_… ID)YesID (spcl_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
specialSpecialYes—
special.createdBystring | nullYes—
special.decidedBystring | nullYes—
special.decisionNotestring | nullYes—
special.endsOnstring | nullYes—
special.groupIdsarray<string>Yes—
special.idstring (spcl_… ID)YesID (spcl_…)
special.serviceIdsarray<string>Yes—
special.spokenWordingstringYes—
special.startsOnstringYes—
special.statusenumYesOne of: "draft", "pending_approval", "approved".
special.submittedBystring | nullYes—
special.titlestringYes—
special.updatedAtstring (date-time)Yes—
special.writtenWordingstring | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/specials/{specialId}/end" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

Send a special waiting for approval back to draft, with a note saying why#

POST /v1/account/pricing/specials/{specialId}/return

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

Path parameters

NameTypeRequiredDescription
specialIdstring (spcl_… ID)YesID (spcl_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringYes1–500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
specialSpecialYes—
special.createdBystring | nullYes—
special.decidedBystring | nullYes—
special.decisionNotestring | nullYes—
special.endsOnstring | nullYes—
special.groupIdsarray<string>Yes—
special.idstring (spcl_… ID)YesID (spcl_…)
special.serviceIdsarray<string>Yes—
special.spokenWordingstringYes—
special.startsOnstringYes—
special.statusenumYesOne of: "draft", "pending_approval", "approved".
special.submittedBystring | nullYes—
special.titlestringYes—
special.updatedAtstring (date-time)Yes—
special.writtenWordingstring | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/specials/{specialId}/return" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

Send a draft special for approval (approved at once when your changes do not need it)#

POST /v1/account/pricing/specials/{specialId}/submit

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

Path parameters

NameTypeRequiredDescription
specialIdstring (spcl_… ID)YesID (spcl_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
specialSpecialYes—
special.createdBystring | nullYes—
special.decidedBystring | nullYes—
special.decisionNotestring | nullYes—
special.endsOnstring | nullYes—
special.groupIdsarray<string>Yes—
special.idstring (spcl_… ID)YesID (spcl_…)
special.serviceIdsarray<string>Yes—
special.spokenWordingstringYes—
special.startsOnstringYes—
special.statusenumYesOne of: "draft", "pending_approval", "approved".
special.submittedBystring | nullYes—
special.titlestringYes—
special.updatedAtstring (date-time)Yes—
special.writtenWordingstring | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/specials/{specialId}/submit" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'

Take back a special you sent for approval#

POST /v1/account/pricing/specials/{specialId}/withdraw

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

Path parameters

NameTypeRequiredDescription
specialIdstring (spcl_… ID)YesID (spcl_…)

Request body

application/json, required.

FieldTypeRequiredDescription
notestringNoUp to 500 characters.

Response 200

FieldTypeRequiredDescription
effectivearray<object>Yes—
effective[].groupIdstring (grp_… ID)YesID (grp_…)
effective[].issuesarray<string>Yes—
effective[].outcomeenumYesOne of: "updated", "needs_review", "blocked_no_backup", "blocked_opening", "no_profile".
effective[].playbookIdstring (pb_… ID)YesID (pb_…)
specialSpecialYes—
special.createdBystring | nullYes—
special.decidedBystring | nullYes—
special.decisionNotestring | nullYes—
special.endsOnstring | nullYes—
special.groupIdsarray<string>Yes—
special.idstring (spcl_… ID)YesID (spcl_…)
special.serviceIdsarray<string>Yes—
special.spokenWordingstringYes—
special.startsOnstringYes—
special.statusenumYesOne of: "draft", "pending_approval", "approved".
special.submittedBystring | nullYes—
special.titlestringYes—
special.updatedAtstring (date-time)Yes—
special.writtenWordingstring | nullYes—

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

Example

bash
curl -X POST "$ANSWERSTACK_API_URL/v1/account/pricing/specials/{specialId}/withdraw" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "string"
}'