i18n
defaultLocale is required. Requests for that locale omit ?locale=, because Strapi treats it as the default. Any other locale is sent as locale on the call, or as params.locale. The call option wins.
Creating a localization
create with a non-default locale cannot insert a localization on its own. Strapi requires it to be added to an existing default-locale document. The client looks that document up with filters, creates it when nothing matches, then PUTs the localized payload against its documentId.
const [err, frArticle] = await articles.create({
payload: { data: { title: "Article en français", body: "..." } },
locale: "fr",
filters: { slug: { $eq: "existing-slug" } },
});filters is how you identify which default-locale document the new localization belongs to. Omitting filters skips the lookup and always creates a fresh default-locale document before localizing it. The lookup uses only filters plus a forced page size of 1. The caller's params shape the response, not which document is the base.
The created base document is written with locale set to defaultLocale on the payload.
Updating and deleting one locale
await articles.update({
documentId: frArticle.documentId,
payload: { data: { title: "Updated" } },
locale: "fr",
});
await articles.delete({ documentId: frArticle.documentId, locale: "fr" });delete with locale removes only that localization. The default-locale document and the other localizations stay.
Single types take locale the same way, without a documentId. Users and uploads ignore locale: those routes do not have it.