The docs are a thin Mintlify-style shell over a real product: nine short concept/SDK pages, one API reference with placeholder auth, a changelog that promises features and pages that don't exist, and a 404 handler that tells jokes instead of redirecting. Critical gaps in authentication, error handling, and Python/TypeScript parity mean a developer copying any example will fail at the first API call.
1. No authentication documentation anywhere on the docs site (critical)
Problem: Every curl example in the API reference uses the literal header Authorization: Bearer 123 with no explanation. The Python and TypeScript SDK pages say only "Make sure to set the environment variable VOKER_API_KEY" — with no instructions on where to obtain a key, what format it takes, whether it expires, scopes, rotation, or how to pass it explicitly. /docs/authentication returns a 404 page ("We asked the model where this page is… It said 'Certainly!… and then returned nothing'"). The changelog mentions a Settings → "API Keys" section but only inside the authenticated product.
Consequence: A developer who lands on the docs and tries any code sample literally cannot make a successful request. Worse, AI coding agents will copy Bearer 123 verbatim into production code — the placeholder isn't marked as a placeholder. There is no end-to-end answer to "how do I authenticate?" on the public docs at all.
The fix: Add a top-level /docs/authentication page that covers: where to generate an API key (link into the in-product Settings → API Keys page), the key's format/prefix, scopes, rotation/revocation, and explicit code samples for setting VOKER_API_KEY and overriding it programmatically. Replace Bearer 123 in every curl block with Bearer $VOKER_API_KEY and mark it as a placeholder.
2. API host in every example is a different subdomain that the docs never name (critical)
Problem: Every curl sample targets https://evals.voker.ai/api/v1/..., but the docs themselves live at app.voker.ai and there is no sentence anywhere stating "The API base URL is https://evals.voker.ai/api/v1." A probe of https://evals.voker.ai/api/v1/events confirms the host is live (405 on GET as expected for a POST endpoint), but a reader has to reverse-engineer this from the examples. There is no mention of regions, environments (prod/sandbox), or API versioning policy beyond the in the path.
Consequence: Developers using the SDK with a custom base URL, agents extracting endpoints programmatically, and anyone debugging a CORS/proxy issue have no canonical "base URL" to anchor to. The mismatch between docs domain and API domain also reads as inconsistent branding and raises legitimate "is this the right host?" questions.
The fix: Add a "Base URL" callout at the top of the API Reference: https://evals.voker.ai/api/v1. Explain the subdomain choice (or move the API to api.voker.ai). Document the versioning policy and whether a sandbox host exists.
3. No error reference; only one 404 case documented per endpoint (critical)
Problem: Each endpoint section lists only a single failure case — 404 Not Found with a type like fingerprint-not-found, person-not-found, agent-not-found, or agent-version-not-found. There is no documentation of 401 (auth failure), 403 (permissions), 422 (validation), 429 (rate limit), or 5xx. There is no central error taxonomy: /docs/errors returns a 404 joke page. The error type slugs are introduced ad hoc and never aggregated.
Consequence: Developers cannot write proper error handling against the API because the shape and meaning of non-404 errors is undocumented. Agents that need to map errors to retry/backoff logic have nothing to key on. Rate limits are entirely unspecified despite the marketing site quoting per-plan event quotas (2k/20k/2M per month).
The fix: Publish /docs/errors with the complete type enum, the HTTP status mapping, and the response body schema. Document rate-limit headers and 429 behavior. Add a complete "Responses" block per endpoint (200, 401, 403, 404, 422, 429, 5xx).
4. Python and TypeScript SDK references disagree on required fields (critical)
Problem: The TypeScript ClientCreateEventPayload types vokerAgent and vokerSession as string | undefined. The Python VokerClient_Events.create signature types them as Optional[str] for agent and a plain str for session. The Quick Start code comments on both SDK pages mark both as // required/# required. The changelog (April 10, 2026) confirms both are now hard requirements as a breaking change: "vokerSession is now required for creating an event. vokerAgent is now required for creating an event." Additionally, the Python VokerClient_Events.create signature omits fingerprint_id entirely while the parallel ApiClient_Events.create and the REST API list it as required.
Consequence: Three sources of truth (type definitions, code comments, changelog) contradict each other on the same fields. A developer who trusts the TypeScript types will send undefined and get a runtime/API error. An agent generating client code from the type signatures will produce broken calls. The missing fingerprint_id on VokerClient_Events.create makes it unclear whether the higher-level client auto-resolves fingerprints or whether the signature is just wrong.
The fix: Make vokerAgent/voker_agent and vokerSession/voker_session non-optional in both the TS and Python type signatures shown in the docs. Clarify in prose whether VokerClient_Events.create auto-attaches a fingerprint (and if so, document how) or add fingerprint_id to its signature.
5. Provider pages are Python-only despite the docs claiming Python and TypeScript support (critical)
Problem: The Providers index says "We support the following Python and TypeScript LLM SDKs: OpenAI, Anthropic, Gemini, AI SDK." The OpenAI, Anthropic, and Gemini provider pages contain only Python code samples — no TypeScript blocks. The AI SDK page is the inverse: TypeScript-only, no Python. The TypeScript SDK page's provider links route a TypeScript developer to Python-only pages. The changelog confirms TypeScript provider examples are missing: the May 1, 2026 entry says "Added TypeScript code examples for OpenAI, Anthropic, and Gemini" — but the scraped pages still don't show them.
Consequence: A TypeScript developer clicking through the documented integration path lands on Python examples with no equivalent. Agents indexing per-provider TS usage will return Python.
The fix: Add TypeScript code blocks alongside Python on every provider page (or split into language tabs). Confirm the May 1 changelog promise actually shipped to the public site.
6. Promised pages from the changelog do not exist (significant)
Problem: The April 3, 2026 changelog entry promises "Added SDK Setup page with a step-by-step quickstart guide." Neither /docs/quickstart nor /docs/getting-started resolves; the nav has no "Getting Started" entry, so new readers land on /docs/overview, which is seven short bullet links. The "SDKs" section header in the nav 404s when clicked. The Feb 13, 2026 entry says "Improved Python, Typescript and Go SDKs" — there is no Go SDK page or nav entry.
Consequence: A new developer has no onboarding path on the docs site. The "SDK Setup" page apparently lives only inside the authenticated product. Anyone searching "Voker Go SDK" based on the changelog will get a 404 jokes page.
The fix: Either ship the public quickstart promised in the April 3 changelog or remove the entry. If a Go SDK does not exist, edit the Feb 13 changelog entry. Make the "SDKs" section header resolve to a real index page (the URL is in the IA already).
7. Core product concepts referenced everywhere have no docs pages (significant)
Location:/docs/concepts/*, /docs/resources/changelog, marketing site
Problem: The marketing site lists three flagship analytics features — Intent Detection, Correction Tracking, Resolution Measurement — and the changelog repeatedly references "Intents, Corrections, and Resolutions" (March 6, March 27, April 10, 2026). The /docs/concepts index only links to Events, Agents, and People. There is no /docs/concepts/intents, /docs/concepts/corrections, or /docs/concepts/resolutions. The "Agent Analytics FAQ" blog post explains these concepts; the technical docs never define them.
Consequence: The features Voker pitches as its core differentiation are completely absent from the technical reference. A developer evaluating the product cannot learn what an Intent or Correction is from the docs — they have to read marketing blog posts. Agents indexing the docs will not be able to answer "what does Voker's resolution measurement do?"
The fix: Add concept pages for Intents, Corrections, and Resolutions under /docs/concepts/. Define each one, link to the API fields and SDK behaviors that produce them, and link out to the blog explainer.
8. Published code examples contain broken or contradictory snippets (significant)
Problem: Three example bugs visible in shipped docs:
OpenAI Async Responses API: imports from openai import OpenAI then instantiates AsyncOpenAI() — AsyncOpenAI is never imported in the example.
Anthropic Beta Messages: ships a literal betas=[], # TODO in published documentation. The Async Beta Messages example below it omits betas entirely, so the two examples disagree on whether the field is required.
Gemini Async Interactions: calls client.aio.interactions.create(...) with no await, even though the sibling "Async Generate Content" example correctly uses await client.aio.models.generate_content(...).
Consequence: Any developer or agent copy-pasting these examples gets NameError: AsyncOpenAI is not defined, a literal "TODO" in production, or a coroutine that never executes. The "two lines to install" pitch on the marketing site is undermined the moment a reader tries one of these snippets.
The fix: Run every code example through actual execution (or at least lint/import checking) in CI. Import AsyncOpenAI in the async block; remove the TODO placeholder or document a real list of betas; add await to the Gemini async call.
9. Casing/naming inconsistency between Python and TypeScript with no mapping table (significant)
Location:/docs/integrations/sdks/python, /docs/integrations/sdks/typescript, all provider pages
Problem: Python uses snake_case (voker_agent, voker_session, voker_agent_version, voker_person, fingerprint_id). TypeScript uses camelCase (vokerAgent, vokerSession, vokerAgentVersion, vokerPerson, fingerprintId). The REST API uses snake_case (agent, agent_version, person, session, fingerprint_id) — but without the voker_ prefix that both SDKs add. Three naming conventions, no field-mapping table.
Consequence: A developer porting between languages or correlating SDK calls with API logs has to mentally translate three name schemes. Agents asked to "convert this TS call into a curl request" will frequently invent wrong field names.
The fix: Add a single field-mapping table to the API reference: REST field → Python kwarg → TypeScript property. Place it once and link from the SDK pages.
10. No llms.txt / llms-full.txt and no sitemap (significant)
Location:/llms-full.txt, /sitemap.xml
Problem: Both /llms-full.txt and /sitemap.xml are caught by the SPA shell and return the unauthenticated login HTML instead of a text file or XML. There is no machine-readable index of the docs.
Consequence: AI coding agents (Voker's own claimed audience — "analytics for AI agents") cannot efficiently index or discover the docs. Crawlers fall through to the login page and harvest marketing copy instead of reference content. Search engines have no canonical URL list.
The fix: Ship a static llms.txt and llms-full.txt at the docs root (Mintlify supports this out of the box). Publish a real sitemap.xml. Configure the SPA to return real 404s for these well-known paths instead of the login shell.
11. 404 pages are jokes instead of useful navigation (significant)
Problem: Missing pages render templated jokes — "Your agent hallucinated this page. (High hallucination probability detected: 100%) Return to Safety", "We asked the model where this page is… It said 'Certainly!… and then returned nothing'", "Low Confidence Response… we didn't even bother showing you the page." No search box, no nearest-match suggestion, no link to the docs index, no canonical 404 status semantics for crawlers.
Consequence: A developer arriving from a stale Google result, a blog post link, or the changelog is dead-ended with no recovery path. Cute on first encounter, infuriating on the third. Crawlers and agents cannot distinguish a missing page from a real one because the body is full of natural-language content rather than an unambiguous "404 Not Found" message.
The fix: Replace the joke 404 with a standard error page: "Page not found" + search + nav tree + link to the docs home. Keep the joke as a small flourish if desired, but lead with utility.
12. Fingerprint schema uses loosely-typed strings with no formats (minor)
Problem:git_commit_date is typed as string (not date-time or epoch). language_version, *_sdk_version, git_commit_hash, git_repository_url have no format/regex/length constraints. all_packages is typed object with no inner schema. There is no OpenAPI document linked from the docs that would let agents discover these types programmatically.
Consequence: Clients can send any string and not know whether the server expects ISO-8601, RFC-3339, or epoch. The opaque object for all_packages means agents and SDK authors must guess the shape.
The fix: Tighten the field types in the reference (e.g., git_commit_date: ISO-8601 timestamp, git_commit_hash: 40-char hex). Publish the underlying OpenAPI spec and link to it from the API reference.
What they do well
Concept pages for Events, Agents/Agent Versions, and People are short and clear in their definitions, even if the surrounding navigation is thin.
The changelog is detailed, dated, and surfaces breaking changes prominently (e.g., the April 10 entry on required fields).
The "two-line drop-in" provider pattern (swap import, keep call shape) is genuinely well-suited to the integration story the docs are trying to tell.
Top 3 recommendations
Ship an authentication page and put a real base URL in the reference. Today a developer cannot make their first API call from the docs alone.
Reconcile the SDK signatures with the API and the changelog. Required vs. optional vs. missing fields disagree across three surfaces; pick one and propagate.
Publish concept pages for Intents, Corrections, and Resolutions, plus llms.txt/sitemap. The product's headline features and the agent-readability story both depend on these existing.
Twenty-three runnable snippets were exercised across the public Voker documentation. Five passed (all package-install commands for the JS/Python provider SDKs and @voker/voker), three failed, and fifteen were skipped because the local environment lacks the required runtime or third-party provider credentials.
The two FAIL classes are docs problems, not environment problems:
API Reference curl examples (Create Event, Create Fingerprint) ship the literal placeholder Authorization: Bearer 123. Running them as written returns HTTP 401 with the message "Missing or invalid API key. ... You can find your API key in your project settings at https://app.voker.ai." No public docs page explains how to obtain the key — /docs/authentication, /docs/quickstart, /docs/getting-started, /docs/integrations/sdks, and /docs/errors all return 404. A reader cannot succeed without leaving the docs.
AI SDK provider snippet (/docs/integrations/providers/ai-sdk). The code as printed declares generateText twice in the same module — once via import { generateText } from 'ai' and once via const { generateText } = wrapAiSdk(ai) — which Node.js rejects with SyntaxError: Identifier 'generateText' has already been declared before any provider call is reached.
The Python SDK and per-provider Python examples cannot be exercised in this sandbox: the published voker package on PyPI requires Python ≥ 3.10 (uses PEP 604 str | None syntax) and only Python 3.9 is installed. The provider examples that import voker.ai.provider_* therefore SKIP for "runtime unavailable." TypeScript provider examples (@voker/voker) import cleanly but fail at the LLM call because no OPENAI_API_KEY / AI_GATEWAY_API_KEY / provider key was supplied — SKIP for "missing credentials."
Notes worth flagging to the docs owner (not verified executions, just observed during audit):
/docs/integrations/providers/openai — Async Responses API imports OpenAI (sync) yet instantiates AsyncOpenAI(). Unrunnable without a fix.
/docs/integrations/providers/anthropic — Beta Messages includes a literal betas=[], # TODO placeholder in shipped docs; the Async Beta Messages variant omits the betas argument, contradicting the sync sample.
/docs/integrations/providers/gemini — Async Interactions invokes client.aio.interactions.create(...) without await, inconsistent with Async Generate Content above it.
/docs/integrations/sdks/typescript — vokerAgent / vokerSession are typed string | undefined even though the changelog says both are required since April 10, 2026 and the snippet comments mark them required.
Required credentials
VOKER_API_KEY — supplied by the user; used only for setting the env var when running the TypeScript SDK / AI SDK snippets. Not transmitted by these snippets before the upstream provider call fails.
OPENAI_API_KEY — not supplied; required by the TS Quick Start and OpenAI provider examples. (Not mentioned anywhere in the docs.)
ANTHROPIC_API_KEY — not supplied; required by Anthropic provider examples.
GEMINI_API_KEY / Google credentials — not supplied; required by Gemini provider examples.
AI_GATEWAY_API_KEY or per-provider key — not supplied; required by the AI SDK example.
POST /api/v1/events with Authorization: Bearer 123 → HTTP 401 {"detail":"Missing or invalid API key. ... You can find your API key in your project settings at https://app.voker.ai."}. Diagnosis: docs ship a placeholder bearer and no public page (auth/quickstart/getting-started) explains how to obtain a real key — those URLs 404. Suggested solution (unapplied): add an Authentication page covering API-key issuance and replace Bearer 123 with Bearer $VOKER_API_KEY in examples.
2
bash (curl)
FAIL
PUT /api/v1/fingerprints with Authorization: Bearer 123 → same HTTP 401 body. Same root cause and suggested fix as row 1.
pip install voker: package exists on PyPI (versions 0.0.3–0.0.12) but every wheel declares Requires-Python >=3.10; this sandbox only has Python 3.9. Runtime unavailable.
4
python
SKIP
Quick Start client.chat.completions.create(voker_agent=..., voker_session=..., model="gpt-4.1-mini", ...) cannot be imported — voker/schema/base/agent_versions.py uses str | None (PEP 604) which fails on Python 3.9 with TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'. Runtime unavailable; also OPENAI_API_KEY not supplied.
Quick Start new OpenAI(); await client.chat.completions.create({ vokerAgent, vokerSession, model: 'gpt-4o', ... }) runs through the import path but the underlying openai constructor throws OpenAIError: Missing credentials. Please pass an apiKey, or set the OPENAI_API_KEY environment variable. The user did not supply an OpenAI key, and the docs page mentions only VOKER_API_KEY. Missing credentials.
pip install openai resolves and installs (openai-2.37.0).
9
python
SKIP
Chat Completions example — runtime unavailable (voker needs Python ≥ 3.10); OPENAI_API_KEY not supplied.
10
python
SKIP
Async Chat Completions — same as above.
11
python
SKIP
Responses API — same as above.
12
python
SKIP
Async Responses API — same as above. Also observed (not executed): snippet imports OpenAI (sync) but instantiates AsyncOpenAI(); suggested fix is to change the import to from openai import AsyncOpenAI.
Generate Content — runtime unavailable; Gemini key not supplied.
19
python
SKIP
Async Generate Content — same.
20
python
SKIP
Interactions — same.
21
python
SKIP
Async Interactions — same. Also observed (not executed): snippet calls client.aio.interactions.create(...) without await; suggested fix is to prefix with await, matching the async pattern in the Generate Content sample.
Snippet as printed — import { generateText } from 'ai'; import * as ai from 'ai'; import { wrapAiSdk } from '@voker/voker/ai/provider-aisdk'; const { generateText } = wrapAiSdk(ai); — fails at parse time with SyntaxError: Identifier 'generateText' has already been declared because ESM modules forbid redeclaring an imported binding. Diagnosis: docs bug. Suggested solution (unapplied): drop the import { generateText } from 'ai'; line (or rename the destructured local) so a copy-paste runs. When that single change is mentally applied the snippet still fails at execution time with _AISDKError [GatewayError]: Unauthenticated. Configure AI_GATEWAY_API_KEY or use a provider module., so beyond the SyntaxError this example also needs a documented provider/key setup step.