{
  "openapi": "3.1.0",
  "info": {
    "title": "Ponyglot Cloud API",
    "version": "1",
    "description": ""
  },
  "paths": {
    "/v1/health": {
      "get": {
        "operationId": "ponyglot_cloud_api_api_health",
        "summary": "Health",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthOut"
                }
              }
            }
          }
        },
        "tags": [
          "meta"
        ]
      }
    },
    "/v1/site": {
      "get": {
        "operationId": "ponyglot_cloud_api_site_site",
        "summary": "Site",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteOut"
                }
              }
            }
          }
        },
        "description": "The site this API key belongs to. Connectors use it to check their key.",
        "tags": [
          "site"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/handshake": {
      "post": {
        "operationId": "ponyglot_cloud_api_site_handshake",
        "summary": "Handshake",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HandshakeOut"
                }
              }
            }
          }
        },
        "description": "The connector reports itself; the cloud answers with the site settings to use.",
        "tags": [
          "site"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HandshakeIn"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/status": {
      "get": {
        "operationId": "ponyglot_cloud_api_site_status",
        "summary": "Status",
        "parameters": [
          {
            "in": "query",
            "name": "prefix",
            "schema": {
              "default": "",
              "title": "Prefix",
              "type": "string"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteStatusOut"
                }
              }
            }
          }
        },
        "description": "Counts per target language across all units of the site (`prefix`: only units whose\nkey starts with it, e.g. all objects of one model).",
        "tags": [
          "site"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "ponyglot_cloud_api_site_usage",
        "summary": "Usage",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageOut"
                }
              }
            }
          }
        },
        "description": "This month's billable characters for the site's usage scope (for connector toolbars).",
        "tags": [
          "site"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/units": {
      "put": {
        "operationId": "ponyglot_cloud_api_units_push_unit",
        "summary": "Push Unit",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncOut"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "description": "Push the complete current state of one unit. Idempotent: retry freely.",
        "tags": [
          "units"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnitSnapshotIn"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      },
      "get": {
        "operationId": "ponyglot_cloud_api_units_units_with_work",
        "summary": "Units With Work",
        "parameters": [
          {
            "in": "query",
            "name": "prefix",
            "schema": {
              "default": "",
              "title": "Prefix",
              "type": "string"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "language",
            "schema": {
              "anyOf": [
                {
                  "maxLength": 15,
                  "minLength": 2,
                  "pattern": "^[A-Za-z0-9\\-_]+$",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Language"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cursor"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 100,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnitsWorkOut"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "description": "The units with something not up to date (missing, stale, waiting for editors on the\nsite, held back by QA), with counts per language; for the connectors' overviews. `prefix`: units\nwhose key starts with it; `language`: only that language.",
        "tags": [
          "units"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/units/batch": {
      "put": {
        "operationId": "ponyglot_cloud_api_units_push_units",
        "summary": "Push Units",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchOut"
                }
              }
            }
          }
        },
        "description": "Push up to 100 units. Each unit is applied on its own; one failure doesn't block others.",
        "tags": [
          "units"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchIn"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/units/{external_key}": {
      "delete": {
        "operationId": "ponyglot_cloud_api_units_delete_unit",
        "summary": "Delete Unit",
        "parameters": [
          {
            "in": "path",
            "name": "external_key",
            "schema": {
              "title": "External Key",
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        },
        "description": "The object was deleted on the site. Idempotent: unknown or already deleted is fine.",
        "tags": [
          "units"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/units/{external_key}/status": {
      "get": {
        "operationId": "ponyglot_cloud_api_units_status",
        "summary": "Status",
        "parameters": [
          {
            "in": "path",
            "name": "external_key",
            "schema": {
              "title": "External Key",
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnitStatusOut"
                }
              }
            }
          }
        },
        "description": "Segment × language matrix of one unit.",
        "tags": [
          "units"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/jobs": {
      "post": {
        "operationId": "ponyglot_cloud_api_jobs_create_job",
        "summary": "Create Job",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobEstimateOut"
                }
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingErrorOut"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingErrorOut"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "description": "Request translation. Results become available via `GET /results` as the job runs.\n\n402: no subscription covers the site. 409: confirm with `confirm: true` after showing\nthe estimate (large jobs, or characters beyond the included volume).",
        "tags": [
          "translation"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobIn"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      },
      "get": {
        "operationId": "ponyglot_cloud_api_jobs_list_jobs",
        "summary": "List Jobs",
        "parameters": [
          {
            "in": "query",
            "name": "active",
            "schema": {
              "default": false,
              "title": "Active",
              "type": "boolean"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/JobOut"
                  },
                  "title": "Response",
                  "type": "array"
                }
              }
            }
          }
        },
        "description": "The 20 most recent jobs of the site.",
        "tags": [
          "translation"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/jobs/{job_id}": {
      "get": {
        "operationId": "ponyglot_cloud_api_jobs_get_job",
        "summary": "Get Job",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "schema": {
              "title": "Job Id",
              "type": "integer"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            }
          }
        },
        "tags": [
          "translation"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/jobs/{job_id}/cancel": {
      "post": {
        "operationId": "ponyglot_cloud_api_jobs_cancel_job",
        "summary": "Cancel Job",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "schema": {
              "title": "Job Id",
              "type": "integer"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobOut"
                }
              }
            }
          }
        },
        "tags": [
          "translation"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/results": {
      "get": {
        "operationId": "ponyglot_cloud_api_jobs_results",
        "summary": "Results",
        "parameters": [
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cursor"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 100,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            },
            "required": false
          },
          {
            "in": "query",
            "name": "unit",
            "schema": {
              "anyOf": [
                {
                  "maxLength": 255,
                  "minLength": 1,
                  "pattern": "^[A-Za-z0-9_.:\\-]+$",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Unit"
            },
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultsOut"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorOut"
                }
              }
            }
          }
        },
        "description": "Translations ready to be written as drafts/suggestions. Acknowledge them afterwards.",
        "tags": [
          "translation"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/results/ack": {
      "post": {
        "operationId": "ponyglot_cloud_api_jobs_acknowledge",
        "summary": "Acknowledge",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AckOut"
                }
              }
            }
          }
        },
        "description": "The connector stored these as drafts/suggestions; they are now in review.",
        "tags": [
          "translation"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AckIn"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/reviews": {
      "post": {
        "operationId": "ponyglot_cloud_api_jobs_report_reviews",
        "summary": "Report Reviews",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReviewsOut"
                }
              }
            }
          }
        },
        "description": "Report editors' decisions from the CMS/admin (approved with final text, or rejected).",
        "tags": [
          "translation"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewsIn"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    },
    "/v1/attention": {
      "get": {
        "operationId": "ponyglot_cloud_api_jobs_attention",
        "summary": "Attention",
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttentionOut"
                }
              }
            }
          }
        },
        "description": "Translations held back for QA review in the dashboard (`separate` QA mode, or connectors\nthat don't show QA errors), so connectors can tell editors what is missing and why.",
        "tags": [
          "translation"
        ],
        "security": [
          {
            "SiteKeyAuth": []
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "HealthOut": {
        "properties": {
          "status": {
            "title": "Status",
            "type": "string"
          },
          "api_version": {
            "title": "Api Version",
            "type": "string"
          }
        },
        "required": [
          "status",
          "api_version"
        ],
        "title": "HealthOut",
        "type": "object"
      },
      "SiteOut": {
        "properties": {
          "id": {
            "title": "Id",
            "type": "integer"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "organization": {
            "title": "Organization",
            "type": "string"
          },
          "source_language": {
            "title": "Source Language",
            "type": "string"
          },
          "target_languages": {
            "items": {
              "$ref": "#/components/schemas/TargetLanguageOut"
            },
            "title": "Target Languages",
            "type": "array"
          },
          "enabled_adapters": {
            "items": {
              "type": "string"
            },
            "title": "Enabled Adapters",
            "type": "array"
          },
          "enabled_engines": {
            "items": {
              "type": "string"
            },
            "title": "Enabled Engines",
            "type": "array"
          }
        },
        "required": [
          "id",
          "name",
          "organization",
          "source_language",
          "target_languages",
          "enabled_adapters",
          "enabled_engines"
        ],
        "title": "SiteOut",
        "type": "object"
      },
      "TargetLanguageOut": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "formality": {
            "title": "Formality",
            "type": "string"
          },
          "engine": {
            "title": "Engine",
            "type": "string"
          },
          "writable": {
            "title": "Writable",
            "type": "boolean"
          }
        },
        "required": [
          "code",
          "formality",
          "engine",
          "writable"
        ],
        "title": "TargetLanguageOut",
        "type": "object"
      },
      "HandshakeOut": {
        "properties": {
          "id": {
            "title": "Id",
            "type": "integer"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "organization": {
            "title": "Organization",
            "type": "string"
          },
          "source_language": {
            "title": "Source Language",
            "type": "string"
          },
          "target_languages": {
            "items": {
              "$ref": "#/components/schemas/TargetLanguageOut"
            },
            "title": "Target Languages",
            "type": "array"
          },
          "enabled_adapters": {
            "items": {
              "type": "string"
            },
            "title": "Enabled Adapters",
            "type": "array"
          },
          "enabled_engines": {
            "items": {
              "type": "string"
            },
            "title": "Enabled Engines",
            "type": "array"
          },
          "review_mode": {
            "title": "Review Mode",
            "type": "string"
          },
          "qa_mode": {
            "description": "`editors`: QA errors are delivered, flagged, for editors to fix (to connectors declaring `qa_errors`). `separate`: they're held back for review in the dashboard.",
            "enum": [
              "editors",
              "separate"
            ],
            "title": "Qa Mode",
            "type": "string"
          },
          "capabilities": {
            "description": "The declared capabilities the cloud understood.",
            "items": {
              "enum": [
                "qa_errors",
                "whole_unit"
              ],
              "type": "string"
            },
            "title": "Capabilities",
            "type": "array"
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "id",
          "name",
          "organization",
          "source_language",
          "target_languages",
          "enabled_adapters",
          "enabled_engines",
          "review_mode",
          "qa_mode",
          "capabilities",
          "warnings"
        ],
        "title": "HandshakeOut",
        "type": "object"
      },
      "HandshakeIn": {
        "properties": {
          "connector_version": {
            "examples": [
              "0.1.0"
            ],
            "maxLength": 50,
            "title": "Connector Version",
            "type": "string"
          },
          "adapters": {
            "examples": [
              [
                "djangocms"
              ]
            ],
            "items": {
              "type": "string"
            },
            "maxItems": 20,
            "title": "Adapters",
            "type": "array"
          },
          "source_language": {
            "examples": [
              "en"
            ],
            "maxLength": 15,
            "minLength": 2,
            "pattern": "^[A-Za-z0-9\\-_]+$",
            "title": "Source Language",
            "type": "string"
          },
          "languages": {
            "description": "Languages configured on the customer site (settings.LANGUAGES).",
            "examples": [
              [
                "en",
                "de",
                "fr"
              ]
            ],
            "items": {
              "maxLength": 15,
              "minLength": 2,
              "pattern": "^[A-Za-z0-9\\-_]+$",
              "type": "string"
            },
            "maxItems": 200,
            "title": "Languages",
            "type": "array"
          },
          "capabilities": {
            "description": "What the connector can handle: `qa_errors` (shows QA errors to editors), `whole_unit` (a unit's translations in one piece per language). Unknown values are ignored.",
            "examples": [
              [
                "qa_errors",
                "whole_unit"
              ]
            ],
            "items": {
              "type": "string"
            },
            "maxItems": 20,
            "title": "Capabilities",
            "type": "array"
          }
        },
        "required": [
          "connector_version",
          "source_language"
        ],
        "title": "HandshakeIn",
        "type": "object"
      },
      "LanguageCountsOut": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "ok": {
            "title": "Ok",
            "type": "integer"
          },
          "stale": {
            "title": "Stale",
            "type": "integer"
          },
          "review": {
            "title": "Review",
            "type": "integer"
          },
          "missing": {
            "title": "Missing",
            "type": "integer"
          },
          "attention": {
            "title": "Attention",
            "type": "integer"
          },
          "attention_url": {
            "default": "",
            "description": "Dashboard: this unit's translations held back by QA in this language (the only ones that need action on the platform).",
            "title": "Attention Url",
            "type": "string"
          }
        },
        "required": [
          "code",
          "ok",
          "stale",
          "review",
          "missing",
          "attention"
        ],
        "title": "LanguageCountsOut",
        "type": "object"
      },
      "SiteStatusOut": {
        "properties": {
          "units_total": {
            "title": "Units Total",
            "type": "integer"
          },
          "segments_total": {
            "title": "Segments Total",
            "type": "integer"
          },
          "glossary_terms": {
            "description": "Terms in the organization's glossary.",
            "title": "Glossary Terms",
            "type": "integer"
          },
          "languages": {
            "items": {
              "$ref": "#/components/schemas/LanguageCountsOut"
            },
            "title": "Languages",
            "type": "array"
          }
        },
        "required": [
          "units_total",
          "segments_total",
          "glossary_terms",
          "languages"
        ],
        "title": "SiteStatusOut",
        "type": "object"
      },
      "UsageOut": {
        "properties": {
          "plan": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Plan code (pro, agency, growth, scale) or null.",
            "title": "Plan"
          },
          "entitled": {
            "description": "Whether hosted translation is available for this site.",
            "title": "Entitled",
            "type": "boolean"
          },
          "reason": {
            "description": "Why not, if not entitled.",
            "title": "Reason",
            "type": "string"
          },
          "month_start": {
            "format": "date-time",
            "title": "Month Start",
            "type": "string"
          },
          "month_end": {
            "format": "date-time",
            "title": "Month End",
            "type": "string"
          },
          "included_characters": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per month; null if not metered.",
            "title": "Included Characters"
          },
          "used_characters": {
            "title": "Used Characters",
            "type": "integer"
          },
          "per_site": {
            "description": "Pro: usage counts per site; otherwise pooled.",
            "title": "Per Site",
            "type": "boolean"
          }
        },
        "required": [
          "plan",
          "entitled",
          "reason",
          "month_start",
          "month_end",
          "included_characters",
          "used_characters",
          "per_site"
        ],
        "title": "UsageOut",
        "type": "object"
      },
      "SyncOut": {
        "properties": {
          "external_key": {
            "title": "External Key",
            "type": "string"
          },
          "unit_created": {
            "title": "Unit Created",
            "type": "boolean"
          },
          "added": {
            "title": "Added",
            "type": "integer"
          },
          "changed": {
            "title": "Changed",
            "type": "integer"
          },
          "removed": {
            "title": "Removed",
            "type": "integer"
          },
          "unchanged": {
            "title": "Unchanged",
            "type": "integer"
          },
          "stale_translations": {
            "title": "Stale Translations",
            "type": "integer"
          },
          "imported_translations": {
            "title": "Imported Translations",
            "type": "integer"
          },
          "fingerprint_mismatches": {
            "items": {
              "type": "string"
            },
            "title": "Fingerprint Mismatches",
            "type": "array"
          }
        },
        "required": [
          "external_key",
          "unit_created",
          "added",
          "changed",
          "removed",
          "unchanged",
          "stale_translations",
          "imported_translations",
          "fingerprint_mismatches"
        ],
        "title": "SyncOut",
        "type": "object"
      },
      "ErrorOut": {
        "properties": {
          "detail": {
            "title": "Detail",
            "type": "string"
          }
        },
        "required": [
          "detail"
        ],
        "title": "ErrorOut",
        "type": "object"
      },
      "SegmentIn": {
        "properties": {
          "key": {
            "description": "Stable id within the unit.",
            "maxLength": 500,
            "minLength": 1,
            "title": "Key",
            "type": "string"
          },
          "text": {
            "maxLength": 100000,
            "title": "Text",
            "type": "string"
          },
          "format": {
            "default": "plain",
            "enum": [
              "plain",
              "html",
              "markdown",
              "rich_text"
            ],
            "title": "Format",
            "type": "string"
          },
          "field": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Field"
          },
          "kind": {
            "anyOf": [
              {
                "maxLength": 50,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hint: title, body, alt_text, meta_description, …",
            "title": "Kind"
          },
          "max_length": {
            "anyOf": [
              {
                "minimum": 1,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Length"
          },
          "position": {
            "anyOf": [
              {
                "minimum": 0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Defaults to the order in the list.",
            "title": "Position"
          },
          "parent_key": {
            "anyOf": [
              {
                "maxLength": 500,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Key"
          },
          "fingerprint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional; the cloud computes its own and reports mismatches.",
            "title": "Fingerprint"
          },
          "translations": {
            "anyOf": [
              {
                "patternProperties": {
                  "^[A-Za-z0-9\\-_]+$": {
                    "type": "string"
                  }
                },
                "propertyNames": {
                  "maxLength": 15,
                  "minLength": 2
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Existing target-language content to import (only fills empty languages).",
            "title": "Translations"
          }
        },
        "required": [
          "key",
          "text"
        ],
        "title": "SegmentIn",
        "type": "object"
      },
      "UnitSnapshotIn": {
        "properties": {
          "external_key": {
            "examples": [
              "djangocms:page:42"
            ],
            "maxLength": 255,
            "minLength": 1,
            "pattern": "^[A-Za-z0-9_.:\\-]+$",
            "title": "External Key",
            "type": "string"
          },
          "adapter": {
            "enum": [
              "djangocms",
              "wagtail",
              "parler",
              "modeltranslation"
            ],
            "title": "Adapter",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "maxLength": 500,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          },
          "path": {
            "anyOf": [
              {
                "maxLength": 2000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "/pricing/"
            ],
            "title": "Path"
          },
          "source_language": {
            "anyOf": [
              {
                "maxLength": 15,
                "minLength": 2,
                "pattern": "^[A-Za-z0-9\\-_]+$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Language"
          },
          "writable_languages": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 15,
                  "minLength": 2,
                  "pattern": "^[A-Za-z0-9\\-_]+$",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Restrict target languages for this unit (e.g. modeltranslation).",
            "title": "Writable Languages"
          },
          "metadata": {
            "additionalProperties": true,
            "title": "Metadata",
            "type": "object"
          },
          "segments": {
            "items": {
              "$ref": "#/components/schemas/SegmentIn"
            },
            "maxItems": 5000,
            "title": "Segments",
            "type": "array"
          }
        },
        "required": [
          "external_key",
          "adapter",
          "segments"
        ],
        "title": "UnitSnapshotIn",
        "type": "object"
      },
      "UnitWorkOut": {
        "properties": {
          "external_key": {
            "title": "External Key",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "adapter": {
            "title": "Adapter",
            "type": "string"
          },
          "last_synced_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Synced At"
          },
          "dashboard_url": {
            "description": "Dashboard: this unit's translations.",
            "title": "Dashboard Url",
            "type": "string"
          },
          "languages": {
            "description": "Only languages with work.",
            "items": {
              "$ref": "#/components/schemas/WorkCountsOut"
            },
            "title": "Languages",
            "type": "array"
          }
        },
        "required": [
          "external_key",
          "label",
          "path",
          "adapter",
          "last_synced_at",
          "dashboard_url",
          "languages"
        ],
        "title": "UnitWorkOut",
        "type": "object"
      },
      "UnitsWorkOut": {
        "properties": {
          "units": {
            "items": {
              "$ref": "#/components/schemas/UnitWorkOut"
            },
            "title": "Units",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page; null when done.",
            "title": "Next Cursor"
          }
        },
        "required": [
          "units"
        ],
        "title": "UnitsWorkOut",
        "type": "object"
      },
      "WorkCountsOut": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "missing": {
            "title": "Missing",
            "type": "integer"
          },
          "stale": {
            "title": "Stale",
            "type": "integer"
          },
          "review": {
            "description": "Delivered, waiting for an editor on the site.",
            "title": "Review",
            "type": "integer"
          },
          "attention": {
            "description": "Held back by a quality check on the platform.",
            "title": "Attention",
            "type": "integer"
          },
          "attention_url": {
            "default": "",
            "description": "Dashboard: these held-back translations.",
            "title": "Attention Url",
            "type": "string"
          }
        },
        "required": [
          "code",
          "missing",
          "stale",
          "review",
          "attention"
        ],
        "title": "WorkCountsOut",
        "type": "object"
      },
      "BatchItemOut": {
        "properties": {
          "external_key": {
            "title": "External Key",
            "type": "string"
          },
          "ok": {
            "title": "Ok",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SyncOut"
              },
              {
                "type": "null"
              }
            ]
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          }
        },
        "required": [
          "external_key",
          "ok"
        ],
        "title": "BatchItemOut",
        "type": "object"
      },
      "BatchOut": {
        "properties": {
          "results": {
            "items": {
              "$ref": "#/components/schemas/BatchItemOut"
            },
            "title": "Results",
            "type": "array"
          }
        },
        "required": [
          "results"
        ],
        "title": "BatchOut",
        "type": "object"
      },
      "BatchIn": {
        "properties": {
          "units": {
            "items": {
              "$ref": "#/components/schemas/UnitSnapshotIn"
            },
            "maxItems": 100,
            "minItems": 1,
            "title": "Units",
            "type": "array"
          }
        },
        "required": [
          "units"
        ],
        "title": "BatchIn",
        "type": "object"
      },
      "QAIssueOut": {
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "severity": {
            "enum": [
              "error",
              "warning"
            ],
            "title": "Severity",
            "type": "string"
          },
          "message": {
            "title": "Message",
            "type": "string"
          }
        },
        "required": [
          "code",
          "severity",
          "message"
        ],
        "title": "QAIssueOut",
        "type": "object"
      },
      "SegmentStatusOut": {
        "properties": {
          "key": {
            "title": "Key",
            "type": "string"
          },
          "field": {
            "title": "Field",
            "type": "string"
          },
          "kind": {
            "title": "Kind",
            "type": "string"
          },
          "parent_key": {
            "title": "Parent Key",
            "type": "string"
          },
          "position": {
            "title": "Position",
            "type": "integer"
          },
          "states": {
            "additionalProperties": {
              "enum": [
                "ok",
                "stale",
                "review",
                "missing",
                "attention"
              ],
              "type": "string"
            },
            "title": "States",
            "type": "object"
          },
          "qa": {
            "additionalProperties": {
              "items": {
                "$ref": "#/components/schemas/QAIssueOut"
              },
              "type": "array"
            },
            "description": "QA issues of the current translation, per language (only where any).",
            "title": "Qa",
            "type": "object"
          },
          "held_back": {
            "description": "Languages whose translation is held back for QA review in the dashboard.",
            "items": {
              "type": "string"
            },
            "title": "Held Back",
            "type": "array"
          }
        },
        "required": [
          "key",
          "field",
          "kind",
          "parent_key",
          "position",
          "states"
        ],
        "title": "SegmentStatusOut",
        "type": "object"
      },
      "UnitStatusOut": {
        "properties": {
          "dashboard_url": {
            "default": "",
            "description": "Dashboard: this unit's translations.",
            "title": "Dashboard Url",
            "type": "string"
          },
          "external_key": {
            "title": "External Key",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "adapter": {
            "title": "Adapter",
            "type": "string"
          },
          "last_synced_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Synced At"
          },
          "segments_total": {
            "title": "Segments Total",
            "type": "integer"
          },
          "segments_needing_work": {
            "title": "Segments Needing Work",
            "type": "integer"
          },
          "languages": {
            "items": {
              "$ref": "#/components/schemas/LanguageCountsOut"
            },
            "title": "Languages",
            "type": "array"
          },
          "segments": {
            "items": {
              "$ref": "#/components/schemas/SegmentStatusOut"
            },
            "title": "Segments",
            "type": "array"
          }
        },
        "required": [
          "external_key",
          "label",
          "path",
          "adapter",
          "last_synced_at",
          "segments_total",
          "segments_needing_work",
          "languages",
          "segments"
        ],
        "title": "UnitStatusOut",
        "type": "object"
      },
      "EstimateOut": {
        "properties": {
          "characters": {
            "description": "Billable characters of this job.",
            "title": "Characters",
            "type": "integer"
          },
          "included_characters": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per month; null if not metered.",
            "title": "Included Characters"
          },
          "used_characters": {
            "description": "Billable characters used this month so far.",
            "title": "Used Characters",
            "type": "integer"
          },
          "reserved_characters": {
            "description": "Expected use of queued and running jobs requested earlier.",
            "title": "Reserved Characters",
            "type": "integer"
          },
          "remaining_characters": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remaining Characters"
          },
          "overage_characters": {
            "title": "Overage Characters",
            "type": "integer"
          },
          "overage_cents": {
            "description": "Estimated extra charge, billed after the month.",
            "title": "Overage Cents",
            "type": "integer"
          },
          "currency": {
            "title": "Currency",
            "type": "string"
          },
          "requires_confirmation": {
            "title": "Requires Confirmation",
            "type": "boolean"
          }
        },
        "required": [
          "characters",
          "included_characters",
          "used_characters",
          "reserved_characters",
          "remaining_characters",
          "overage_characters",
          "overage_cents",
          "currency",
          "requires_confirmation"
        ],
        "title": "EstimateOut",
        "type": "object"
      },
      "JobEstimateOut": {
        "properties": {
          "languages": {
            "items": {
              "type": "string"
            },
            "title": "Languages",
            "type": "array"
          },
          "estimated_segments": {
            "title": "Estimated Segments",
            "type": "integer"
          },
          "estimated_characters": {
            "title": "Estimated Characters",
            "type": "integer"
          },
          "estimated_tm_segments": {
            "title": "Estimated Tm Segments",
            "type": "integer"
          },
          "cost": {
            "$ref": "#/components/schemas/EstimateOut"
          }
        },
        "required": [
          "languages",
          "estimated_segments",
          "estimated_characters",
          "estimated_tm_segments",
          "cost"
        ],
        "title": "JobEstimateOut",
        "type": "object"
      },
      "JobError": {
        "properties": {
          "language": {
            "title": "Language",
            "type": "string"
          },
          "message": {
            "title": "Message",
            "type": "string"
          },
          "segments": {
            "title": "Segments",
            "type": "integer"
          }
        },
        "required": [
          "language",
          "message",
          "segments"
        ],
        "title": "JobError",
        "type": "object"
      },
      "JobOut": {
        "properties": {
          "id": {
            "title": "Id",
            "type": "integer"
          },
          "type": {
            "title": "Type",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "languages": {
            "items": {
              "type": "string"
            },
            "title": "Languages",
            "type": "array"
          },
          "units": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Units"
          },
          "prefix": {
            "default": "",
            "title": "Prefix",
            "type": "string"
          },
          "force": {
            "title": "Force",
            "type": "boolean"
          },
          "estimated_segments": {
            "title": "Estimated Segments",
            "type": "integer"
          },
          "estimated_characters": {
            "description": "Billable: excludes TM hits and repeated texts within the job.",
            "title": "Estimated Characters",
            "type": "integer"
          },
          "estimated_tm_segments": {
            "description": "Segments the translation memory covers.",
            "title": "Estimated Tm Segments",
            "type": "integer"
          },
          "done_segments": {
            "title": "Done Segments",
            "type": "integer"
          },
          "failed_segments": {
            "title": "Failed Segments",
            "type": "integer"
          },
          "characters": {
            "description": "Billed: source characters sent to engines.",
            "title": "Characters",
            "type": "integer"
          },
          "qa_failed_segments": {
            "description": "Translated but held back by QA errors; resolved in the review queue.",
            "title": "Qa Failed Segments",
            "type": "integer"
          },
          "tm_segments": {
            "title": "Tm Segments",
            "type": "integer"
          },
          "tm_characters": {
            "description": "Not billed: covered by the translation memory.",
            "title": "Tm Characters",
            "type": "integer"
          },
          "reused_segments": {
            "title": "Reused Segments",
            "type": "integer"
          },
          "reused_characters": {
            "description": "Not billed: repeats of text in this job.",
            "title": "Reused Characters",
            "type": "integer"
          },
          "errors": {
            "items": {
              "$ref": "#/components/schemas/JobError"
            },
            "title": "Errors",
            "type": "array"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Started At"
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finished At"
          }
        },
        "required": [
          "id",
          "type",
          "status",
          "languages",
          "force",
          "estimated_segments",
          "estimated_characters",
          "estimated_tm_segments",
          "done_segments",
          "failed_segments",
          "characters",
          "qa_failed_segments",
          "tm_segments",
          "tm_characters",
          "reused_segments",
          "reused_characters",
          "errors",
          "created_at",
          "started_at",
          "finished_at"
        ],
        "title": "JobOut",
        "type": "object"
      },
      "BillingErrorOut": {
        "properties": {
          "detail": {
            "title": "Detail",
            "type": "string"
          },
          "code": {
            "enum": [
              "subscription_required",
              "subscription_inactive",
              "site_not_covered",
              "confirmation_required"
            ],
            "title": "Code",
            "type": "string"
          },
          "estimate": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EstimateOut"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "detail",
          "code"
        ],
        "title": "BillingErrorOut",
        "type": "object"
      },
      "JobIn": {
        "properties": {
          "type": {
            "default": "delta",
            "description": "delta: stale and missing segments of the whole site; translate: the given units.",
            "enum": [
              "delta",
              "translate"
            ],
            "title": "Type",
            "type": "string"
          },
          "units": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 255,
                  "minLength": 1,
                  "pattern": "^[A-Za-z0-9_.:\\-]+$",
                  "type": "string"
                },
                "maxItems": 1000,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Units"
          },
          "prefix": {
            "anyOf": [
              {
                "maxLength": 255,
                "pattern": "^[a-z0-9_]+:[^\\s]*$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "delta only: units whose key starts with this, e.g. `parler:blog.post:` (all objects of one model).",
            "title": "Prefix"
          },
          "languages": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 15,
                  "minLength": 2,
                  "pattern": "^[A-Za-z0-9\\-_]+$",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Default: all writable target languages.",
            "title": "Languages"
          },
          "force": {
            "default": false,
            "description": "Also retranslate up-to-date segments.",
            "title": "Force",
            "type": "boolean"
          },
          "confirm": {
            "default": false,
            "description": "Confirm a job that needs it (large, or beyond the included volume); see the 409 response.",
            "title": "Confirm",
            "type": "boolean"
          },
          "estimate_only": {
            "default": false,
            "description": "Only return what the job would translate and cost; create nothing.",
            "title": "Estimate Only",
            "type": "boolean"
          }
        },
        "title": "JobIn",
        "type": "object"
      },
      "ResultOut": {
        "properties": {
          "id": {
            "description": "Opaque generated-version ID, e.g. r_5012.",
            "title": "Id",
            "type": "string"
          },
          "unit": {
            "title": "Unit",
            "type": "string"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "language": {
            "title": "Language",
            "type": "string"
          },
          "text": {
            "title": "Text",
            "type": "string"
          },
          "format": {
            "title": "Format",
            "type": "string"
          },
          "source_fingerprint": {
            "title": "Source Fingerprint",
            "type": "string"
          },
          "origin": {
            "title": "Origin",
            "type": "string"
          },
          "engine": {
            "title": "Engine",
            "type": "string"
          },
          "job_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "qa": {
            "description": "QA issues to show the editor: warnings; errors too in `editors` QA mode (for connectors that declared `qa_errors`), otherwise results with errors are held back.",
            "items": {
              "$ref": "#/components/schemas/QAIssueOut"
            },
            "title": "Qa",
            "type": "array"
          }
        },
        "required": [
          "id",
          "unit",
          "key",
          "language",
          "text",
          "format",
          "source_fingerprint",
          "origin",
          "engine",
          "job_id"
        ],
        "title": "ResultOut",
        "type": "object"
      },
      "ResultsOut": {
        "properties": {
          "results": {
            "items": {
              "$ref": "#/components/schemas/ResultOut"
            },
            "title": "Results",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pass as `cursor` to get the next page; null when done.",
            "title": "Next Cursor"
          }
        },
        "required": [
          "results"
        ],
        "title": "ResultsOut",
        "type": "object"
      },
      "AckOut": {
        "properties": {
          "acknowledged": {
            "title": "Acknowledged",
            "type": "integer"
          }
        },
        "required": [
          "acknowledged"
        ],
        "title": "AckOut",
        "type": "object"
      },
      "AckIn": {
        "properties": {
          "ids": {
            "items": {
              "anyOf": [
                {
                  "maxLength": 64,
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "maxItems": 1000,
            "minItems": 1,
            "title": "Ids",
            "type": "array"
          }
        },
        "required": [
          "ids"
        ],
        "title": "AckIn",
        "type": "object"
      },
      "ReviewsOut": {
        "properties": {
          "updated": {
            "title": "Updated",
            "type": "integer"
          },
          "ignored": {
            "description": "IDs that are legacy, unknown, superseded or not awaiting review.",
            "items": {
              "anyOf": [
                {
                  "maxLength": 64,
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Ignored",
            "type": "array"
          }
        },
        "required": [
          "updated",
          "ignored"
        ],
        "title": "ReviewsOut",
        "type": "object"
      },
      "ReviewIn": {
        "properties": {
          "id": {
            "anyOf": [
              {
                "maxLength": 64,
                "type": "string"
              },
              {
                "type": "integer"
              }
            ],
            "description": "Opaque result ID from `GET /results`.",
            "title": "Id"
          },
          "outcome": {
            "enum": [
              "approved",
              "rejected"
            ],
            "title": "Outcome",
            "type": "string"
          },
          "text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final text if the editor changed it (approved only).",
            "title": "Text"
          },
          "reviewer": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reviewer"
          }
        },
        "required": [
          "id",
          "outcome"
        ],
        "title": "ReviewIn",
        "type": "object"
      },
      "ReviewsIn": {
        "properties": {
          "reviews": {
            "items": {
              "$ref": "#/components/schemas/ReviewIn"
            },
            "maxItems": 500,
            "minItems": 1,
            "title": "Reviews",
            "type": "array"
          }
        },
        "required": [
          "reviews"
        ],
        "title": "ReviewsIn",
        "type": "object"
      },
      "AttentionItemOut": {
        "properties": {
          "unit": {
            "title": "Unit",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "language": {
            "title": "Language",
            "type": "string"
          },
          "issues": {
            "items": {
              "$ref": "#/components/schemas/QAIssueOut"
            },
            "title": "Issues",
            "type": "array"
          },
          "since": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the translation was produced.",
            "title": "Since"
          }
        },
        "required": [
          "unit",
          "label",
          "key",
          "language",
          "issues",
          "since"
        ],
        "title": "AttentionItemOut",
        "type": "object"
      },
      "AttentionOut": {
        "properties": {
          "qa_mode": {
            "title": "Qa Mode",
            "type": "string"
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/AttentionItemOut"
            },
            "title": "Items",
            "type": "array"
          },
          "truncated": {
            "description": "More items exist than listed (at most 500).",
            "title": "Truncated",
            "type": "boolean"
          }
        },
        "required": [
          "qa_mode",
          "items",
          "truncated"
        ],
        "title": "AttentionOut",
        "type": "object"
      }
    },
    "securitySchemes": {
      "SiteKeyAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "servers": [
    {
      "url": "https://api.ponyglot.app"
    }
  ]
}
