Coinbase Developer Platform Documentation Audit
The CDP docs are a sprawling product index with serious structural rot: canonical URLs advertised in llms.txt redirect or 404, product names have been renamed mid-flight (Server Wallets + Embedded Wallets → "Non-custodial wallets") without updating inbound links, and the same parameters (env var names, supported networks, error envelopes) get different answers on different pages. Agents that ingest skill.md will generate requests against endpoint shapes that don't exist.
1. Embedded Wallets and Server Wallets URLs both redirect to the same renamed page, with no migration notice (critical)
Location: https://docs.cdp.coinbase.com/server-wallets/v2/introduction/welcome and https://docs.cdp.coinbase.com/embedded-wallets/welcome (both listed in llms.txt)
Problem: Both canonical product welcome URLs advertised in llms.txt silently redirect to https://docs.cdp.coinbase.com/wallets/non-custodial-wallets/overview. The destination page no longer uses either historical product name ("Server Wallets" or "Embedded Wallets"). The /embedded-wallets/quickstart URL further redirects to /wallets/quickstart/user-auth, titled "Quickstart: User Wallet" — a third label.
Consequence: Every external blog post, Stack Overflow answer, and AI agent that learned "Server Wallets" or "Embedded Wallets" as the product is now reading a page that doesn't acknowledge those names exist. Developers searching for SDK docs by their old product name can't confirm they landed in the right place; agents indexing llms.txt end up with mismatched entity names vs. page content.
The fix: Add a "Previously known as Server Wallets / Embedded Wallets" callout at the top of /wallets/non-custodial-wallets/overview. Update llms.txt to point at the canonical post-rename URL. Keep a redirect but emit a deprecation banner explaining the consolidation.
2. Multiple env-var naming conventions for the same API credential (critical)
Location: /get-started/authentication/jwt-authentication, /api-reference/v2/authentication, /sdks/cdp-sdks-v2/typescript, /get-started/build-with-ai/cdp-cli/how-it-works
Problem: The same CDP API key is referenced under different variable names across canonical docs. The CDP CLI page's env-var table (evidence [38]) explicitly documents CDP_KEY_ID / CDP_KEY_SECRET / CDP_WALLET_SECRET. The JWT page tells users to substitute "key name" and "key secret". The v2 API reference's "Environment setup" section uses a KEY_ID/KEY_SECRET-style export. The TypeScript SDK quickstart points users at CDP_API_KEY_ID / CDP_API_KEY_SECRET / CDP_WALLET_SECRET. The CDP CLI page's prose also mentions both cdp env custom --url … and CDP_URL as parallel mechanisms with no statement of precedence.
Consequence: A developer copying the JWT snippet and then the SDK snippet into the same project will read credentials from two different env vars and one will be empty. Agents writing onboarding scripts won't know which name is canonical; CI configurations end up duplicating the same secret under multiple names "to be safe."
The fix: Pick one canonical pair (the SDK's CDP_API_KEY_ID / CDP_API_KEY_SECRET is the most namespaced) and rewrite every authentication-touching snippet to use it. Add a single "Environment variables" reference table linked from every auth page. Explicitly state precedence when cdp env custom --url and CDP_URL are both set.
3. Agent-facing skill.md documents endpoints that don't exist (critical)
Location: https://docs.cdp.coinbase.com/skill.md
Problem: The root agent-context file tells AI agents to call POST /evm-accounts, POST /evm-accounts/{id}/send-transaction, POST /evm-smart-accounts/{id}/send-user-operation, POST /transfers/{id}/execute. The actual API reference for "Create EVM account" shows the host is https://api.cdp.coinbase.com/platform/v2 and the path is POST /v2/evm/accounts — i.e., /platform/v2/evm/accounts, not /evm-accounts.
Consequence: This is the single most consequential failure mode for agent-facing docs: an AI agent loading skill.md will confidently generate requests against a hostname/path combination that does not exist. Every "use Claude to build with CDP" demo that relies on this file is broken at the network layer, and the failure looks like a 404 from a real-looking endpoint.
The fix: Rewrite skill.md to use the actual production paths (POST /platform/v2/evm/accounts, POST /platform/v2/evm/accounts/{address}/transactions, etc.) and include the base URL explicitly so agents emit full URLs. Add a test that diffs the paths in skill.md against the OpenAPI spec on every release.
4. Create EVM account request and response schemas use different field names for the same data (critical)
Location: /api-reference/v2/rest-api/evm-accounts/create-evm-account
Problem: The documented request body accepts a single accountPolicy (string, e.g., "accountPolicy": "123e4567-…"), but the example response returns policies (an array, e.g., "policies": ["123e4567-…"]). The request name is singular-scalar; the response name is plural-array, and the singular accountPolicy is absent from the response.
Consequence: Anyone code-generating types from the OpenAPI definition will produce a request type and a response type that don't round-trip. Developers writing client wrappers will silently lose policy information on read-back or guess the mapping. Agents extracting schemas to compose CRUD flows will fail to match accountPolicy → policies without semantic help.
The fix: Either accept policies: string[] on the request to match the response, or return accountPolicy: string on responses with a single policy and policies: string[] only when multiple exist (and document the relationship explicitly). Whichever you pick, name the field identically in both directions.
5. x402 facilitator's supported networks disagree across three pages (critical)
Location: /x402/welcome, /x402/quickstart-for-sellers, /get-started/supported-networks
Problem: Three contradictory statements about which networks the Coinbase-hosted x402 facilitator supports:
/x402/welcome: "Base, Polygon, Arbitrum, World, and Solana"/x402/quickstart-for-sellers: "Base, Base Sepolia, Polygon, Arbitrum, World, World Sepolia, Solana, Solana Devnet"/get-started/supported-networks: "CDP Facilitator: Base. Self-hosted Facilitator: any EVM network"
Consequence: A developer building on Polygon mainnet sees the welcome page say "yes," sees the supported-networks matrix say "no, only Base," and has no way to know which is current. The quickstart's testnet list adds World Sepolia but doesn't include Polygon's or Arbitrum's testnets at all. Agents reading the docs to pick a network will silently pick wrong.
The fix: Designate one page as the source of truth for x402 facilitator coverage (probably the quickstart table), add a build-time check that the welcome page and supported-networks page render from the same data, and version the matrix so changes are obvious.
6. Multiple top-level entry points render as nav-only chrome (critical)
Location: /index, /get-started/quickstart, /sdks, /api-reference/payment-apis/overview, /agent-kit/welcome, /custom-stablecoins/overview
Problem: llms.txt advertises /index as "Main documentation entry point for CDP products" and /get-started/quickstart as "Entry point to CDP products, common workflows, and platform concepts." Both pages render as ~1 KB of navigation chrome — no hero, no intro, no product overview, no body content under the H1 "Develop with Coinbase." The same pattern repeats on the SDK landing page (a series of header-only ## Python, ## TypeScript, ## Go, ## Java, ## .Net stubs with no link targets, descriptions, or version info), the Payment APIs Overview ("## Sandbox", "## Postman", "## Accounts", "## Deposit Destinations" stubs and an "OpenAPI Spec" "download" link with no URL or sha), the AgentKit welcome (five header-only feature cards followed by an empty "Quick Links" section), and the Custom Stablecoins overview (Mint and Burn, Reserve Management, Proof of Reserves, Conversions anchors with no body).
Consequence: Agents indexing the docs through llms.txt retrieve pages that contain only the navigation tree and conclude there is no quickstart, no SDK metadata, and no OpenAPI download. They will refuse to scaffold a project or hallucinate one. Humans landing on docs.cdp.coinbase.com see a sidebar with no orientation. A developer searching for "the official Python SDK for Coinbase Prime" lands on a literal ## Python heading with no body.
The fix: Write actual quickstart content under the H1 — a 3-step "what to install, how to authenticate, your first API call" — that mirrors what each SDK page would say. Each SDK card should at minimum link to its install command, package name, supported runtime versions, and the canonical reference. Publish the actual OpenAPI URL on the Payment APIs page. Generate these stubs from a single manifest so they stay in sync.
7. Authentication overview links a 404 page from five rows of its product-compatibility table (critical)
Location: /get-started/authentication/overview
Problem: The product-compatibility table cites "Coinbase App API Key Authentication" as the authoritative reference for five rows (Advanced Trade API, Advanced Trade SDK, Coinbase App API, Coinbase App SDK, and is referenced again in body text). The linked URL /coinbase-app/coinbase-app-api-key-authentication returns a hard 404.
Consequence: A developer using the Advanced Trade SDK is told elsewhere "use ECDSA keys only" and is sent to a 404 for the canonical "how to" instructions. They are now guessing how to format the key, what algorithm parameters to use, and whether ECDSA-only really means P-256 vs secp256k1.
The fix: Either restore the page at /coinbase-app/coinbase-app-api-key-authentication or rewrite the five table rows to link to wherever those instructions actually live today. Add a link-check CI step so navigation-table URLs cannot ship broken.
8. Webhook signature header leaks the third-party vendor "Hook0" into the public API surface (significant)
Location: /webhooks/verify-signatures
Problem: The header documented for webhook signature verification is X-Hook0-Signature, with an X-Hook0-Id companion header. "Hook0" is an open-source webhooks-as-a-service product — a third-party vendor whose brand has leaked into the public CDP webhook contract. The page also does not explain why the signed payload concatenates timestamp.headerNames.headerValues.rawBody or how v1= versioning will evolve.
Consequence: This couples CDP's public API to a vendor name customers shouldn't have to know about. If Coinbase ever swaps vendors, every customer integration breaks because they verified against X-Hook0-Signature. Security-conscious developers will also be unable to audit the scheme without explanation of the format.
The fix: Alias the headers to X-CDP-Signature / X-CDP-Event-Id (or X-Coinbase-*) at the edge, deprecate the Hook0 names with a 12-month support window, and document the canonical scheme as Coinbase's own contract rather than a vendor's.
9. Webhook update is a full-replace with no read-modify-write example (significant)
Location: /webhooks/quickstart
Problem: The update flow buries a critical foot-gun in line 1 of the example: "update requires all fields, even ones you aren't changing — it's a full replace." There is no example anywhere on the page of how to fetch the current subscription state before issuing the replace, and curl/REST equivalents for any of the CLI operations are not shown.
Consequence: A developer who wants to add an event filter to an existing subscription will issue an update that doesn't include their existing address list, and silently delete it from production. The "all fields" warning is easy to miss; the absence of a read-modify-write example makes it nearly inevitable.
The fix: Show a worked read-modify-write example before the update call (get → modify → put). Add a callout box on the foot-gun line. Add REST/curl equivalents so users don't have to assume the CLI's verbs map cleanly onto API verbs.
10. Error envelope schema contradicts itself between general errors, rate limits, and idempotency pages (significant)
Location: /api-reference/v2/errors, /api-reference/v2/rate-limits, /api-reference/v2/idempotency
Problem: The errors page establishes a four-to-five-field envelope (errorType, errorMessage, correlationId, errorLink, plus optional unauthorizedCapabilities). The rate-limit page's example payload omits correlationId, errorLink, and unauthorizedCapabilities. The idempotency page enumerates three error states (invalid_request, idempotency_error, already_exists) — two of which the dedicated errors page does not list at all.
Consequence: Developers writing error handlers based on the errors page will have null-pointer crashes (or silent log gaps) when the rate-limit envelope doesn't include correlationId. Anyone writing a switch statement on errorType won't account for already_exists because it's not in the canonical enum.
The fix: Either ship correlationId and errorLink on every error envelope (preferred — they're support-critical fields) or update the errors page to mark them as conditionally present. Maintain a single enum of errorType values that every page renders from.
11. Transfers resource has two canonical reference pages with different field sets (significant)
Location: /api-reference/v2/rest-api/transfers/transfers and /payments/transfers/overview
Problem: The API reference page enumerates four lifecycle statuses and a fees array. The Transfers overview adds validateOnly (mutually exclusive with execute), amountType: target mode, four fee-type categories (bank/conversion/network/other), and a travelRule object schema — none of which appear on the API reference page. Meanwhile /api-reference/v2/rest-api/payments/transfers and /api-reference/v2/rest-api/payments/list-transfers (paths other pages link to) both return 404.
Consequence: Developers building a transfer flow off the API reference page will not know validateOnly exists and will create real (billable) transfers when doing preflight checks. Travel rule compliance fields are absent from the reference schema. The 404'd payments/transfers URLs are what most internal links target.
The fix: Merge the two pages — the resource overview belongs at the top of the API reference page, with the schema details unified. Add redirects from /api-reference/v2/rest-api/payments/transfers and /api-reference/v2/rest-api/payments/list-transfers to the live URLs.
12. The MCP "Agentic Wallet" capability matrix contradicts the MCP product page (significant)
Location: /agentic-wallet/welcome vs. /agentic-wallet/mcp/welcome
Problem: The Agentic Wallet welcome's comparison table says the MCP variant cannot "Send & trade" — "(MCP agents discover and pay for services only)." The MCP welcome on the very next page advertises that MCP agents "Make automatic payments on Base, Polygon, and Solana" and "Access paid APIs." Both pages are about the same product.
Consequence: Developers picking between CLI and MCP get one answer from the comparison table and the opposite answer from the product page. Agents that consume both pages to decide capability boundaries will fail policy checks unpredictably.
The fix: Reconcile the "Send & trade" row — distinguish "send to any address" (apparently CLI-only) from "pay an x402 service" (MCP can do this). Rewrite the comparison cell to be specific instead of binary yes/no.
13. Supported Networks page contradicts Trade API welcome on Optimism support (significant)
Location: /get-started/supported-networks vs. /trade-api/welcome
Problem: Trade API welcome lists "Ethereum, Base, Arbitrum, Optimism and Polygon mainnet networks." The Supported Networks EVM table has columns for Base / Ethereum / Arbitrum / Polygon only — Optimism is not a column at all, so a reader can't confirm Optimism support and the row reads as if Trade API supports only those four chains.
Consequence: Developers planning a Trade API integration on Optimism cannot validate from the canonical networks table that Optimism is supported. The same table omits BNB, Avalanche, Zora, and other chains that skill.md says are EVM-supported.
The fix: Expand the EVM matrix to cover every supported chain (matching the chains listed in skill.md's "Supported Networks" section) and have each product page render its row from the matrix instead of restating it in prose.
14. Site navigation prominently features sections that 404 (critical)
Location: Multiple
Problem: The site navigation captured on the /index page includes top-level sections that resolve to 404:
/onramp/overviewand/onramp/welcome— both 404 despite "Onramp" being a primary payments product/customersand/customers/overview— 404 despite "CUSTOMERS" being a top-level nav section/faucets/overview,/onchain-tools/faucet,/onchain-tools/faucet/overview— all 404 despite Faucet being featured in the CDP CLI and supported-networks docs/coinbase-oauth2/welcome— 404 despite OAuth being in the auth overview's product table/server-wallets/v2/evm-features/account-creation— 404 (the entire/server-wallets/v2/subtree appears removed but is still cited inllms.txt)
Consequence: Users clicking the most visible navigation entries hit 404s. For Onramp specifically, the Headless Onramp page tells readers to call "the Create Onramp Order API" and "the Buy Options API" but the in-doc reference at /onramp/headless-onramp/api-reference is also a 404 — so there is no reachable endpoint reference from the Onramp section at all.
The fix: Run a sitemap-wide link check now and either restore the pages, redirect them to current equivalents, or remove them from the nav and llms.txt. Add link-checking to CI for llms.txt and the nav config so this can't regress.
15. Security best-practices page documents OAuth lifecycles for a product whose docs are 404 (significant)
Location: /get-started/authentication/security-best-practices and /coinbase-oauth2/welcome
Problem: The security best-practices page contains a full "OAuth client security" section that names a 1-hour access-token lifetime, one-time refresh tokens, state-parameter CSRF guidance, and redirect URI requirements. The Authentication Overview product table includes a "Sign in with Coinbase" row pointing at "OAuth Documentation." But /coinbase-oauth2/welcome — the page where OAuth is actually supposed to be introduced — is a hard 404.
Consequence: A developer trying to follow the security guidance has nowhere to learn how the OAuth flow is initiated, where the authorize endpoint lives, what scopes exist, or how to register a client. They will improvise — and the security-best-practices page does not even say what to improvise from.
The fix: Publish (or restore) /coinbase-oauth2/welcome with the authorize URL, scopes, registration flow, and a worked example. Link it from the security-best-practices page and from the Authentication Overview product-table row that references it.
16. JSON-RPC API authenticates via key-in-URL with no security warning (significant)
Location: /api-reference/json-rpc-api/core
Problem: The documented JSON-RPC base URL is https://api.developer.coinbase.com/rpc/v1/base/<MY-CLIENT-API-KEY>. Embedding the API key in the URL path causes it to leak into HTTP server logs, proxy logs, Referer headers, browser history, and observability tools. The page does not warn about this.
Consequence: Customers reusing the same client API key across services will rotate it after the first time it shows up in a vendor log export. There's also no guidance on whether Client API Keys for JSON-RPC are scoped, throttled, or revocable on leak.
The fix: Either move the key to a header (Authorization: Bearer … or X-CDP-Client-Key) and update the docs, or add an explicit "this key will appear in logs; treat it as low-trust" callout and explain scoping and revocation.
17. "Billing Unit" is referenced for every JSON-RPC method without explaining what one is (significant)
Location: /api-reference/json-rpc-api/core
Problem: Every method documents a "Billing Unit value" (e.g., "eth_blockNumber … Billing Unit value of this method is 30") but no page explains what a Billing Unit is, how it converts to dollars, or how it maps to plan tiers.
Consequence: Developers cannot estimate cost. A developer choosing between eth_call (cost?) and eth_getLogs (cost?) for the same use case has no rubric. Finance teams cannot model RPC spend.
The fix: Publish a "Billing Units" page that defines the unit, gives a USD conversion (or a link to the pricing page where conversion lives), and lists units-per-month for each tier. Link it from every method.
18. Headless Onramp lists card-decline error codes with no HTTP status mapping, and sandbox policy contradicts production (significant)
Location: /onramp/headless-onramp/overview
Problem: The page lists at least 13 (likely more — the page says "Some possible error codes are listed below") ERROR_CODE_* values from the onramp_api.commit_error post-message event, but never says what HTTP status the v2 Onramp Order API returns for "invalid request" or how to map post-message error codes back to API-level error responses. The linked in-doc API reference (/onramp/headless-onramp/api-reference) is a 404. Separately, the page tells users to verify their users' phone numbers and bans VoIP numbers in production ("must be a real cell phone number, not a VoIP phone number"), but the sandbox section says "you can use any random phone number, as long as it's in a valid US phone number format."
Consequence: Developers building card-decline UX cannot tell whether to show the user "your bank declined" (ERROR_CODE_GUEST_CARD_HARD_DECLINED) by handling an HTTP 4xx response, by listening to a post-message event, or both. Retry policy is undefined. Worse, a team that passes sandbox QA using VoIP numbers (or any randomly-formatted US number) will fail in production when real users get rejected by the live verification rules. Sandbox is supposed to mirror production behavior.
The fix: Add a section titled "Error sources" that distinguishes API-response errors from post-message errors, list the complete error-code set (or commit to "the canonical list lives in the OpenAPI spec"), and publish (or restore) the Onramp API reference page so error codes can be cross-referenced. Make sandbox phone-number validation match production rules, or at least add a banner naming the difference and the tests it won't catch.
19. Sandbox vs. production hostname mapping is documented only for Payments (significant)
Location: /get-started/sandbox
Problem: The sandbox overview table tells testers the base URL is sandbox.cdp.coinbase.com for sandbox vs. api.cdp.coinbase.com for live — but the table is explicitly about custodial Payments. There is no cross-page table reconciling sandbox vs. production hostnames for webhooks, x402, non-custodial wallets, Trade API, or JSON-RPC. Other docs consistently target api.cdp.coinbase.com without naming a sandbox equivalent.
Consequence: A developer wanting to test webhook delivery, an x402 payment flow, or a Trade API call against sandbox has no canonical answer for the host they should point at. They will either guess (and silently exercise production) or assume there is no sandbox for that product.
The fix: Publish a single "Sandbox base URLs" matrix that names the host (or "sandbox not available") for every CDP product. Cross-link it from each product's quickstart. If non-payments products genuinely have no sandbox, say so explicitly.
20. Two API-reference landing pages that don't cross-link or agree (significant)
Location: /api-reference/introduction vs. /api-reference/v2/introduction
Problem: CDP ships two distinct API-reference entry points. /api-reference/introduction is a ~600-character stub with a Getting Started list of two links and a "demo apps" pointer. /api-reference/v2/introduction is a marketing page with product cards (Payments, Wallets, Stablecoins, Trading, Onchain Tools, Customers) that duplicates copy from /api-reference/v2/authentication. Neither page cross-links the other, and they don't agree on tone, scope, or structure.
Consequence: A developer arriving at one entry point may never find the other. Agents indexing the API surface will ingest two different "introductions" that contradict each other on what CDP even contains.
The fix: Pick one canonical API-reference landing page. Redirect the other. Link the canonical page from the docs nav, llms.txt, and the API-reference subtree's index.
21. Changelog has no machine-readable feed and no product filter (minor)
Location: /get-started/changelog
Problem: Entries mix product launches, bug fixes, and protocol upgrades in single bullets. There is no RSS feed, no JSON feed, no filterable index by product (Embedded Wallets, x402, Trade API, etc.). The page-level metadata that is present (tag pills like "Product Updates", "Wallets", "Data API", "x402", "New Releases") is not used as a filter UI or exposed as a machine-readable field.
Consequence: Developers tracking specific products (e.g., only x402 changes) have to scan the entire feed. Agents that want to ingest "what changed since my last sync" have no machine-readable feed and no stable category vocabulary.
The fix: Publish /changelog.rss and /changelog.json with category tags per entry. Add a product filter to the rendered page. Stabilize and document the tag vocabulary.
22. CDP CLI agent skill renders backslash-escaped Markdown literally and points at a renamed product path (minor)
Location: /cdp-cli/skill.md
Problem: The published skill.md for the CDP CLI agent skill contains literal \*\* sequences (e.g., "\*\*Check Node.js\*\*") that an agent will read as escaped asterisks rather than bold markers. The skill also points users to https://portal.cdp.coinbase.com/products/server-wallet/accounts even though the rest of the docs have renamed the product to "non-custodial wallets."
Consequence: An agent reading the skill produces malformed onboarding output. The "server-wallet" Portal URL is inconsistent with the public product name, confusing humans who follow the link.
The fix: Strip the backslash escaping (publish the file as authored Markdown) and update Portal URLs to use the post-rename product paths. Add a build-time check that skill.md files round-trip through a Markdown renderer cleanly.
23. Paymaster quickstart's Node prerequisite contradicts every other docs page (minor)
Location: /paymaster/guides/quickstart
Problem: Paymaster declares "node >= 14.0.0" and "npm >= 6.0.0" as prerequisites. Every other quickstart (non-custodial wallets, CDP CLI, CDP CLI agent skill) requires Node 22+. Node 14 has been EOL since April 2023.
Consequence: A developer who installs Node 14 to satisfy Paymaster, then adds the CDP SDK to the same project, will hit cryptic install errors from the SDK's Node-22-only requirements. The mismatched floor invites users to ship on an EOL runtime.
The fix: Update Paymaster's prerequisites to Node 22+ to match the rest of the platform. If Paymaster truly works on older Node, state the minimum SDK-supported version for the rest of the integration path.
24. AgentKit quickstart npm install string is malformed (minor)
Location: /agent-kit/getting-started/quickstart
Problem: The page documents npm install -g create-onchain-agent/@latest as the global-install fallback. The /@latest segment is not valid npm syntax — /@latest parses as a path component, not a version tag. The conventional form is create-onchain-agent@latest.
Consequence: Copy-pasting the command fails or, worse, npm interprets the slash as a scope marker and installs nothing useful. A developer trying the global-install path hits a confusing error on step 1.
The fix: Change to npm install -g create-onchain-agent@latest. Add npm-syntax linting to the CI that publishes the docs.
25. TypeScript SDK quickstart reports a typo in updateAccount examples (minor)
Location: /sdks/cdp-sdks-v2/typescript
Problem: Source notes for this page record that both EVM and Solana updateAccount examples misspell the parameter as addresss (three s's) instead of address. The visible scrape excerpt for the page cut off at "Load client config from shell" before showing the snippet, so the typo should be re-verified against the live published version before publication, but if present it is in the official TypeScript SDK quickstart that users will copy-paste.
Consequence: Copying the snippet into TypeScript will either (a) fail at compile time if types are strict, or (b) silently succeed at runtime but never update the intended account because addresss is an unrecognized field. Agents extracting and executing this snippet without semantic review will hit silent no-ops.
The fix: Verify, fix every occurrence of addresss → address in the TypeScript SDK quickstart, and run a linter against published code examples that catches "kwarg present in snippet but not in SDK type signature."
What they do well
- The error reference establishes a clear envelope contract (
errorType,errorMessage,correlationId,errorLink) — the design is good even though execution drifts. - The Headless Onramp
commit_errortaxonomy is unusually detailed (named, human-readable card-decline codes for the common failure modes). - The sandbox-vs-live comparison table on
/get-started/sandboxis the kind of side-by-side rubric the rest of the docs would benefit from copying.
Top 3 recommendations
- Fix the agent-facing layer first.
skill.mddocuments endpoints that don't exist (/evm-accountsvs. real/platform/v2/evm/accounts). Rewrite it against the OpenAPI spec, add a CI diff, and ship Coinbase-branded webhook headers (X-CDP-Signature) to eliminate the leakedHook0vendor name. - Pick one name per thing. One env-var convention (recommend
CDP_API_KEY_ID/CDP_API_KEY_SECRET/CDP_WALLET_SECRET), one product label per product (Server Wallets/Embedded Wallets → "Non-custodial Wallets" everywhere, including Portal URLs), one supported-networks matrix that every product page renders from, one set of field names that survive request → response round-trips (accountPolicy↔policies). - Add a link checker and a sandbox map to CI. Multiple top-level nav entries (
/customers,/onramp/overview,/onramp/welcome,/coinbase-oauth2/welcome,/faucets/overview) 404 from the homepage.llms.txtadvertises URLs that redirect or 404. Publish a sandbox-hostnames matrix that covers every product so testers stop guessing. Both are fixable with a 10-minute crawl and a build-time gate.