VocalDocscontracts 1.65.0

Authentication and keys

Every request to the Vocal API carries a bearer credential in the Authorization header. A server uses an API key; a signed-in Member uses the token of its sign-in. This guide covers both, the two environments, and the request conventions every operation shares.

On the Phase 0 host. Served: the API key routes since contracts 1.51.0, and the conventions below on every operation of 1.60.0.

API keys

A key has the form vk_<env>_<lookup>_<secret>, where <env> is live or test. Send it from your server only:

curl "$VOCAL_API/v1/agents" -H "Authorization: Bearer $VOCAL_API_KEY"

$VOCAL_API stands for the API's base URL and $VOCAL_API_KEY for your key; never put a key in a browser, an app or a URL. Vocal stores a per-key salt and a hash of the secret, so the full key is shown once, in the answer that creates it.

Keys are managed by Members, never by another key: listing, creating, reading and revoking keys are "Session only" operations that refuse every API key with forbidden.

StepOperation
Create a key for one environment with its scopesPOST /v1/api-keys
List the keys, newest first, never their secretsGET /v1/api-keys
Revoke a keyPOST /v1/api-keys/{key_id}/revoke

A Member can grant only the scopes its role holds (scope_not_grantable), and a scope that no key may hold is refused (scope_session_only). A revoked key is refused by every api instance within 5 seconds (a target) and stays listed for the audit trail. The scopes page lists every scope with the operations that need it; the content scopes, such as transcripts:read, make each read an audited content read.

The two environments

A key belongs to live or test, and sees only the Calls and other runtime records of its own environment. Configuration, such as Agents, Policies and Tools, is shared by both.

livetest
CallsWeb and phoneWeb only: a phone Call is refused, an outbound one with dial_not_allowed and the reason live_environment_required
Phone number routingAllowedRefused with forbidden
Real ProvidersYesYes, within a daily allowance of 60 minutes of Calls (a target); past it a Call answers 429 test_daily_cap_reached. Calls on mock Providers never count

Use synthetic data only in test.

Conventions every operation shares

  • Bodies are JSON with snake_case fields. An unknown request field is refused with 400, and a client ignores response fields it does not know.
  • Request ids. Every answer carries X-Request-Id; quote it when you report a problem.
  • Idempotency. Operations marked so on their reference page take an Idempotency-Key header. The key is kept 24 hours per Organization, environment and route, and a retry with the same key replays the first answer. POST /v1/calls requires one.
  • Revisions. An editable resource has a revision. An update names it in If-Match; a missing header answers 428 precondition_required and a stale one 412 revision_mismatch.
  • Pagination. Lists take limit (1 to 100) and the opaque cursor of the previous page's next_cursor.
  • Rate limits. Every operation can answer 429 rate_limited. Answers carry the RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers, and a 429 or 503 carries Retry-After. The limits are targets and the same for every Organization.
  • Errors. Every answer that is not a success is an ErrorEnvelope with a stable code; the error codes page lists each with its HTTP status.

Members

A Member signs in with Amazon Cognito, and its token is accepted as the bearer credential. GET /v1/members/me reads the signed-in Member and refuses every API key. Managing Members, the Organization's settings and the Compliance profile are Session only as well. The customer application where Members will do this, the Dashboard, is planned.