Locales
Open in
A locale is a language and region a product answers in. The file lists them, and every page, email and template is generated in each.
Names, fields, codes and prices never change between locales. Filled: what a reader sees.
What every locale gets
locales lists the languages, the first the default. Every Interface that prints words prints them in each.
| Family | What it does |
|---|---|
| The source text | The comments and descriptions in the file are the source; nothing else is typed twice |
| Translations | Generated for each locale at deploy into a file per locale beside the definition, reviewed as a diff, and corrected by a person or an agent |
| Names that never change | Nouns, fields, Verbs, Problem codes, paths and prices are the same in every locale, so code and agents never branch on language |
| Pages | The landing site, the portal and the docs under a path per locale, such as /de/, each with its Markdown twin and an llms.txt per locale |
| Replies | Accept-Language picks the locale of a reply's words: descriptions, a Problem's detail and its cure; Content-Language names it |
| Messages | Templates, notifications, receipts and invoices in each recipient's own preference, then the org's, then the default |
| Formats | Dates, times, numbers and amounts written the locale's way, in the Customer's timezone; prices stay in the currency settlement names |
| Scripts | Right-to-left languages laid out in every generated UI and email |
| Search | The words index of each Noun tokenises per language, so a search in German finds German text |
| Authored content | A Content item holds a version per locale, each drafted, reviewed and published on its own |
| Terms | The terms, privacy policy and DPA rendered per locale, with the default locale's text named as the one that governs |
Example
The company product answers in English, German and Canadian French.
import { define, secret } from 'apis.dev'
/** Any company by its domain, with its headcount and sector. */
export default define({
name: 'companyfacts', domain: 'companyfacts.apis.dev',
sources: { firms: { origin: 'https: //firms.example.com', key: secret('FIRMS_KEY') } },
Company: {
domain: { type: 'url!#', from: 'firms', map: 'website' },
employees: { type: 'number? ', from: 'firms', map: 'headcount' },
sector: { type: 'string? ', from: 'firms', map: 'industry' },
},
locales: ['en', 'de', 'fr-CA'], // the first is the default
offer: { 'Company.get': 0.002, 'Company.search': 0.005 },
})A miss asked in German answers in German; the code, the status and the price stay the same.
HTTP/1.1 404 Not Found
Content-Type: application/ problem+json
Content-Language: de
X-Cost: price= 0, currency= "USD"
X-Request-Id: req_4f2b7d01e9a63c58b0d6
{
"type": "https: //companyfacts.apis.dev/ docs/ errors#not_found",
"title": "Not Found",
"status": 404,
"detail": "Kein Unternehmen mit der Domain kestrel.example.",
"code": "not_found",
"instance": "req_4f2b7d01e9a63c58b0d6"
}Locales and translations, state by state
A translation is a line of the Version it ships in, so a rollback rolls it back too.
| Thing | States | What moves it |
|---|---|---|
| A locale | declared, translating, reviewed, live | A deploy that adds it; its review; the next deploy serves it on every Interface at once |
| A translated line | generated, reviewed, corrected, then stale when its source changes | Each deploy; a reviewer; a correction is a diff like any other |
| A page in a locale | current, stale | Its lines; a stale page serves the default locale's line in its place and says so |
| A content item's locale version | drafted, reviewed, published, withdrawn | Its author and reviewer, as any authored item |
What readers, members and agents meet
- A reader. The site, the docs and every email in its own language, with dates and amounts written its way.
- A member. The portal and every UI in its own preference, set once, on every device.
- A developer. One set of names and codes whatever the language, and docs that read naturally in its own.
- An agent.
Accept-Languagefor words it shows a person, and names it never has to translate.
Every locale is generated from the file's own words, so a page, a Problem and an email say the same thing in every language.
Agent calls, streams and bulk jobs
The shapes a call takes past one request: agent-to-agent calls as Actions, output streamed as it is written, bulk jobs, large files and SDK releases.
What every product gets
Everything around your API, live on your own domain from one deploy: CLI, MCP, SDKs, docs, a landing site, a portal and Stripe billing.