BetterAgent Documentation Audit
One-line state: a tight six-page Nextra site that reads cleanly but is riddled with cross-page contradictions — two different names for the provider you import, an env var the code reads but no page sets, a "default" component you can't install, and a bolded server-action rule the company's own homepage example violates. For a hosted backend exposing an HTTP/SSE API, there is no API reference, no error page, and no dashboard documentation at all.
1. The provider you import has two different names across pages (critical)
Location: /quickstart, /ai-setup, /components, /agent-setup.md
Problem: The Quickstart, AI Setup, and agent-setup.md tell you to import the generated wrapper: import { AgentProvider } from "@/components/betteragent-provider". But the AI Setup prose says "Wraps your root layout with BetterAgentProvider", the AI-Setup client-actions snippet shows <BetterAgentProvider ... actions={...}>, and the Components page "Getting started" imports BetterAgentProvider directly from betteragent-react. So within the same flow the symbol flips between AgentProvider (generated, local path) and BetterAgentProvider (package export).
Consequence: A developer — or an AI coding agent following the copy-paste prompt — picks one name and the other half of the snippets won't resolve. Mixing the generated AgentProvider (which auto-wires server actions) with the raw BetterAgentProvider from the package (which doesn't) silently drops server-action wiring, and the agent loses tools with no error.
The fix: Pick one canonical name per import path. Document explicitly: "AgentProvider is the generated wrapper in components/betteragent-provider.tsx; it re-exports/configures BetterAgentProvider for you. Always import AgentProvider." Then make every code sample (including the actions prop example) use that exact symbol.
2. apiUrl reads an env var that no page ever sets (critical)
Location: /quickstart
Problem: The provider example passes apiUrl={process.env.NEXT_PUBLIC_BETTERAGENT_API_URL}, but the .env.local snippet on the same page sets only NEXT_PUBLIC_BETTERAGENT_CLIENT_KEY=ba_client_..., and betteragent init is described as writing only the client key. NEXT_PUBLIC_BETTERAGENT_API_URL is referenced but never written, defaulted, or explained anywhere in the docs.
Consequence: Copy the snippet verbatim and apiUrl resolves to undefined. Depending on the SDK's fallback behavior this either silently points the engine at the wrong host or breaks requests — and the developer has no documented variable to fix because the docs never tell them it exists or what value it takes (the CLI page's production default is https://www.betteragent.dev, but that's never connected to this client env var).
The fix: Either drop the apiUrl prop from the Quickstart example (let it default), or add NEXT_PUBLIC_BETTERAGENT_API_URL=https://www.betteragent.dev to the .env.local snippet and document its purpose, default, and when to override it.
3. The bolded "no array export" rule is broken by the homepage's flagship example (critical)
Location: /tools and /ai-setup vs https://www.betteragent.dev/ (homepage)
Problem: The Tools page states as a hard rule: "No array export — export each action individually. "use server" files cannot export arrays". AI Setup repeats it. But the marketing homepage's server-actions.betteragent.ts sample does exactly the forbidden thing — export const serverActions = [ defineServerAction({...}) ] — and additionally omits the required "use server" directive that the docs say "the file must start with."
Consequence: The homepage is the first code most people (and indexing agents) see. Following it produces a server-actions file that the documented import * pickup mechanism won't load and that violates the "use server" requirement — the agent ends up with zero server-action tools and no obvious reason why. Two of the product's own canonical surfaces teach mutually exclusive patterns.
The fix: Rewrite the homepage sample to match the docs: add "use server" and export each defineServerAction individually rather than as an array. Treat the homepage code as part of the docs surface that must pass the same rules.
4. The "default" Components example renders ChatDrawer, which isn't in the registry and can't be installed (critical)
Location: /components
Problem: The "Available components" registry table lists exactly four: sidebar, chat-popup, cmd-k, inline-bar. But the Attribution section says the prop is "available on ChatSidebar, ChatPopup, ChatCmdk, ChatInlineBar, and ChatDrawer", and the default example renders <ChatDrawer />. ChatDrawer appears in no registry row, and the CLI's betteragent add NAME option lists only sidebar | chat-popup | cmd-k | inline-bar — no drawer.
Consequence: A developer copies the default <ChatDrawer /> example, then has no documented way to install it — betteragent add drawer isn't a listed option. Either the component is real and undocumented (so they can't find it) or it's vestigial and the example is dead. Both leave the canonical example un-runnable.
The fix: Decide whether ChatDrawer ships. If yes, add a drawer row to the registry table and to betteragent add's NAME list. If no, change the default example to a registered component (e.g. <ChatSidebar />) and remove ChatDrawer from the attribution list.
5. No API reference, error catalog, auth deep-dive, or dashboard docs for a hosted HTTP/SSE backend (critical)
Location: Whole site (nav: Introduction, Quickstart, AI Setup, CLI Reference, Tool Files, Components)
Problem: BetterAgent is described as a hosted backend the SDK talks to over an HTTP/SSE API (the engine performs "server-to-server" requests, the CLI resolves an api URL, the provider takes a clientKey/authToken). Yet there is no endpoint reference, no request/response schema, no SSE stream format, no error/status-code page, no troubleshooting page, and no changelog. The sidebar's "System" entry is just the light/dark theme switcher, not a docs section.
Consequence: When a request fails, there's no documented error shape or status code to match against — and agents, which can't apply human judgment, fail silently. Anyone wanting to call the API directly, debug a 4xx/5xx, or understand the SSE protocol has nothing to read. There's also no machine-readable OpenAPI spec for agents to discover endpoints from.
The fix: Add an API Reference (endpoints, auth header, SSE event schema, error codes) and a Troubleshooting page mapping common failures to causes. Publish an OpenAPI spec so agents and tooling can discover the surface programmatically.
6. The same Quickstart page reports two different route/action counts (significant)
Location: /quickstart
Problem: On one page, betteragent init reports "Found 8 routes · 4 server actions" while betteragent discover reports "Found 11 route handlers · 9 server action exports" for the same project.
Consequence: A developer can't tell which number is authoritative or whether init is missing 3 routes and 5 actions. It reads like init silently skipped tools — exactly the kind of discrepancy that makes someone distrust whether their agent actually sees all its tools.
The fix: Make the two example outputs consistent (same project, same numbers), or explain why init and discover legitimately count differently (e.g. init scopes to a subset) so the gap is intentional and understood.
7. The CLI is installed as a dev dependency on some pages and a runtime dependency on others (significant)
Location: /quickstart, /cli vs /components
Problem: Quickstart and the CLI Reference install with npm install -D betteragent-cli (dev dependency). The Components page installs the CLI as a regular dependency.
Consequence: Inconsistent install instructions for the same package. A reader following both pages ends up unsure whether the CLI belongs in devDependencies or dependencies, which matters for CI/production install pruning (npm install --production would drop a dev-dep CLI).
The fix: Standardize on one (a CLI is almost always -D) and use the identical command on every page.
8. The Quickstart documents only two authToken forms; a third exists (significant)
Location: /quickstart vs /ai-setup and /agent-setup.md
Problem: Quickstart lists authToken as String ("forwarded as Authorization: Bearer <token>") and Object ("forwarded verbatim"). AI Setup and agent-setup.md list a third form: Function (Client Component only): called per-request for refreshed tokens.
Consequence: A developer who only reads the Quickstart (the page literally titled for getting started) never learns about the Function form — the only documented way to supply refreshed/rotating tokens. They'll hardcode a one-time token and hit silent auth failures when it expires.
The fix: Add the Function form to the Quickstart's authToken list, with a one-line note on when to use it (token refresh in client components).
9. localhost:3000 dev artifacts leak into the CLI reference examples (significant)
Location: /cli
Problem: The documented API-URL resolution order ends in the production default https://www.betteragent.dev, and betteragent whoami output shows api: https://www.betteragent.dev. But the init example and the betteragent.config.json example both use "apiUrl": "http://localhost:3000".
Consequence: Readers may copy http://localhost:3000 into their committed betteragent.config.json and then wonder why the CLI can't reach the backend, or ship a config pointing at a non-existent local server. It reads like an internal dev environment that wasn't scrubbed before publishing.
The fix: Replace http://localhost:3000 in the published examples with the production default, and if a local-dev override is worth showing, label it explicitly as "for local development only."
10. Routes depend on "project settings" / a dashboard that the docs never document (significant)
Location: /tools (and Introduction)
Problem: The Tools page says route tools hit "the baseUrl you configured in your project settings." The provider needs a clientKey; login uses a secret key ("the secret key you copied"). But nowhere in the docs is the dashboard/project-settings surface documented — where you set baseUrl, where the client key and secret key come from, or how to find them.
Consequence: A developer following the docs reaches a step that assumes a configured baseUrl and copied keys, with no page explaining where those live or how to set them. Route tools will silently fail to reach the right backend if baseUrl was never configured, and the docs give no place to go.
The fix: Add a "Project settings" page (or section in Introduction) documenting the dashboard: where to find the client key and secret key, how to set baseUrl, and how these map to the CLI/provider values.
11. Runtime hard caps exist but appear nowhere in the docs (significant)
Location: /tools vs https://www.betteragent.dev/ (homepage)
Problem: The homepage advertises concrete runtime limits ��� 20 turns/conversation, 80k tokens/conversation, 8KB per tool result, 30s route timeout. None of these appear in the docs. The Tools page only says return values should be "concise… the agent uses it to decide the next step," never stating the 8KB cap or the 30s route timeout.
Consequence: A developer designing a route tool that returns a large payload or takes >30s has no documented limit to design against — they'll discover the 8KB truncation or timeout in production, not in the docs. "Keep it concise" is unactionable without the number.
The fix: Add a "Limits" section to Tool Files (and/or a Limits page): 8KB tool-result cap, 30s route timeout, 20 turns and 80k tokens per conversation. State what happens at each limit (truncation vs error).
12. The docs never say which model powers the agent or whether it can be changed (significant)
Location: Whole docs site vs homepage
Problem: The homepage names the models and prices (claude-sonnet-4.6 as the default at $3/1M, claude-haiku-4.5 at $0.80, claude-opus-4.5 at $15). The docs never mention which model runs the agent, that there's a default, or whether/how a developer can select among them.
Consequence: A developer evaluating quality/cost tradeoffs, or trying to switch from the default to a cheaper/smarter model, has no documentation to act on. Model choice directly affects behavior and cost, yet it's documented only on a marketing page.
The fix: Add a "Models" page to the docs: the default model, the available alternatives, and how to configure the model per project (or state explicitly that the model is fixed).
13. Free allowance is "500 credits/30-day period" in the docs but "500 / month" everywhere else (significant)
Location: /ai-setup and /agent-setup.md vs /pricing and homepage
Problem: The AI-Setup "Key facts" and agent-setup.md both state "Free plan: 500 credits/30-day period." The pricing page says "500 credits / month" and the homepage says "500 free credits / mo."
Consequence: A rolling 30-day window and a calendar month are different billing semantics — they reset on different days and affect when a developer's free credits replenish. Three surfaces give two answers, so a developer budgeting against the free tier can't trust either.
The fix: Pick the correct semantics (rolling 30-day vs calendar month), state it once authoritatively, and make the docs, pricing page, and homepage match it word for word.
14. "Edit this page" / "Give feedback" links point at the upstream Nextra repo, not BetterAgent (minor)
Location: / (docs footer, every page)
Problem: The footer "Give us feedback" and "Edit this page" links resolve to github.com/shuding/nextra (the docs framework) rather than a BetterAgent content repo — leftover template defaults. There is also no link to a BetterAgent GitHub org or repo anywhere in the docs.
Consequence: Feedback and edit suggestions get filed against the wrong project (the framework author's repo), so they never reach BetterAgent. Contributors and reporters are silently misrouted.
The fix: Point docsRepositoryBase/feedback links at BetterAgent's own docs repo (or remove them if the repo is private), and add a link to the project's GitHub if one exists.
15. Component names switch between kebab-case and PascalCase with no documented mapping (minor)
Location: /components, /cli
Problem: The registry table and betteragent add use kebab-case (sidebar, chat-popup, cmd-k, inline-bar), while the code examples use PascalCase exports (ChatSidebar, ChatPopup, ChatCmdk, ChatInlineBar). The cmd-k → ChatCmdk mapping in particular is non-obvious, and no page states the rule.
Consequence: After running betteragent add cmd-k, a developer has to guess the import name (ChatCmdk? ChatCmdK? ChatCommandK?). The casing of Cmdk isn't derivable from cmd-k, costing a trial-and-error import.
The fix: Add a column or note mapping each registry id to its exported component name (cmd-k → ChatCmdk, etc.), or show the import line alongside each betteragent add command.
What they do well
- The AI-first onboarding is genuinely thought through: a copy-paste setup prompt plus a confirmed-live machine-readable
agent-setup.md(HTTP 200) gives coding agents a real ingestion path most docs lack. - The credits model is explained concretely and consistently between the docs "Key facts" and the pricing page (2/start, 1/message, 3/tool call), with good guidance to describe when to use a tool, not just what it does.
- The six-page structure is lean and scannable — Quickstart → CLI → Tools → Components is a sensible spine once the contradictions are resolved.
Top 3 recommendations
- Fix the copy-paste-breaks-immediately trio first: one canonical provider name (#1), set/document
NEXT_PUBLIC_BETTERAGENT_API_URL(#2), and either install or stop renderingChatDrawer(#4). These are the issues that make the documented happy path fail on first run. - Make the homepage obey the docs' own rules: rewrite the server-actions sample to add
"use server"and drop the array export (#3), since it's the most-seen code and currently teaches the forbidden pattern. - Add the missing backend layer: an API reference + error/troubleshooting page + Limits and Models pages + a Project Settings page (#5, #10, #11, #12), so the hosted HTTP/SSE product is actually documented beyond the SDK install flow.