Documentation Index
Fetch the complete documentation index at: https://docs.tryvox.co/llms.txt
Use this file to discover all available pages before exploring further.
v3 Public Launch Audit Checklist
PR #12 작업용 내부 체크리스트입니다. v3 public launch 문서를
domains/voxai/api-server의 현재 구현과 맞춰 보고, endpoint별로 검증
상태를 체크하면서 수정합니다.
목표
v3 API reference와 관련 가이드가 currentapi-server public contract와
일치하도록 검증하고, 잘못된 예시, 설명, 스키마, 누락된 제약을 최소 수정으로
고칩니다.
작업 원칙
- 먼저 이 파일에 증거와 상태를 기록합니다.
- 문서 수정은 체크리스트에 근거를 남긴 뒤 수행합니다.
- source of truth는 current
api-server코드, generated public OpenAPI, v3 schema, service validation, tests입니다. - 코드와 문서가 충돌하면 문서를 고칩니다.
- 코드 contract 자체가 불명확하면
UNVERIFIED또는ISSUE로 남깁니다. - endpoint별 상태는
TODO,PASS,FIXED,ISSUE,UNVERIFIED중 하나로 표시합니다.
Source Of Truth
| 항목 | 위치 |
|---|---|
| Docs PR branch | domains/voxai/docs, branch codex-v3-api-reference |
| Docs OpenAPI | api-reference/v3/openapi.json |
| Docs navigation | docs.json > API 참조 > v3 |
| API server | domains/voxai/api-server |
| v3 app mount | app/main.py |
| v3 router | app/api/v3/router.py |
| v3 endpoint handlers | app/api/v3/endpoints/*.py |
| v3 schemas | app/api/v3/schemas/** |
| public OpenAPI generator | scripts/generate_v3_public_openapi.py |
| contract audit script | scripts/v3_audit.py |
| v3 tests | tests/v3/** |
Baseline Evidence
- Checked out correct docs submodule branch:
domains/voxai/docs>codex-v3-api-reference. - Read nearest
AGENTS.mdindomains/voxai/docs. - Read
api-serverAGENTS.mdandARCHITECTURE.md. - Generated current api-server public OpenAPI:
uv run python scripts/generate_v3_public_openapi.py --output /tmp/current-v3-public-openapi.json --servers-from /Users/ryanhan/Documents/development/voxai/vox-mono/domains/voxai/docs/api-reference/v3/openapi.json - Compared docs OpenAPI operations against generated api-server operations.
- Ran
scripts/v3_audit.pyagainst current docs OpenAPI: 7 blockers, 6 warnings, 1 info. - Replace stale docs OpenAPI after reviewing the generated diff.
- Update
docs.jsonnavigation after reviewing missing public operations. - Re-ran API-side audit with the 4 confirmed-private flow helper endpoints passed as intentional excludes. Result: 0 blockers, 52 warnings, 1 info for accepted exclusions. Without those explicit excludes, current api-server still reports exactly those 4 endpoints as missing from public OpenAPI.
- Run docs validation after edits.
- Verified docs OpenAPI contract is equal to expected api-server OpenAPI after removing the 4 confirmed-private flow helper endpoints, pruning unreachable schemas, and ignoring docs-localized
description/summarytext. - Verified docs OpenAPI operation list equals v3
docs.jsonnavigation operation list. - Verified stale v2 endpoint examples and versionless API reference links are gone from v3 launch guide pages; historical changelog entries intentionally keep v2 links where the release predates v3.
- Patched
scripts/sync-openapi.shso future live OpenAPI syncs keep the 4 confirmed-private flow helper endpoints and their private-only schemas out of the docs snapshot. - Ran
mint validatewith Node 20.18 in PATH: build validation passed. - Ran
mint broken-linkswith Node 20.18 in PATH: no broken links found.
Baseline Findings
| Status | Finding | Evidence | Next Action |
|---|---|---|---|
| PASS | Docs OpenAPI has 58 operations; current api-server generated public OpenAPI has 62 before docs-side public-scope filtering. | Re-generated api-server OpenAPI from current source: paths=45 ops=62 schemas=176 pruned_schemas=16. After removing the 4 confirmed-private helpers and pruning unreachable schemas, the filtered source contract has 58 operations and 161 schemas. | Keep these endpoints out of public docs unless product scope changes. |
| FIXED | Docs OpenAPI/navigation included private flow operations after an over-broad generated-spec sync. | Removed POST /agents/validate-flow-data, POST /agents/autofix-flow-data, POST /agents/{agent_id}/operations, and POST /flow-data/autofix from docs OpenAPI and v3 navigation. | Consider aligning api-server generator/audit allowlist so these are treated like hidden routes. |
| FIXED | Docs sync script could reintroduce private flow helpers on the next live OpenAPI sync. | scripts/sync-openapi.sh now deletes all 4 confirmed-private paths and their private-only component schemas before writing api-reference/v3/openapi.json. | Keep docs-side filter until api-server generator/audit scope is aligned. |
| FIXED | Generated OpenAPI descriptions were too English-heavy for the Korean public docs surface. | Localized v3 operation descriptions, request-body descriptions, shared response descriptions, and high-visibility schema descriptions in api-reference/v3/openapi.json. | Keep code identifiers and enum values in English, but avoid English prose in user-facing docs text. |
| ISSUE | API-side generator/audit still treats the 4 flow helper endpoints as public candidates unless they are passed as intentional excludes. | scripts/v3_audit.py exits 0 with the 4 explicit excludes, but exits 1 with exactly those 4 endpoint-parity blockers without them. The api-server companion PR was closed and removed from scope. | Keep docs-side sync filter; revisit api-server generator/audit scope separately if product wants source tooling to encode this public/private split. |
| PASS | Endpoint-by-endpoint docs surface review completed for 58 public operations. | Docs OpenAPI is source-generated, private endpoints are excluded, examples validate, navigation matches OpenAPI, and scripts/v3_audit.py reports 0 blockers when the 4 confirmed-private helpers are passed as intentional excludes. | Re-run the full pass before public launch if api-server v3 routes change. |
POST /agents/autofix-flow-dataPOST /agents/validate-flow-dataPOST /agents/{agent_id}/operationsPOST /flow-data/autofix
UNREVIEWED_CAMEL_CASE_PROPERTYwarnings are restricted toagent.data/flow_datapayload internals and are documented as explicit compatibility exceptions inapi-reference/v3/introduction.mdx.ORG_ID_NOT_USED_IN_HANDLERwarnings are limited to authenticated catalog reads (models,schemas, available telephone lines) and an excluded traffic split endpoint. Org-owned resources still require org context.- Knowledge endpoint import-boundary warnings are source architecture debt, but the public request/response schema is still generated from v3 response models and does not expose provider or persistence types.
Cross-Cutting Review Checklist
| Status | Area | What To Check | Evidence |
|---|---|---|---|
| PASS | Public route inventory | Every public api-server operation appears in docs OpenAPI and v3 navigation. | Docs OpenAPI/nav are internally aligned at 58 operations after excluding 4 confirmed-private flow helper endpoints. |
| PASS | Hidden route pruning | Routes intentionally excluded from public launch stay hidden. | scripts/sync-openapi.sh deletes the 4 confirmed-private helper paths and private-only schemas; audit reports 1 accepted-exclusion info when those helpers are passed as intentional excludes. |
| PASS | Authentication | All operations document bearer organization API key auth. | BearerAuth is present and no operation has empty security. |
| PASS | Error envelope | Error responses use { "error": { "code", "message", "details" } }. | scripts/v3_audit.py error envelope check passed for docs OpenAPI after excluding private endpoints. |
| PASS | Error codes | Endpoint-specific error codes are present where available. | scripts/v3_audit.py error code metadata check passed for docs OpenAPI after excluding private endpoints. |
| PASS | Pagination | List endpoints use cursor, limit, items, next_cursor, total_count. | scripts/v3_audit.py pagination contract check passed for docs OpenAPI after excluding private endpoints. |
| PASS | Timestamp format | _at fields use unix ms; seconds compatibility is documented only where code supports it. | scripts/v3_audit.py timestamp contract check passed for docs OpenAPI after excluding private endpoints. |
| PASS | Request examples | Examples validate against the generated request schema and service-level validation. | Public OpenAPI has 12 JSON request examples; all 12 validate against their request schemas with jsonschema in the api-server uv environment. |
| PASS | Response schemas | Response schemas match endpoint response_model. | Docs OpenAPI contract matches expected api-server generated OpenAPI after excluding 4 confirmed-private endpoints, pruning schemas, and ignoring localized description/summary text. |
| PASS | PATCH semantics | Partial updates, null clearing, empty payload behavior, and nested object handling are accurate. | scripts/v3_audit.py patch contract check passed for docs OpenAPI after excluding private endpoints. |
| FIXED | Agent data casing | General API uses snake_case; agent.data and flow_data camelCase exceptions are explicit. | Updated api-reference/v3/introduction.mdx to mention both agent.data and flow_data camelCase exceptions. |
| PASS | Flow data | Node/edge examples use canonical runtime fields accepted by validator. | POST /agents flow example validates against generated request schema; private flow helper endpoints are excluded from public docs. |
| PASS | Knowledge IDs | Public docs consistently use numeric knowledge_id, not UUID. | OpenAPI path params use integer knowledge_id; AgentKnowledge.knowledgeIds and NodeKnowledgeConfig.knowledgeIds describe numeric public IDs from GET /v3/knowledges; strict request validation tests exist in tests/v3/unit/test_knowledge_strict_validation.py. |
| PASS | Org scope | Cross-resource references are org-scoped, or marked UNVERIFIED. | scripts/v3_audit.py reference scope check passed. Resource handlers use auth.require_organization_id(); agent runtime references validate LLM/voice/tool/knowledge refs with org context; model/schema catalog endpoints are authenticated public catalog reads. |
| FIXED | Guides | Guide pages do not point users to stale v2 endpoints for v3 launch flows. | Updated docs/build/variables/dynamic-variables.mdx from v2 calls/campaigns examples to v3 request shape. |
| FIXED | Links | API reference links point to /api-reference/v3/introduction or exact v3 endpoint pages. | Updated guide links to /api-reference/v3/introduction; exports.mdx now points to GET /calls and GET /calls/{call_id} instead of a nonexistent v3 export endpoint. |
| PASS | Build validation | Mintlify/docs validation passes or failure is recorded. | PATH="/Users/ryanhan/.nvm/versions/node/v20.18.0/bin:$PATH" mint validate passed; mint broken-links passed. |
Detailed Endpoint Verification Matrix
Every public operation was checked one by one against the current docs OpenAPI, the v3 navigation, and a freshly regenerated api-server OpenAPI after removing the four confirmed-private helper endpoints.Examples is the count of request
examples currently present in OpenAPI. 0 means no explicit request example is
published for that request body; it does not indicate a failing example.
| Status | Operation | Nav | Auth | Request | Examples | Success Response | Errors | Source |
|---|---|---|---|---|---|---|---|---|
| PASS | GET /calls/{call_id} | yes | BearerAuth | none | n/a | 200:application/json:CallResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /calls | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_CallListItemResponse_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /calls | yes | BearerAuth | application/json:CreateCallRequest | 2 | 201:application/json:CallResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /campaigns/{campaign_id} | yes | BearerAuth | none | n/a | 200:application/json:CampaignResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /campaigns/{campaign_id} | yes | BearerAuth | application/json:UpdateCampaignV3Request | 0 | 200:application/json:CampaignResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /campaigns | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_CampaignResponse_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /campaigns | yes | BearerAuth | application/json:CreateCampaignV3Request | 2 | 201:application/json:CampaignResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /campaigns/{campaign_id}/cancel | yes | BearerAuth | none | n/a | 200:application/json:CancelCampaignV3Response | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /campaigns/{campaign_id}/pause | yes | BearerAuth | none | n/a | 200:application/json:PauseCampaignV3Response | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /campaigns/{campaign_id}/resume | yes | BearerAuth | none | n/a | 200:application/json:ResumeCampaignV3Response | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /telephone-numbers/available | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_AvailableTelephoneLineResponse_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /telephone-numbers/purchase | yes | BearerAuth | application/json:PurchaseNumberRequest | 0 | 201:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /telephone-numbers/register | yes | BearerAuth | application/json:RegisterNumberRequest | 2 | 201:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /organization-telephone-numbers | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_TelephoneNumberResponse_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /organization-telephone-numbers/{organization_telephone_number_id} | yes | BearerAuth | none | n/a | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /organization-telephone-numbers/{organization_telephone_number_id} | yes | BearerAuth | application/json:UpdateTelephoneNumberRequest | 0 | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | DELETE /organization-telephone-numbers/{organization_telephone_number_id} | yes | BearerAuth | none | n/a | 200:application/json:DeleteTelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /organization-telephone-numbers/{organization_telephone_number_id}/agent | yes | BearerAuth | application/json:UpdateAgentMappingRequest | 0 | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /organization-telephone-numbers/{organization_telephone_number_id}/sip | yes | BearerAuth | application/json:UpdateSipConfigRequest | 0 | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /organization-telephone-numbers/{organization_telephone_number_id}/revoke-cancel | yes | BearerAuth | none | n/a | 200:application/json:TelephoneNumberResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /alert-rules | yes | BearerAuth | application/json:CreateAlertRuleRequest | 0 | 201:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /alert-rules | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_AlertRuleResponse_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /alert-rules/{alert_rule_id} | yes | BearerAuth | none | n/a | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /alert-rules/{alert_rule_id} | yes | BearerAuth | application/json:UpdateAlertRuleRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | DELETE /alert-rules/{alert_rule_id} | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /alert-rules/{alert_rule_id}/condition | yes | BearerAuth | application/json:UpdateConditionRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /alert-rules/{alert_rule_id}/channels | yes | BearerAuth | application/json:UpdateChannelsRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /alert-rules/{alert_rule_id}/schedule | yes | BearerAuth | application/json:UpdateScheduleRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /alert-rules/{alert_rule_id}/enable | yes | BearerAuth | none | n/a | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /alert-rules/{alert_rule_id}/disable | yes | BearerAuth | none | n/a | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /alert-rules/{alert_rule_id}/pause | yes | BearerAuth | application/json:PauseAlertRuleRequest | 0 | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /alert-rules/{alert_rule_id}/resume | yes | BearerAuth | none | n/a | 200:application/json:AlertRuleResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /alert-rules/{alert_rule_id}/incidents | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_AlertIncidentResponse_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /alert-rules/{alert_rule_id}/test-notification | yes | BearerAuth | none | n/a | 200:application/json:TestNotificationResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /incidents | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_AlertIncidentResponse_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /tools | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_ToolSummary_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /tools | yes | BearerAuth | application/json:CreateToolRequest | 2 | 201:application/json:ToolDetail | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /tools/{tool_id} | yes | BearerAuth | none | n/a | 200:application/json:ToolDetail | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /tools/{tool_id} | yes | BearerAuth | application/json:UpdateToolRequest | 0 | 200:application/json:ToolDetail | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | DELETE /tools/{tool_id} | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /schemas | yes | BearerAuth | none | n/a | 200:application/json:ListSchemasResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /schemas/{namespace}/{schema_type} | yes | BearerAuth | none | n/a | 200:application/json:SchemaDefinition | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /knowledges | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_KnowledgeSummary_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /knowledges | yes | BearerAuth | application/json:CreateKnowledgeRequest | 0 | 201:application/json:KnowledgeSummary | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | DELETE /knowledges/{knowledge_id} | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /knowledges/{knowledge_id}/documents | yes | BearerAuth | none | n/a | 200:application/json:PaginatedResponse_KnowledgeDocumentSummary_ | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /knowledges/{knowledge_id}/documents | yes | BearerAuth | application/json:oneOf(CreateTextDocumentRequest|CreateWebpageDocumentRequest); multipart/form-data:object | 0 | 201:application/json:KnowledgeDocumentSummary | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | DELETE /knowledges/{knowledge_id}/documents/{document_id} | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /agents | yes | BearerAuth | application/json:CreateAgentRequest | 2 | 201:application/json:AgentMutationResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /agents | yes | BearerAuth | none | n/a | 200:application/json:ListAgentsResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /agents/{agent_id} | yes | BearerAuth | none | n/a | 200:application/json:AgentResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | PATCH /agents/{agent_id} | yes | BearerAuth | application/json:UpdateAgentRequest | 2 | 200:application/json:AgentMutationResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | DELETE /agents/{agent_id} | yes | BearerAuth | none | n/a | 204:empty | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /agents/{agent_id}/versions | yes | BearerAuth | application/json:CreateAgentVersionRequest | 0 | 201:application/json:CreateAgentVersionResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /agents/{agent_id}/versions | yes | BearerAuth | none | n/a | 200:application/json:ListAgentVersionsResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | POST /agents/{agent_id}/versions/{version}/publish | yes | BearerAuth | none | n/a | 200:application/json:PublishAgentVersionResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /models/llms | yes | BearerAuth | none | n/a | 200:application/json:ListLLMModelsResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
| PASS | GET /models/voices | yes | BearerAuth | none | n/a | 200:application/json:ListVoiceModelsResponse | 400,401,403,404,409,429,500,503 ErrorResponse | contract-match |
Endpoint Checklist
PASS in this section means the public documentation surface was checked for
path, method, navigation, bearer auth, request schema, response schema, documented
errors, examples where present, and known guide references. It is not a blanket
backend implementation sign-off; source-side generator/audit debt is tracked in
the findings above and intentionally left outside this docs PR.
Agents
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | POST /agents | api-reference/v3/openapi.json, docs.json | app/api/v3/endpoints/agent.py, app/api/v3/schemas/agent/**, tests/v3/integration/test_agent_endpoints.py | create schema, single-prompt defaults, flow flow_data requirement, examples, 201 schema, strict refs |
| PASS | GET /agents | same | same | pagination, filters, summary shape |
| PASS | GET /agents/{agent_id} | same | same | version selector, response shape, 404 |
| PASS | PATCH /agents/{agent_id} | same | same | partial update, empty nested dicts, null clearing, flow_data replacement, strict refs |
| PASS | DELETE /agents/{agent_id} | same | same | 204, soft-delete semantics |
| PASS | POST /agents/validate-flow-data | excluded from public docs | app/api/v3/endpoints/flow_validation.py, user scope correction | Non-public endpoint. Must stay out of public OpenAPI and nav. |
| PASS | POST /agents/autofix-flow-data | excluded from public docs | app/api/v3/endpoints/agent.py, user scope correction | Non-public endpoint. Must stay out of public OpenAPI and nav. |
| PASS | POST /agents/{agent_id}/operations | excluded from public docs | app/api/v3/endpoints/agent.py, user scope correction | Non-public endpoint. Must stay out of public OpenAPI and nav. |
Agent Versions
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /agents/{agent_id}/versions | OpenAPI, nav | app/api/v3/endpoints/agent_version.py | list shape, version names |
| PASS | POST /agents/{agent_id}/versions | OpenAPI, nav | same | 201, snapshot semantics |
| PASS | POST /agents/{agent_id}/versions/{version}/publish | OpenAPI, nav | same | version pattern, production publish behavior |
Calls
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /calls | OpenAPI, nav | app/api/v3/endpoints/calls.py, tests/v3/calls/** | filters, pagination, status mapping, timestamps |
| PASS | POST /calls | OpenAPI, nav | same | request field names, agent mapping, traffic split behavior, dynamic variables example |
| PASS | GET /calls/{call_id} | OpenAPI, nav | same | detail shape, transcript, call_analysis, not-found |
Campaigns
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /campaigns | OpenAPI, nav | app/api/v3/endpoints/campaigns.py, tests/v3/campaigns/** | filters, pagination, statuses |
| PASS | POST /campaigns | OpenAPI, nav | same | tasks shape, agent mapping, from_number, dynamic variables, call windows |
| PASS | GET /campaigns/{campaign_id} | OpenAPI, nav | same | detail shape |
| PASS | PATCH /campaigns/{campaign_id} | OpenAPI, nav | same | editable fields and status guards |
| PASS | POST /campaigns/{campaign_id}/cancel | OpenAPI, nav | same | action response, conflict cases |
| PASS | POST /campaigns/{campaign_id}/pause | OpenAPI, nav | same | pause body, timestamp normalization |
| PASS | POST /campaigns/{campaign_id}/resume | OpenAPI, nav | same | resume semantics |
Telephone Numbers
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /organization-telephone-numbers | OpenAPI, nav | app/api/v3/endpoints/telephone_numbers.py, telephone tests | filters, org-owned ID |
| PASS | GET /organization-telephone-numbers/{organization_telephone_number_id} | OpenAPI, nav | same | ID type, response |
| PASS | PATCH /organization-telephone-numbers/{organization_telephone_number_id} | OpenAPI, nav | same | mutable metadata |
| PASS | PATCH /organization-telephone-numbers/{organization_telephone_number_id}/agent | OpenAPI, nav | same | inbound/outbound agent mapping, clear semantics |
| PASS | PATCH /organization-telephone-numbers/{organization_telephone_number_id}/sip | OpenAPI, nav | same | SIP settings, custom number limits |
| PASS | DELETE /organization-telephone-numbers/{organization_telephone_number_id} | OpenAPI, nav | same | cancel/delete semantics, response |
| PASS | POST /organization-telephone-numbers/{organization_telephone_number_id}/revoke-cancel | OpenAPI, nav | same | revoke constraints |
| PASS | GET /telephone-numbers/available | OpenAPI, nav | same | filters, purchasable line ID |
| PASS | POST /telephone-numbers/purchase | OpenAPI, nav | same | telephone_line_id, not phone string |
| PASS | POST /telephone-numbers/register | OpenAPI, nav | same | SIP registration example |
Tools
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /tools | OpenAPI, nav | app/api/v3/endpoints/tools.py | list summary vs detail |
| PASS | POST /tools | OpenAPI, nav | same | API tool schema, auth config, examples |
| PASS | GET /tools/{tool_id} | OpenAPI, nav | same | detail shape |
| PASS | PATCH /tools/{tool_id} | OpenAPI, nav | same | partial update, auth shape parity |
| PASS | DELETE /tools/{tool_id} | OpenAPI, nav | same | 204 delete |
Schemas And Flow Data
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /schemas | OpenAPI, nav | app/api/v3/endpoints/schemas.py, schema registry tests | namespace/category, include_schema |
| PASS | GET /schemas/{namespace}/{schema_type} | OpenAPI, nav | same | schema body, version query, public names |
| PASS | POST /flow-data/autofix | excluded from public docs | app/api/v3/endpoints/flow_data.py, user scope correction | Non-public endpoint. Must stay out of public OpenAPI and nav. |
Knowledges
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /knowledges | OpenAPI, nav | app/api/v3/endpoints/knowledges.py, knowledge tests | numeric ID, pagination, org scope |
| PASS | POST /knowledges | OpenAPI, nav | same | request schema and response |
| PASS | DELETE /knowledges/{knowledge_id} | OpenAPI, nav | same | 204, org-scope not-found |
| PASS | GET /knowledges/{knowledge_id}/documents | OpenAPI, nav | same | list filters, statuses |
| PASS | POST /knowledges/{knowledge_id}/documents | OpenAPI, nav | same | JSON vs multipart body, source types, ingestion trigger |
| PASS | DELETE /knowledges/{knowledge_id}/documents/{document_id} | OpenAPI, nav | same | UUID document ID, 204, org scope |
Models
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /models/llms | OpenAPI, nav | app/api/v3/endpoints/model.py, model tests | pagination, capabilities |
| PASS | GET /models/voices | OpenAPI, nav | same | provider/language filters, capabilities |
Alerts And Incidents
| Status | Operation | Docs Evidence | API Evidence | Checks |
|---|---|---|---|---|
| PASS | GET /alert-rules | OpenAPI, nav | app/api/v3/endpoints/alert.py, alert tests | filters, pagination |
| PASS | POST /alert-rules | OpenAPI, nav | same | condition, channels, schedule |
| PASS | GET /alert-rules/{alert_rule_id} | OpenAPI, nav | same | detail response |
| PASS | PATCH /alert-rules/{alert_rule_id} | OpenAPI, nav | same | metadata patch |
| PASS | DELETE /alert-rules/{alert_rule_id} | OpenAPI, nav | same | 204 delete |
| PASS | PATCH /alert-rules/{alert_rule_id}/channels | OpenAPI, nav | same | replacement semantics |
| PASS | PATCH /alert-rules/{alert_rule_id}/condition | OpenAPI, nav | same | metric/operators |
| PASS | PATCH /alert-rules/{alert_rule_id}/schedule | OpenAPI, nav | same | HH:MM, timezone |
| PASS | POST /alert-rules/{alert_rule_id}/disable | OpenAPI, nav | same | action response |
| PASS | POST /alert-rules/{alert_rule_id}/enable | OpenAPI, nav | same | action response |
| PASS | POST /alert-rules/{alert_rule_id}/pause | OpenAPI, nav | same | until, paused state |
| PASS | POST /alert-rules/{alert_rule_id}/resume | OpenAPI, nav | same | action response |
| PASS | POST /alert-rules/{alert_rule_id}/test-notification | OpenAPI, nav | same | side effect and response |
| PASS | GET /alert-rules/{alert_rule_id}/incidents | OpenAPI, nav | same | pagination and status filters |
| PASS | GET /incidents | OpenAPI, nav | same | org-wide list filters |
Full Reverification Pass 2026-05-08
Objective restated as concrete deliverables:- Rebuild the checklist against the current docs PR branch and current
domains/voxai/api-serversource. - Check every public endpoint for method/path/nav/auth/request/response/errors.
- Check examples, descriptions, schema descriptions, and public/private scope.
- Compare docs OpenAPI with freshly generated api-server OpenAPI.
- Run real validation gates and fix any issues found.
| Requirement | Evidence | Status |
|---|---|---|
| Current branch state checked | domains/voxai/docs on codex-v3-api-reference; domains/voxai/api-server current checkout on develop. | PASS |
| Every public endpoint checked | Detailed Endpoint Verification Matrix has 58 public operation rows; current OpenAPI operation count is 58. | PASS |
| Public/private scope checked | POST /agents/validate-flow-data, POST /agents/autofix-flow-data, POST /agents/{agent_id}/operations, and POST /flow-data/autofix are absent from docs OpenAPI and nav. | PASS |
| api-server generator compared | ENV=development-ryan uv run python scripts/generate_v3_public_openapi.py ... returned paths=45 ops=62 schemas=176 pruned_schemas=16; docs-side filtering of the 4 confirmed-private helpers yields 58 public operations and 161 schemas. | PASS |
| Contract diff checked | Filtered generated api-server OpenAPI and docs OpenAPI match after pruning unreachable schemas and removing docs-localized description/summary. | PASS |
| Navigation checked | v3 docs.json nav operation list has 58 entries and matches OpenAPI exactly. | PASS |
| API-side audit checked | ENV=development-ryan uv run python scripts/v3_audit.py --openapi-file ... exits 0 with the 4 confirmed-private helpers passed as intentional excludes: 0 blockers, 52 warnings, 1 info. Without those ad-hoc excludes it exits 1 with exactly 4 known endpoint-parity blockers. | PASS |
| Example validity checked | JSON Schema validation over all JSON request and response examples returned examples_checked=476 failures=0. | PASS |
| Description coverage checked | Operation summaries/descriptions, request-body descriptions, parameter descriptions, schema descriptions, and schema property descriptions returned description_coverage_issues=0. | PASS |
| Tone checked | User-facing OpenAPI prose and v3 introduction copy were normalized toward ~합니다/~습니다; direct imperative endings were removed from public-facing descriptions. | PASS |
| api-server v3 tests checked | Current api-server checkout returns 3 failed, 1113 passed, 18 skipped, 75 warnings; failures are source-side (validate-flow-data, webhook_version default, generator count) and are not fixed in this docs PR. | ISSUE |
- Current api-server generator/audit still need explicit excludes for the 4 confirmed-private flow helper endpoints. The companion api-server PR was closed and removed from scope.
- Current api-server
AgentWebhookSettings.webhook_versionhas no default, so docs OpenAPI must not publishwebhookVersion.default = "v2". - Docs OpenAPI keeps full schema/property descriptions while matching the
current source contract after docs-localized
description/summarytext is removed.
Focused Recheck 2026-05-09
Objective restated as concrete deliverables:- Spend a focused pass rebuilding the checklist instead of trusting prior results.
- Check every public API operation one by one.
- Verify every operation’s status codes, request schemas, response schemas, and public/private scope against current api-server source.
- Check description consistency, natural Korean tone, and developer-friendly wording without over-explaining.
- Fix docs when the recheck finds drift.
| Requirement | Evidence | Status |
|---|---|---|
| Current source regenerated | ENV=development-ryan uv run python scripts/generate_v3_public_openapi.py --output /tmp/v3-recheck-current-api-server.json ... returned paths=45 ops=62 schemas=176 pruned_schemas=16. | PASS |
| Every public operation rechecked | Operation-level script compared all 58 public operations after removing the 4 confirmed-private helper paths. | PASS |
| Status codes match source | Operation-level comparison returned operations_checked=58 and status_or_schema_mismatches=0 after ignoring localized descriptions. | PASS |
| Request and response schemas match source | Full normalized contract comparison returned docs_ops=58, filtered_gen_ops=58, docs_schemas=161, filtered_gen_schemas=161, and normalized contract match. | PASS |
| Docs-side schema drift fixed | Removed stale webhookVersion.default = "v2" from api-reference/v3/openapi.json because current source has no default. | FIXED |
| Operation descriptions complete | Operation scan returned operation_description_issues=0 across summaries, descriptions, request bodies, parameters, and response descriptions. | PASS |
| Schema descriptions complete | Schema/property coverage scan returned schema_description_issues=0. | PASS |
| Naturalness and tone checked | Public v3 files were scanned for direct imperative/plain-style endings and stale labels; only audit-meta mentions of TODO/ISSUE/UNVERIFIED were found. Human review of all 58 operation summaries/descriptions found the wording concise enough for API reference use. | PASS |
| External docs comparison considered | No external docs were needed in this pass because the only concrete drift was against current api-server source; the docs surface already follows the common concise API-reference pattern of summary, short operational description, request/response schema, examples, and error envelope. | PASS |
| Source-side issues not hidden | scripts/v3_audit.py without ad-hoc excludes still reports exactly 4 known private-helper blockers; ENV=development-ryan uv run pytest tests/v3 -q currently fails 3 source-side tests. Both are recorded as source-side issues outside this docs PR. | PASS |
Completion Audit
Concrete objective: make a Markdown checklist, check every endpoint one by one, compare the public docs against currentapi-server, and fix incorrect examples,
descriptions, schemas, links, or public/private scope mistakes.
| Requirement | Artifact / Evidence | Status |
|---|---|---|
| Endpoint-by-endpoint checklist exists | This file contains a detailed 58-row public endpoint matrix and a grouped endpoint checklist with 58 public operations plus 4 confirmed-private exclusions. | PASS |
| Every public endpoint was individually rechecked | Detailed matrix row count returned 58. No ISSUE, TODO, or UNVERIFIED rows were found in the detailed matrix. | PASS |
| Docs OpenAPI has only public v3 endpoints | OpenAPI operation count returned 58. | PASS |
| v3 navigation lists exactly the public OpenAPI operations | Recursive docs.json v3 nav extraction returned 58 operation entries, matching the OpenAPI operation count. | PASS |
| Private helper endpoints stay hidden | Search for the four private helper paths in docs.json and api-reference/v3/openapi.json returned no matches. | PASS |
| Docs OpenAPI matches current api-server source after confirmed-private exclusions | Freshly regenerated api-server OpenAPI produces 62 operations before docs-side filtering. After removing the 4 confirmed-private helpers and pruning unreachable schemas, docs OpenAPI has no contract diff after removing localized description/summary text. | PASS |
| Status codes and operation schemas match current source | Operation-level comparison returned operations_checked=58 and status_or_schema_mismatches=0. | PASS |
| Published request and response examples are valid | JSON Schema validation over OpenAPI JSON examples returned examples_checked=476 failures=0. | PASS |
| Schema descriptions are complete | Coverage check over operations, request bodies, parameters, schemas, and schema properties returned description_coverage_issues=0. | PASS |
| Public-facing tone is consistent | v3 introduction and OpenAPI descriptions were normalized toward ~합니다/~습니다; direct imperative endings no longer appear in public-facing v3 prose. | PASS |
| Bad v2 examples and stale API reference links are fixed | v3 launch guide pages now point to /api-reference/v3/introduction; dynamic variable REST examples use /v3/calls and /v3/campaigns request shapes. Historical changelog v2 links point to /api-reference/v2/introduction. | PASS |
| Build and link validation pass | PATH="/Users/ryanhan/.nvm/versions/node/v20.18.0/bin:$PATH" mint validate passed. mint broken-links passed. | PASS |
| Remaining source-side uncertainty is explicitly tracked | scripts/v3_audit.py exits 0 only when the 4 confirmed-private helpers are passed as intentional excludes; without them it exits 1 with exactly those 4 endpoint-parity blockers. Current tests/v3 also has 3 source-side failures outside this docs PR. | PASS |
Work Log
- 2026-05-08: Created checklist in the correct docs submodule. Baseline mismatch: docs OpenAPI 58 operations vs generated api-server public OpenAPI 62 operations.
-
2026-05-08: API-side audit of the current docs OpenAPI found 7 blockers:
4 missing public operations, missing
minPropertieson 2 PATCH schemas, and non-integer timestamp fields on schema registry metadata. -
2026-05-08: Initially synced
api-reference/v3/openapi.jsonfrom generated api-server public OpenAPI, then corrected scope after product clarification:POST /agents/validate-flow-data,POST /agents/autofix-flow-data,POST /agents/{agent_id}/operations, andPOST /flow-data/autofixare not public and were removed from docs OpenAPI/navigation. -
2026-05-08: Scanned guide pages for stale API references. Found and fixed v2 examples in
docs/build/variables/dynamic-variables.mdxand versionless API reference links in outbound/post-call/export guides. Also clarified that v3 public API has no dedicated CSV export endpoint; programmatic extraction usesGET /callsandGET /calls/{call_id}. -
2026-05-08: Verified
api-reference/v3/openapi.jsoncontract matches the expected api-server generated OpenAPI after excluding the four confirmed-private flow helper endpoints, pruning unreachable schemas, and ignoring docs-localizeddescription/summarytext. Verified v3 OpenAPI operations anddocs.jsonv3 navigation operations have no diff. - 2026-05-08: Validated public OpenAPI JSON request examples. Result: 12 examples checked, 0 schema validation failures.
-
2026-05-08: Checked knowledge ID contract. Public OpenAPI uses numeric
integer
knowledge_idpath params and numericknowledgeIdsarrays; no UUID wording was found for public knowledge IDs. -
2026-05-08: Patched
scripts/sync-openapi.shto enforce docs-side public launch exclusions for the four confirmed-private flow helper endpoints and their private-only schemas. Verified the filter output has 58 operations and matchesapi-reference/v3/openapi.json. -
2026-05-08: Fixed stale changelog links found by validation:
/docs/operate/deploy/ctinow points to the SIP trunking guide, and historical versionless API reference links now point to the v2 API reference. -
2026-05-08: Ran docs validation with Node 20.18 in PATH.
mint validatepassed andmint broken-linkspassed. - 2026-05-08: Added a detailed endpoint-by-endpoint verification matrix with nav/auth/request schema/example count/success response/error envelope/source parity columns for all 58 public operations. Re-generated api-server OpenAPI from current source and confirmed the docs OpenAPI still matches after the four confirmed-private helper endpoints are filtered out.
-
2026-05-08: Localized user-facing v3 OpenAPI descriptions in the docs snapshot.
Operation descriptions, request-body descriptions, shared error response text,
and high-visibility schema descriptions now use Korean prose while preserving
code identifiers, enum values, and schema names. Re-verified the contract by
stripping
description/summaryfields from the docs and filtered generated specs and comparing the normalized JSON. -
2026-05-08: Rebuilt the full verification checklist and re-ran the audit
against current
api-serversource. Found one missing coverage class: schema/property descriptions. Added descriptions until the coverage check returneddescription_coverage_issues=0. -
2026-05-08: Source-side recheck exposed api-server v3 test failures:
public generator expected 61 ops while current source emitted 62, and
AgentWebhookSettings.webhook_versiondefault did not match the existing PROD-1493 test. A companion api-server PR was opened briefly, then closed and removed from scope. The docs PR therefore keeps source-side issues tracked rather than patching api-server. -
2026-05-09: Re-generated current api-server OpenAPI after the companion PR was
removed:
paths=45 ops=62 schemas=176 pruned_schemas=16. After docs-side removal of the 4 confirmed-private helper endpoints and unreachable schemas, the filtered source contract has 58 operations and 161 schemas. Docs OpenAPI matches that filtered contract after removing localizeddescription/summarytext. -
2026-05-08: Normalized public-facing v3 prose toward
~합니다/~습니다. Replaced direct imperative endings in OpenAPI descriptions and the v3 introduction with formal descriptive endings. -
2026-05-09: Removed stale
webhookVersion.default = "v2"from docs OpenAPI because current api-server source has no default. Re-ran operation-level status code/request schema/response schema comparison for all 58 public operations:status_or_schema_mismatches=0.