{
    "openapi": "3.1.0",
    "info": {
        "title": "Tolk API",
        "version": "1.0.0",
        "description": "The Tolk API lets a project read and write its keys and translations from code: the `everyday-nl/tolk-laravel` package, a GitHub Action or your own scripts.\n\n## Base URL and versioning\n\nAll endpoints live on their own domain, with the version in the path:\n\n```\nhttps://api.tolk.every-day.io/v1\n```\n\nThere is no API on the app domain. Breaking changes only ever come in a new version (`/v2`); within `/v1`, fields and endpoints are only added.\n\n## Authentication\n\nEvery request needs a project token in the `Authorization` header:\n\n```\ncurl https://api.tolk.every-day.io/v1/project \\\n  -H \"Authorization: Bearer $TOLK_TOKEN\"\n```\n\nA manager creates tokens under _Settings \u00b7 API tokens_ of the project. The token is shown once; Tolk only stores its hash. The project follows from the token: there is no project in the URL, and a `?project=` parameter is ignored.\n\n- **Scopes.** A token always has `read` and optionally `write`. The reading endpoints need `read`; `PATCH /keys/{keyHash}`, `POST /keys/diff`, `POST /keys/sync`, `PUT /translations/{locale}` and `POST /imports` need `write`.\n- **401** \u2013 no token, a malformed, unknown, expired or revoked token, or the project or its customer was deleted.\n- **403** \u2013 the token lacks the scope of the endpoint, or the project is archived (a token of an archived project works again once the project is restored).\n- **Rate limit.** 120 requests per minute per token. Every answer carries `X-RateLimit-Limit` and `X-RateLimit-Remaining`; above the limit the answer is `429` with `Retry-After` (seconds). Before the token is checked, every client IP address may send 600 requests per minute, with a valid token or not; above that the answer is also `429` with `Retry-After`.\n\n## Conventions\n\n- **JSON only.** Every answer is JSON, also an error and an unknown URL, with or without an `Accept` header. The one exception is the file of `GET /exports/{profileKey}`.\n- **Envelope.** One object is `{\"data\": {\u2026}}`. A list is `{\"data\": [\u2026], \"meta\": {\"nextCursor\": \"\u2026\", \"limit\": 500}}`.\n- **Fields** are camelCase. **Dates** are ISO 8601 in UTC: `2026-10-07T12:00:00Z`.\n- **Errors** are `{\"message\": \"\u2026\"}`; a validation error (`422`) adds `errors` per field, with the index of a list item in the field name: `{\"message\": \"\u2026\", \"errors\": {\"keys.12.value\": [\"\u2026\"]}}`.\n- **Conflicts.** A `409` means the project is busy and the request can be repeated: `{\"message\": \"\u2026\", \"reason\": \"source_language_change\"}` while the source language of the project is being changed, `\"reason\": \"busy\"` when another writer holds the lock.\n- **Language.** Messages follow `Accept-Language` (`nl` or `en`, default `nl`). This documentation is in English.\n\n### Pagination\n\nLists (`GET /keys`, `GET /translations/{locale}`) use an opaque cursor and are ordered by key:\n\n1. Request the first page, optionally with `limit` (1\u20131000, default 500).\n2. As long as `meta.nextCursor` is not `null`, request the next page with `cursor=<meta.nextCursor>` and the same filters.\n\nA cursor that Tolk cannot read gives `422` on the field `cursor`. Never build a cursor yourself.\n\n## Key identity\n\nA key is identified by its `hash`, so a key with a sentence as its name never has to be put in a URL. The package computes both hashes locally:\n\n- `hash` = SHA-1 (lowercase hex) of `namespace + \"\\x1F\" + key + \"\\x1F\" + (context ?? \"\")`. The separator is the unit separator `U+001F`. The namespace of a key without one is `*`. An empty context and no context give the same hash.\n- `sourceHash` = SHA-1 of the source text; for a plural key the SHA-1 of the JSON of the forms sorted by category (UTF-8 unescaped, e.g. `{\"one\":\"E\u00e9n artikel\",\"other\":\":count artikelen\"}`); `null` without a source text.\n\nExamples:\n\n| Input                                                                           | Hash                                       |\n| ------------------------------------------------------------------------------- | ------------------------------------------ |\n| `hash` of namespace `*`, key `Pay now`, no context                              | `0e5e60b24eff16607ccbb7dbbe7141b7a0c5de48` |\n| `hash` of namespace `checkout`, key `Order`, context `noun`                     | `6a769493d0f894ecd2d4bb324ac5113a61056602` |\n| `sourceHash` of `Nu betalen`                                                    | `09269d72c5af31fb3cc4752832089843eaaeb603` |\n| `sourceHash` of the forms `{\"one\": \"E\u00e9n artikel\", \"other\": \":count artikelen\"}` | `8d7fabf1eb21b47eac0cf2d9a47e340abf7a51b8` |\n\n### Pushing keys\n\n1. `POST /keys/diff` with the `hash` and `sourceHash` of every local key: Tolk answers which hashes are `new`, `changed` (another source text) or `restored` (archived in Tolk), and how many are unchanged. The diff changes nothing.\n2. `POST /keys/sync` with only the new, changed and restored keys (with their source text). A sync is idempotent: repeating it after a `409` finishes the job.\n3. To archive the keys that disappeared from the code, page through `GET /keys`, compare the hashes with the local ones and send the missing ones in `archive` of a sync.\n\n## Imports, exports and jobs\n\nLong work runs as a job. An answer `202 Accepted` holds the job (`{\"data\": {\"id\": 42, \"type\": \"import\", \"status\": \"queued\", \u2026}}`) and a `Location` header with its URL: poll `GET /jobs/{jobId}` until `status` is `succeeded` or `failed`. A failed job has `error`: a stable `code` (such as `needs_mapping` or `zip_slip`) and a `message`.\n\n- **Import.** `POST /imports` takes `multipart/form-data` with `files[]` (JSON, PHP, PO, MO, CSV, XLSX, XLIFF or a zip of them) and optionally `locale`, `format`, `namespace`, `overwrite` (`1`/`0`, default `0`), `createUnknownKeys` (default `1`) and `tag`. Tolk recognises the format, language and namespace from each path, as the import dialog does, and imports without a preview. An unsafe or unreadable upload is a `422` on `files.N` and nothing is stored. A spreadsheet needs a column mapping saved as a preset in Tolk.\n\n```\ncurl https://api.tolk.every-day.io/v1/imports \\\n  -H \"Authorization: Bearer $TOLK_TOKEN\" \\\n  -F \"files[]=@lang/de.json\" -F \"overwrite=1\"\n```\n\n- **Export.** `GET /exports/{profileKey}` answers the file of an export profile (`GET /project` lists them under `exportProfiles`), optionally for `locales` (a comma list) and with `missing` (`fallback`, `empty` or `omit`). Keep the `ETag` and send it back as `If-None-Match`: an unchanged export is a `304` without a body. The ETag is the hash of the bytes, so a change that does not alter the file keeps it. A large export that is not built yet is a `202` with a job; fetch the export again once the job succeeded.\n\n```\ncurl https://api.tolk.every-day.io/v1/exports/laravel-json?locales=de,fr \\\n  -H \"Authorization: Bearer $TOLK_TOKEN\" \\\n  -H 'If-None-Match: \"<etag of the previous download>\"' -o lang.zip\n```\n\n## Webhooks\n\nA manager adds webhooks under _Settings \u00b7 Webhooks_. Tolk sends a `POST` with a JSON body to the URL for every event the webhook follows:\n\n```json\n{\n    \"id\": \"0f9c2b5e-\u2026\",\n    \"event\": \"keys.synced\",\n    \"createdAt\": \"2026-10-07T12:00:00Z\",\n    \"project\": { \"slug\": \"webshop\", \"name\": \"Webshop\" },\n    \"data\": { \"created\": 12, \"updated\": 3, \"restored\": 0, \"archived\": 1 }\n}\n```\n\nEvery delivery has these headers:\n\n- `X-Tolk-Event` \u2013 the event;\n- `X-Tolk-Delivery` \u2013 the id of the delivery (also `id` in the body; a retry keeps it, so it deduplicates);\n- `X-Tolk-Timestamp` \u2013 the moment of this attempt, in Unix seconds;\n- `X-Tolk-Signature` \u2013 `sha256=` followed by the lowercase hex HMAC-SHA256, with the secret of the webhook, over `<timestamp>.<body>`.\n\nTo verify a delivery: refuse a timestamp more than 300 seconds from your clock, compute the HMAC over the timestamp, a dot and the raw body, and compare it with the signature in constant time. Answer with a `2xx` within 5 seconds (Tolk does not wait longer and follows no redirects); any other answer, or none, is retried with a growing delay. A delivery can arrive more than once.\n\nThe payloads carry counters and locales, never texts or keys: fetch the content through the API.\n\n| Event                  | When                                                         | `data`                                                                                                                                         |\n| ---------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |\n| `translations.updated` | translations changed; at most once per 5 minutes per project | `{\"contentVersion\": 1234, \"since\": \"2026-10-07T12:00:00Z\", \"languages\": [{\"locale\": \"de\", \"translated\": 1544, \"total\": 2412, \"percent\": 64}]}` |\n| `language.completed`   | a target language reaches 100%                               | `{\"language\": {\"locale\": \"de\", \"name\": \"Deutsch\", \"translated\": 2412, \"total\": 2412}}`                                                         |\n| `keys.synced`          | a sync created, changed or restored keys                     | `{\"created\": 12, \"updated\": 3, \"restored\": 0, \"archived\": 1}`                                                                                  |\n| `import.finished`      | an import succeeded or failed                                | see below                                                                                                                                      |\n| `ai_job.finished`      | an AI translation job ended                                  | see below                                                                                                                                      |\n\n`import.finished` names the job of `GET /jobs/{jobId}` and the counters of the import (`result` is `null` when it failed; `error.code` is the code of the job):\n\n```json\n{\n    \"job\": {\n        \"id\": 42,\n        \"type\": \"import\",\n        \"status\": \"succeeded\",\n        \"error\": null,\n        \"finishedAt\": \"2026-10-07T12:00:00Z\"\n    },\n    \"import\": {\n        \"id\": 7,\n        \"locales\": [\"de\"],\n        \"result\": {\n            \"newKeys\": 3,\n            \"newTranslations\": 412,\n            \"changedTranslations\": 0,\n            \"unchanged\": 1544,\n            \"skipped\": 2,\n            \"placeholderErrors\": 1\n        }\n    }\n}\n```\n\n`ai_job.finished` has the outcome of an AI translation job, without costs; `status` is `completed`, `failed`, `cancelled` or `budget_exceeded`:\n\n```json\n{\n    \"job\": {\n        \"id\": 17,\n        \"locale\": \"de\",\n        \"status\": \"completed\",\n        \"mode\": \"direct\",\n        \"scope\": \"untranslated\",\n        \"error\": null,\n        \"totalItems\": 960,\n        \"translatedItems\": 950,\n        \"flaggedItems\": 3,\n        \"failedItems\": 0,\n        \"skippedItems\": 7,\n        \"startedAt\": \"2026-10-07T11:58:00Z\",\n        \"finishedAt\": \"2026-10-07T12:00:00Z\"\n    }\n}\n```\n"
    },
    "servers": [
        {
            "url": "https://api.tolk.every-day.io/v1",
            "description": "Tolk API"
        }
    ],
    "security": [
        {
            "bearer": []
        }
    ],
    "paths": {
        "/exports/{profileKey}": {
            "get": {
                "operationId": "v1.exports.show",
                "description": "The export of a profile (`GET /v1/project` lists them) in the languages of `locales` (a comma list; default: the\nlanguages of the profile, else every language of the project), with `missing` deciding what a missing\ntranslation becomes (default: the choice of the profile). The answer is the file with its `ETag`; send that back\nin `If-None-Match` (also weak, in a list, or `*`) and an unchanged export is a `304` without a body. A large\nexport that is not built yet is a `202` with a job: poll `GET /v1/jobs/{jobId}` until it succeeded and fetch the\nexport again.",
                "summary": "Download an export",
                "tags": [
                    "Exports"
                ],
                "parameters": [
                    {
                        "name": "profileKey",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "locales",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "maxLength": 1000
                        }
                    },
                    {
                        "name": "missing",
                        "in": "query",
                        "schema": {
                            "anyOf": [
                                {
                                    "$ref": "#/components/schemas/MissingTranslations"
                                },
                                {
                                    "type": "null"
                                }
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The file of the export, with the media type of its format (`application/json`, `text/x-php`, `application/zip`, \u2026).",
                        "content": {
                            "*/*": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        },
                        "headers": {
                            "ETag": {
                                "description": "The strong ETag of the bytes (sha256); send it back in `If-None-Match`.",
                                "required": true,
                                "schema": {
                                    "type": "string"
                                }
                            },
                            "Content-Disposition": {
                                "description": "The file name: `attachment; filename=\"\u2026\"`.",
                                "required": true,
                                "schema": {
                                    "type": "string"
                                }
                            },
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "The work is queued as a job: follow it at the `Location` (`GET /v1/jobs/{jobId}`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiJobResponse"
                                }
                            }
                        },
                        "headers": {
                            "Location": {
                                "description": "The URL of the job.",
                                "required": true,
                                "schema": {
                                    "type": "string"
                                }
                            },
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "304": {
                        "description": "Not modified: the `ETag` in `If-None-Match` is still the current one. No body.",
                        "headers": {
                            "ETag": {
                                "description": "The strong ETag of the bytes (sha256); send it back in `If-None-Match`.",
                                "required": true,
                                "schema": {
                                    "type": "string"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found in the project of the token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error: the messages per field (`keys.12.value`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/imports": {
            "post": {
                "operationId": "v1.imports.store",
                "description": "Uploads translation files (`multipart/form-data`, `files[]`: JSON, PHP, PO, MO, CSV, XLSX, XLIFF or a zip of them)\nand imports them without a preview, as dialog 10 would after confirming: the format, namespace and language are\nrecognised from each path unless the request forces them. A file that is refused (unsafe archive, wrong contents\nfor its extension, too large) is a `422` on `files.N` and nothing is stored. Otherwise the answer is `202` with\nthe job and its `Location`: follow it with `GET /v1/jobs/{jobId}`. A spreadsheet needs a saved column mapping\n(a preset with the same header row); without one the job fails with `needs_mapping`. A preset without a\nlanguage column only creates keys (with `createUnknownKeys`), and such a spreadsheet cannot be imported together\nwith translations: the job fails with `keys_only_mixed`. An import of more than\n50.000 lines (keys \u00d7 languages over all files, `TOLK_IMPORT_MAX_LINES`) fails with `too_many_lines`: split it.",
                "summary": "Import files",
                "tags": [
                    "Imports"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "$ref": "#/components/schemas/ImportUploadData"
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "The work is queued as a job: follow it at the `Location` (`GET /v1/jobs/{jobId}`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiJobResponse"
                                }
                            }
                        },
                        "headers": {
                            "Location": {
                                "description": "The URL of the job.",
                                "required": true,
                                "schema": {
                                    "type": "string"
                                }
                            },
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error: the messages per field (`keys.12.value`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/jobs/{jobId}": {
            "get": {
                "operationId": "v1.jobs.show",
                "description": "An import (`POST /v1/imports`) or export (`GET /v1/exports/{profileKey}`) job of the project: its status\n(`queued`, `running`, `succeeded`, `failed`), its progress, its result once it succeeded and the reason once it\nfailed. Poll it until it is `succeeded` or `failed`; for an export, fetch the export again for the file.",
                "summary": "Get a job",
                "tags": [
                    "Jobs"
                ],
                "parameters": [
                    {
                        "name": "jobId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiJobResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found in the project of the token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/keys": {
            "get": {
                "operationId": "v1.keys.index",
                "description": "One page of the keys of the project, ordered by their id, with the cursor of the next page. Filters on\nnamespace, tag name (`untagged`: keys without a tag), archived state and last change.",
                "summary": "List the keys",
                "tags": [
                    "Keys"
                ],
                "parameters": [
                    {
                        "name": "namespace",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "maxLength": 191
                        }
                    },
                    {
                        "name": "tag",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "maxLength": 50
                        }
                    },
                    {
                        "name": "archived",
                        "in": "query",
                        "schema": {
                            "$ref": "#/components/schemas/ArchivedFilter"
                        }
                    },
                    {
                        "name": "updatedSince",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ]
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "maxLength": 200
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "minimum": 1,
                            "maximum": 1000
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiKeyListResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error: the messages per field (`keys.12.value`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/keys/{keyHash}": {
            "patch": {
                "operationId": "v1.keys.update",
                "description": "Changes the description, the maximum length or the tags (the new set) of the key with this hash. A field that\nis left out stays as it is; `null` clears the description or the maximum length.",
                "summary": "Update a key",
                "tags": [
                    "Keys"
                ],
                "parameters": [
                    {
                        "name": "keyHash",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/KeyUpdateData"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiKeyResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found in the project of the token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The project is busy: a source-language change is running, or another writer holds the lock. Try again.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "reason": {
                                            "type": "string",
                                            "enum": [
                                                "source_language_change",
                                                "busy"
                                            ]
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "reason"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error: the messages per field (`keys.12.value`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/keys/diff": {
            "post": {
                "operationId": "v1.keys.diff",
                "description": "Tells which of the sent hashes are new, changed (another source hash), archived or unchanged, without\nchanging anything.",
                "summary": "Compare key hashes",
                "tags": [
                    "KeysDiff"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/KeysDiffData"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiKeysDiffResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error: the messages per field (`keys.12.value`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/keys/sync": {
            "post": {
                "operationId": "v1.keys.sync",
                "description": "Creates and updates the sent keys with their source text and archives the sent hashes. Tags are added, never\nremoved. A key that would change between singular and plural is refused per item (`plural_changed`). The\nsame sync twice changes nothing the second time. When the new and restored keys would take the customer over\nits key limit, nothing is written and the answer is a `422` with `reason: key_limit_reached`.",
                "summary": "Synchronise keys",
                "tags": [
                    "KeysSync"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/KeysSyncData"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiKeysSyncResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The project is busy: a source-language change is running, or another writer holds the lock. Try again.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "reason": {
                                            "type": "string",
                                            "enum": [
                                                "source_language_change",
                                                "busy"
                                            ]
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "reason"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error: the messages per field (`keys.12.value`). When the new and restored keys do not fit the key limit of the customer, also `reason: key_limit_reached` with the limit, the keys in use and the keys the sync would add.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        },
                                        "reason": {
                                            "type": "string",
                                            "enum": [
                                                "key_limit_reached"
                                            ]
                                        },
                                        "limit": {
                                            "type": "integer"
                                        },
                                        "used": {
                                            "type": "integer"
                                        },
                                        "requested": {
                                            "type": "integer"
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/project": {
            "get": {
                "operationId": "v1.project",
                "description": "The project of the token: its slug, name and type, the source locale, the content version and the languages\n(the source first). There is no project in the URL: the token decides.",
                "summary": "Get the project",
                "tags": [
                    "Project"
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiProjectResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/stats": {
            "get": {
                "operationId": "v1.stats",
                "description": "The counters of every language of the project (the source first): keys, translated, outdated, placeholder\nerrors and the rounded percentage, plus the content version of the project.",
                "summary": "Get the progress per language",
                "tags": [
                    "Stats"
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiStatsResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/translations/{locale}": {
            "get": {
                "operationId": "v1.translations.show",
                "description": "One page of the active keys of the project with their translation in this language, ordered by key id, also\nthe keys without a translation yet (`value`, `forms` and `version` are then `null`). The source language can be\nread too. Filter on status, namespace, tag name (`untagged` for keys without a tag) and the last change of the\ntranslation; follow `meta.nextCursor` for the next page.",
                "summary": "List the translations of a language",
                "tags": [
                    "Translations"
                ],
                "parameters": [
                    {
                        "name": "locale",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "$ref": "#/components/schemas/TranslationStatusFilter"
                        }
                    },
                    {
                        "name": "namespace",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "maxLength": 191
                        }
                    },
                    {
                        "name": "tag",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "maxLength": 50
                        }
                    },
                    {
                        "name": "updatedSince",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ]
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "schema": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "maxLength": 200
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "minimum": 1,
                            "maximum": 1000
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiTranslationListResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found in the project of the token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error: the messages per field (`keys.12.value`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            },
            "put": {
                "operationId": "v1.translations.update",
                "description": "Writes at most one block of translations of a target language, overwriting (`overwrite`) or only filling empty\nones (`fill_empty`). An empty `value` clears a translation; `version` refuses the item when the translation\nchanged since it was read. Items that are not written come back in `skipped` with the reason; placeholder errors\ndo not block a write and come back in `issues`. The source language is not writable: its texts change through\n`POST /keys/sync`.",
                "summary": "Write translations of a language",
                "tags": [
                    "Translations"
                ],
                "parameters": [
                    {
                        "name": "locale",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/TranslationsUpdateData"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/ApiTranslationsUpdateResponse"
                                }
                            }
                        },
                        "headers": {
                            "X-RateLimit-Limit": {
                                "description": "Requests per minute of the token.",
                                "schema": {
                                    "type": "integer"
                                }
                            },
                            "X-RateLimit-Remaining": {
                                "description": "Requests left in the current minute.",
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthenticated: no token, or an invalid, expired or revoked token, or the project or its customer was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The token lacks the scope of this endpoint, or the project is archived.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Not found in the project of the token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The project is busy: a source-language change is running, or another writer holds the lock. Try again.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "reason": {
                                            "type": "string",
                                            "enum": [
                                                "source_language_change",
                                                "busy"
                                            ]
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "reason"
                                    ]
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error: the messages per field (`keys.12.value`).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    },
                                    "required": [
                                        "message",
                                        "errors"
                                    ]
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests: the rate limit of the token is reached.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string"
                                        }
                                    },
                                    "required": [
                                        "message"
                                    ]
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds until the next request is allowed.",
                                "required": true,
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearer": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "tolk_\u2026"
            }
        },
        "schemas": {
            "ApiCursorMetaData": {
                "type": "object",
                "properties": {
                    "nextCursor": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "limit": {
                        "type": "integer"
                    }
                },
                "required": [
                    "nextCursor",
                    "limit"
                ],
                "title": "ApiCursorMetaData"
            },
            "ApiExportProfileData": {
                "type": "object",
                "properties": {
                    "slug": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "format": {
                        "$ref": "#/components/schemas/Format"
                    },
                    "locales": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    }
                },
                "required": [
                    "slug",
                    "name",
                    "format",
                    "locales"
                ],
                "title": "ApiExportProfileData"
            },
            "ApiIssueData": {
                "type": "object",
                "properties": {
                    "rule": {
                        "$ref": "#/components/schemas/PlaceholderRule"
                    },
                    "level": {
                        "$ref": "#/components/schemas/IssueLevel"
                    },
                    "placeholder": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "form": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "suggestion": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "rule",
                    "level",
                    "placeholder",
                    "form",
                    "suggestion"
                ],
                "title": "ApiIssueData"
            },
            "ApiJobData": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "import",
                            "export"
                        ]
                    },
                    "status": {
                        "$ref": "#/components/schemas/TrackedJobStatus"
                    },
                    "progress": {
                        "$ref": "#/components/schemas/ApiJobProgressData"
                    },
                    "result": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "additionalProperties": {
                            "type": [
                                "integer",
                                "string",
                                "boolean"
                            ]
                        }
                    },
                    "error": {
                        "anyOf": [
                            {
                                "$ref": "#/components/schemas/ApiJobErrorData"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "createdAt": {
                        "type": "string"
                    },
                    "startedAt": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "finishedAt": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "id",
                    "type",
                    "status",
                    "progress",
                    "result",
                    "error",
                    "createdAt",
                    "startedAt",
                    "finishedAt"
                ],
                "title": "ApiJobData"
            },
            "ApiJobErrorData": {
                "type": "object",
                "properties": {
                    "code": {
                        "type": "string"
                    },
                    "message": {
                        "type": "string"
                    }
                },
                "required": [
                    "code",
                    "message"
                ],
                "title": "ApiJobErrorData"
            },
            "ApiJobProgressData": {
                "type": "object",
                "properties": {
                    "done": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "integer"
                    }
                },
                "required": [
                    "done",
                    "total"
                ],
                "title": "ApiJobProgressData"
            },
            "ApiJobResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/ApiJobData"
                    }
                },
                "required": [
                    "data"
                ],
                "title": "ApiJobResponse"
            },
            "ApiKeyData": {
                "type": "object",
                "properties": {
                    "hash": {
                        "type": "string"
                    },
                    "namespace": {
                        "type": "string"
                    },
                    "key": {
                        "type": "string"
                    },
                    "context": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "isPlural": {
                        "type": "boolean"
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "maxLength": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "sourceHash": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "source": {
                        "anyOf": [
                            {
                                "$ref": "#/components/schemas/ApiTextData"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "archived": {
                        "type": "boolean"
                    },
                    "updatedAt": {
                        "type": "string"
                    }
                },
                "required": [
                    "hash",
                    "namespace",
                    "key",
                    "context",
                    "isPlural",
                    "description",
                    "maxLength",
                    "sourceHash",
                    "source",
                    "tags",
                    "archived",
                    "updatedAt"
                ],
                "title": "ApiKeyData"
            },
            "ApiKeyListResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiKeyData"
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/ApiCursorMetaData"
                    }
                },
                "required": [
                    "data",
                    "meta"
                ],
                "title": "ApiKeyListResponse"
            },
            "ApiKeyResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/ApiKeyData"
                    }
                },
                "required": [
                    "data"
                ],
                "title": "ApiKeyResponse"
            },
            "ApiKeySyncRejectionData": {
                "type": "object",
                "properties": {
                    "hash": {
                        "type": "string"
                    },
                    "reason": {
                        "type": "string",
                        "const": "plural_changed"
                    }
                },
                "required": [
                    "hash",
                    "reason"
                ],
                "title": "ApiKeySyncRejectionData"
            },
            "ApiKeysDiffData": {
                "type": "object",
                "properties": {
                    "new": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "changed": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "restored": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "unchanged": {
                        "type": "integer"
                    }
                },
                "required": [
                    "new",
                    "changed",
                    "restored",
                    "unchanged"
                ],
                "title": "ApiKeysDiffData"
            },
            "ApiKeysDiffResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/ApiKeysDiffData"
                    }
                },
                "required": [
                    "data"
                ],
                "title": "ApiKeysDiffResponse"
            },
            "ApiKeysSyncResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/ApiKeysSyncResultData"
                    }
                },
                "required": [
                    "data"
                ],
                "title": "ApiKeysSyncResponse"
            },
            "ApiKeysSyncResultData": {
                "type": "object",
                "properties": {
                    "created": {
                        "type": "integer"
                    },
                    "updated": {
                        "type": "integer"
                    },
                    "restored": {
                        "type": "integer"
                    },
                    "unchanged": {
                        "type": "integer"
                    },
                    "archived": {
                        "type": "integer"
                    },
                    "rejected": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiKeySyncRejectionData"
                        }
                    }
                },
                "required": [
                    "created",
                    "updated",
                    "restored",
                    "unchanged",
                    "archived",
                    "rejected"
                ],
                "title": "ApiKeysSyncResultData"
            },
            "ApiProjectData": {
                "type": "object",
                "properties": {
                    "slug": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "type": {
                        "$ref": "#/components/schemas/ProjectType"
                    },
                    "sourceLocale": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "contentVersion": {
                        "type": "integer"
                    },
                    "languages": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiProjectLanguageData"
                        }
                    },
                    "exportProfiles": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiExportProfileData"
                        }
                    }
                },
                "required": [
                    "slug",
                    "name",
                    "type",
                    "sourceLocale",
                    "contentVersion",
                    "languages",
                    "exportProfiles"
                ],
                "title": "ApiProjectData"
            },
            "ApiProjectLanguageData": {
                "type": "object",
                "properties": {
                    "locale": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "isRtl": {
                        "type": "boolean"
                    },
                    "fallback": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "locale",
                    "name",
                    "isRtl",
                    "fallback"
                ],
                "title": "ApiProjectLanguageData"
            },
            "ApiProjectResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/ApiProjectData"
                    }
                },
                "required": [
                    "data"
                ],
                "title": "ApiProjectResponse"
            },
            "ApiStatsData": {
                "type": "object",
                "properties": {
                    "contentVersion": {
                        "type": "integer"
                    },
                    "languages": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiStatsLanguageData"
                        }
                    }
                },
                "required": [
                    "contentVersion",
                    "languages"
                ],
                "title": "ApiStatsData"
            },
            "ApiStatsLanguageData": {
                "type": "object",
                "properties": {
                    "locale": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "isSource": {
                        "type": "boolean"
                    },
                    "totalKeys": {
                        "type": "integer"
                    },
                    "translated": {
                        "type": "integer"
                    },
                    "outdated": {
                        "type": "integer"
                    },
                    "qaErrors": {
                        "type": "integer"
                    },
                    "percent": {
                        "type": "integer"
                    },
                    "lastTranslatedAt": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "locale",
                    "name",
                    "isSource",
                    "totalKeys",
                    "translated",
                    "outdated",
                    "qaErrors",
                    "percent",
                    "lastTranslatedAt"
                ],
                "title": "ApiStatsLanguageData"
            },
            "ApiStatsResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/ApiStatsData"
                    }
                },
                "required": [
                    "data"
                ],
                "title": "ApiStatsResponse"
            },
            "ApiTextData": {
                "type": "object",
                "properties": {
                    "value": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "forms": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "additionalProperties": {
                            "type": "string"
                        }
                    }
                },
                "required": [
                    "value",
                    "forms"
                ],
                "title": "ApiTextData"
            },
            "ApiTranslationData": {
                "type": "object",
                "properties": {
                    "hash": {
                        "type": "string"
                    },
                    "namespace": {
                        "type": "string"
                    },
                    "key": {
                        "type": "string"
                    },
                    "context": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "isPlural": {
                        "type": "boolean"
                    },
                    "value": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "forms": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "additionalProperties": {
                            "type": "string"
                        }
                    },
                    "isTranslated": {
                        "type": "boolean"
                    },
                    "isOutdated": {
                        "type": "boolean"
                    },
                    "issues": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiIssueData"
                        }
                    },
                    "version": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "updatedAt": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "hash",
                    "namespace",
                    "key",
                    "context",
                    "isPlural",
                    "value",
                    "forms",
                    "isTranslated",
                    "isOutdated",
                    "issues",
                    "version",
                    "updatedAt"
                ],
                "title": "ApiTranslationData"
            },
            "ApiTranslationIssuesData": {
                "type": "object",
                "properties": {
                    "hash": {
                        "type": "string"
                    },
                    "rules": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/PlaceholderRule"
                        }
                    }
                },
                "required": [
                    "hash",
                    "rules"
                ],
                "title": "ApiTranslationIssuesData"
            },
            "ApiTranslationListResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiTranslationData"
                        }
                    },
                    "meta": {
                        "$ref": "#/components/schemas/ApiCursorMetaData"
                    }
                },
                "required": [
                    "data",
                    "meta"
                ],
                "title": "ApiTranslationListResponse"
            },
            "ApiTranslationSkipData": {
                "type": "object",
                "properties": {
                    "hash": {
                        "type": "string"
                    },
                    "reason": {
                        "type": "string",
                        "enum": [
                            "unknown",
                            "archived",
                            "conflict",
                            "translated",
                            "plural_mismatch"
                        ]
                    },
                    "currentVersion": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    }
                },
                "required": [
                    "hash",
                    "reason",
                    "currentVersion"
                ],
                "title": "ApiTranslationSkipData"
            },
            "ApiTranslationsUpdateResponse": {
                "type": "object",
                "properties": {
                    "data": {
                        "$ref": "#/components/schemas/ApiTranslationsUpdateResultData"
                    }
                },
                "required": [
                    "data"
                ],
                "title": "ApiTranslationsUpdateResponse"
            },
            "ApiTranslationsUpdateResultData": {
                "type": "object",
                "properties": {
                    "updated": {
                        "type": "integer"
                    },
                    "cleared": {
                        "type": "integer"
                    },
                    "unchanged": {
                        "type": "integer"
                    },
                    "skipped": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiTranslationSkipData"
                        }
                    },
                    "issues": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ApiTranslationIssuesData"
                        }
                    }
                },
                "required": [
                    "updated",
                    "cleared",
                    "unchanged",
                    "skipped",
                    "issues"
                ],
                "title": "ApiTranslationsUpdateResultData"
            },
            "App.Modules.Api.Data.V1.ImportUploadData": {
                "type": "object",
                "description": "The multipart input of `POST /v1/imports`: the files under the upload rules (each at most\n`api.imports.max_kilobytes`), the language of files without a language in their path (else the recognised one,\nthen the source language), a format and a namespace that override the recognition, and the import choices.\nBooleans are sent as `1` or `0`.",
                "properties": {
                    "files": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "format": "binary",
                            "contentMediaType": "application/octet-stream",
                            "description": "Maximum file size: 51200 kilobytes. Maximum file size: 51200 kilobytes."
                        },
                        "minItems": 1,
                        "maxItems": 20
                    },
                    "format": {
                        "type": "string"
                    },
                    "namespace": {
                        "type": "string",
                        "pattern": "^[^\\x04\\x1F\\r\\n]+$",
                        "minLength": 1
                    },
                    "tag": {
                        "type": "string",
                        "pattern": "^[^,\\r\\n]+$"
                    }
                },
                "required": [
                    "files"
                ],
                "title": "App.Modules.Api.Data.V1.ImportUploadData"
            },
            "App.Modules.Api.Data.V1.KeyUpdateData": {
                "type": "object",
                "description": "The body of `PATCH /v1/keys/{keyHash}`: the description (`null` clears it), the maximum length\n(`null` clears it) and the tags (replace the set). Every field is optional; a field that is left out stays as it\nis, but at least one is given (else a 422 on `fields`). The tags are at most `api.keys.tags_per_key` names with\nthe rules of a tag name, distinct without regard to letter case.",
                "properties": {
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "uniqueItems": true
                    }
                },
                "title": "App.Modules.Api.Data.V1.KeyUpdateData"
            },
            "App.Modules.Api.Data.V1.KeysDiffData": {
                "type": "object",
                "description": "The body of `POST /v1/keys/diff`: the hashes of the keys the package knows, each with the\nhash of its source text (`null` without one). At most `api.keys.diff_max_items`; the items are validated in one\npass by one rule for the whole list.",
                "properties": {
                    "keys": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 10000
                    }
                },
                "required": [
                    "keys"
                ],
                "title": "App.Modules.Api.Data.V1.KeysDiffData"
            },
            "App.Modules.Api.Data.V1.KeysSyncData": {
                "type": "object",
                "description": "The body of `POST /v1/keys/sync`: the keys with their source text (exactly one of `value` and\n`forms`) and the hashes to archive, together at least one. The items are validated in one pass by one rule per\nlist, against the source language and the tags of the project of\nthe token.",
                "properties": {
                    "keys": {
                        "type": "string",
                        "maxLength": 5000
                    },
                    "archive": {
                        "type": "string",
                        "maxLength": 5000
                    }
                },
                "title": "App.Modules.Api.Data.V1.KeysSyncData"
            },
            "ArchivedFilter": {
                "type": "string",
                "description": "Which keys `GET /v1/keys` lists: only active keys (the default), active and archived keys, or only archived keys.\n",
                "enum": [
                    "exclude",
                    "include",
                    "only"
                ],
                "title": "ArchivedFilter"
            },
            "Format": {
                "type": "string",
                "description": "The import and export formats with their capabilities: the registry of readers and writers. A new format is a case here, a reader and/or a writer and golden-file tests.\n",
                "enum": [
                    "laravel_php",
                    "laravel_json",
                    "json_js",
                    "js_module",
                    "po",
                    "pot",
                    "mo",
                    "wordpress_php",
                    "wordpress_jed",
                    "csv",
                    "xlsx",
                    "xliff12",
                    "xliff20"
                ],
                "title": "Format"
            },
            "ImportUploadData": {
                "type": "object",
                "properties": {
                    "files": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "format": "binary"
                        }
                    },
                    "locale": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 35
                    },
                    "format": {
                        "anyOf": [
                            {
                                "$ref": "#/components/schemas/Format"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "namespace": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 191
                    },
                    "overwrite": {
                        "type": "boolean"
                    },
                    "createUnknownKeys": {
                        "type": "boolean"
                    },
                    "tag": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 50
                    }
                },
                "required": [
                    "files"
                ],
                "title": "ImportUploadData"
            },
            "IssueLevel": {
                "type": "string",
                "description": "How serious a placeholder issue is. Only errors are stored in `translations.qa_errors`.\n",
                "enum": [
                    "error",
                    "warning"
                ],
                "title": "IssueLevel"
            },
            "KeyUpdateData": {
                "type": "object",
                "properties": {
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 1000
                    },
                    "maxLength": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "minimum": 1,
                        "maximum": 65535
                    },
                    "tags": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "maxItems": 10
                    }
                },
                "title": "KeyUpdateData"
            },
            "KeysDiffData": {
                "type": "object",
                "properties": {
                    "keys": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "hash": {
                                    "type": "string"
                                },
                                "sourceHash": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                }
                            },
                            "required": [
                                "hash",
                                "sourceHash"
                            ]
                        },
                        "minItems": 1,
                        "maxItems": 10000
                    }
                },
                "required": [
                    "keys"
                ],
                "title": "KeysDiffData"
            },
            "KeysSyncData": {
                "type": "object",
                "properties": {
                    "keys": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "namespace": {
                                    "type": "string"
                                },
                                "key": {
                                    "type": "string"
                                },
                                "context": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "value": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "forms": {
                                    "type": "object",
                                    "additionalProperties": {
                                        "type": [
                                            "string",
                                            "null"
                                        ]
                                    }
                                },
                                "description": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "maxLength": {
                                    "type": [
                                        "integer",
                                        "null"
                                    ]
                                },
                                "tags": {
                                    "type": "array",
                                    "items": {
                                        "type": "string"
                                    }
                                }
                            },
                            "required": [
                                "key"
                            ]
                        },
                        "maxItems": 5000
                    },
                    "archive": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "maxItems": 5000
                    }
                },
                "title": "KeysSyncData"
            },
            "MissingTranslations": {
                "type": "string",
                "description": "What an export writes for a missing translation: fall back along the fallback chain, leave it empty, or omit it.\n",
                "enum": [
                    "fallback",
                    "empty",
                    "omit"
                ],
                "title": "MissingTranslations"
            },
            "PlaceholderRule": {
                "type": "string",
                "description": "Every rule of the placeholder validation, shared by PHP and TypeScript.\n",
                "enum": [
                    "laravel.missing",
                    "laravel.unknown",
                    "laravel.case_mismatch",
                    "laravel.plural_intervals",
                    "printf.missing",
                    "printf.unknown",
                    "printf.type_mismatch",
                    "printf.order",
                    "printf.mixed_numbering",
                    "printf.bare_percent",
                    "icu.missing",
                    "icu.unknown",
                    "icu.unbalanced",
                    "html.missing",
                    "html.unknown",
                    "html.unbalanced",
                    "html.attribute_changed"
                ],
                "title": "PlaceholderRule"
            },
            "ProjectType": {
                "type": "string",
                "description": "The kind of codebase a project translates. The UI offers Laravel and WordPress (theme or plugin); `other` stays for existing projects but cannot be chosen.\n",
                "enum": [
                    "laravel",
                    "wp_theme",
                    "wp_plugin",
                    "other"
                ],
                "title": "ProjectType"
            },
            "TrackedJobStatus": {
                "type": "string",
                "description": "The state of a tracked job: waiting on the queue, running, and the two end states.\n",
                "enum": [
                    "queued",
                    "running",
                    "succeeded",
                    "failed"
                ],
                "title": "TrackedJobStatus"
            },
            "TranslationStatusFilter": {
                "type": "string",
                "description": "Which rows `GET /v1/translations/{locale}` lists: every active key (the default), only the translated ones, or only the ones without a translation.\n",
                "enum": [
                    "all",
                    "translated",
                    "untranslated"
                ],
                "title": "TranslationStatusFilter"
            },
            "TranslationWriteMode": {
                "type": "string",
                "description": "How a block writer treats a translation that already has text.\n| |\n|---|\n| `overwrite` <br/> Replaces the text, or clears it with an empty text. |\n| `fill_empty` <br/> Only writes empty or missing translations; one with text is skipped. |",
                "enum": [
                    "overwrite",
                    "fill_empty"
                ],
                "title": "TranslationWriteMode"
            },
            "TranslationsUpdateData": {
                "type": "object",
                "properties": {
                    "mode": {
                        "$ref": "#/components/schemas/TranslationWriteMode"
                    },
                    "translations": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "hash": {
                                    "type": "string"
                                },
                                "value": {
                                    "type": "string"
                                },
                                "forms": {
                                    "type": "object",
                                    "additionalProperties": {
                                        "type": "string"
                                    }
                                },
                                "version": {
                                    "type": "integer"
                                }
                            },
                            "required": [
                                "hash"
                            ]
                        },
                        "minItems": 1,
                        "maxItems": 1000
                    }
                },
                "required": [
                    "mode",
                    "translations"
                ],
                "title": "TranslationsUpdateData"
            }
        }
    }
}