Eden AI Documentation Audit
Eden AI's V3 docs ship a usable narrative for LLM and Universal AI endpoints, but the foundation an agent or careful integrator needs — a real OpenAPI spec, internally consistent rate limits, working sidebar URLs, and one canonical model-naming convention — is broken in several places at once.
1. Canonical OpenAPI spec is the Mintlify "Plant Store" sample (critical)
Location: https://edenai.co/docs/api-reference/openapi.json (and indirectly the auto-generated /docs/api-reference/... pages)
Problem: The file served at the canonical OpenAPI URL is the unmodified Mintlify scaffold: "title": "OpenAPI Plant Store", "servers": [{"url": "http://sandbox.mintlify.com"}], paths /plants and /plants/{id}, a Plant schema, and a /plant/webhook webhook. Separately, the rendered API Reference pages (e.g. info/list-features) describe Eden AI's real routes (/v3/info, /v3/chat/completions, /v3/universal-ai, etc.) but every field is a placeholder "<string>" with no descriptions, examples, or enum values — they're driven by a real-but-underspecified second spec.
Consequence: Any agent or developer who follows the standard pattern of importing openapi.json into a client generator, Postman, an MCP server, or an LLM context window gets a plant store API — not Eden AI. Even readers who land on the rendered reference pages get route paths without usable schemas. For a product whose entire positioning is "OpenAI-compatible drop-in," there is no machine-readable contract at the canonical URL and no documented contract on the rendered pages.
The fix: Replace /docs/api-reference/openapi.json with a real, complete OpenAPI 3.1 document for the V3 API (chat/completions, responses, embeddings, universal-ai, info, models, async jobs, upload, custom_token, cost_management). Set servers to https://api.edenai.run/v3. Populate the rendered reference pages from this real spec so each field shows the actual type, example, and description instead of <string>.
2. Default rate-limit number contradicts itself across three pages (critical)
Location: /docs/v3/overview/plans-prices and /docs/v3/overview/rate-limits
Problem: On the Plans & Pricing page, the comparison table says Rate limit — 10 reqs/sec (+ on request). The same page's "Self-serve AI API" section then says Rate limit — 7 requests/second by default, upgradable to 15 req/sec on request. The Rate Limits page disagrees with both: Every account starts at 10 requests per second... If 10 req/sec is not enough... the limit can be adjusted on request. So one page says the default is both 10 and 7 in different paragraphs, and the upgrade ceiling is alternately "+ on request," 15, or unspecified.
Consequence: A developer sizing for throughput, configuring a load test, or designing client-side backoff has no defensible number to pick. Worse, this is the kind of contradiction that agents resolve silently and wrongly — Claude Code will quote whichever page it saw last, and the integrator won't know they're working from incorrect numbers until production traffic gets 429s.
The fix: Pick one canonical default (likely 10 req/s) and one upgrade ceiling. Replace every other number with that one. Add the exact 429 response shape and Retry-After semantics to the Rate Limits page. Cross-link the two pages so updates can't drift again.
3. "List LLM Models" — the literal sidebar label — 404s at its obvious slug (critical)
Location: /docs/v3/llms/list-llm-models (404) vs. working /docs/v3/llms/listing-models
Problem: The sidebar nav item is "List LLM Models." The natural URL list-llm-models returns 404. The page actually renders at listing-models. Same pattern repeats with /docs/v3/integrations/openai-python-sdk (404) vs. openai-sdk-python (works), /docs/v3/introduction (404 — despite being the top sidebar item), and /docs/v3/expert-models/features/audio/speech-to-text (404 — even though "Speech To Text" is in llms.txt and the sidebar).
Consequence: Four high-traffic, sidebar-promoted pages all return 404 at their obvious URLs. The Web Search docs say "Use the List LLM Models endpoint to find models where capabilities.web_search is true" — a developer who guesses the URL or has an agent infer it from the label lands on 404 every time. For agents, this is the worst kind of breakage: the discovery index promises a page that doesn't exist where it should.
The fix: Add server-side redirects from every natural slug (list-llm-models, openai-python-sdk, introduction, speech-to-text) to the rendering URLs. Better: rename the rendering URLs to match the labels and llms.txt entries, then redirect the legacy slugs.
4. Model-string format is inconsistent (Claude Opus 4.7 vs. 4-7) within the same page (critical)
Location: /docs/v3/integrations/claude-code, /docs/v3/integrations/openai-sdk-python, /docs/v3/llms/smart-routing, /docs/v3/llms/chat-completions
Problem: The Claude Code integration page sets:
export ANTHROPIC_MODEL="anthropic/claude-opus-4.7" # period
export ANTHROPIC_DEFAULT_OPUS_MODEL="anthropic/claude-opus-4-7" # hyphen
The two env vars on the same page use different separators for the same model. The OpenAI Python SDK page lists anthropic/claude-opus-4-5 (hyphen). The chat-completions reference uses anthropic/claude-sonnet-4-5 (hyphen). The Claude Code troubleshooting block doubles down on claude-opus-4.7 (period). Separately, the Smart Routing "Use Case Reference" table drops the provider/ prefix entirely (gpt-4o, claude-sonnet-4-5, claude-opus-4-5, gpt-4o-mini, claude-haiku-4-5) — but chat-completions makes provider/model mandatory.
Consequence: Model strings are the one identifier that must be byte-exact — there is no fuzzy matching. A user copying the Claude Code snippet verbatim will have ANTHROPIC_MODEL and ANTHROPIC_DEFAULT_OPUS_MODEL resolve to different (or non-existent) models, with no visible warning. A user copying a smart-routing candidate without the provider/ prefix gets a different failure mode again.
The fix: Pick one separator (almost certainly hyphen, matching everything else in the catalog), require the provider/ prefix everywhere, and enforce both in CI against /v3/models. Add a doc-level test that every model string mentioned in .mdx files resolves at the /v3/models endpoint.
5. Model-count claim is inconsistent: 300+, 315+, 500+, and a lone "50+ providers" (significant)
Location: /docs/v3/quickstart/first-llm-call, /docs/v3/integrations/claude-code, /docs/v3/integrations/openai-sdk-python, /docs/v3/integrations/n8n, root docs page
Problem: The root docs page and most marketing surfaces say "500+ AI models." The First LLM Call page's intro promises "500+ models" but the body says "Eden AI provides access to 300+ LLM models," and the in-page link says "Discover all 315+ LLM models." The n8n page introduces a fourth metric — "+300 LLM models from 50+ providers" — and is the only page in the scraped content that asserts a provider count, which isn't corroborated anywhere else.
Consequence: Developers and procurement readers see contradictory scale claims on the same product. Agents asked "how many models does Eden AI support" will quote whichever number they saw last. It also undermines credibility — if the docs can't agree on the headline number, why trust the parameter tables?
The fix: Pull the model count (and provider count) dynamically from /v3/models and /v3/info at docs build time and render each in one place. Reference those single numbers everywhere else.
6. 402 Payment Required error body shape contradicts the documented error shape (significant)
Location: /docs/v3/general/buying-credits vs. /docs/v3/general/monitoring
Problem: The Buying Credits page documents a 402 response as:
{"error": "Insufficient credits"}
The Monitoring page documents Eden AI errors with a structured shape:
{"error": {"type": "validation_error", "message": {...}}}
And a 404 with a third shape entirely: {"details": "Not Found"}. The Embeddings page lists 400/401/402/404/429/5xx as HTTP statuses but never shows their response bodies.
Consequence: A developer writing error-handling code can't know which shape to parse for which class of error. An agent generating retry logic will pick one shape and silently mishandle the others — a 402 client that reads error.message will hit undefined and crash, while a 400 client that reads error as a string will get an object.
The fix: Pick one error envelope (the structured {error: {type, message}} shape is the obvious choice) and use it for every endpoint. Add a single "Error Reference" page that enumerates every status code, the canonical body shape, and the documented type values.
7. The cost field has two contradictory meanings depending on billing mode (significant)
Location: /docs/v3/general/byok vs. /docs/v3/general/buying-credits
Problem: The Buying Credits page describes cost as authoritative: "This is the amount in USD deducted from your balance for that request." The BYOK page says the opposite for the same field: "the cost field in API responses reflects the estimated cost based on the provider's public pricing. Actual billing happens on the provider's side." Nothing in the response itself flags which mode is in effect.
Consequence: A developer building a cost-tracking dashboard, a per-tenant budgeting system, or a finops report will conflate the two values. A BYOK customer will see "spend" numbers that have no relationship to their actual provider invoice, and a non-BYOK customer reading the BYOK page first will distrust their real billing.
The fix: Add an is_estimated (or billing_mode) boolean to the response next to cost, document both meanings on every page that mentions the field, and link BYOK and Buying Credits to a single Cost Semantics reference.
8. provider_params is a documented silent-passthrough with no validation or examples (significant)
Location: /docs/v3/expert-models/provider-parameters
Problem: The page says: "provider_params are not validated by Eden AI — they are passed directly to the provider. Invalid parameters may cause provider-side errors." There are no examples for any common feature, no schema, no link to provider docs, and no examples of the error shape returned when a provider rejects an unknown field. The page exists to declare the escape hatch and then stops.
Consequence: For a unified-API product, this is the canonical footgun: the abstraction silently leaks. A developer guessing parameter names gets opaque provider errors. An agent generating code from this page will hallucinate plausible-looking keys with no signal that they were ignored.
The fix: Add at least one worked example per major feature (OCR, speech-to-text, image generation) showing real provider-specific keys. Add a "common errors" section showing the exact shape that wraps a provider rejection. If feasible, validate provider_params against a per-provider allowlist and reject unknown keys behind a flag.
9. The "List LLM Models" capabilities flags are referenced everywhere but never linked from the pages that need them (significant)
Location: /docs/v3/llms/web-search, /docs/v3/llms/structured-output, /docs/v3/llms/image-generation
Problem: The Web Search page says: "Not all models support web search. Use the List LLM Models endpoint to find models where capabilities.web_search is true." It does not link to the page. The Structured Output page lists only three providers (OpenAI, Anthropic, Google) as supported, and tells the reader to fall back to json_object mode otherwise — with no programmatic way to detect support. The Image Generation page only documents one model family (Gemini Flash Image). For each, the only authoritative answer is the capabilities object, but the connection between "feature page" and "discoverability endpoint" is implicit.
Consequence: A developer reading the Web Search page can't tell which models actually support it. An agent generating code from these pages will copy web_search_options into requests for models that silently ignore the flag.
The fix: Add to every feature page a "Which models support this?" panel that calls /v3/models at docs build time and renders the actual list of supporting models, plus a snippet that filters on the relevant capability.
10. Web Search example uses openai/gpt-5.2 — inconsistent with every other example in the docs (significant)
Location: /docs/v3/llms/web-search
Problem: The canonical Web Search example uses "model": "openai/gpt-5.2". Every other docs page that names an OpenAI model uses openai/gpt-4, openai/gpt-4o, openai/gpt-4-turbo, or openai/gpt-3.5-turbo. No supporting catalog reference, no version note, no in-page acknowledgement that this is a different generation.
Consequence: Even if gpt-5.2 does resolve at /v3/models, the inconsistency means a developer can't tell whether they should use it or the gpt-4o everyone else gets. Agents copying this snippet will propagate a model literal that may not match the surrounding examples in the user's project.
The fix: Verify openai/gpt-5.2 resolves against /v3/models. Either align the rest of the docs to use the same generation, or replace this snippet with a model that matches the rest of the catalog. Add a docs CI check that every model literal in .mdx resolves at /v3/models.
11. v2 endpoints are documented from inside the V3 docs site without explanation (significant)
Location: /docs/v3/general/sandbox, /docs/v3/general/custom-api-keys, /docs/v3/general/monitoring
Problem: The V3 docs document several core flows against /v2/... endpoints:
- Sandbox token creation:
POST https://api.edenai.run/v2/user/custom_token/ - Custom API keys CRUD:
/v2/user/custom_token/(all five methods) - Cost monitoring:
GET https://api.edenai.run/v2/cost_management/
Nowhere does the V3 documentation explain why some endpoints are on V2, whether they are stable, or when they will be ported. The root page warns that "users before 2026/01/05" can still use the old old-app.edenai.run host — but the V2 endpoints under api.edenai.run are something different again.
Consequence: A developer building against V3 reasonably assumes everything lives under /v3. They will instead discover that token management, sandbox provisioning, and cost monitoring all require a different base path that the OpenAPI spec doesn't describe. Multi-version path mixing is exactly the kind of inconsistency agents miss when generating SDKs.
The fix: Either migrate custom_token and cost_management to /v3 with stable schemas, or add an explicit "V2 endpoints still used in V3" section explaining the rationale, lifecycle, and migration plan. Add both V2 and V3 to the OpenAPI spec.
12. Payload size limit on file upload is "100 MB" with no per-feature breakdown (significant)
Location: /docs/v3/llms/file-upload
Problem: The File Upload page says "Default maximum: 100 MB per file" then immediately undermines itself: "Actual limits may vary by feature and provider. Check provider-specific documentation for exact limits." No table of actual per-feature limits is provided. The Common Errors block lists 413 Payload Too Large as "Compress or split the file" — without telling the reader the threshold for splitting.
Consequence: A developer building an OCR or financial-parser flow has no a priori way to know whether their 40 MB scanned PDF will succeed. The recommended action ("check provider-specific documentation") forces them off Eden AI's docs and onto each provider's site — exactly what an AI gateway should make unnecessary.
The fix: Surface the per-feature/per-provider limits in a table on the file-upload page, populated from the same registry that powers /v3/info.
13. Async job endpoints are referenced by the webhooks page but never documented anywhere (significant)
Location: /docs/v3/expert-models/webhooks, llms.txt
Problem: The Webhooks page describes the polling alternative as "you repeatedly call GET /v3/universal-ai/async/{job_id}." It also implies async submission via POST /v3/universal-ai with a webhook_receiver field. The llms.txt index lists "Create Async Job / Get Async Job / List Async Jobs / Delete Async Job" — but none of these have dedicated narrative pages in the scraped content, and the rendered OpenAPI spec doesn't describe their schemas.
Consequence: Async is positioned as the canonical pattern for long-running tasks (OCR, speech-to-text, video generation) yet the request shape, polling cadence, terminal states, and job lifecycle are described only obliquely from the Webhooks page. A developer who doesn't want to use webhooks has no reference for how to poll correctly.
The fix: Add a dedicated "Async Jobs" page that documents the submission payload, job states, polling endpoint, list/delete endpoints, retention (cross-linked to the 7-day data-retention claim), and example responses. Include these in the real OpenAPI spec.
14. Anthropic-native endpoints exist in the API but have no narrative documentation (significant)
Location: /docs/api-reference/... (rendered routes), llms.txt
Problem: The rendered API reference and llms.txt both list "Anthropic Messages" and "Count Anthropic Tokens" as first-class endpoints alongside Chat, Responses, Moderations, Embeddings, and Models. There is no narrative page covering them in the scraped content — no use case explanation, no example payload, no statement of whether they mirror Anthropic's /v1/messages shape or Eden AI's translated shape, no caveats about which Anthropic features (caching, vision, citations, tool use) are supported.
Consequence: Eden AI's most-promoted integration story is "use Claude Code through us," and the cleanest way to do that for many teams is the Anthropic-native endpoint. The endpoints exist; the contract for them does not. Agents writing Anthropic-compatible client code have nothing to ground against.
The fix: Add a narrative page for the Anthropic Messages endpoint with payload examples, supported Anthropic features, and the relationship to OpenAI chat completions. Document Count Anthropic Tokens with the same pattern as a token-counting helper.
15. Caching is in the discovery index but has no documented page (significant)
Location: llms.txt ("General Topics" → "Caching")
Problem: The llms.txt index lists "Caching" alongside Fallback, BYOK, Custom API Keys, Monitoring, Sandbox, Support, and Users & Organisation. Nothing in the scraped content covers prompt-cache semantics, which providers support it, how the cache key is computed, how cache hits are billed, or how cache_control (or its Eden AI equivalent) flows through the gateway.
Consequence: Caching is the single biggest knob for both cost and latency in modern LLM apps. A developer who reads llms.txt, sees "Caching," and clicks through gets nothing. Agents will either skip caching entirely or invent parameters that don't pass through the gateway.
The fix: Add a Caching page covering: which providers support prompt caching through Eden AI, how to opt in, how cache hits/misses show up in the cost and usage fields, TTLs, and which model families pass cache_control through.
16. Webhook signature public key is only obtainable by emailing support (significant)
Location: /docs/v3/expert-models/webhooks
Problem: The signature verification section reads: "Ask Eden AI support for the webhook public key (webhook_rsa.pub.pem) and store it with your service configuration." The public key for verifying webhook signatures is gated by a manual support request. There is no JWKS endpoint, no rotation policy, no fingerprint published in the docs.
Consequence: A developer who wants to verify webhook signatures (which the docs explicitly recommend) is gated by a manual support exchange. Key rotation has no documented mechanism — if Eden AI rotates the key, every customer's verification silently breaks until they email support again. Agents cannot bootstrap webhook verification at all.
The fix: Publish the current webhook public key at a stable URL (https://api.edenai.run/.well-known/webhook-key.pem or a JWKS endpoint), document the rotation policy and overlap window, and include the key fingerprint in the docs page. Provide a verification snippet that fetches the key at runtime.
17. temperature allowed range is 0–2 but several providers cap it lower with no warning (significant)
Location: /docs/v3/llms/chat-completions, /docs/v3/integrations/n8n
Problem: The chat-completions parameter table states temperature range 0–2, default 1.0 and similarly -2 to 2 for frequency_penalty/presence_penalty. Several upstream providers (Anthropic among them) cap temperature at 1.0 and don't accept frequency/presence penalties at all. The page does not warn that out-of-range or unsupported values may be silently clamped, ignored, or rejected by some providers. The n8n page repeats the same 0–2 range without caveat.
Consequence: A developer setting temperature=1.7 for Claude won't get the output diversity they expect — the value is silently clamped or rejected by the provider, and the OpenAI-compatible facade hides the discrepancy. This shows up as quality regressions in production with no obvious cause. Penalties for Anthropic and other providers are similarly silent no-ops.
The fix: Add a "Provider compatibility" callout to the parameter table noting clamping/unsupported behavior per provider, or link to a per-model capabilities flag the request can pre-check. Echo the effective parameter values back in the response when the gateway clamps them.
18. Self-serve vs. Advanced plan capability claims contradict each other (significant)
Location: /docs/v3/general/users-organisation vs. /docs/v3/overview/plans-prices
Problem: The Users & Organisation page says "Advanced team and organisation features are available on the Advanced AI Platform plan" and then lists "Multi-Project Workspace" as one of those features. The same page later says: "The Self-serve AI API Gateway plan already includes multiple API keys and unlimited seats." The Plans & Pricing table says self-serve includes "Multiple API keys," "Unlimited seats," and "Auto-refill credits" — but doesn't list multi-project workspace either way.
Consequence: A team evaluating Eden AI cannot tell whether they can have separate dev/staging/prod projects on self-serve, or whether they have to talk to sales. Sales-gated capabilities being unclear is a real conversion problem.
The fix: Add multi-project workspace, RBAC roles, and per-project budgets explicitly to the comparison table with clear yes/no marks per plan. Resolve whether multi-project is self-serve or Advanced and say so once.
19. "Servers location" page promises European data centers, body shifts to "provider data centers" without resolving the question (significant)
Location: /docs/v3/data-governance/servers-location
Problem: The page opens: "Eden AI's infrastructure is hosted in secure European data centers to ensure optimal performance and compliance." The body section is titled "Provider Data Centers" and says: "When you make API calls through Eden AI, your data is processed by the underlying AI providers. Each provider operates their own data centers — locations vary per provider and model. To check the server location of a specific provider or model, refer to the Eden AI model catalog."
Consequence: A compliance reviewer needs a definitive answer about where data is processed for GDPR/Schrems II reasons. The page promises "European" then redirects them to a model catalog that doesn't (per the scraped content) document data-residency per model. The result reads as if Eden AI is European but your data goes wherever the provider is — which may be true, but is exactly the kind of ambiguity that fails procurement.
The fix: Separate two facts cleanly: (1) Eden AI's control-plane/metadata location (with the actual region), and (2) per-provider data-residency. For the second, render a table from the catalog showing residency per provider per region, not "refer to the catalog."
20. Expert Model feature output tables have empty Description columns (significant)
Location: /docs/v3/expert-models/features/text/ai-detection (and likely other expert-model feature pages)
Problem: The AI Detection output table lists ai_score, prediction, items[].text, items[].ai_score, items[].ai_score_detail as required output fields — every Description column is blank. The reader is told these fields exist, their types, that they are required, but not what they mean. Is ai_score a probability in [0,1], a score in [0,100], or provider-specific? No way to know from the page.
Consequence: A developer downstream-processing these scores (thresholding, charting, alerting) has to guess at semantics or call the API and reverse-engineer the values. An agent writing handler code will produce confidently-typed but semantically wrong logic. Given the same shape likely repeats across other feature pages, this is a systematic gap.
The fix: Populate every Description column. For score-style fields, declare the range and direction (higher = more confident vs. less). For prediction, enumerate the allowed values. Generate the table from the same registry that powers /v3/info so it can't drift.
21. Plans & Pricing page is unreachable at its natural slug (minor)
Location: /docs/v3/overview/plans-and-pricing (404) vs. the working /docs/v3/overview/plans-prices
Problem: The hyphenated, human-readable slug plans-and-pricing returns the docs site's 404 page. The page actually renders at the abbreviated plans-prices. "Plans & Pricing" appears as a link target by display name across the docs (LLM endpoint page, Rate Limits page, Streaming "Next Steps," llms.txt index), but the scraped content doesn't show the .mdx link targets, so this is at minimum a guessable-URL gap rather than a proven broken internal link.
Consequence: External blog posts, AI agents inferring URLs from titles, and humans typing the natural form all land on a 404 for the most commercially important page.
The fix: Add a redirect from /docs/v3/overview/plans-and-pricing → /docs/v3/overview/plans-prices (or rename the canonical slug to the natural form and redirect the short one).
22. Async-result retention and uploaded-file retention both 7 days but never cross-referenced (minor)
Location: /docs/v3/data-governance/data-retention and /docs/v3/llms/file-upload
Problem: Both pages independently state a 7-day retention window — files expire after 7 days, async results retained for 7 days. Neither cross-links the other, and there is no statement about whether an async job whose input file has expired can still be re-fetched, or whether the result's 7-day clock is from job submission or job completion.
Consequence: A developer designing a retention/audit policy can't reconcile the two clocks. For long-running OCR jobs near the boundary, this matters.
The fix: Add a single "Retention" cross-reference in both pages, and clarify whether the clock starts at submission, completion, or last access.
23. Status page lives at an unusual subdomain that isn't whitelisted in any obvious way (minor)
Location: /docs/v3/general/support, /docs/v3/integrations/claude-code
Problem: The status page URL is https://app-edenai.instatus.com/ — a hyphenated app-edenai subdomain on instatus.com rather than the more conventional status.edenai.co. The Support page and Claude Code troubleshooting reference it by URL with no explanation of the subdomain pattern.
Consequence: Users adding the status page to monitoring whitelists or DNS allowlists may type the expected status.edenai.co and miss outages. Looks like a third-party tracker to some security tooling.
The fix: Register a CNAME at status.edenai.co pointing to the instatus host, and update the docs to use that hostname.
What they do well
- The
llms.txtindex exists and is reasonably complete for an agent to discover the surface area — Eden AI is ahead of most peers in even providing one. - The Webhooks page has unusually concrete operational detail (canonical JSON, retry table with per-status behavior, idempotency reminder, exact timeout values).
- The Embeddings page is the one place that documents HTTP status codes against meanings — a pattern worth promoting to every endpoint.
Top 3 recommendations
- Replace the Plant Store OpenAPI scaffold with a real V3 spec and populate the rendered reference pages from it. This single change unblocks SDK generation, MCP servers, Postman collections, and agent integrations — every other doc problem becomes easier when there's a machine-readable contract with real fields instead of
<string>. - Pick one canonical model-naming convention (hyphen, with mandatory
provider/prefix) and one canonical rate-limit number, then enforce both in docs CI. Wire a build-time check that every model literal in.mdxresolves at/v3/modelsand every rate-limit reference matches a single source of truth. - Fill the documented-but-missing pages — Async Jobs, Caching, Anthropic Messages — and add per-page capability panels driven by
/v3/modelsand/v3/info. The discovery index promises pages that don't exist and feature pages that don't say which models support them; closing both gaps fixes the largest agent-parsing failures.