{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/motaword/json-schema/motaword-project-schema.json",
  "title": "Project",
  "x-generated": "2026-10-28",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/_original/motaword-api-openapi.yml#/components/schemas/Project",
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "format": "int64"
    },
    "name": {
      "description": "Human-readable project identifier. Returns \"{pivotOf}-{pivotPublicIndex}\" for pivot children (e.g. \"123-2\") and the quote ID string for normal projects.",
      "type": "string"
    },
    "source_language": {
      "type": "string"
    },
    "target_languages": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "word_count": {
      "type": "integer",
      "format": "int64"
    },
    "word_count_analysis": {
      "type": "object",
      "properties": {
        "base": {
          "type": "number",
          "format": "int64"
        },
        "exclusion": {
          "type": "number",
          "format": "int64"
        },
        "duplicate": {
          "type": "number",
          "format": "int64"
        },
        "tm": {
          "type": "number",
          "format": "int64"
        },
        "dtp": {
          "type": "number",
          "format": "int64"
        },
        "final": {
          "type": "number",
          "format": "int64"
        }
      }
    },
    "pricing_analysis": {
      "type": [
        "object",
        "null"
      ],
      "description": "Line-item breakdown of how the quote price was assembled. Components\nare self-describing (kind, label, unit, …) so the UI renders one list\nregardless of what the quote contains — translation lines, DTP, fees,\ninterpretation hours and discounts can all coexist in the same array.\nService-specific raw values that don't fit the generic component shape\nare exposed via `meta` for UI affordances like badges/tooltips.\n",
      "properties": {
        "currency": {
          "type": "string",
          "description": "Currency for `total` and every `components[*].amount`."
        },
        "total": {
          "type": "number",
          "format": "float",
          "description": "Sum of all component amounts (negative discounts subtract)."
        },
        "components": {
          "type": "array",
          "description": "Renderable line items in display order.",
          "items": {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "description": "Component type so the UI can pick styling/icons.",
                "enum": [
                  "rate_x_quantity",
                  "flat_fee",
                  "minimum_fee",
                  "discount",
                  "surcharge"
                ]
              },
              "label": {
                "type": "string",
                "description": "Primary line text (e.g. \"On-Site Consecutive interpretation\")."
              },
              "quantity": {
                "type": "number",
                "format": "float",
                "description": "Present for `rate_x_quantity` (e.g. hours, words)."
              },
              "unit": {
                "type": "string",
                "description": "Unit for `quantity` (e.g. \"hour\", \"word\")."
              },
              "unit_price": {
                "type": "number",
                "format": "float",
                "description": "Per-unit price for `rate_x_quantity` components."
              },
              "amount": {
                "type": "number",
                "format": "float",
                "description": "Contribution to `total` (negative for discounts)."
              },
              "note": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Optional secondary line (e.g. \"1h 2m requested · 3h minimum applied\")."
              }
            }
          }
        },
        "meta": {
          "type": "object",
          "description": "Free-form raw values that don't fit the generic component shape\nbut the UI may want for badges/tooltips. Contents vary by quote\ntype — the UI cherry-picks fields it understands.\n",
          "additionalProperties": true
        }
      }
    },
    "documents": {
      "type": "object",
      "properties": {
        "documents": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/Document"
          }
        },
        "meta": {
          "$ref": "#/$defs/PagingMeta"
        }
      }
    },
    "coupon_code": {
      "type": "object",
      "properties": {
        "code": {
          "type": "string"
        },
        "id": {
          "type": "number"
        }
      }
    },
    "price": {
      "type": "object",
      "properties": {
        "amount": {
          "type": "number",
          "format": "float"
        },
        "currency": {
          "type": "string",
          "default": "usd"
        },
        "base_amount": {
          "type": "number",
          "format": "float"
        },
        "base_currency": {
          "type": "string",
          "default": "usd"
        },
        "usd_amount": {
          "description": "USD is our base pricing currency. If `currency` is different, this will help.",
          "type": "number",
          "format": "float"
        }
      }
    },
    "price_without_discount": {
      "type": "object",
      "properties": {
        "amount": {
          "type": "number",
          "format": "float"
        },
        "currency": {
          "type": "string",
          "default": "usd"
        },
        "base_amount": {
          "type": "number",
          "format": "float"
        },
        "base_currency": {
          "type": "string",
          "default": "usd"
        },
        "usd_amount": {
          "description": "USD is our base pricing currency. If `currency` is different, this will help.",
          "type": "number",
          "format": "float"
        }
      }
    },
    "status": {
      "$ref": "#/$defs/ProjectStatus"
    },
    "delivery_at": {
      "description": "Unix epoch time",
      "type": "integer",
      "format": "int64"
    },
    "estimated_delivery_at": {
      "description": "Estimated time string",
      "type": "string"
    },
    "completed_on": {
      "type": "string",
      "format": "date-time",
      "description": "the date-time notation as defined by RFC 3339, section 5.6, for example, 2017-07-21T17:32:28Z"
    },
    "is_certified": {
      "type": "boolean"
    },
    "certificationType": {
      "type": "string"
    },
    "usState": {
      "type": "string"
    },
    "is_continuous": {
      "type": "boolean"
    },
    "is_evaluation": {
      "type": "boolean"
    },
    "is_interpretation": {
      "type": "boolean"
    },
    "interpretation": {
      "$ref": "#/$defs/InterpretationRequest"
    },
    "alternative_prices": {
      "$ref": "#/$defs/InterpretationPrices"
    },
    "is_upgrade_quote": {
      "type": "boolean"
    },
    "upgraded_to_quote_id": {
      "type": "integer",
      "description": "If this evaluation project was upgraded, the ID of the upgrade quote."
    },
    "continuous_project_type": {
      "type": "string"
    },
    "subjects": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "valid_until": {
      "description": "Unix epoch time. Available only if status is `pending`.",
      "type": "integer",
      "format": "int64"
    },
    "reference_code": {
      "type": "string"
    },
    "client": {
      "description": "User entity for Client. This is only given when project is requested with detailed=true",
      "$ref": "#/$defs/User"
    },
    "callback_url": {
      "type": "string",
      "description": "Callback URL to notify when project status changed."
    },
    "custom": {
      "type": "object",
      "description": "Custom data provided while creating a new project."
    },
    "styleguides": {
      "type": "object",
      "properties": {
        "styleguides": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/Document"
          }
        },
        "meta": {
          "$ref": "#/$defs/PagingMeta"
        }
      }
    },
    "progress": {
      "$ref": "#/$defs/Progress"
    },
    "vendors": {
      "description": "Per-target-language vendors joined or working in the project. Returned when `with[]=vendors`. Customer dashboards receive a redacted shape (first name, surname initial, avatar, is_proofreader); exclusive API clients receive the full User object.",
      "$ref": "#/$defs/ProjectVendors"
    },
    "created_at": {
      "description": "Unix epoch time",
      "type": "integer",
      "format": "int64"
    },
    "method": {
      "$ref": "#/$defs/QuoteMethod"
    },
    "targetOrganization": {
      "type": "string"
    },
    "services": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "is_same_day_delivery": {
      "description": "Same day setting for Evaluation files",
      "type": "boolean"
    },
    "is_wage_level_selected": {
      "description": "Indicates whether an additional wage level selection has been requested for Evaluation files.",
      "type": "boolean"
    },
    "is_soc_selected": {
      "description": "Indicates whether an additional Standard Occupational Classification (SOC) selection has been requested for Evaluation files.",
      "type": "boolean"
    },
    "ask_dtp_service": {
      "description": "Indicates whether DTP service is available and should be offered to the user based on corporate pricing availability.",
      "type": "boolean"
    },
    "translation_addon": {
      "$ref": "#/$defs/TranslationAddon"
    },
    "show_dtp_info": {
      "description": "Indicates whether DTP info link should be shown based on corporate status and file page counts.",
      "type": "boolean"
    },
    "ask_post_edit_service": {
      "description": "Indicates whether Post-Edit service is available and should be offered to the user based on corporate pricing availability.",
      "type": "boolean"
    },
    "notes": {
      "description": "User note for the project optional",
      "type": "string"
    },
    "errors": {
      "type": "array",
      "description": "A list of errors. Visible when creating a project and uploading your documents at the same time, in case of multiple errors.",
      "items": {
        "$ref": "#/$defs/Error"
      }
    },
    "links": {
      "$ref": "#/$defs/ProjectLinks"
    }
  },
  "$defs": {
    "AdditionalErrorData": {
      "type": "object",
      "properties": {
        "file_id": {
          "type": "string"
        },
        "file_size": {
          "type": "integer"
        },
        "additional_info": {
          "type": "string"
        }
      }
    },
    "Analysis": {
      "type": "object",
      "properties": {
        "base": {
          "$ref": "#/$defs/WordCountResult"
        },
        "duplicate": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/WordCountResult"
          }
        },
        "matches": {
          "$ref": "#/$defs/TMResult"
        },
        "mtm": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/MTResult"
          }
        },
        "styles": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/StyleResult"
          }
        },
        "style_density": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/StyleDensityResult"
          }
        },
        "exclusion": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "previously_billed": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/WordCountResult"
          }
        },
        "detected_language": {
          "type": "string"
        },
        "columns_summary": {
          "$ref": "#/$defs/ColumnsSummaryResult"
        }
      }
    },
    "ColumnsSummaryResult": {
      "type": "object",
      "properties": {
        "sheets": {
          "type": "object",
          "additionalProperties": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "recommendations": {
          "type": "object",
          "additionalProperties": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "delimiter": {
          "type": "string"
        },
        "enclosure": {
          "type": "string"
        }
      }
    },
    "Document": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64"
        },
        "project_id": {
          "type": "integer",
          "format": "int64"
        },
        "name": {
          "type": "string"
        },
        "data": {
          "type": "string",
          "format": "byte",
          "description": "Base64-encoded content of your file. Transient field used while uploading a file via JSON content."
        },
        "scheme": {
          "type": "object"
        },
        "services": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "subject": {
          "type": "string"
        },
        "file_type": {
          "type": "string",
          "description": "Extension of the file"
        },
        "source_language": {
          "type": "string"
        },
        "target_languages": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "word_count": {
          "type": "integer",
          "format": "int64"
        },
        "process_status": {
          "$ref": "#/$defs/FileProcessStatus"
        },
        "review_in_manual_editor": {
          "type": "boolean"
        },
        "manual_files": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/ManualFile"
          }
        },
        "translation_due_at": {
          "description": "Unix epoch — when this manual file's translation is due. Same across all languages on the file.",
          "type": [
            "integer",
            "null"
          ],
          "format": "int64"
        },
        "translation_is_overdue": {
          "description": "True when the manual translation deadline has passed.",
          "type": "boolean"
        },
        "proofreading_due_at": {
          "description": "Unix epoch — when this manual file's proofreading is due. Same across all languages on the file.",
          "type": [
            "integer",
            "null"
          ],
          "format": "int64"
        },
        "proofreading_is_overdue": {
          "description": "True when the manual proofreading deadline has passed.",
          "type": "boolean"
        },
        "search_score": {
          "type": "number",
          "format": "float"
        },
        "has_custom_package": {
          "type": "boolean"
        },
        "uploaded_at": {
          "description": "Unix epoch time",
          "type": "integer",
          "format": "int64"
        },
        "analysis": {
          "$ref": "#/$defs/Analysis"
        },
        "links": {
          "$ref": "#/$defs/DocumentLinks"
        },
        "method": {
          "$ref": "#/$defs/ProcessMethod"
        },
        "has_embedded_image": {
          "type": "boolean"
        },
        "may_contain_watermark": {
          "type": "boolean"
        },
        "price": {
          "description": "Price override for custom file/service or subscription item. Not editable for usual translation operations. Only visible for updates, not reads.",
          "type": "object",
          "properties": {
            "amount": {
              "type": "number",
              "format": "float"
            },
            "currency": {
              "type": "string",
              "default": "USD"
            }
          }
        },
        "content": {
          "description": "Text content of the file. Only available for style guide files when 'content' is included in the 'with' parameter.",
          "type": "string"
        }
      }
    },
    "DocumentLinks": {
      "allOf": [
        {
          "$ref": "#/$defs/LinksMeta"
        },
        {
          "type": "object",
          "properties": {
            "download": {
              "$ref": "#/$defs/Href"
            },
            "project": {
              "$ref": "#/$defs/Href"
            },
            "thumbnail": {
              "description": "Thumbnail preview URL of the document. If doc has a page structure, this is probably only the first page.",
              "$ref": "#/$defs/Href"
            },
            "preview-box": {
              "description": "Box.com URL to preview this document. This URL is temporary. You need to re-fetch the file to refresh the Box.com preview URL. Available for documents and style guides.",
              "$ref": "#/$defs/Href"
            },
            "preview-pdf": {
              "description": "This is our fallback preview URL, providing a PDF file. Use this file to embed in your PDF viewer. Available for documents and style guides.",
              "$ref": "#/$defs/Href"
            },
            "preview-pdf-viewer": {
              "description": "This is another version of preview-pdf, this time pointing to a preview viewer page on front application. This page requires authentication and comes with its own PDF viewer.",
              "$ref": "#/$defs/Href"
            },
            "editors": {
              "type": "object",
              "additionalProperties": {
                "description": "MotaWord editor link for this file, in this language code.",
                "$ref": "#/$defs/Href"
              }
            },
            "admins": {
              "type": "object",
              "additionalProperties": {
                "description": "MotaWord admin link for this file, in this language code.",
                "$ref": "#/$defs/Href"
              }
            },
            "progress": {
              "description": "Progress endpoint URL for this file",
              "$ref": "#/$defs/Href"
            },
            "strings": {
              "description": "Strings endpoint URL for this file",
              "$ref": "#/$defs/Href"
            },
            "highlighted": {
              "description": "Highlighted source preview URL for this file",
              "$ref": "#/$defs/Href"
            }
          }
        }
      ]
    },
    "DocumentProgress": {
      "type": "object",
      "description": "Per-language progress for a single document. Keys are common language codes.",
      "properties": {
        "languages": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/ProgressSub"
          }
        }
      }
    },
    "Error": {
      "type": "object",
      "properties": {
        "code": {
          "type": "string"
        },
        "http_code": {
          "type": "integer",
          "format": "int32"
        },
        "name": {
          "type": "string"
        },
        "message": {
          "type": "string"
        },
        "help": {
          "type": "string"
        },
        "extra_data": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/AdditionalErrorData"
          },
          "description": "Additional structured data related to the error."
        }
      }
    },
    "FileProcessStatus": {
      "description": "Where a file is in analysis. `waiting` and `retrying` mean the word count is not final yet, so a zero word_count carries no meaning until this reads `processed` or one of the failure states.",
      "type": "string",
      "enum": [
        "waiting",
        "processed",
        "retrying",
        "duplicate",
        "unsupported",
        "too_small",
        "too_large",
        "drive_error"
      ]
    },
    "Href": {
      "type": "object",
      "properties": {
        "href": {
          "type": "string"
        }
      }
    },
    "InterpretationModalityPrice": {
      "description": "Coupon-applied, currency-converted price for one interpretation modality, with a matching breakdown.",
      "type": "object",
      "properties": {
        "amount": {
          "type": "number",
          "format": "float",
          "description": "Local-currency amount after coupon."
        },
        "currency": {
          "type": "string",
          "description": "Local currency the customer pays in."
        },
        "base_amount": {
          "type": "number",
          "format": "float",
          "description": "Base-currency amount after coupon."
        },
        "base_currency": {
          "type": "string",
          "description": "Platform base currency (typically usd)."
        },
        "analysis": {
          "$ref": "#/$defs/InterpretationPricingAnalysis"
        }
      }
    },
    "InterpretationPrices": {
      "description": "Cross-modality price preview for an interpretation quote. The same\nrequest priced under each modality (on_site / video / phone), with\nany active coupon applied. Lets the wizard show all three side-by-side\nwithout creating a quote per modality.\n",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "on_site": {
          "$ref": "#/$defs/InterpretationModalityPrice"
        },
        "video": {
          "$ref": "#/$defs/InterpretationModalityPrice"
        },
        "phone": {
          "$ref": "#/$defs/InterpretationModalityPrice"
        }
      }
    },
    "InterpretationPricingAnalysis": {
      "description": "Detailed breakdown of how the interpretation price for one modality was computed.",
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "time_mode": {
          "type": "string",
          "description": "shared (one window applied to every day) | per_day (entry per date)"
        },
        "requested_hours": {
          "type": "number",
          "format": "float",
          "description": "Hours the customer asked for, before the minimum-hours floor."
        },
        "minimum_hours": {
          "type": "number",
          "format": "float",
          "description": "Modality minimum hours floor applied per day."
        },
        "billable_hours": {
          "type": "number",
          "format": "float",
          "description": "Hours actually billed after the minimum-hours floor."
        },
        "per_hour_rate": {
          "type": "number",
          "format": "float",
          "description": "Per-hour rate used (DB rate or Config fallback)."
        },
        "currency": {
          "type": "string"
        },
        "travel_fee": {
          "type": "number",
          "format": "float",
          "description": "Per-day travel fee (on-site only; 0 otherwise)."
        },
        "travel_fee_total": {
          "type": "number",
          "format": "float",
          "description": "travel_fee × day_count."
        },
        "day_count": {
          "type": "integer"
        },
        "hours_per_day": {
          "type": "number",
          "format": "float",
          "description": "Shared-mode hours per day. 0 in per_day mode."
        },
        "days": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "date": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "start_time": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "end_time": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "requested_hours": {
                "type": "number",
                "format": "float"
              },
              "billable_hours": {
                "type": "number",
                "format": "float"
              }
            }
          }
        }
      }
    },
    "InterpretationRequest": {
      "type": "object",
      "description": "Extra details for an interpretation project. Stored verbatim as the contents of a placeholder quote_file.",
      "properties": {
        "setting": {
          "type": "string",
          "enum": [
            "on_site",
            "video",
            "phone"
          ]
        },
        "mode": {
          "type": "string",
          "enum": [
            "consecutive",
            "simultaneous"
          ]
        },
        "subject_matter": {
          "type": "string",
          "enum": [
            "deposition",
            "uscis_interview",
            "hearing",
            "mediation",
            "parent_meeting",
            "other"
          ]
        },
        "subject_details": {
          "type": "string"
        },
        "court_certified": {
          "type": "boolean"
        },
        "context_note": {
          "type": "string",
          "maxLength": 2000,
          "description": "Free-text brief the customer writes for the interpreter (e.g. patient\ncontext, sensitive terms, names). Editable by the client on the project\ndetail page for every interpretation setting; read-only to vendors. For\nvideo/AI it is mirrored into the live session metadata.\n"
        },
        "domain": {
          "type": "string",
          "maxLength": 50,
          "description": "Domain tag for the brief (medical/legal/business/education/social/general)."
        },
        "date_selection_type": {
          "type": "string",
          "enum": [
            "single",
            "range",
            "multiple"
          ]
        },
        "dates": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "date"
          }
        },
        "start_time": {
          "type": "string",
          "description": "Daily start time in HH:MM (24h), applied to each selected date."
        },
        "end_time": {
          "type": "string",
          "description": "Daily end time in HH:MM (24h), applied to each selected date."
        },
        "time_mode": {
          "type": "string",
          "description": "Controls how the interpreter's hours are computed across days:\n- `shared` (default): top-level start_time/end_time apply to every selected date.\n- `per_day`: each entry in `daily_times` carries its own start_time/end_time;\n  pricing sums per-entry hours instead of multiplying a single shift by the day count.\nMissing/null defaults to `shared` so existing quotes keep their pricing behavior.\n",
          "enum": [
            "shared",
            "per_day"
          ]
        },
        "daily_times": {
          "type": "array",
          "description": "Used only when `time_mode` is `per_day`. Each entry overrides the shared\nstart_time/end_time for that specific date. Entries missing start_time\nor end_time contribute 0 hours and are ignored for pricing.\n",
          "items": {
            "type": "object",
            "properties": {
              "date": {
                "type": "string",
                "format": "date"
              },
              "start_time": {
                "type": "string",
                "description": "Per-day start time in HH:MM (24h)."
              },
              "end_time": {
                "type": "string",
                "description": "Per-day end time in HH:MM (24h)."
              }
            }
          }
        },
        "timezone": {
          "type": "string",
          "description": "IANA-style short code for the time zone the start/end times are expressed in. Required for video and phone interpretation.",
          "enum": [
            "eastern",
            "central",
            "mountain",
            "pacific",
            "alaska",
            "hawaii"
          ]
        },
        "location": {
          "type": "object",
          "properties": {
            "address": {
              "type": "string",
              "description": "Street address (Address Line 1). For example, \"123 Main St\"."
            },
            "address_line_2": {
              "type": "string",
              "description": "Optional second address line such as an apartment, suite, unit, or floor."
            },
            "city": {
              "type": "string"
            },
            "state": {
              "type": "string",
              "description": "USPS two-letter state abbreviation (e.g. \"NY\", \"CA\")."
            },
            "zip_code": {
              "type": "string",
              "description": "US ZIP code. Accepts 5-digit (\"10001\") or ZIP+4 (\"10001-1234\")."
            },
            "country": {
              "type": "string",
              "description": "Two-letter ISO country code (e.g. \"US\", \"CA\", \"GB\"). Inferred from the address by the AI / Places autocomplete; surfaces in dispatch + pricing rules."
            }
          }
        },
        "contact": {
          "type": "object",
          "description": "Person who will be present at the on-site location or who we will dial for phone interpretation. Required for on-site and phone settings; video sessions don't carry a contact (the video link routes everyone in).",
          "properties": {
            "name": {
              "type": "string"
            },
            "phone": {
              "type": "string"
            },
            "email": {
              "type": "string"
            }
          }
        },
        "video_conference": {
          "type": "object",
          "description": "How the video session's meeting link is provided. Only meaningful when\nsetting=video. `mode` chooses the source — auto-generated by us\n(Google Meet), customer-supplied at booking, or shared later.\n",
          "properties": {
            "mode": {
              "type": "string",
              "enum": [
                "motaword",
                "customer",
                "later"
              ]
            },
            "url": {
              "type": "string",
              "description": "Customer-supplied meeting URL when `mode=customer`."
            },
            "meeting_id": {
              "type": "string",
              "description": "Optional meeting ID (e.g. Zoom). Only used when `mode=customer`."
            },
            "passcode": {
              "type": "string",
              "description": "Optional meeting passcode/password. Only used when `mode=customer`."
            }
          }
        },
        "chat": {
          "type": "array",
          "description": "Persisted AI conversation history for this interpretation request. Append-only — one entry per turn (user or assistant). Captured at Step 1 Continue / Step 2 Next / order-now checkpoints, so the admin view can show what the customer asked and how the AI replied. The transcript is also kept in localStorage on the customer side; this field is the server-side mirror.",
          "items": {
            "type": "object",
            "properties": {
              "role": {
                "type": "string",
                "enum": [
                  "user",
                  "assistant"
                ]
              },
              "text": {
                "type": "string"
              },
              "kind": {
                "type": "string",
                "description": "Prompt schema that produced this turn. interpretation_search_turn = Step 1, interpretation_detail_turn = Step 2."
              },
              "hidden": {
                "type": "boolean",
                "description": "True for synthetic user turns the UI sends (e.g. Step 2 mount trigger). Display them in admin with a \"synthetic\" tag so the operator knows the customer didn't type them."
              },
              "openai_response_id": {
                "type": "string",
                "description": "OpenAI Responses API response_id for assistant turns. Lets the operator open the corresponding thread in the OpenAI dashboard for deep debugging without needing to wire a direct link from admin."
              }
            }
          }
        },
        "openai_conversation_id": {
          "type": "string",
          "description": "The latest OpenAI response_id of this interpretation's conversation chain — the anchor for resuming via previous_response_id. Stored alongside chat so the OpenAI thread can be located even after the customer's localStorage is cleared."
        }
      }
    },
    "LanguagePair": {
      "type": "object",
      "properties": {
        "source_language": {
          "type": "string"
        },
        "target_language": {
          "type": "string"
        }
      }
    },
    "LinksMeta": {
      "type": "object",
      "properties": {
        "self": {
          "$ref": "#/$defs/Href"
        }
      }
    },
    "MTResult": {
      "type": "object",
      "properties": {
        "language_code": {
          "type": "string"
        },
        "mt_matches": {
          "$ref": "#/$defs/WordCountResult"
        }
      }
    },
    "ManualFile": {
      "type": "object",
      "properties": {
        "language": {
          "type": "string"
        },
        "translationFileId": {
          "description": "Translation-side file id. Pass this as :manualFileId on translation-workflow action endpoints (assign/approve/giveup translation).",
          "type": "integer",
          "format": "int64"
        },
        "proofreadingFileId": {
          "description": "Proofreading-side file id. Pass this as :manualFileId on proofreading-workflow action endpoints (assign/approve/giveup proofreading).",
          "type": "integer",
          "format": "int64"
        },
        "driveFileId": {
          "type": "integer",
          "format": "int64"
        },
        "isTranslated": {
          "type": "boolean"
        },
        "isProofread": {
          "type": "boolean"
        },
        "state": {
          "description": "State machine position for this manual file-language row.",
          "type": "string",
          "enum": [
            "unassigned",
            "translation_in_progress",
            "translated",
            "proofreading_in_progress",
            "proofread"
          ]
        },
        "translatorId": {
          "type": [
            "integer",
            "null"
          ],
          "format": "int64"
        },
        "proofreaderId": {
          "type": [
            "integer",
            "null"
          ],
          "format": "int64"
        },
        "isMineTranslator": {
          "description": "True when the requesting vendor is the assigned translator for this language.",
          "type": "boolean"
        },
        "isMineProofreader": {
          "description": "True when the requesting vendor is the assigned proofreader for this language.",
          "type": "boolean"
        },
        "translator": {
          "$ref": "#/$defs/User"
        },
        "proofreader": {
          "$ref": "#/$defs/User"
        },
        "driveLink": {
          "type": "string"
        },
        "translationRate": {
          "type": [
            "number",
            "null"
          ],
          "format": "float",
          "description": "Vendor per-word translation rate for this file (from the assignment). Null when fixed-rate or not applicable."
        },
        "proofreadingRate": {
          "type": [
            "number",
            "null"
          ],
          "format": "float",
          "description": "Vendor per-word proofreading rate for this file. Null when fixed-rate or not applicable."
        },
        "fixedRate": {
          "type": [
            "number",
            "null"
          ],
          "format": "float",
          "description": "Flat fixed amount for this file (overrides per-word). Null when the file is priced per-word."
        }
      }
    },
    "PagingLinksMeta": {
      "allOf": [
        {
          "$ref": "#/$defs/LinksMeta"
        },
        {
          "type": "object",
          "properties": {
            "next": {
              "type": "string"
            },
            "previous": {
              "type": "string"
            }
          }
        }
      ]
    },
    "PagingMeta": {
      "type": "object",
      "properties": {
        "paging": {
          "type": "object",
          "properties": {
            "page": {
              "type": "integer",
              "format": "int64",
              "default": 1
            },
            "per_page": {
              "type": "integer",
              "format": "int64",
              "default": 10
            },
            "count": {
              "type": "integer",
              "format": "int64"
            },
            "total_count": {
              "type": "integer",
              "format": "int64"
            },
            "links": {
              "$ref": "#/$defs/PagingLinksMeta"
            }
          }
        }
      }
    },
    "ProcessMethod": {
      "type": "string",
      "enum": [
        "tika",
        "tms",
        "ocr",
        "evaluation",
        "evaluation_single_source",
        "evaluation_course_by_course_grade",
        "evaluation_course_by_course_credit",
        "evaluation_course_by_course_gpa",
        "evaluation_h_1b_position",
        "evaluation_h_1b_soc",
        "evaluation_h_1b_wage_level",
        "evaluation_h_1b_work_experience",
        "evaluation_h_1b_qualifications_academic",
        "evaluation_h_1b_qualifications_experience",
        "evaluation_h_1b_combo",
        "evaluation_l1a",
        "evaluation_l1b",
        "evaluation_tn_position",
        "evaluation_tn_bq",
        "evaluation_tn_combo",
        "evaluation_extraordinary_ability",
        "evaluation_o_1a_criteria",
        "evaluation_o_1b_arts_criteria",
        "evaluation_o_1b_motion_picture_criteria",
        "evaluation_eb_1a_criteria",
        "evaluation_eb_1b_criteria",
        "evaluation_eb2_exceptional_ability",
        "evaluation_niw",
        "interpretation_onsite",
        "interpretation_video",
        "interpretation_phone",
        "interpretation_ai",
        "interpretation_video_ondemand",
        "interpretation_phone_ondemand",
        "native",
        "website",
        "text",
        "zip",
        "tms_active",
        "tm",
        "video",
        "audio",
        "media",
        "custom"
      ]
    },
    "ProfileSurvey": {
      "type": "object",
      "properties": {
        "experience": {
          "type": "string"
        },
        "daily_translation_capacity": {
          "type": "string"
        },
        "daily_proofreading_capacity": {
          "type": "string"
        },
        "translator_association": {
          "type": "string"
        },
        "is_certified_translator": {
          "type": "string"
        },
        "is_sworn_translator": {
          "type": "string"
        },
        "proofreader_experience": {
          "type": "string"
        },
        "current_services": {
          "type": "string"
        },
        "sdl_trados": {
          "type": "string"
        },
        "memoq": {
          "type": "string"
        },
        "memsource": {
          "type": "string"
        },
        "smartling": {
          "type": "string"
        },
        "smartcat": {
          "type": "string"
        },
        "subtitle_edit": {
          "type": "string"
        },
        "subtitle_workshop": {
          "type": "string"
        },
        "wordbee": {
          "type": "string"
        },
        "xtm": {
          "type": "string"
        },
        "transsuite_2000": {
          "type": "string"
        },
        "xbench": {
          "type": "string"
        },
        "wordfast": {
          "type": "string"
        },
        "omegat": {
          "type": "string"
        },
        "dtp_software": {
          "type": "string"
        },
        "software": {
          "type": "string"
        },
        "working_timezone": {
          "type": "string"
        },
        "specialization": {
          "type": "string"
        },
        "work_with": {
          "type": "string"
        },
        "work_type": {
          "type": "string"
        },
        "working_as": {
          "type": "string"
        },
        "vendor_profile_lsp": {
          "type": "string"
        },
        "reference": {
          "type": "string",
          "description": "JSON-encoded array of references — `[{ fullName, organization, jobTitle, email, phone, relationship }]`, up to 3 entries."
        },
        "skype_id": {
          "type": "string"
        },
        "interpreter_experience_years": {
          "type": "string"
        },
        "dialect_specifications": {
          "type": "string"
        },
        "interpretation_specialization": {
          "type": "string"
        },
        "has_security_clearance": {
          "type": "string"
        },
        "security_clearance_level": {
          "type": "string"
        },
        "availability": {
          "type": "string"
        },
        "geographic_coverage": {
          "type": "string"
        },
        "device_type": {
          "type": "string"
        },
        "operating_system": {
          "type": "string"
        },
        "has_webcam": {
          "type": "string"
        },
        "has_noise_canceling_headset": {
          "type": "string"
        },
        "internet_connection_type": {
          "type": "string"
        },
        "download_speed": {
          "type": "string"
        },
        "video_platforms": {
          "type": "string"
        },
        "work_authorization_status": {
          "type": "string"
        },
        "certifications": {
          "type": "string",
          "description": "JSON-encoded array of certifications — `[{ name, nameOther, issuingOrganization, certificationNumber, issueDate, expirationDate, certificateFile }]`. `certificateFile` is the stored filename from POST /vendor/certificate-file."
        },
        "professional_bio": {
          "type": "string",
          "description": "Plain-text professional bio / experience summary shown on the vendor profile. 100-1000 chars enforced on the frontend."
        },
        "background_check_consent": {
          "type": "string",
          "description": "Legal & Agreements consent — `yes` once the vendor agrees to the background check."
        },
        "subcontractor_agreement": {
          "type": "string",
          "description": "Legal & Agreements consent — `yes` once the vendor agrees to the subcontractor terms."
        },
        "confidentiality_agreement": {
          "type": "string",
          "description": "Legal & Agreements consent — `yes` once the vendor agrees to the confidentiality terms."
        },
        "electronic_signature": {
          "type": "string",
          "description": "Vendor's typed legal name, used as the electronic signature on the Legal & Agreements step."
        },
        "signature_date": {
          "type": "string",
          "description": "Date the Legal & Agreements step was signed. Auto-stamped on save."
        }
      }
    },
    "Progress": {
      "allOf": [
        {
          "type": "object",
          "properties": {
            "project_status": {
              "$ref": "#/$defs/ProjectStatus"
            },
            "languages": {
              "type": "object",
              "additionalProperties": {
                "$ref": "#/$defs/ProgressSub"
              }
            },
            "documents": {
              "type": "object",
              "description": "Per-(document, language) progress. Keys are document IDs as strings. Empty for completed projects, TMS-less projects, and continuous projects.",
              "additionalProperties": {
                "$ref": "#/$defs/DocumentProgress"
              }
            },
            "links": {
              "$ref": "#/$defs/ProgressLink"
            },
            "vendor_translation_words_done": {
              "type": "integer",
              "format": "int64",
              "description": "Source words this vendor has translated so far on this project. Vendor-only — null/absent for client requesters."
            },
            "vendor_proofreading_words_done": {
              "type": "integer",
              "format": "int64",
              "description": "Source words this vendor has *purely* proofread so far on this project —\npost-edit work is reported separately on `vendor_post_edit_words_done`.\nVendor-only — null/absent for client requesters.\n"
            },
            "vendor_post_edit_words_done": {
              "type": "integer",
              "format": "int64",
              "description": "Source words this vendor has post-edited so far on this project.\nPost-edit is a distinct billing line from pure proofreading\n(often a higher per-word rate) — admins see them split on the\ncontributions screen via Project::costReport(), and this field\nmirrors that split for the vendor-facing API. Vendor-only.\n"
            },
            "vendor_total_words": {
              "type": "integer",
              "format": "int64",
              "description": "Total source word count assigned to this vendor on this project. Vendor-only."
            },
            "vendor_earnings": {
              "type": "number",
              "format": "float",
              "description": "Running USD earnings for this vendor on this project (translation + proofreading + post-edit). Vendor-only."
            }
          }
        },
        {
          "$ref": "#/$defs/ProgressSub"
        }
      ]
    },
    "ProgressLink": {
      "allOf": [
        {
          "$ref": "#/$defs/LinksMeta"
        },
        {
          "type": "object",
          "properties": {
            "project": {
              "$ref": "#/$defs/Href"
            }
          }
        }
      ]
    },
    "ProgressSub": {
      "type": "object",
      "properties": {
        "total": {
          "type": "number",
          "format": "float"
        },
        "translation": {
          "type": "number",
          "format": "float"
        },
        "proofreading": {
          "type": "number",
          "format": "float"
        },
        "word_count": {
          "type": "integer",
          "format": "int64"
        }
      }
    },
    "ProjectLinks": {
      "allOf": [
        {
          "$ref": "#/$defs/LinksMeta"
        },
        {
          "type": "object",
          "properties": {
            "documents": {
              "$ref": "#/$defs/Href"
            },
            "glossaries": {
              "$ref": "#/$defs/Href"
            },
            "styleguides": {
              "$ref": "#/$defs/Href"
            },
            "webhooks": {
              "$ref": "#/$defs/Href"
            },
            "invoice": {
              "$ref": "#/$defs/Href"
            },
            "activities": {
              "$ref": "#/$defs/Href"
            },
            "comments": {
              "$ref": "#/$defs/Href"
            },
            "progress": {
              "$ref": "#/$defs/Href"
            },
            "package": {
              "$ref": "#/$defs/Href"
            },
            "download": {
              "$ref": "#/$defs/Href"
            },
            "receipt": {
              "$ref": "#/$defs/Href"
            },
            "payment": {
              "$ref": "#/$defs/Href"
            },
            "edit": {
              "$ref": "#/$defs/Href"
            },
            "quote-pdf": {
              "$ref": "#/$defs/Href"
            }
          }
        }
      ]
    },
    "ProjectStatus": {
      "type": "string",
      "enum": [
        "pending",
        "started",
        "completed",
        "translated",
        "proofread"
      ]
    },
    "ProjectVendors": {
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "translators": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/User"
            }
          },
          "proofreader": {
            "$ref": "#/$defs/User"
          }
        }
      }
    },
    "QuoteMethod": {
      "type": "string",
      "enum": [
        null,
        "translation",
        "transcription",
        "regular",
        "manual",
        "mixed",
        "dtp",
        "transcript",
        "mt",
        "post_edit",
        "custom",
        "evaluation",
        "evaluation_single_source",
        "evaluation_course_by_course_grade",
        "evaluation_course_by_course_credit",
        "evaluation_course_by_course_gpa",
        "evaluation_h_1b_position",
        "evaluation_h_1b_soc",
        "evaluation_h_1b_wage_level",
        "evaluation_h_1b_work_experience",
        "evaluation_h_1b_qualifications_academic",
        "evaluation_h_1b_qualifications_experience",
        "evaluation_h_1b_combo",
        "evaluation_l1a",
        "evaluation_l1b",
        "evaluation_tn_position",
        "evaluation_tn_bq",
        "evaluation_tn_combo",
        "evaluation_extraordinary_ability",
        "evaluation_o_1a_criteria",
        "evaluation_o_1b_arts_criteria",
        "evaluation_o_1b_motion_picture_criteria",
        "evaluation_eb_1a_criteria",
        "evaluation_eb_1b_criteria",
        "evaluation_eb2_exceptional_ability",
        "evaluation_niw",
        "interpretation_onsite",
        "interpretation_video",
        "interpretation_phone",
        "interpretation_ai",
        "interpretation_video_ondemand",
        "interpretation_phone_ondemand"
      ]
    },
    "StyleDensityResult": {
      "type": "object",
      "properties": {
        "word_count": {
          "type": "integer"
        },
        "rule": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "text_units": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "StyleResult": {
      "type": "object",
      "properties": {
        "content": {
          "type": "string"
        },
        "styles": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "content_coded": {
          "type": "string"
        }
      }
    },
    "TMResult": {
      "type": "object",
      "properties": {
        "language_code": {
          "type": "string"
        },
        "project_tm_matches": {
          "$ref": "#/$defs/WordCountResult"
        },
        "imported_tm_matches": {
          "$ref": "#/$defs/WordCountResult"
        },
        "prospective_tm_matches": {
          "$ref": "#/$defs/WordCountResult"
        }
      }
    },
    "TranslationAddon": {
      "type": "object",
      "description": "Certified-translation add-on offered on evaluation quotes whose documents are not in English. The amount is already included in the parent quote's price.\n",
      "properties": {
        "available": {
          "type": "boolean",
          "description": "Whether the add-on can be offered for this quote at all."
        },
        "enabled": {
          "type": "boolean",
          "description": "Whether the customer has turned it on."
        },
        "quote_id": {
          "type": [
            "integer",
            "null"
          ],
          "description": "The linked translation quote, when one exists."
        },
        "document_ids": {
          "type": "array",
          "description": "Evaluation documents currently included in the add-on.",
          "items": {
            "type": "integer"
          }
        },
        "display_share": {
          "type": [
            "number",
            "null"
          ],
          "format": "float",
          "description": "The add-on's coupon-aware slice of the parent quote's displayed total, allocated pro-rata on the amount actually folded into that total. Use this for a price breakdown; `price` is the child quote's own standalone price and does not add up to the parent total. Null when no add-on exists or the parent is not yet priced.\n"
        },
        "price": {
          "type": [
            "object",
            "null"
          ],
          "description": "Price of the translation portion on its own.",
          "properties": {
            "amount": {
              "type": "number",
              "format": "float"
            },
            "currency": {
              "type": "string",
              "default": "usd"
            },
            "base_amount": {
              "type": "number",
              "format": "float"
            },
            "base_currency": {
              "type": "string",
              "default": "usd"
            },
            "usd_amount": {
              "description": "USD is our base pricing currency. If `currency` is different, this will help.",
              "type": "number",
              "format": "float"
            }
          }
        },
        "pricing_status": {
          "type": "string",
          "enum": [
            "none",
            "pending",
            "ready"
          ],
          "description": "`pending` while a copied document is still being counted. The wizard must not show a total or allow checkout until this is `ready`.\n"
        },
        "delivery_in": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Translation duration in minutes, on its own."
        }
      }
    },
    "User": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64"
        },
        "name": {
          "type": "string"
        },
        "first_name": {
          "type": "string"
        },
        "last_name": {
          "type": "string"
        },
        "has_pwd": {
          "type": "boolean"
        },
        "locale": {
          "type": "string",
          "description": "User Locale"
        },
        "timezone": {
          "type": "string"
        },
        "do_not_contact": {
          "type": "boolean"
        },
        "corporate_id": {
          "type": "integer",
          "format": "int64"
        },
        "is_client": {
          "type": "boolean"
        },
        "is_developer": {
          "type": "boolean"
        },
        "is_vendor": {
          "type": "boolean"
        },
        "vendor": {
          "type": "object",
          "properties": {
            "profile_survey": {
              "type": "object",
              "description": "Vendor Profile Survey answers",
              "$ref": "#/$defs/ProfileSurvey"
            },
            "id": {
              "type": "integer",
              "format": "int64"
            },
            "native_language": {
              "type": "string",
              "description": "Native language of user"
            },
            "can_work_manual_files": {
              "type": "boolean"
            },
            "is_frozen": {
              "type": "boolean"
            },
            "is_proofreader": {
              "type": "boolean"
            },
            "language_pairs": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/LanguagePair"
              }
            },
            "pam_tqs": {
              "type": "number",
              "format": "float"
            },
            "vendor_type": {
              "type": "string"
            },
            "vendor_types": {
              "description": "Modern permission-derived capability set — translator / proofreader\n/ interpreter, any subset. Prefer this over `vendor_type` (which is\nthe legacy single-value collapse kept for backward compatibility).\n",
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "translator",
                  "proofreader",
                  "interpreter"
                ]
              }
            },
            "account_status": {
              "description": "Domain-level account state the React VendorAccountAlert banner conditions on.",
              "type": "string"
            },
            "email_open_rate": {
              "type": "number",
              "format": "float"
            },
            "resume_file_name": {
              "description": "Filename (not path) of the resume currently on file. Empty / omitted when no resume is uploaded. Use this to decide whether to show \"Upload resume\" vs \"Replace resume\" on the UI.",
              "type": "string"
            },
            "profile_completed": {
              "description": "True when the vendor has answered all required profile survey questions (see VendorProfileSurvey::VENDOR_PROFILE_REQUIRED_FIELDS).",
              "type": "boolean"
            },
            "translator_agreement_pending": {
              "description": "True when the vendor has not consented to the latest translator-agreement version. The React dashboard renders a blocking re-consent modal on every page when this is true.",
              "type": "boolean"
            }
          }
        },
        "client": {
          "type": "object",
          "properties": {
            "corporate": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer",
                  "format": "int64"
                },
                "name": {
                  "type": "string"
                },
                "logo": {
                  "type": "string"
                },
                "ask_additional_docs": {
                  "type": "boolean"
                }
              }
            },
            "nps": {
              "type": "number",
              "format": "float"
            },
            "subjects": {
              "type": "object",
              "additionalProperties": {
                "type": "integer",
                "format": "int64"
              }
            }
          }
        },
        "status": {
          "type": "string"
        },
        "created_at": {
          "description": "Unix epoch time",
          "type": "integer",
          "format": "int64"
        },
        "last_seen_online_at": {
          "description": "Unix epoch time",
          "type": "integer",
          "format": "int64"
        },
        "profile_picture_path": {
          "type": "string"
        },
        "user_groups": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/UserGroup"
          }
        },
        "native_language": {
          "deprecated": true,
          "type": "string",
          "description": "\\@deprecated. Native language of user"
        },
        "can_work_manual_files": {
          "deprecated": true,
          "description": "\\@deprecated. use `vendor` key",
          "type": "boolean"
        },
        "is_proofreader": {
          "deprecated": true,
          "description": "\\@deprecated. use `vendor` key",
          "type": "boolean"
        },
        "language_pairs": {
          "deprecated": true,
          "description": "\\@deprecated. use `vendor` key",
          "type": "array",
          "items": {
            "$ref": "#/$defs/LanguagePair"
          }
        },
        "project_count": {
          "type": "integer",
          "format": "int64"
        },
        "admin_id": {
          "type": "integer",
          "format": "int64"
        },
        "links": {
          "$ref": "#/$defs/UserLinks"
        }
      }
    },
    "UserGroup": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64"
        },
        "name": {
          "type": "string"
        },
        "corporate_id": {
          "type": "integer",
          "format": "int64"
        },
        "permissions": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      }
    },
    "UserLinks": {
      "allOf": [
        {
          "$ref": "#/$defs/LinksMeta"
        },
        {
          "type": "object",
          "properties": {
            "stats": {
              "$ref": "#/$defs/Href"
            },
            "responsivity": {
              "description": "vendor users only",
              "$ref": "#/$defs/Href"
            },
            "projects": {
              "description": "client users only",
              "$ref": "#/$defs/Href"
            },
            "login_as": {
              "description": "Exculusive users only",
              "$ref": "#/$defs/Href"
            }
          }
        }
      ]
    },
    "WordCountResult": {
      "type": "object",
      "properties": {
        "word_count": {
          "type": "integer"
        },
        "meta": {
          "type": "string"
        }
      }
    }
  }
}