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

# Translate with AI (write)

> Machine-translate the project's candidate keys into one or more target languages with the resolved engine. Runs asynchronously — poll the returned `jobId`.

Candidates are filtered in SQL before any model sees a string (`onlyEmpty` / `onlyOutdated` / tag filters / `keyPrefix` / explicit `keyIds`). With `?branch=` the run targets a branch instead of main. Writes follow the project's approval workflow exactly as in the app.

**Constraints:**
- Metered against the org's AI credits when running on a TextSetu platform key; free on a BYOK key.
- `autoApprove` is honored only for callers that can approve; otherwise writes land as proposals.



## OpenAPI

````yaml /openapi/textsetu.json post /projects/{projectId}/ai/translations
openapi: 3.1.0
info:
  title: TextSetu API
  version: 1.2.0
  description: >-
    Public REST API for TextSetu. Authenticate with a Personal Access Token
    (tsu_pat_…) or a project token (tsu_proj_…) via the `Authorization: Bearer
    <token>` header.


    **Authorization is permission-based.** Every token carries an explicit
    allow-list of RBAC permission keys (e.g. `translation_read`), and each
    endpoint declares the permission it requires (`x-permission`). A token's
    effective access is its underlying authority ∩ its allow-list — a PAT is
    further bounded by its owner's role-based permissions, so it can only
    narrow, never exceed, what the owner already has. A project token is bound
    to a single project. There are no coarse read/write/manage scopes.


    **Response envelope.** Every endpoint returns `{ "success": true, "data": …
    }` on success and `{ "success": false, "error": { "code", "message" } }` on
    failure.


    **Rate limit.** 600 requests/minute, keyed by token (or by IP when
    unauthenticated). Exceeding it returns 429 with the standard error envelope.
servers:
  - url: https://api.textsetu.com/api/v1
    description: Production
  - url: /api/v1
    description: This server (self-hosted / same-origin)
security:
  - bearerAuth: []
tags:
  - name: Projects
    description: >-
      Read project metadata — settings, key separator, and the
      approval/branching flags that shape how the other endpoints behave.
  - name: Languages
    description: >-
      List and manage a project's target languages. Each language is referenced
      by its BCP-47 code; the source language is flagged separately.
  - name: Translations
    description: >-
      Manage a project's translations: create, read, update, and delete
      translation keys — the identifiers your app looks up, carrying metadata
      (description, tags, screenshot) — and set the translated value for a key
      in a given language. Value writes honor the project's approval workflow —
      non-approver writes land as `pending_review`.
  - name: Stats
    description: >-
      Per-language completeness and approval progress for a project — the
      numbers behind the dashboard.
  - name: Import/Export
    description: >-
      Bulk-load source files into a project or export the current translations.
      Supports the same file formats as the web app.
  - name: Branches
    description: >-
      Work on translations in isolation and merge them back. Branch reads/writes
      mirror the main endpoints but stage changes as a diff until merge. See the
      [branching guide](/docs/guides/branches).
  - name: Glossary
    description: >-
      Manage term bases — approved terminology and its translations — and check
      a string against them. See the [glossary guide](/docs/guides/glossary).
  - name: Translation Memory
    description: >-
      Reusable translation stores. Fuzzy-match and concordance-search prior
      translations to reuse them. See the [translation memory
      guide](/docs/guides/translation-memory).
  - name: AI
    description: >-
      Machine-translate a project with the org's configured AI engine (brand
      voice, glossary/TM grounding, and an optional review pass). Runs
      asynchronously — start a run and poll the returned `jobId`.
  - name: Webhooks
    description: >-
      Get notified when a project's translations change, instead of polling.
      Register an HTTPS endpoint, subscribe it to the events you care about, and
      TextSetu POSTs a signed payload whenever one occurs. Payloads follow the
      [Standard Webhooks](https://www.standardwebhooks.com) spec — verify the
      `webhook-signature` header with any compatible library. Delivery is
      at-least-once and unordered, so treat `webhook-id` as an idempotency key.
      Failed deliveries are retried five times over roughly seven hours, and
      every attempt is inspectable and replayable via the delivery log.
  - name: Meta
    description: Service-level and cross-cutting endpoints.
paths:
  /projects/{projectId}/ai/translations:
    post:
      tags:
        - AI
      summary: Translate with AI (write)
      description: >-
        Machine-translate the project's candidate keys into one or more target
        languages with the resolved engine. Runs asynchronously — poll the
        returned `jobId`.


        Candidates are filtered in SQL before any model sees a string
        (`onlyEmpty` / `onlyOutdated` / tag filters / `keyPrefix` / explicit
        `keyIds`). With `?branch=` the run targets a branch instead of main.
        Writes follow the project's approval workflow exactly as in the app.


        **Constraints:**

        - Metered against the org's AI credits when running on a TextSetu
        platform key; free on a BYOK key.

        - `autoApprove` is honored only for callers that can approve; otherwise
        writes land as proposals.
      parameters:
        - name: projectId
          in: path
          required: true
          schema:
            type: string
          description: Project id (UUID) or id-embedded path slug.
        - name: branch
          in: query
          schema:
            type: string
          description: >-
            Target an open translation branch instead of main. Required when the
            project's main branch is protected.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                targetLanguageCodes:
                  minItems: 1
                  type: array
                  items:
                    type: string
                    minLength: 2
                  description: Target BCP-47 language codes to translate into.
                  examples:
                    - - fr
                      - de
                keyIds:
                  description: >-
                    Restrict to these key ids. Omit to consider every key in the
                    project.
                  type: array
                  items:
                    type: string
                onlyEmpty:
                  description: >-
                    Translate only keys with no existing value in the target
                    language.
                  type: boolean
                onlyOutdated:
                  description: >-
                    Include values flagged outdated (the source changed after
                    the value was last set).
                  type: boolean
                includeTags:
                  description: Only keys carrying at least one of these tags.
                  type: array
                  items:
                    type: string
                excludeTags:
                  description: Skip keys carrying any of these tags.
                  type: array
                  items:
                    type: string
                keyPrefix:
                  description: Only keys whose id starts with this prefix, e.g. `home.`.
                  type: string
                autoApprove:
                  description: >-
                    Approvers only: apply directly instead of proposing when the
                    project requires approval. Ignored for callers without
                    approval rights (the write still lands as a proposal).
                  type: boolean
                review:
                  description: >-
                    Run the engine's review pass on this run. Omit to follow the
                    engine default.
                  type: boolean
                batch:
                  description: >-
                    Use the provider's asynchronous batch path (~50% cheaper,
                    higher latency).
                  type: boolean
              required:
                - targetLanguageCodes
      responses:
        '202':
          description: The queued job's id and initial status.
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                properties:
                  success:
                    type: boolean
                    const: true
                  data:
                    type: object
                    properties:
                      jobId:
                        type: string
                        description: >-
                          Id of the queued AI translation job. Poll the status
                          endpoint with it.
                        examples:
                          - job_a1b2c3d4
                      status:
                        type: string
                        description: Initial job status (usually `queued`).
                        examples:
                          - queued
                    required:
                      - jobId
                      - status
                    additionalProperties: false
        '400':
          description: >-
            AI is not available for this project, no model is configured for a
            pair, or the target/branch is invalid.
        '401':
          description: The token has no associated user to attribute writes to.
        '402':
          description: >-
            Insufficient AI credits to cover the run (platform-key runs only;
            BYOK is never blocked).
        '403':
          description: Forbidden / main branch protected.
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API token: tsu_pat_… (PAT) or tsu_proj_… (project token). The token's
        granted RBAC permissions determine access; see each operation's
        `x-permission`.

````