{"openapi":"3.0.3","info":{"title":"Agent Axis Public API","description":"Agent Axis is a multi-tenant CRM for insurance agencies. This public REST API lets certified\nintegration partners read workspace data (calls, leads, recordings, transcripts) and register\noutbound webhooks.\n\n## Base URL\n\nAll API requests are made to **`https://app.agentaxis.app`** (not the docs host).\n\n## Authentication\n\nInclude a workspace integration API key on every request:\n\n```\nAuthorization: Bearer aax_live_…\n```\n\nKeys are issued by a **platform admin** for a single workspace. OAuth 2.0 Authorization Code + PKCE\nis also supported for partners such as Sales Savant.\n\n## Response envelope\n\nEvery JSON response uses a B2B-style envelope ([reference](https://services.b2baisaas.com/openapi.json)):\n\n```json\n{\n  \"success\": true,\n  \"message\": \"Calls retrieved successfully\",\n  \"data\": { }\n}\n```\n\nErrors return `success: false` with an HTTP 4xx/5xx status.\n\n## Pagination\n\nList endpoints accept `limit` (max 100) and `cursor`. Responses include `data.next_cursor`\nwhen more pages exist.\n\n## Rate limits\n\nBursty backfill on first connect, then steady-state low. When throttled, the API returns **429**\nwith a `Retry-After` header.\n\n## Webhooks (Sales Savant)\n\nPartners register `POST /api/v1/integrations/sales-savant/webhooks` with a shared signing secret.\nDeliveries use HMAC-SHA256 headers: `X-Agent-Axis-Signature`, `X-Agent-Axis-Timestamp`,\n`X-Agent-Axis-Event-Id`.\n\n## Getting credentials\n\nContact your Agent Axis platform administrator or visit\n[https://app.agentaxis.app/admin](https://app.agentaxis.app/admin) to issue integration keys.","version":"1.0.0","contact":{"name":"Agent Axis Integrations","url":"https://agentaxis.app"}},"servers":[{"url":"https://app.agentaxis.app","description":"Production API"}],"tags":[{"name":"Meta","description":"Specification and discovery"},{"name":"Integrations — Sales Savant","description":"Call coaching integration — calls, recordings, transcripts, webhooks"},{"name":"Workspaces","description":"Workspace-scoped CRM resources"},{"name":"OAuth 2.0","description":"Authorization Code + PKCE for partner connections"}],"x-tagGroups":[{"name":"Integrations","tags":["Integrations — Sales Savant"]},{"name":"Workspace API","tags":["Workspaces"]},{"name":"Auth","tags":["OAuth 2.0"]}],"paths":{"/openapi.json":{"get":{"tags":["Meta"],"summary":"Download OpenAPI specification","operationId":"get-openapi-spec","responses":{"200":{"description":"OpenAPI 3.0.3 JSON document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/integrations/sales-savant/me":{"get":{"tags":["Integrations — Sales Savant"],"summary":"Get connected identity","description":"Identity probe after OAuth or API key connect. Returns workspace account id and authorized scopes.","operationId":"sales-savant-get-me","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Identity retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiSuccessResponse"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SalesSavantIdentity"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/integrations/sales-savant/users":{"get":{"tags":["Integrations — Sales Savant"],"summary":"List workspace agents","description":"Active workspace members for call attribution. Requires `users.read`.","operationId":"sales-savant-list-users","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Users retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiSuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SalesSavantUser"}}}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/integrations/sales-savant/calls":{"get":{"tags":["Integrations — Sales Savant"],"summary":"List completed calls","description":"Paginated completed calls for backfill and poll fallback. Requires `calls.read`.","operationId":"sales-savant-list-calls","security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UpdatedSince"},{"name":"start","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"end","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"user_id","in":"query","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Calls retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiSuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SalesSavantCall"}},"next_cursor":{"type":"string","nullable":true}}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/integrations/sales-savant/calls/{id}":{"get":{"tags":["Integrations — Sales Savant"],"summary":"Get call by ID","operationId":"sales-savant-get-call","security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/CallId"}],"responses":{"200":{"description":"Call retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiSuccessResponse"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SalesSavantCall"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/integrations/sales-savant/calls/{id}/recording":{"get":{"tags":["Integrations — Sales Savant"],"summary":"Get call recording URL","description":"Signed R2 download URL (60 min expiry). Requires `recordings.read`. Returns 404 when not ready.","operationId":"sales-savant-get-recording","security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/CallId"}],"responses":{"200":{"description":"Recording URL generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiSuccessResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/integrations/sales-savant/calls/{id}/transcript":{"get":{"tags":["Integrations — Sales Savant"],"summary":"Get call transcript","description":"Plain-text transcript MVP. Requires `transcripts.read`. Returns 404 when not ready.","operationId":"sales-savant-get-transcript","security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/CallId"}],"responses":{"200":{"description":"Transcript retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiSuccessResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/integrations/sales-savant/webhooks":{"get":{"tags":["Integrations — Sales Savant"],"summary":"List webhook subscriptions","operationId":"sales-savant-list-webhooks","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Webhooks retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiSuccessResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Integrations — Sales Savant"],"summary":"Register webhook subscription","description":"Accepts `{ delivery_url, events, secret }` (Sales Savant spec) or legacy `{ target_url, event_types }`.","operationId":"sales-savant-create-webhook","security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"delivery_url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["call.completed","recording.ready","transcript.ready"]}},"secret":{"type":"string","minLength":16}}}}}},"responses":{"201":{"description":"Webhook created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiSuccessResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/integrations/sales-savant/webhooks/{id}":{"delete":{"tags":["Integrations — Sales Savant"],"summary":"Revoke webhook subscription","operationId":"sales-savant-delete-webhook","security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/WebhookId"}],"responses":{"200":{"description":"Webhook revoked successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiSuccessResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/workspaces/{workspaceId}/calls":{"get":{"tags":["Workspaces"],"summary":"List workspace calls","description":"Completed calls for the workspace tied to the API key. Requires `calls.read`.","operationId":"workspace-list-calls","security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/WorkspaceId"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Calls retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiSuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceCallSummary"}},"next_cursor":{"type":"string","nullable":true}}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/workspaces/{workspaceId}/leads":{"get":{"tags":["Workspaces"],"summary":"List workspace leads","description":"Lead summaries for the workspace tied to the API key. Requires `leads.read`.","operationId":"workspace-list-leads","security":[{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/WorkspaceId"},{"$ref":"#/components/parameters/UpdatedSince"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"}],"responses":{"200":{"description":"Leads retrieved successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiSuccessResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceLeadSummary"}},"next_cursor":{"type":"string","nullable":true}}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/oauth/authorize":{"get":{"tags":["OAuth 2.0"],"summary":"Authorization endpoint (Authorization Code + PKCE)","description":"Redirects the workspace owner to grant access. Sales Savant builds the authorize URL with `code_challenge` (S256).","operationId":"oauth-authorize","parameters":[{"name":"client_id","in":"query","schema":{"type":"string","default":"sales-savant"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","format":"uri"}},{"name":"response_type","in":"query","schema":{"type":"string","enum":["code"]}},{"name":"scope","in":"query","schema":{"type":"string"}},{"name":"state","in":"query","schema":{"type":"string"}},{"name":"code_challenge","in":"query","schema":{"type":"string"}},{"name":"code_challenge_method","in":"query","schema":{"type":"string","enum":["S256","plain"]}}],"responses":{"302":{"description":"Redirect to client with authorization code"},"400":{"description":"Invalid request"},"403":{"description":"Access denied"}}}},"/api/oauth/token":{"post":{"tags":["OAuth 2.0"],"summary":"Token endpoint","description":"Exchange authorization code for Bearer access token (workspace API key).","operationId":"oauth-token","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token"]},"code":{"type":"string"},"redirect_uri":{"type":"string","format":"uri"},"code_verifier":{"type":"string"}}}}}},"responses":{"200":{"description":"Token issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenResponse"}}}},"400":{"description":"invalid_grant or invalid_request"}}}},"/api/oauth/revoke":{"post":{"tags":["OAuth 2.0"],"summary":"Revoke access token","operationId":"oauth-revoke","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]}}}},"responses":{"200":{"description":"Token revoked"}}}}},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"Workspace integration API key issued by a platform admin. Format: `aax_live_…`. OAuth token exchange returns the same key as `access_token`."}},"parameters":{"WorkspaceId":{"name":"workspaceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Agent Axis workspace UUID. Must match the API key scope."},"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Page size (max 100)."},"Cursor":{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from a previous response `next_cursor`."},"UpdatedSince":{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"},"description":"ISO 8601 UTC — return rows updated on or after this time."},"CallId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Call UUID."},"WebhookId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Webhook subscription UUID."}},"schemas":{"ApiSuccessResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"OK"},"data":{"type":"object"}},"required":["success","message","data"]},"ApiErrorResponse":{"type":"object","description":"Standard error envelope.","properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Invalid or missing API key"},"data":{"nullable":true,"type":"object"}},"required":["success","message"]},"PaginatedMeta":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object"}},"next_cursor":{"type":"string","nullable":true}}},"SalesSavantIdentity":{"type":"object","properties":{"account_id":{"type":"string","format":"uuid"},"user_id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"name":{"type":"string"},"workspace_name":{"type":"string"},"integration":{"type":"string","example":"sales-savant"},"scopes":{"type":"array","items":{"type":"string"}}},"required":["account_id"]},"SalesSavantUser":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"name":{"type":"string"},"role":{"type":"string"},"active":{"type":"boolean"}},"required":["id","email"]},"SalesSavantCall":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"started_at":{"type":"string","format":"date-time"},"ended_at":{"type":"string","format":"date-time"},"duration_seconds":{"type":"integer"},"direction":{"type":"string","enum":["inbound","outbound","meeting"]},"disposition":{"type":"string"},"host":{"type":"object"},"participants":{"type":"array","items":{"type":"object"}},"recording":{"type":"object"},"transcript":{"type":"object"},"contact":{"type":"object"},"metadata":{"type":"object"}},"required":["id","started_at","ended_at","host","participants"]},"WorkspaceCallSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"created_at":{"type":"string","format":"date-time"},"ended_at":{"type":"string","format":"date-time"},"duration_seconds":{"type":"integer","nullable":true},"direction":{"type":"string"},"status":{"type":"string"},"agent_user_id":{"type":"string","format":"uuid","nullable":true},"lead_id":{"type":"string","format":"uuid","nullable":true}}},"WorkspaceLeadSummary":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"display_name":{"type":"string","nullable":true},"lead_source":{"type":"string","nullable":true},"assigned_user_id":{"type":"string","format":"uuid","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"WebhookSubscription":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"delivery_url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["active","inactive"]}}},"OAuthTokenResponse":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","example":"Bearer"},"expires_in":{"type":"integer"},"refresh_token":{"type":"string"},"scope":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Missing or invalid Bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"Forbidden":{"description":"Insufficient scope, wrong workspace, or revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"NotFound":{"description":"Resource not found or not ready yet (recordings/transcripts).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}},"RateLimited":{"description":"Too many requests — honor Retry-After when present.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorResponse"}}}}}}}