Dodo Payments documentation — a Mintlify docs site (MDX content, no app code). Live at docs.dodopayments.com.
This repo has no package.json (only a gitignored package-lock.json). Do not run npm install, npm run, or expect npm scripts. The toolchain is global CLIs + standalone scripts.
- Dev server:
mintlify dev(serves atlocalhost:3000). Requiresdocs.jsonin cwd. - The CLI is published as both
mintlifyandmint. CI usesmint validate(npm install -g mint); README usesmintlify dev. Treat them as the same tool, current namemint. - Check broken links:
mintlify broken-links. - Helper scripts run directly with Node 24 (which strips TS types):
node scripts/<name>.ts. They are written CommonJS-style (require) with// @ts-nocheck— do NOT convert to ESM/imports.
Content is plain MDX organized by section, mirrored across 13 translated language folders:
features/,developer-resources/,api-reference/,integrations/,changelog/,miscellaneous/,community/— English source content (lives at repo root, NOT in anen/folder).ar/ cn/ de/ es/ fr/ hi/ id/ it/ ja/ ko/ pt-BR/ sv/ vi/— machine-translated copies. Never hand-edit these; they are regenerated (see Translations).docs.json— Mintlify config + the entire navigation tree (11k+ lines, onelanguages[]entry per locale). Editing this is required for any new/moved/deleted page.openapi/openapi.documented.yml— 35k-line OpenAPI 3.1 spec. Source of truth forapi-reference/pages.scripts/— i18n + page-hygiene tooling (TS, run vianode).images/,fonts/,logo/,styles.css,seo.js,favicon.svg— assets.
features/— product & billing features (products, subscription, usage/credit/seat/hybrid billing, checkout, customers, payouts, MoR explainers).usage-based-billing/is a subdir.developer-resources/— guides, SDK docs (sdks/), framework adaptors & boilerplates,webhooks/(withintents/andexamples/),ingestion-blueprints/,billing-deconstructions/.integrations/— flat dir of third-party integrations (Slack, Zapier, HubSpot, Resend, Segment, …). Grouped by type only indocs.json, not on disk.api-reference/— thin OpenAPI-bound stubs in per-resource subdirs (products/,subscriptions/, …).changelog/— one file per release, namedv<MAJOR>.<MINOR>.<PATCH>.mdx; grouped by month indocs.json.miscellaneous/,community/, plus root pagesintroduction.mdxandmigrate-to-dodo.mdx.
- All content files are
.mdxwith frontmatter, kebab-case filenames (payment-methods.mdx). - Every page MUST be registered in
docs.jsonnavigationor it 404s. New page → add it to the Englishlanguage: "en"tabs/groups indocs.json. - API reference pages are thin frontmatter stubs that bind to the OpenAPI spec, e.g.:
To add/change an endpoint, edit
--- openapi: get /products title: List Products description: Get a list of all products associated with your account. keywords: ["Dodo Payments", "API reference", "REST API", "list products"] ---openapi/openapi.documented.ymland the matchingapi-reference/**/*.mdxstub. API stubs omiticon/sidebarTitle. - No content reuse mechanism exists: there are no shared snippets and no
snippets/directory (the sync script lists one but it is not present).importstatements in.mdxexist only inside code examples, never to pull in shared MDX. Each page is self-contained.
Required on every content page: title, description, keywords, icon. Usually also sidebarTitle when the title is long.
---
sidebarTitle: "Checkout"
title: "Checkout Features"
description: "Conversion-optimized, globally compliant checkout with multi-currency, multi-language support, automatic tax calculation, discount codes, add-ons, and smart address collection."
icon: "cart-shopping"
keywords: ["Dodo Payments", "checkout features", "payment platform", "SaaS billing"]
---
description— one or two complete sentences, ~120–160 chars (it is the SEO meta description).keywords— YAML array, always starts with"Dodo Payments", then 2–5 topic terms.icon— either a Mintlify icon name (FontAwesome-style kebab-case, e.g.cart-shopping,credit-card,circle-question,chart-line) or a logo path for integrations (/images/logos/<service>.svg).tag— optional status badge:NEW,BETA, orDEPRECATED(e.g.tag: NEW). Quoting is inconsistent in-repo; either form works.noindex: true— rare, suppresses SEO indexing for a page.- These keys are locked from translation (
tag,openapi,api,iconini18n.json); the repair script restores them if a translation mangles them.
- Second person ("you"/"your") for the reader; imperative for instructions ("Go to", "Click", "Enter"); "we"/"our" only for the company's actions.
- Short, active sentences. Title Case for all headings.
- Typical page flow: optional hero
<Frame>image →<Info>/intro paragraph →<CardGroup>of related links → H2 sections (concept → how it works → API/config) → closing<CardGroup>. - Bold UI elements and dashboard paths (
**Settings → Business**,**Add Endpoint**). Backticks for params, fields, values, env vars (product_id,return_url). - Capitalize proper feature names: "Dodo Payments", "Merchant of Record", "Customer Portal", "Adaptive Currency".
Use Mintlify components, never raw HTML. Most used: <Steps>/<Step> (sequential setup), <CardGroup cols={2}>/<Card icon href> (nav, at top and bottom), <Tabs>/<Tab> and <CodeGroup> (multi-language code), <Info> <Tip> <Warning> <Note> <Check> callouts (Info most common), <AccordionGroup>/<Accordion> (FAQ/optional detail), <Frame> (images), <ParamField> (API fields). Mermaid diagrams appear in conceptual pages.
- Images: always
<Frame><img src="/images/<section>/<file>.png" alt="descriptive" style={{ maxHeight: '500px', width: 'auto' }} /></Frame>. Absolute/images/...paths, kebab-case filenames, never a bare<img>. - Code blocks: include a language tag; add
expandableafter it when >4 lines (```typescript expandable). Use<CodeGroup>to show the same thing in Node.js / Python / cURL; tag withlang Title(e.g.```typescript Node.js). - Links: internal links are absolute, extension-less paths (
/features/subscription,/api-reference/checkout-sessions/create) — notfeatures/subscription.mdx.
- Create
changelog/v<MAJOR>.<MINOR>.<PATCH>.mdxwithtitle: "v1.102.0 (Month DD, YYYY)"and the standard changelogkeywords. - Body sections:
## New Features,## Bug Fixes,## Breaking Changesas applicable. - Register it in
docs.jsonunder the right month group of the Changelog tab.
Translation is automated via lingo.dev (i18n.json config, i18n.lock checksums). English at root is the only source you edit.
- Full sync:
node scripts/syncAllLanguages.ts(needsOPENAI_API_KEY). It temporarily moves English content into anen/folder, runs lingo.dev, renames Lingo↔Mintlify codes (notezh-CN↔cn), repairs MDX, prunes orphaned/excluded files, updatesdocs.json, then moves English back. Flags:--dry-run,--skip-lingo,--skip-cleanup,--skip-addUpdate. - Triggered in CI by the manual
Sync Languagesworkflow (.github/workflows/sync-languages.yml), which opens async-languages-*PR. node scripts/validateAndRepairTranslations.ts— post-translation MDX repair (restores locked JSX tags, fixes split code fences, restores English-only frontmatter directives likeopenapi/tag/icon).--self-testruns its unit tests;--langs ar,esscopes it.node scripts/addUpdateLanguage.ts [lang...]— regenerates a locale's nav indocs.jsonfrom English, prefixing paths and dropping pages missing on disk.miscellaneous/faq.mdxis intentionally excluded from translation (seei18n.json+ script exclude lists).
node scripts/findMissingPages.ts— lists.mdxfiles not referenced indocs.json.node scripts/deleteNonIndexedPages.ts— deletes unreferenced.mdx. Safe by default;--dry-runto preview, requires--force/-fto actually delete. Be careful: it scans the whole repo including language folders.
seo.js injects global Organization + WebSite JSON-LD on all pages and a FAQPage schema parsed from the accordions on /miscellaneous/faq. docs.json holds the redirects array — add a redirect there whenever you rename or move a page (many existing /guides/* → new-path redirects show the pattern).
Mintlify runs Vale as a CI check on every PR. Config lives at .vale.ini (root) with the vocabulary at styles/config/vocabularies/Mintlify/accept.txt.
accept.txtis the allowlist. When a build flagsDid you really mean 'X'?for a legitimate product name, API field, or vendor, addXthere (case-sensitive — add each variant you use, e.g.Addonandaddon) rather than reword the docs. Keep it sorted case-insensitively.- Because the repo has its own
.vale.ini, Mintlify's built-in vocabulary is not loaded;accept.txtalready carries a copy of it. Don't remove those entries. - The 13 translated locale folders are excluded from linting — they're machine-generated, never hand-edited, and not English. Fix prose in the English source; the next sync propagates it.
- Run it locally with
vale .(needs Vale ≥ 3.10 for MDX).
- Always test with
mintlify devbefore committing; runmint validate/mintlify broken-linksfor link/MDX checks, andvale .for prose. - Commits follow conventional commits:
docs(...),fix(...),feat(...),style(...),refactor(...). - Deployment is automatic on push to
main(Mintlify). No build step to run locally. AGENTS.md,.github/,node_modules/are listed in.mintignore(excluded from the docs build).