Contactivity
Voice.md

Flows

A flow is a voice app of kind flow: a graph of nodes (say, gather, dial, AI agent, condition, HTTP request, ...) that answers calls. You create and edit the flow's draft graph through voice apps (POST /voice-apps with kind: "flow" and flow: {...}, then PATCH /voice-apps/{id}). The endpoints here validate a graph and manage published versions: calls are answered by the published version, or by the draft until the first publish.

Auth, errors, paging and idempotency work as described in the overview.

Base URL: https://api.contactivity.io/v1/projects/{project_id}

Method Path Scope Purpose
POST /flows/validate apps:read Validate a graph without saving it
GET /flows/{app_id}/versions apps:read List published versions
POST /flows/{app_id}/versions apps:write Publish the draft as a new version
GET /flows/{app_id}/versions/{version} apps:read Fetch a version with its graph
POST /flows/{app_id}/versions/{version}/rollback apps:write Publish an older version again

The graph

Field Type Notes
start string Id of the first node. Default: the first node.
variables object Initial variables (name: value). Names match ^[A-Za-z_][A-Za-z0-9_.]{0,63}$.
nodes array, required 1-200 nodes {id, type, config, position}. id: 1-64 of A-Z a-z 0-9 _ -, unique.
edges array, required Up to 400 edges {from, to, label, condition}.

Node types: say, play, pause, gather, dial, record, enqueue, conference, ai_agent, redirect, transfer, hangup, set, condition, http, conversation, tool. conversation, tool and condition nodes can form an AI region that one agent conversation runs. A graph is at most 256 KB of JSON.

Edge condition: {var, op, value} with op one of eq, ne, gt, lt, contains, regex, empty, not_empty, or {op: "schedule", tz, days, start, end} (days mon..sun, times HH:MM).

Validate a graph

POST /flows/validate takes a graph as the body and returns {valid, errors, warnings}. Each issue is {node?, edge?, message}. It checks the structure, every node's settings, and references to this project's voice apps, queues and numbers. A body that is not a graph comes back as valid: false, not as an error.

sh
curl https://api.contactivity.io/v1/projects/$PROJECT_ID/flows/validate \
  -H "Authorization: Bearer $CONTACTIVITY_API_KEY" \
  -H "Content-Type: application/json" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"nodes":[{"id":"hi","type":"say","config":{"text":"Hello"}},{"id":"bye","type":"hangup","config":{}}],
       "edges":[{"from":"hi","to":"bye"}]}'
json
{"valid": true, "errors": [], "warnings": []}

Errors: 400 invalid_parameter only when the body cannot be read.

Versions

Version object:

Field Type Notes
version integer 1, 2, 3, ...
note string Release note
author string or null User id, or api-key when published with an API key
author_email string or null
created_at timestamp
graph object Fetch only

List versions

GET /flows/{app_id}/versions, newest first, paged (limit, starting_after). Besides data, has_more and next_cursor, the response carries published (the version answering calls, null before the first publish) and draft_changed (the draft differs from the newest version).

sh
curl https://api.contactivity.io/v1/projects/$PROJECT_ID/flows/app_us1_abc/versions \
  -H "Authorization: Bearer $CONTACTIVITY_API_KEY"

Errors: 400 invalid_parameter (limit, starting_after), 404 not_found (no flow app with this id).

Publish

POST /flows/{app_id}/versions snapshots the draft as the next version and makes it answer calls. The body is optional: {"note": "..."} (at most 500 characters). The graph is validated first; a graph with errors (for example an AI agent app deleted since) is refused with the first error as the message.

sh
curl https://api.contactivity.io/v1/projects/$PROJECT_ID/flows/app_us1_abc/versions \
  -H "Authorization: Bearer $CONTACTIVITY_API_KEY" \
  -H "Content-Type: application/json" -H "Idempotency-Key: $(uuidgen)" \
  -d '{"note": "New opening hours"}'

Returns 201 with the version. Errors: 400 invalid_parameter (note, or flow node <id>: ...), 400 unknown_parameter, 400 invalid_json, 404 not_found.

Fetch a version

GET /flows/{app_id}/versions/{version} returns the version with its graph. Errors: 404 not_found.

Roll back

POST /flows/{app_id}/versions/{version}/rollback publishes that version's graph as a new version (the draft is unchanged). Optional body {"note"}; default note Rollback to version N. The graph is validated again. Returns 201 with the new version. Errors as for publish.