Context.dev Documentation Audit
The reference layer (OpenAPI specs, EIC taxonomy, latency percentiles, llms.txt) is unusually rigorous — but the marketing FAQ, the quickstart, and the generated code samples disagree with it on credits, error codes, identifiers, asset domains, and timeouts, and the disagreements are exactly the kind that pass human review and break an agent.
1. Credit exhaustion surfaces as 403/USAGE_EXCEEDED per the spec, but the FAQ says 401 and the error catalog documents neither (critical)
Location: https://www.context.dev/ (FAQ), docs.context.dev/optimization/troubleshooting.md, docs.context.dev/api-reference/web-scraping/scrape-images.md
Problem: The FAQ states: "When your credits are depleted, API calls will return a 401 error." But the Scrape Images OpenAPI spec defines a '403' response — "Forbidden - Insufficient permissions or usage limit exceeded" with error_code enum: [FORBIDDEN, USAGE_EXCEEDED, DISABLED, INSUFFICIENT_PERMISSIONS], and the /web/extract ErrorResponse enum also lists USAGE_EXCEEDED. The spec separately defines 401 as "Invalid or missing API key." So exhaustion surfaces as 403 USAGE_EXCEEDED per the spec, not the FAQ's 401. Meanwhile the canonical Troubleshooting catalog ("the most common status codes") lists only 400/401/408/422/429/500 — it never mentions 403 or USAGE_EXCEEDED at all.
Consequence: A developer who writes if (status === 401) refillCredits() — exactly what the FAQ tells them to expect — will never trigger that branch, because real exhaustion comes back as 403 USAGE_EXCEEDED and reads like an auth failure. An agent that greps the published error catalog for how to handle 403 finds nothing and silently mis-handles the most predictable production error a metered API has.
The fix: Correct the FAQ to say credit exhaustion returns 403 USAGE_EXCEEDED, and add a 403 row plus the USAGE_EXCEEDED/DISABLED/INSUFFICIENT_PERMISSIONS codes to the Troubleshooting catalog so it actually matches the OpenAPI specs.
2. The flagship /web/extract reference sample ships an invalid placeholder schema; the ticker sample is a bare placeholder (critical)
Location: docs.context.dev/api-reference/web-extraction/extract-structured-website-data.md, docs.context.dev/api-reference/brand-intelligence/retrieve-brand-data-by-stock-ticker.md
Problem: The auto-generated x-codeSamples for /web/extract pass schema: { type: 'bar', properties: 'bar', required: 'bar', additionalProperties: 'bar' }. That is not a valid JSON Schema — properties must be an object, required must be an array. The ticker endpoint's sample is client.brand.retrieveByTicker({ ticker: 'ticker' }), where 'ticker' is a literal placeholder, not a real symbol. Contrast the /web/extract guide, which shows a correct schema (type: "object", properties: { founded_year: {...} }, required: ["founded_year"]).
Consequence: An agent (or a developer) that copies the API-reference sample — the canonical, most-linked example for the platform's flagship endpoint — sends an invalid schema and gets a validation error on the first call. The two surfaces for the same endpoint disagree on what a working request even looks like.
The fix: Replace the generated placeholder schema with the working example from the guide, and substitute a real ticker (e.g. 'AAPL') so the samples run unmodified.
3. The Quickstart's sample Brand response tags a value the EIC taxonomy says cannot exist (significant)
Location: docs.context.dev/quickstart.md, docs.context.dev/guides/classification/EIC.md
Problem: Per the Quickstart's sample Brand response, the classification uses the EIC subindustry "Cafes & Coffee Shops". The EIC reference defines a closed set — "24 top-level industries, 220 subindistries" returned as "exact strings" — and the Hospitality & Tourism subindustries are "Restaurants & Food Service", "Hotels & Accommodation", "Tourism Experiences & Activities", etc. The EIC page is explicit: "there is no 'Cafes & Coffee Shops' anywhere in the 220-value enum," and "Both industry and subindustry are returned as exact strings: match them verbatim if you're using them as keys, enums, or routing rules."
Consequence: A developer who builds routing or enum logic against the value shown in the Quickstart will never match a real response — the typed enum is incapable of emitting "Cafes & Coffee Shops". The one sample most newcomers copy teaches a value the API can't return.
The fix: Change the sample response's industries.eic subindustry to a real enum member such as "Restaurants & Food Service", and verify the published sample against the EIC enum.
4. ISIN is listed as a resolvable identifier in the MCP "Next steps," but no ISIN endpoint or parameter exists (significant)
Location: docs.context.dev/install-mcp.md, docs.context.dev/api-reference/brand-intelligence/retrieve-brand-data-by-stock-ticker.md, docs.context.dev/llms.txt
Problem: The MCP "Next steps" section says: "What the agent can resolve: name, domain, email, ticker, ISIN, transaction." But the ticker endpoint accepts only ticker (+ optional ticker_exchange); there is no ISIN parameter on it and no ISIN endpoint anywhere. The llms.txt Brand Intelligence index lists lookups by transaction, name, domain, email, ticker, and simplified — no ISIN. So ISIN is advertised as a capability in exactly one place (install-mcp Next steps) despite there being no ISIN surface anywhere in the API.
Consequence: An agent briefed by the MCP "Next steps" list will attempt to resolve a brand by ISIN and hit a wall — there is no surface to call. ISIN is advertised as a capability the platform does not have.
The fix: Remove ISIN from the install-mcp resolvable-identifier list, or ship an ISIN parameter/endpoint and document it in the reference and llms.txt.
5. The marketing FAQ's flat credit costs contradict the documented per-endpoint costs — in both directions (significant)
Location: https://www.context.dev/ (FAQ), docs.context.dev/optimization/prefetching.md, docs.context.dev/api-reference/web-scraping/scrape-images.md
Problem: The FAQ says "Brand API calls (logo retrieval, color extraction, font detection, brand profiles, prefetch) cost 10 credits per call" — yet the Prefetching page says prefetch is "0 Credits on both." The FAQ also says "Web endpoints (scraping) cost 1 credit per call," but the Scrape Images spec says "When enrichment is enabled, the entire call costs 5 credits."
Consequence: Credit budgeting goes wrong both ways: a developer over-reserves for prefetch (expecting 10 credits for a free call) and under-reserves for enriched image scraping (expecting 1 credit, charged 5). For anyone sizing a plan against the FAQ, the math is off.
The fix: Align the FAQ with the per-endpoint costs — mark prefetch as 0 credits and document the 5-credit enrichment surcharge on scraping endpoints.
6. The 429 error envelope is documented two incompatible ways: numeric code vs string error_code (significant)
Location: docs.context.dev/optimization/rate-limits.md, docs.context.dev/optimization/troubleshooting.md, docs.context.dev/guides/extract-structured-data-from-websites.md
Problem: The Rate Limits page shows the 429 envelope as { "status": "error", "message": "Rate limit exceeded", "code": 429 } — a numeric code. Troubleshooting says every envelope carries a "machine-readable error_code" and notes "429 responses use code instead." But the extract guide documents 429 as "RATE_LIMITED on 429" — i.e. a string error_code. So one page says a 429 carries code: 429 (number), another says it carries error_code: RATE_LIMITED (string).
Consequence: A developer or agent writing a single error parser cannot reliably branch on a rate-limit response — depending on which page they read, they key off code or error_code, and one of those will be missing at runtime. Silent failure for the exact path (backoff) where correct parsing matters most.
The fix: Publish one canonical 429 envelope schema and make all three pages match it (ideally include both the numeric status and a stable error_code string).
7. Prefetch is "Subscriber-only," yet it's recommended everywhere as the universal latency fix — including to the free tier (significant)
Location: docs.context.dev/optimization/prefetching.md, https://www.context.dev/ (FAQ), docs.context.dev/introduction.md, docs.context.dev/quickstart.md
Problem: The Prefetching page states prefetch is "0 Credits on both. No rate limit. Subscriber-only." But the FAQ ("use the Prefetch endpoint to request brand data in advance"), the Introduction ("Use the prefetch endpoints to hide this latency"), and the Quickstart error table ("Better: prefetch") all recommend it unconditionally — including to free-tier users, who get "500 one-time credits" and no subscription.
Consequence: A free-tier developer hitting cold-start latency follows the docs' own advice, tries to prefetch, and discovers the recommended fix is gated behind a paid plan. The mitigation the docs lean on hardest is unavailable to exactly the users most likely to read the getting-started pages.
The fix: Flag the subscriber requirement wherever prefetch is recommended, and give free-tier users the alternative explicitly (raise the client timeout to ≥60s).
8. The FAQ promises monthly credit replenishment for "each plan"; the Rate Limits page says the free tier is a one-time grant (significant)
Location: https://www.context.dev/ (FAQ), docs.context.dev/optimization/rate-limits.md, docs.context.dev/introduction.md
Problem: The FAQ says "Each plan includes a monthly API credit allowance that replenishes automatically at the start of each billing cycle." The Rate Limits table footnote contradicts this for the free tier: "Free plan credits are a one-time grant, not a monthly allowance," and the Introduction confirms "500 one-time API credits."
Consequence: A developer prototyping on the free tier reads the FAQ, assumes their 500 credits refill monthly, and ships something that quietly dies when the one-time grant is exhausted and never comes back.
The fix: Scope the "monthly allowance that replenishes automatically" claim to paid plans, and state the free-tier grant is one-time in the FAQ itself.
9. A Context.dev product returns hosted asset URLs on a different domain (brand.dev), undocumented as a cross-domain dependency (significant)
Location: docs.context.dev/api-reference/web-scraping/scrape-images.md, https://www.context.dev/ (FAQ)
Problem: The Scrape Images OpenAPI spec describes the enrichment fields as living on a different domain than the product: enrichment.hostedUrl "Host materializable images on the Brand.dev CDN and return their URL and MIME type," and enrichment.url "Brand.dev CDN URL, when hosted." Nothing in the docs explains the relationship between Context**.dev** and brand.dev, that hosted assets are served off-domain, or how that interacts with the FAQ's promise that "Image/logo URLs are guaranteed to remain valid for up to 1 year."
Consequence: A developer who allowlists context.dev for CSP, egress firewalls, or link-validation will have hosted image URLs silently break because they resolve to brand.dev. An agent or security reviewer that sees a brand.dev asset URL returned by a context.dev API has no documented basis to trust it, and no way to reconcile the 1-year validity SLA with an undocumented third-party-looking host.
The fix: Document the brand.dev CDN relationship explicitly — state that hosted/enriched assets are served from brand.dev, list the domains callers must allowlist, and tie the 1-year URL-validity guarantee to that host.
10. Prefetch is filed under "Utility" in the index but under "Brand API" everywhere else, breaking endpoint-to-SDK mapping (significant)
Location: docs.context.dev/llms.txt, https://www.context.dev/ (FAQ), docs.context.dev/optimization/prefetching.md
Problem: The llms.txt index files the two prefetch endpoints under a top-level "Utility" group, separate from "Brand Intelligence API." But every other surface treats prefetch as a Brand capability: the HTTP paths are /brand/prefetch and /brand/prefetch-by-email, and the FAQ buckets prefetch under "Brand API calls (logo retrieval, color extraction, font detection, brand profiles, prefetch)." Because the Stainless SDK namespaces are generated from these groups, prefetch is reachable under the Utility namespace rather than the Brand namespace an integrator would expect from the /brand/... path.
Consequence: An agent (or a developer) that maps the endpoint catalog to SDK calls looks for prefetch under client.brand.* — matching the /brand/prefetch path and the FAQ's "Brand API" grouping — and doesn't find it, because the index places it in a separate Utility namespace. The same capability is categorized two different ways across the docs.
The fix: Categorize prefetch consistently — either move it under Brand Intelligence in llms.txt to match the /brand/prefetch* paths and the FAQ, or document the Utility grouping and the resulting SDK namespace so callers know where to look.
11. Hosted MCP routes your secret API key to a third-party domain with no explanation (significant)
Location: docs.context.dev/install-mcp.md, docs.context.dev/agent-quickstart.md
Problem: The hosted MCP server lives at https://context-dev.stlmcp.com (a Stainless domain), and the setup instructions have users send x-context-dev-api-key: ctxt_secret_... to it. The docs never note that this is a third-party host or how the key is handled there — while a separate page warns "Never call the Context.dev API directly from a browser. The key would be visible to anyone with devtools. Always proxy through your backend."
Consequence: Security-conscious developers are told to be careful with the secret key in one place, then told to send it to an unexplained external domain in another, with no guidance on the trust boundary. This is the only security-relevant gap in the docs and it directly undercuts the docs' own key-handling warning.
The fix: Name the hosting provider and describe how the key is handled, or offer a first-party hosted endpoint; point cautious users to the documented stdio/local-HTTP option.
12. Client-side timeout and cold-hit latency guidance contradict each other across three pages: 10–30s vs 30s vs 60s against a 5-minute max (minor)
Location: https://www.context.dev/ (FAQ), docs.context.dev/introduction.md, docs.context.dev/optimization/troubleshooting.md
Problem: The FAQ understates cold-hit latency as "First-time domain lookups may take 10-30 seconds" and tells developers to "increase your client-side timeout to at least 30 seconds." The Introduction says "set a client-side timeout of at least 60 seconds" and its own cold-hit table puts p99 at "~1 minute," while Troubleshooting documents a "5-minute platform maximum." So the FAQ's 10–30s range and 30s timeout both fall below the docs' own p99 and platform cap.
Consequence: A developer who follows the FAQ's figures sets a 30-second timeout based on a 10–30s expectation, then sees 408 timeouts on cold-hit domains that the docs themselves say routinely take up to ~60 seconds (and as long as 5 minutes).
The fix: Standardize on a single cold-hit range and timeout recommendation (≥60s, noting the 5-minute max) across the FAQ, Introduction, and Troubleshooting, and correct the FAQ's "10-30 seconds" claim.
13. Cache hit rate is quoted as both 70% and 60% (minor)
Location: https://www.context.dev/ (FAQ), docs.context.dev/introduction.md, docs.context.dev/optimization/prefetching.md
Problem: The FAQ says "Approximately 70% of requests hit cached brands," while the Introduction says "Around 60% of brand lookups hit the cache" and the Prefetching page says "about 60% of all Brand API calls already hit that warm cache."
Consequence: Minor on its own, but for anyone using the cache-hit figure to estimate p50 latency or cost, the two numbers give materially different planning assumptions — and the disagreement undercuts confidence in the latency tables.
The fix: Pick one figure and use it on all three pages.
14. Prefetching references /brand/ai/* endpoints that appear in no index (minor)
Location: docs.context.dev/optimization/prefetching.md, docs.context.dev/llms.txt
Problem: The Prefetching page's "What prefetch does not do" section lists "/web/scrape/*, /web/crawl, /web/screenshot, and /brand/ai/*" as endpoints not covered by the brand cache. But /brand/ai/* appears nowhere in the API-reference index or in llms.txt, which enumerates the full endpoint catalog and lists no such group.
Consequence: A developer or agent that sees /brand/ai/* referenced as real endpoints goes looking for their specs and finds nothing — a dead reference to an undocumented (or nonexistent) surface.
The fix: Either document the /brand/ai/* endpoints in the reference and llms.txt, or remove the reference if they aren't shipping.
15. The Quickstart error table omits 400, which the canonical catalog documents as common (minor)
Location: docs.context.dev/quickstart.md, docs.context.dev/optimization/troubleshooting.md
Problem: The Quickstart "Handle errors" table lists only 401/408/422/429/500. The canonical Troubleshooting catalog documents 400 as a common code: "Invalid input, or a well-formed domain that can't be resolved." The Quickstart table drops it entirely (and also omits 403 — see Finding 1).
Consequence: A developer who cargo-cults the Quickstart table — the first error-handling reference they encounter — ships no 400 branch and silently mis-handles invalid input and unresolvable domains, one of the documented common failures.
The fix: Add a 400 row to the Quickstart error table (invalid input / unresolvable domain) so it matches the canonical catalog.
What they do well
- The EIC taxonomy is genuinely well-specified — 24 industries, 220 exact-string subindustry enums, the single cross-listed subindustry explicitly called out, and a clear note that label changes are detectable schema changes. This is reference writing done right (which is what makes the Quickstart sample violating it so avoidable).
- Machine-readable entry points exist — an llms.txt index and a Stainless-generated OpenAPI spec give agents a real starting point, not just prose.
- Latency is quantified, not hand-waved — p50/p90/p99 cold-hit tables and explicit cache behavior beat the usual "fast and reliable" filler.
Top 3 recommendations
- Unify the error contract. One canonical catalog that includes 403/
USAGE_EXCEEDEDand 400, and one 429 envelope schema — so the FAQ, Quickstart, Troubleshooting, Rate Limits, and the OpenAPI specs all agree on what a failure looks like. - Fix the generated code samples. The
/web/extractplaceholder schema (type: 'bar') and theticker: 'ticker'placeholder must become runnable, and the Quickstart's EIC sample value must be a real enum member, since agents copy reference samples verbatim. - Reconcile the marketing FAQ with the docs. Credits (prefetch 0 vs 10, scrape 1 vs 5), free-tier replenishment (one-time vs monthly), the cache-hit number (60 vs 70), and the cold-hit/timeout guidance (10–30s/30s vs 60s) should each have one answer — and the
brand.devCDN relationship and prefetch's namespace should be documented where integrators will hit them.