API Reference
API Reference
GitHub
Templates

Languages

Manage the languages used for template localizations

The language registry is a per-project list of locale codes. It exists so the console can offer a fixed set of choices when you localize a template, rather than leaving every language a free-text field where pt-BR, pt_br and ptbr become three different locales by accident.

The registry does not decide what a send resolves

Which localization a send picks is decided by the template’s default_language field, not by this registry. Marking a language default here only preselects it in the console when you create a template — the console labels it Fallback for that reason. See Overview for the resolution order that actually runs.

The record

FieldTypeNotes
idstringUUID, minted on create
codestringThe locale code a localization references, 2-10 characters, lowercased on write
namestringWhat a person reads in the picker, up to 100 characters
is_defaultbooleanAt most one per project — setting it clears whichever language held it
created_attimestamp

Every route is project-scoped, so a session request needs the X-Mailyard-Project-Id header. An API key carries its project already and needs nothing extra.

Create

POST /api/v1/languages
curl -X POST http://localhost:3000/api/v1/languages \
  -H "Authorization: Bearer myk_..." \
  -H "Content-Type: application/json" \
  -d '{"code": "fr", "name": "French", "is_default": false}'

code and name are both required. The response is 201 with the stored record:

{
  "language": {
    "id": "0198f6a1-3c7e-7b21-9f4d-2a5c8e0b1d33",
    "code": "fr",
    "name": "French",
    "is_default": false,
    "created_at": "2026-01-01T00:00:00Z"
  }
}

A code already present in the project is refused with 409.

List

GET /api/v1/languages?limit=20

Replace

PUT /api/v1/languages/{id}

PUT replaces the whole record

This is not a partial update. code and name are required on every call, and omitting is_default sets it to false — which silently clears the project’s fallback if the language you are editing held it. Send the fields you want kept, not only the ones you want changed.

{ "code": "fr", "name": "Francais", "is_default": true }

Renaming a code onto one another language already uses is refused with 409.

Delete

DELETE /api/v1/languages/{id}

Returns 204. This removes the registry entry only. Localizations already written against that code keep their content and keep sending — they store the code as a string, not a reference. The effect is that the code stops being offered in the console.

Next

Localization covers writing the per-language content itself.