API reference
Connections
CRM and calendar connections
| Method | Path | Summary |
|---|---|---|
GET | /v1/account/connections | The connector catalog and the account's connections |
POST | /v1/account/connections | Save a connection: its health check must pass first; the token goes to Vault |
POST | /v1/account/connections/mcp | Use a tool server as the CRM or calendar: map each step to an approved tool. The read-only checks must pass first |
POST | /v1/account/connections/oauth/confirm | Finish a sign-in to connect a CRM or calendar, with the token the callback handed the browser. Only the person who started it can (ADR 0111) |
POST | /v1/account/connections/oauth/start | Start signing in to connect a CRM or calendar, or to reconnect one. Returns where to send the browser |
POST | /v1/account/connections/sandbox-link | "Open sandbox CRM": a short-lived sign-in link to the account sandbox |
DELETE | /v1/account/connections/{connectionId} | Delete a connection that no playbook uses (the sandbox stays) |
POST | /v1/account/connections/{connectionId}/guided-test | Write to the real system to prove the mapping: create a test contact, book the first open time and cancel it. Only when a member confirms |
POST | /v1/account/connections/{connectionId}/inbound-secret | Make a new secret for signing requests your system sends to this connection’s webhook URL (v2, ADR 0112). Shown once; the previous one stops working |
PUT | /v1/account/connections/{connectionId}/mcp | Change a tool server connection's mapping. The read-only checks must pass first |
POST | /v1/account/connections/{connectionId}/test | Run the health check and record the result |
GET | /v1/account/rep-calendars | Which members have connected their own calendar, by their sign-in email |
The connector catalog and the account's connections#
GET /v1/account/connections
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
catalog | array<ConnectorManifest> | Yes | — |
catalog[].auth | enum | Yes | One of: "api_token", "oauth", "webhook_secret", "tool_connection", "none". |
catalog[].connector | string | Yes | — |
catalog[].description | string | Yes | — |
catalog[].displayName | string | Yes | — |
catalog[].dynamicRoles | boolean | Yes | — |
catalog[].options | array<object> | Yes | — |
catalog[].options[].key | string | Yes | — |
catalog[].options[].label | string | Yes | — |
catalog[].options[].required | boolean | No | — |
catalog[].options[].type | enum | Yes | One of: "string", "number", "boolean". |
catalog[].roles | array<enum> | Yes | Items: "crm", "scheduler". |
catalog[].signInWith | string | null | Yes | — |
connections | array<Connection> | Yes | — |
connections[].config | map | Yes | — |
connections[].config.{key} | any | No | Any key. |
connections[].connector | string | Yes | — |
connections[].connectorName | string | Yes | — |
connections[].createdAt | string (date-time) | Yes | — |
connections[].hasSecret | boolean | Yes | — |
connections[].id | string (conn_… ID) | Yes | ID (conn_…) |
connections[].inboundSecretAt | string (date-time) | null | Yes | — |
connections[].inboundSignedAt | string (date-time) | null | Yes | — |
connections[].kind | enum | Yes | One of: "sandbox", "live". |
connections[].lastCheckedAt | string (date-time) | null | Yes | — |
connections[].lastError | string | null | Yes | — |
connections[].name | string | Yes | — |
connections[].priceSync | boolean | Yes | — |
connections[].roles | array<enum> | Yes | Items: "crm", "scheduler". |
connections[].status | enum | Yes | One of: "connected", "error", "pending". |
connections[].updatedAt | string (date-time) | Yes | — |
connections[].warnings | array<string> | Yes | — |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X GET "$ANSWERSTACK_API_URL/v1/account/connections" \
-H "Authorization: Bearer $ACCESS_TOKEN"Save a connection: its health check must pass first; the token goes to Vault#
POST /v1/account/connections
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Request body
application/json, required.
| Field | Type | Required | Description |
|---|---|---|---|
config | object | No | Default: \{\}. |
config.baseUrl | string (uri) | No | Up to 500 characters. |
config.{key} | string | number | boolean | No | Any key. |
connector | string | Yes | Pattern: ^[a-z][a-z0-9_]\{1,40\}$. |
name | string | Yes | 1–120 characters. |
token | string | No | 1–4000 characters. |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
connection | Connection | Yes | — |
connection.config | map | Yes | — |
connection.config.{key} | any | No | Any key. |
connection.connector | string | Yes | — |
connection.connectorName | string | Yes | — |
connection.createdAt | string (date-time) | Yes | — |
connection.hasSecret | boolean | Yes | — |
connection.id | string (conn_… ID) | Yes | ID (conn_…) |
connection.inboundSecretAt | string (date-time) | null | Yes | — |
connection.inboundSignedAt | string (date-time) | null | Yes | — |
connection.kind | enum | Yes | One of: "sandbox", "live". |
connection.lastCheckedAt | string (date-time) | null | Yes | — |
connection.lastError | string | null | Yes | — |
connection.name | string | Yes | — |
connection.priceSync | boolean | Yes | — |
connection.roles | array<enum> | Yes | Items: "crm", "scheduler". |
connection.status | enum | Yes | One of: "connected", "error", "pending". |
connection.updatedAt | string (date-time) | Yes | — |
connection.warnings | array<string> | Yes | — |
health | object | Yes | — |
health.latencyMs | number | Yes | — |
health.message | string | No | — |
health.ok | boolean | Yes | — |
Errors: 400, 401, 403, 404, 409, 422, 429, 500, with an ErrorBody body.
Example
curl -X POST "$ANSWERSTACK_API_URL/v1/account/connections" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"connector": "string",
"name": "string"
}'Use a tool server as the CRM or calendar: map each step to an approved tool. The read-only checks must pass first#
POST /v1/account/connections/mcp
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Request body
application/json, required.
| Field | Type | Required | Description |
|---|---|---|---|
methods | map | Yes | — |
methods.{key} | object | No | Any key. |
methods.{key}.args | map | No | Default: \{\}. |
methods.{key}.args.{key} | string | number | boolean | null | No | Any key. |
methods.{key}.result | map | No | Default: \{\}. |
methods.{key}.result.{key} | string | object | No | Any key. |
methods.{key}.tool | string | Yes | 1–128 characters. |
name | string | Yes | 1–120 characters. |
toolConnectionId | string (tcn_… ID) | Yes | ID (tcn_…) |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
checks | array<ConnectionCheck> | Yes | — |
checks[].check | string | Yes | — |
checks[].detail | string | Yes | — |
checks[].ok | boolean | Yes | — |
connection | Connection | Yes | — |
connection.config | map | Yes | — |
connection.config.{key} | any | No | Any key. |
connection.connector | string | Yes | — |
connection.connectorName | string | Yes | — |
connection.createdAt | string (date-time) | Yes | — |
connection.hasSecret | boolean | Yes | — |
connection.id | string (conn_… ID) | Yes | ID (conn_…) |
connection.inboundSecretAt | string (date-time) | null | Yes | — |
connection.inboundSignedAt | string (date-time) | null | Yes | — |
connection.kind | enum | Yes | One of: "sandbox", "live". |
connection.lastCheckedAt | string (date-time) | null | Yes | — |
connection.lastError | string | null | Yes | — |
connection.name | string | Yes | — |
connection.priceSync | boolean | Yes | — |
connection.roles | array<enum> | Yes | Items: "crm", "scheduler". |
connection.status | enum | Yes | One of: "connected", "error", "pending". |
connection.updatedAt | string (date-time) | Yes | — |
connection.warnings | array<string> | Yes | — |
Errors: 400, 401, 403, 404, 409, 422, 429, 500, with an ErrorBody body.
Example
curl -X POST "$ANSWERSTACK_API_URL/v1/account/connections/mcp" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"toolConnectionId": "tcn_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE",
"methods": {}
}'Finish a sign-in to connect a CRM or calendar, with the token the callback handed the browser. Only the person who started it can (ADR 0111)#
POST /v1/account/connections/oauth/confirm
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Request body
application/json, required.
| Field | Type | Required | Description |
|---|---|---|---|
confirm | string | Yes | 20–200 characters. |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
connection | string | No | — |
reason | enum | No | One of: "unauthorized", "forbidden", "not_found", "rate_limited", "unavailable", "timeout", "misconfigured", "missing_permissions", "calendar_not_found", "calendar_read_only", "personal_account", "mailbox_access_denied", "failed". |
result | enum | Yes | One of: "ok", "denied", "expired", "missing_scopes", "failed", "error", "wrong_user", "other_account". |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X POST "$ANSWERSTACK_API_URL/v1/account/connections/oauth/confirm" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"confirm": "string"
}'Start signing in to connect a CRM or calendar, or to reconnect one. Returns where to send the browser#
POST /v1/account/connections/oauth/start
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Request body
application/json, required.
| Field | Type | Required | Description |
|---|---|---|---|
config | map | No | (variant 1) Default: \{\}. |
config.{key} | string | number | boolean | No | (variant 1) Any key. |
connector | string | Yes | (variant 1) Pattern: ^[a-z][a-z0-9_]\{1,40\}$. |
name | string | Yes | (variant 1) 1–120 characters. |
connectionId | string (conn_… ID) | Yes | (variant 2) ID (conn_…) |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
authorizationUrl | string | Yes | — |
expiresInSeconds | integer | Yes | — |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X POST "$ANSWERSTACK_API_URL/v1/account/connections/oauth/start" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"connector": "string",
"name": "string"
}'"Open sandbox CRM": a short-lived sign-in link to the account sandbox#
POST /v1/account/connections/sandbox-link
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
expiresInSeconds | integer | Yes | — |
url | string | Yes | — |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X POST "$ANSWERSTACK_API_URL/v1/account/connections/sandbox-link" \
-H "Authorization: Bearer $ACCESS_TOKEN"Delete a connection that no playbook uses (the sandbox stays)#
DELETE /v1/account/connections/{connectionId}
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
connectionId | string (conn_… ID) | Yes | ID (conn_…) |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
deleted | enum | Yes | One of: true. |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X DELETE "$ANSWERSTACK_API_URL/v1/account/connections/{connectionId}" \
-H "Authorization: Bearer $ACCESS_TOKEN"Write to the real system to prove the mapping: create a test contact, book the first open time and cancel it. Only when a member confirms#
POST /v1/account/connections/{connectionId}/guided-test
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
connectionId | string (conn_… ID) | Yes | ID (conn_…) |
Request body
application/json, required.
| Field | Type | Required | Description |
|---|---|---|---|
confirm | enum | Yes | One of: true. |
groupId | string (grp_… ID) | No | ID (grp_…) |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
checks | array<ConnectionCheck> | Yes | — |
checks[].check | string | Yes | — |
checks[].detail | string | Yes | — |
checks[].ok | boolean | Yes | — |
ok | boolean | Yes | — |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X POST "$ANSWERSTACK_API_URL/v1/account/connections/{connectionId}/guided-test" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"confirm": true
}'Make a new secret for signing requests your system sends to this connection’s webhook URL (v2, ADR 0112). Shown once; the previous one stops working#
POST /v1/account/connections/{connectionId}/inbound-secret
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
connectionId | string (conn_… ID) | Yes | ID (conn_…) |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
connection | Connection | Yes | — |
connection.config | map | Yes | — |
connection.config.{key} | any | No | Any key. |
connection.connector | string | Yes | — |
connection.connectorName | string | Yes | — |
connection.createdAt | string (date-time) | Yes | — |
connection.hasSecret | boolean | Yes | — |
connection.id | string (conn_… ID) | Yes | ID (conn_…) |
connection.inboundSecretAt | string (date-time) | null | Yes | — |
connection.inboundSignedAt | string (date-time) | null | Yes | — |
connection.kind | enum | Yes | One of: "sandbox", "live". |
connection.lastCheckedAt | string (date-time) | null | Yes | — |
connection.lastError | string | null | Yes | — |
connection.name | string | Yes | — |
connection.priceSync | boolean | Yes | — |
connection.roles | array<enum> | Yes | Items: "crm", "scheduler". |
connection.status | enum | Yes | One of: "connected", "error", "pending". |
connection.updatedAt | string (date-time) | Yes | — |
connection.warnings | array<string> | Yes | — |
header | string | Yes | — |
secret | string | Yes | — |
url | string | Yes | — |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X POST "$ANSWERSTACK_API_URL/v1/account/connections/{connectionId}/inbound-secret" \
-H "Authorization: Bearer $ACCESS_TOKEN"Change a tool server connection's mapping. The read-only checks must pass first#
PUT /v1/account/connections/{connectionId}/mcp
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
connectionId | string (conn_… ID) | Yes | ID (conn_…) |
Request body
application/json, required.
| Field | Type | Required | Description |
|---|---|---|---|
methods | map | Yes | — |
methods.{key} | object | No | Any key. |
methods.{key}.args | map | No | Default: \{\}. |
methods.{key}.args.{key} | string | number | boolean | null | No | Any key. |
methods.{key}.result | map | No | Default: \{\}. |
methods.{key}.result.{key} | string | object | No | Any key. |
methods.{key}.tool | string | Yes | 1–128 characters. |
name | string | Yes | 1–120 characters. |
toolConnectionId | string (tcn_… ID) | Yes | ID (tcn_…) |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
checks | array<ConnectionCheck> | Yes | — |
checks[].check | string | Yes | — |
checks[].detail | string | Yes | — |
checks[].ok | boolean | Yes | — |
connection | Connection | Yes | — |
connection.config | map | Yes | — |
connection.config.{key} | any | No | Any key. |
connection.connector | string | Yes | — |
connection.connectorName | string | Yes | — |
connection.createdAt | string (date-time) | Yes | — |
connection.hasSecret | boolean | Yes | — |
connection.id | string (conn_… ID) | Yes | ID (conn_…) |
connection.inboundSecretAt | string (date-time) | null | Yes | — |
connection.inboundSignedAt | string (date-time) | null | Yes | — |
connection.kind | enum | Yes | One of: "sandbox", "live". |
connection.lastCheckedAt | string (date-time) | null | Yes | — |
connection.lastError | string | null | Yes | — |
connection.name | string | Yes | — |
connection.priceSync | boolean | Yes | — |
connection.roles | array<enum> | Yes | Items: "crm", "scheduler". |
connection.status | enum | Yes | One of: "connected", "error", "pending". |
connection.updatedAt | string (date-time) | Yes | — |
connection.warnings | array<string> | Yes | — |
Errors: 400, 401, 403, 404, 409, 422, 429, 500, with an ErrorBody body.
Example
curl -X PUT "$ANSWERSTACK_API_URL/v1/account/connections/{connectionId}/mcp" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"toolConnectionId": "tcn_2ZPh7XbT0v9Ao4iJ3qK1mN8sRgE",
"methods": {}
}'Run the health check and record the result#
POST /v1/account/connections/{connectionId}/test
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
connectionId | string (conn_… ID) | Yes | ID (conn_…) |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
connection | Connection | Yes | — |
connection.config | map | Yes | — |
connection.config.{key} | any | No | Any key. |
connection.connector | string | Yes | — |
connection.connectorName | string | Yes | — |
connection.createdAt | string (date-time) | Yes | — |
connection.hasSecret | boolean | Yes | — |
connection.id | string (conn_… ID) | Yes | ID (conn_…) |
connection.inboundSecretAt | string (date-time) | null | Yes | — |
connection.inboundSignedAt | string (date-time) | null | Yes | — |
connection.kind | enum | Yes | One of: "sandbox", "live". |
connection.lastCheckedAt | string (date-time) | null | Yes | — |
connection.lastError | string | null | Yes | — |
connection.name | string | Yes | — |
connection.priceSync | boolean | Yes | — |
connection.roles | array<enum> | Yes | Items: "crm", "scheduler". |
connection.status | enum | Yes | One of: "connected", "error", "pending". |
connection.updatedAt | string (date-time) | Yes | — |
connection.warnings | array<string> | Yes | — |
health | object | Yes | — |
health.latencyMs | number | Yes | — |
health.message | string | No | — |
health.ok | boolean | Yes | — |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X POST "$ANSWERSTACK_API_URL/v1/account/connections/{connectionId}/test" \
-H "Authorization: Bearer $ACCESS_TOKEN"Which members have connected their own calendar, by their sign-in email#
GET /v1/account/rep-calendars
Authentication: Bearer token: Authorization: Bearer <token> (Supabase access token).
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
calendars | array<RepCalendarStatus> | Yes | — |
calendars[].accountEmail | string | null | Yes | — |
calendars[].lastCheckedAt | string (date-time) | null | Yes | — |
calendars[].lastError | string | null | Yes | — |
calendars[].provider | string | Yes | — |
calendars[].status | enum | Yes | One of: "connected", "error", "pending". |
calendars[].userEmail | string | Yes | — |
calendars[].userId | string (usr_… ID) | Yes | ID (usr_…) |
Errors: 400, 401, 403, 404, 409, 429, 500, with an ErrorBody body.
Example
curl -X GET "$ANSWERSTACK_API_URL/v1/account/rep-calendars" \
-H "Authorization: Bearer $ACCESS_TOKEN"