> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usertour.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a localization

> Add a locale content can be translated into. A `code` stays reserved while its localization is soft-deleted: creating that code again RESTORES the deleted one — same id, with every translation it held (each with the enabled state it had) — and the response says so with `restored: true`.



## OpenAPI

````yaml /api-reference-v2/openapi.json post /v2/projects/{projectId}/localizations
openapi: 3.0.0
info:
  title: Usertour API v2
  description: >-
    Project-scoped v2 API. Authenticate with a personal API token — an opaque
    `utp_...` string (NOT a JWT: do not try to decode it), created in the
    Usertour app under Settings → API, sent as `Authorization: Bearer utp_...`.
  version: '2.0'
  contact: {}
servers:
  - url: https://api.usertour.io
security: []
tags: []
paths:
  /v2/projects/{projectId}/localizations:
    post:
      tags:
        - Localizations
      summary: Create a localization
      description: >-
        Add a locale content can be translated into. A `code` stays reserved
        while its localization is soft-deleted: creating that code again
        RESTORES the deleted one — same id, with every translation it held (each
        with the enabled state it had) — and the response says so with
        `restored: true`.
      operationId: ApiLocalizationsController_create
      parameters:
        - name: projectId
          required: true
          in: path
          description: Project ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateLocalizationBodyDto'
      responses:
        '201':
          description: Created localization
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreatedLocalizationDto'
        '400':
          description: >-
            Invalid request — E1017 validation (may carry `issues`; an invalid
            orderBy/limit is also E1017), E1015 invalid scope, E0003 invalid
            against current domain state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '401':
          description: Missing or expired API key — E1010, E1020.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '403':
          description: >-
            Refused — E1000 invalid key, E1011 project not in token scope, E1012
            insufficient scope, E1029 environment not in token scope, E1032
            environment creation needs a token without env-targeted capabilities
            (its allowlist cannot cover a not-yet-existing environment), E0043
            the project's plan does not include the feature (e.g. webhooks
            require a paid plan on cloud).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '409':
          description: E1023 a live localization already uses this code
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '429':
          description: >-
            Rate limit exceeded — E1013. The limit follows the project's plan
            (100/500/1000/3000 requests per minute); unknown credentials share a
            per-IP bucket. Every response also carries X-RateLimit-Limit /
            -Remaining / -Reset for pacing; a 429 adds the standard Retry-After
            header (seconds to back off).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
      security:
        - bearer: []
components:
  schemas:
    CreateLocalizationBodyDto:
      type: object
      properties:
        code:
          type: string
          minLength: 2
          maxLength: 35
          description: >-
            The value matched against an end user's `locale_code` attribute to
            pick their translation, and how a version translation is addressed
            in the URL path. Letters, digits, `-` and `_` only. Unique within
            the project, case-insensitively (delivery ignores case). Usually the
            locale tag, but free-form: `fr-enterprise` next to `fr` gives one
            language two variants.
        name:
          type: string
          minLength: 2
          maxLength: 64
          description: >-
            The language this locale stands for, e.g. "French (France)". Machine
            translation is asked to translate INTO this name, so a real language
            name (copied from `GET /v2/locales`) translates better than an
            improvised label.
        locale:
          type: string
          minLength: 2
          maxLength: 35
          description: >-
            The locale tag this entry stands for, e.g. `fr-FR`. `GET
            /v2/locales` lists the common tags with the language name to file
            each one under.
      required:
        - code
        - name
        - locale
      additionalProperties: false
    CreatedLocalizationDto:
      type: object
      properties:
        id:
          type: string
        object:
          type: string
          enum:
            - localization
        code:
          type: string
          description: >-
            The locale's code — how version translations are addressed, and the
            value matched against the end user's `locale_code` attribute to pick
            a translation at delivery.
        name:
          type: string
          description: >-
            The language this locale stands for, e.g. "French (France)" — also
            what machine translation is asked to translate into.
        locale:
          type: string
          description: The locale tag this entry was created from, e.g. `fr-FR`.
        isDefault:
          type: boolean
          description: >-
            The source language content is authored in. It has no translation of
            its own — version translations exist only for the non-default
            locales.
        deleted:
          type: boolean
          description: >-
            Soft-deleted: no longer offered or delivered, but the translations
            it holds on every version are kept, so restoring it brings them all
            back.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        restored:
          type: boolean
          description: >-
            true when this `code` belonged to a soft-deleted localization: that
            one was RESTORED (same id, with every translation it held) instead
            of a new one being created.
      required:
        - id
        - object
        - code
        - name
        - locale
        - isDefault
        - deleted
        - createdAt
        - updatedAt
        - restored
    ErrorResponseDto:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: >-
                Stable machine-readable code (e.g. E1017). Match on this, never
                on `message`.
            message:
              type: string
              description: Human-readable summary. Wording may change between releases.
            issues:
              description: >-
                Validation errors (E1017) may carry one entry per problem so
                every field can be fixed in a single round-trip. Absent on other
                errors.
              type: array
              items:
                type: object
                properties:
                  rule:
                    type: string
                    description: >-
                      Which validation layer rejected it: schema |
                      reactive_condition | action_not_allowed | step_shape |
                      reference_target | auto_start | media_url. New values may
                      be added; treat an unknown value as a generic validation
                      failure.
                  message:
                    type: string
                  path:
                    description: >-
                      Path into the request body (e.g.
                      `steps[0].triggers[0].when[1]`).
                    type: string
                required:
                  - rule
                  - message
            doc_url:
              type: string
              description: Base URL of the API documentation.
      required:
        - error
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: utp_... personal API token (opaque)
      type: http

````