Skip to main content

Changelog

This page tracks what's actually shipped on the public API, MCP server, and this documentation set — not the product as a whole.

2026-10-07 — Narrower agent scopes; security tests run on production

  • Two new scopes, split out of agents:write: agents:delete (deleting an agent, which is permanent) and agents:test (simulations, tester callers and security scans, each paid model usage). A key that edits agents no longer deletes them or starts test runs unless it is granted those too. Every key that held agents:write was given both, so no existing integration changes. See Authentication.
  • Security & behaviour tests run on production. POST /agents/:id/security/scan queues a scan and a test runner executes it; GET /agents/:id/security returns the score and every failed scenario. The same response now carries runnerAvailable and runnerLastSeenAt, and the scan answers 503 SECURITY_TESTS_UNAVAILABLE only while the runner has not checked in for 15 minutes. A scan that can no longer finish — not picked up within 30 minutes, or not reported back within an hour — carries latest.error instead of reading as a score of 0.

2026-10-07 — Every agent function on the API, run as a customer would

2026-10-06. The API now does everything the dashboard's agent editor does: 35 new operations under Agents — full configuration (GET/PATCH /agents/:id/config, about 133 settings), delete and duplicate, simulations and testers, security tests, the three creation wizards, calendar booking, per-agent integration settings, webhook test and log, share links, statistics and usage — plus file upload, per-stage visibility and test search in the Knowledge Base. They run the editor's own code, so they apply the editor's rules exactly.

2026-10-07. Every one of them was then exercised against production from outside, through api.voicematrix.ai, with a key minted like a customer's and Hebrew content throughout. What that run found, all fixed on this date:

  • A malformed agent id answered 500 on the new routes; it is a 404 now.
  • GET /agents never filled phone_number, though this page showed it; it does now, with phone_numbers for agents that answer on several lines. ?status=draft is accepted.
  • Hebrew agent names stopped at 50 letters in /config (and in the dashboard): the limit counted bytes. It counts characters now, 100.
  • The create example on this site used a voice no engine speaks; create stored it and /config then refused the agent's own settings. Create and update now check the voice against the engine, and the example uses a real voice. The reserved gemini-aistudio engine now needs its entitlement on create, as in the dashboard.
  • The questionnaire wizard served an English template prompt instead of writing one: the model's completion budget was spent before any text. It writes the prompt again (in the dashboard too).
  • Re-uploading a knowledge file under the same name kept the old version live beside the new one; it is refused now (409 KNOWLEDGE_DOCUMENT_EXISTS) — delete, then upload. A Windows-1255 Hebrew .txt failed with a 500; it is a clear 400 INVALID_FILE_ENCODING.
  • Google Calendar and Gmail per-agent settings answered 200 and saved nothing, and HubSpot and Salesforce settings failed for every agent after the first. All four save now.
  • The agent webhook saved with no events sent nothing; enabling it now defaults to both events. Its URL must be public, checked when saved and on every delivery. Its full contract is now documented: Agent Webhook.
  • stats.avgDuration was always 0; usage/daily returned null instead of []; duplicating an agent added a newline to its prompt; an invalid transfer number answered 403 instead of 400.
  • Simulation and tester responses could carry an embedded agent's credentials; they are withheld, as in /config. Reading an agent's webhook log now also needs calls:read (it holds transcripts).
  • Security & behaviour tests are not available on production yet; the scan endpoint says so (503 SECURITY_TESTS_UNAVAILABLE) instead of queueing a run that would never start.
  • The OpenAPI document now describes the request body of every write operation (24 had none).

2026-08-25 — Live acceptance run (docs proven against a running server)

Every claim on these pages that can be executed was executed against the DEV deployment: a real API key was minted, every documented /ext endpoint called, a real lead.created delivered to a public endpoint, its signature verified with the code printed on this site, and the MCP server driven end to end. Two more errors surfaced that no amount of source-reading had caught, both of which would have broken a customer following the docs literally:

  • Leads — the create example was missing a required field. agent_id is marked optional in the request schema, but the handler rejects a blank one with 400 VALIDATION_ERROR — "agent_id is required" (leads_handler.go:143-150). The documented example omitted it, so copy-pasting it returned a 400. Fixed, and the requirement is now stated.
  • Webhooks — the Test-endpoint claim was backwards. The page said a test writes no delivery-log row. It does: measured on a fresh webhook, the delivery log went from 0 rows to 1 (is_test: true, status: success). The flag keeps the attempt out of the failure count and the retry queue, not out of the log. Rewritten, with the real response body.

Also corrected: the event catalog's response is keyed events, not data (the one list endpoint outside the standard envelope), and MCP's protocolVersion is negotiated per client rather than the fixed value previously shown.

What the run confirmed working exactly as written: the nested error envelope with field-level fields[]; INSUFFICIENT_SCOPE on a scope the key lacks; UNSUPPORTED_API_VERSION for an unknown VoiceMatrix-Version; Idempotency-Key replaying the original resource instead of creating a second; the secret being returned on create and never again; the corrected HMAC signature recipe — verified against real deliveries, both the legacy v1= scheme and the Standard Webhooks headers; the event catalog being exactly five events; and the MCP server's nine read-only tools, refusing unknown tools and reporting missing scopes as clean errors.

2026-08-25 — Verification pass on the rewrite

A mechanical check of every page against origin/main — every internal link, every /ext route, event name, scope, error code, file reference, and the webhook delivery constants — found four things the 2026-08-24 rewrite still had wrong or missing. All four are fixed on this date. Nothing in the product changed.

  • Signature verification was wrong on three pages. Webhooks and both the JavaScript and Python examples hashed the body alone, with no v1= prefix and no timestamp. The server signs "<timestamp>.<body>" and prefixes v1= (webhook_dispatcher.go:57-62), so a verifier copied from the old text would have rejected every delivery. The Standard Webhooks headers, which were already being sent, are now documented as well.
  • Errors listed 7 codes; the public surface returns 53. Every code is now listed with its HTTP status, grouped by where it comes from.
  • Webhooks had no endpoint table — five of the eight /webhooks* routes were never named on the page. Added, together with the delivery payload envelope.
  • SDKs & OpenAPI said Standard Webhooks was still to be adopted. It is on the wire already; the page now says what actually remains (the secret format).
  • cURL examples showed a malformed key returning INVALID_API_KEY. The server answers INVALID_API_KEY_FORMAT for anything not shaped like vm_live_ + 32 characters and reserves INVALID_API_KEY for a well-formed key that is unknown or revoked. Both codes are now documented, with the distinction spelled out.

2026-08-24 — Documentation rewrite

Every page in integrations/docs/ was rewritten from scratch after an audit found the previous version described an API that doesn't exist: wrong host (api.voicematrix.net instead of the real api.voicematrix.ai), wrong base path (/v1 instead of /api/v1/ext), a webhook event catalog where only 4 of the 12 listed events are real (and which omitted agent.error, one that is), a flat error shape that doesn't match what the server actually returns, and a fictional vm_test_ key format. See README.md for the full list of what changed. Nothing in the product changed today — only what's written about it.

2026-08-05 — Developer Platform Release 1

  • Self-serve API key creation opened for starter-tier accounts (previously blocked) and for direct_user role (previously only super_admin/reseller/allmode could reach the page).
  • Key properties (rate_limit_tier, expires_at, daily_call_limit) moved from caller-controlled to server-derived.
  • OpenAPI spec confirmed rendering valid JSON at the live endpoint for the first time in 4 months (see SDKs & OpenAPI for the root cause).
  • Production acceptance run completed end-to-end: register → key → first agent → webhook → real event → replay → same flow over MCP. 15/15 checks passed.

2026-08-04 — Webhook event catalog corrected

Per the design note on WebhookEvents in webhooks_handler.go:

  • Added call.started and agent.error to the catalog — both fire in production and were previously unsubscribable. Production already held a call.started subscription that the dashboard had accepted and nothing had ever delivered.
  • Fixed the create-webhook validator rejecting call.ended with 400 Invalid event despite it firing in production, while it simultaneously accepted three events that nothing emits.
  • The catalog and the validator were unified onto one WebhookEvents slice, so the list a customer is offered and the list the server accepts can no longer disagree.

Events such as call.transferred, call.failed, and the appointment.* family were never in the code catalog at all — they existed only in the old documentation, which is why subscribing to them silently produced nothing rather than an error.

Known open items

Tracked here so they aren't silently dropped between doc revisions:

  • No official SDK (Python/TypeScript) — see SDKs & OpenAPI.
  • Call transcripts are not application-layer encrypted — see Security & Data Residency.
  • Webhook secrets are minted as whsec_<uuid>, not the base64 form the Standard Webhooks spec expects — the headers are spec-compliant, but library users must use the raw-key constructor (see Webhooks).
  • No customer-programmable agent tools (custom function calling) — every tool in agent_worker.py is hardcoded.
  • A 404 webhook delivery is classified the same as a 400/422 (see Errors).
  • No pagination/filtering/deprecation contract beyond what's documented per-resource.
All pages