openapi: 3.0.3
info:
  title: Stract API
  description: |
    Get structured output from unstructured inputs

    ## Machine authentication

    Programmatic access to the API is authenticated with an API key. Include the API key in every request as a bearer token in the `authorization` header:

    ```
    authorization: bearer [apiKey]
    ```
  version: 0.9.0
  contact:
    name: Matt
    email: matt@stract-api.com

servers:
  - url: https://api.stract-api.com
    description: Production

security:
  - bearerAuth: []

paths:
  /my_user:
    get:
      summary: Get the current user
      description: Retrieve the profile of the currently authenticated user
      responses:
        '200':
          description: Current user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: User not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    put:
      summary: Edit the current user
      description: Update one or more properties of the currently authenticated user. At least one property must be provided.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EditMyUserRequest'
      responses:
        '200':
          description: Successfully updated user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '400':
          description: Request body has no fields set || User fields are not of the correct type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: User not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /account:
    get:
      summary: Get information about user's account
      description: Retrieve information about the account the current user belongs to
      responses:
        '200':
          description: Current account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
        '401':
          description: All users must be connected to an account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    put:
      summary: Edit the current account
      description: Update the account the current user belongs to. Only account admins may perform this action.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EditAccountRequest'
      responses:
        '200':
          description: Successfully updated account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
        '400':
          description: Account object is missing a required field || Account object field is not the correct type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /account/user:
    get:
      summary: Get the users in the current account
      description: Retrieve all users belonging to the current user's account. Only account admins may perform this action.
      responses:
        '200':
          description: List of account users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AccountUser'
        '401':
          description: Not permitted to access this resource
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      summary: Add a user to the current account
      description: >-
        Create a new user and add them to the current user's account. Only account admins may
        perform this action, and the account must have an active subscription to add other users.
        Accounts with a team subscription are limited to 10 users.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAccountUserRequest'
      responses:
        '200':
          description: Successfully created account user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountUser'
        '400':
          description: Account user object is missing a required field || Account user object field is not the correct type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api-key:
    get:
      summary: Get the current account's API keys
      description: Retrieve all API keys belonging to the current user's account
      responses:
        '200':
          description: List of API keys
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ApiKey'
        '401':
          description: Not permitted to access this resource
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /current_credits:
    get:
      summary: Get the current credit balance
      description: Retrieve the credit balance for the user's account
      responses:
        '200':
          description: Current account credits
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountCreditCache'
        '401':
          description: All users must be connected to an account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /current_org_credits:
    get:
      summary: Get the current organization credit balance
      description: Retrieve the shared organization credit balance for the user's account
      responses:
        '200':
          description: Current organization credits
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountCreditCache'
        '401':
          description: All users must be connected to an account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /llm_model:
    get:
      summary: Get the available LLM models
      description: Retrieve the list of LLM models that can be selected via llm_model_id when creating a job
      responses:
        '200':
          description: List of LLM models
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/LlmModel'
        '401':
          description: All users must be connected to an account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /account_credit_ledger:
    get:
      summary: Get the account credit ledger
      description: Retrieve the credit ledger entries created by the current user within their account
      responses:
        '200':
          description: List of account credit ledger entries
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AccountCreditLedger'
        '401':
          description: All users must be connected to an account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /transaction/{transactionId}:
    parameters:
      - $ref: '#/components/parameters/TransactionId'

    post:
      summary: Post a payment transaction
      description: Process a completed payment transaction and apply the resulting credits to the user's account
      responses:
        '200':
          description: Successfully processed transaction, returns the updated account credit cache
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountCreditCache'
        '400':
          description: Transaction ID is not a valid string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: All users must be connected to an account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Transaction data was invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /struct:
    get:
      summary: Get all data structures
      description: Retrieve all data structures for user
      responses:
        '200':
          description: List of structs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Struct'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    post:
      summary: Create a new data structure
      description: Create a new data structure to be used in document analysis
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateStructRequest'
      responses:
        '200':
          description: Successfully created struct
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Struct'
        '400':
          description: Struct object is missing || Struct object field is not the correct type || Struct object is missing a required field
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /struct/{structId}/archive:
    parameters:
      - $ref: '#/components/parameters/StructId'
    post:
      summary: Archive a struct
      description: Marks the specified struct as archived
      responses:
        '200':
          description: Successfully archived struct
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: ID of the archived struct
        '400':
          description: Struct ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /struct/{structId}/field:
    parameters:
      - $ref: '#/components/parameters/StructId'
    get:
      summary: Get data fields for a struct
      description: Retrieve all data field definitions in the specified struct
      responses:
        '200':
          description: List of fields
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Field'
        '400':
          description: Struct ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      summary: Create fields for a struct
      description: Create one or more fields for the specified struct
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/CreateFieldRequest'
      responses:
        '200':
          description: Successfully created fields
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Field'
        '400':
          description: Struct ID is not UUID || Field object is missing fields || Field object fields are not of the correct type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /field/{fieldId}:
    parameters:
      - $ref: '#/components/parameters/FieldId'

    put:
      summary: Edit a field
      description: Update one or more properties of the specified field. At least one property must be provided.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EditFieldRequest'
      responses:
        '200':
          description: Successfully updated field
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Field'
        '400':
          description: Field ID is not a valid UUID || Request body has no fields set || Field fields are not of the correct type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    delete:
      summary: Delete a field
      description: Delete the specified field
      responses:
        '200':
          description: Successfully deleted field
          content:
            application/json:
              schema:
                type: object
                required:
                  - fieldId
                properties:
                  fieldId:
                    type: string
                    format: uuid
                    description: ID of the deleted field
        '400':
          description: Field ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /struct/{structId}/job:
    parameters:
      - $ref: '#/components/parameters/StructId'

    post:
      summary: Create a job
      description: Create a job to extract structured data from a catalog or set of documents using the specified struct
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateJobRequest'
      responses:
        '200':
          description: Successfully created job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
        '400':
          description: Data is invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this struct or the specified catalog/documents
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    get:
      summary: Get all jobs for the specified struct
      description: Get all jobs for the specified struct
      responses:
        '200':
          description: List of jobs for struct
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Job'
        '400':
          description: Struct ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this struct
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /struct/{structId}/job/sync:
    parameters:
      - $ref: '#/components/parameters/StructId'

    post:
      summary: Upload a document, run an analysis job on that document, and download the output. For API use.
      description: >-
        Uploads a single document, processes it, runs an analysis job against it using the 
        specified struct, and returns the extracted data as a file, all in one request.
        Please note that it is best to use this endpoint with shorter documents (<20k characters),
        otherwise the request is likely to timeout. Files are capped at 100MB, and raw text files (such as .txt, .csv or .json) are capped at 10MB for analysis.

        The IDs of the document and the job are returned in the `stract-document-id` and
        `stract-job-id` response headers so the document and job can be retrieved later, for example
        with `GET /job/{jobId}` or `GET /document/{documentId}/link`.


        The request waits about 100 seconds for the job to finish. If it has not finished by then,
        a `202` is returned and the job keeps running; use the job ID to check on it and download the
        output later. The ID headers are also included on the `202` and `422` responses. The
        document ID header is included on a `400` caused by an invalid request field, 
        so you can run a subsequent job on that document without having to upload again. Audio 
        files are not supported on this endpoint.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
                - additional_instructions
                - output_type
              properties:
                file:
                  type: string
                  format: binary
                  description: >-
                    The file to upload. Supported extensions: .png, .jpg, .jpeg, .webp,
                    .heic, .heif, .tif, .tiff, .avif, .bmp, .pdf, .txt, .csv, .json,
                    .xml, .html, .log, .md, .yaml, .yml, .ini, .conf, .cfg, .sql, .svg,
                    .doc, .docx, .xls, .xlsx, .ppt, .pptx, .eml, .msg, .rtf. If you require
                    any other file types supported please contact us at matt@stract-api.com
                    with the request.
                additional_instructions:
                  type: string
                  description: Additional instructions to guide the data extraction, can be empty string
                  example: Focus on extracting financial figures only
                output_type:
                  type: string
                  enum:
                    - json
                    - csv
                  description: Format of the output file returned in the response
                llm_model_id:
                  type: string
                  description: ID of the LLM model to use for this job. Optional; if omitted, or not a recognized model ID, no specific model is set on the job.
                  example: google.gemma-3-27b-it
      responses:
        '200':
          description: File containing the extracted data for the uploaded document, in the requested output type
          headers:
            content-disposition:
              schema:
                type: string
              description: Indicates the response should be downloaded as a file
              example: attachment; filename="output_20260720_12:00.json"
            stract-document-id:
              $ref: '#/components/headers/StractDocumentId'
            stract-job-id:
              $ref: '#/components/headers/StractJobId'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/JobOutputRecord'
            text/csv:
              schema:
                type: string
                description: CSV text with a quoted header row followed by one quoted-value row per document (empty string if the job has no output)
                example: |
                  "document_name","fieldOne","fieldTwo"
                  "invoice.pdf","valueOne","valueTwo"
        '202':
          description: The job did not finish in time. It is still running, use the job ID to retrieve its output later.
          headers:
            stract-document-id:
              $ref: '#/components/headers/StractDocumentId'
            stract-job-id:
              $ref: '#/components/headers/StractJobId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '400':
          description: >-
            Struct ID is not a valid UUID || Request field is missing or invalid (additional_instructions,
            output_type) || File extension is not supported || The file is too large (100MB maximum) || The document cannot be processed. The
            stract-document-id header is included when the document was already created before the
            error, which is the case for an invalid request field or a document that cannot be processed.
          headers:
            stract-document-id:
              $ref: '#/components/headers/StractDocumentId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Insufficient credits for file upload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: The job ended without completing successfully, so there is no output to return
          headers:
            stract-document-id:
              $ref: '#/components/headers/StractDocumentId'
            stract-job-id:
              $ref: '#/components/headers/StractJobId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /struct/{structId}/job/sync/text:
    parameters:
      - $ref: '#/components/parameters/StructId'

    post:
      summary: Create a document from text, run an analysis job on that document, and download the output. For API use.
      description: >-
        Creates a document directly from text in the request body, runs an analysis job against
        it using the specified struct, and returns the extracted data as a file, all in one
        request.
        
        Please note that it is best to use this endpoint with shorter documents (<20k characters),
        otherwise the request is likely to timeout. The request body is capped at 10MB.

        The IDs of the document and the job are returned in the `stract-document-id` and
        `stract-job-id` response headers so the document and job can be retrieved later, for
        example with `GET /job/{jobId}` or `GET /document/{documentId}/link`.


        The request waits about 100 seconds for the job to finish. If it has not finished by then,
        a `202` is returned and the job keeps running; use the job ID to check on it and download
        the output later. The ID headers are also included on the `202` and `422` responses.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - text
                - additional_instructions
                - output_type
              properties:
                name:
                  type: string
                  minLength: 2
                  description: Name of the document
                  example: Meeting notes
                text:
                  type: string
                  minLength: 2
                  description: Text content of the document
                  example: Discussed Q3 budget and hiring plans.
                additional_instructions:
                  type: string
                  description: Additional instructions to guide the data extraction, can be empty string
                  example: Focus on extracting financial figures only
                output_type:
                  type: string
                  enum:
                    - json
                    - csv
                  description: Format of the output file returned in the response
                llm_model_id:
                  type: string
                  description: ID of the LLM model to use for this job. Optional; if omitted, or not a recognized model ID, no specific model is set on the job.
                  example: google.gemma-3-27b-it
      responses:
        '200':
          description: File containing the extracted data for the created document, in the requested output type
          headers:
            content-disposition:
              schema:
                type: string
              description: Indicates the response should be downloaded as a file
              example: attachment; filename="output_20260720_12:00.json"
            stract-document-id:
              $ref: '#/components/headers/StractDocumentId'
            stract-job-id:
              $ref: '#/components/headers/StractJobId'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/JobOutputRecord'
            text/csv:
              schema:
                type: string
                description: CSV text with a quoted header row followed by one quoted-value row per document (empty string if the job has no output)
                example: |
                  "document_name","fieldOne","fieldTwo"
                  "Meeting notes","valueOne","valueTwo"
        '202':
          description: The job did not finish in time. It is still running, use the job ID to retrieve its output later.
          headers:
            stract-document-id:
              $ref: '#/components/headers/StractDocumentId'
            stract-job-id:
              $ref: '#/components/headers/StractJobId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '400':
          description: >-
            Struct ID is not a valid UUID || Request field is missing or invalid (name, text,
            additional_instructions, output_type)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: The job ended without completing successfully, so there is no output to return
          headers:
            stract-document-id:
              $ref: '#/components/headers/StractDocumentId'
            stract-job-id:
              $ref: '#/components/headers/StractJobId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job:
    get:
      summary: Get all jobs for the user
      description: Retrieve all jobs belonging to the user's account, across all structs
      responses:
        '200':
          description: List of jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Job'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job/{jobId}:
    parameters:
      - $ref: '#/components/parameters/JobId'

    get:
      summary: Get a job by ID
      description: Retrieve the specified job
      responses:
        '200':
          description: Job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
        '400':
          description: Job ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job/{jobId}/job_document:
    parameters:
      - $ref: '#/components/parameters/JobId'

    get:
      summary: Get the status of document analysis in a job
      description: Retrieve the per-document status and analysis results for the specified job
      responses:
        '200':
          description: List of job documents
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/JobDocument'
        '400':
          description: Job ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job_document/{jobDocId}/output:
    parameters:
      - $ref: '#/components/parameters/JobDocId'

    get:
      summary: Get the output for a job document
      description: Retrieve the extracted structured data for the specified job document
      responses:
        '200':
          description: Job document output (null if the document has not yet been processed)
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/JobOutput'
                nullable: true
        '400':
          description: Job document ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this job document
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job/{jobId}/output_json:
    parameters:
      - $ref: '#/components/parameters/JobId'

    get:
      summary: Get the output for a job as JSON
      description: Download the extracted structured data for every document in the job as a JSON file
      responses:
        '200':
          description: JSON file containing the output for each document in the job
          headers:
            content-disposition:
              schema:
                type: string
              description: Indicates the response should be downloaded as a file
              example: attachment; filename="output_20260720_12:00.json"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/JobOutputRecord'
        '400':
          description: Job ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job/{jobId}/output_csv:
    parameters:
      - $ref: '#/components/parameters/JobId'

    get:
      summary: Get the output for a job as CSV
      description: Download the extracted structured data for every document in the job as a CSV file. The header row is the union of fields across all documents (including document_name); a document missing a given field leaves that cell empty.
      responses:
        '200':
          description: CSV file containing the output for each document in the job (empty string if the job has no outputs)
          headers:
            content-disposition:
              schema:
                type: string
              description: Indicates the response should be downloaded as a file
              example: attachment; filename="output_20260720_12:00.csv"
          content:
            text/csv:
              schema:
                type: string
                description: CSV text with a quoted header row followed by one quoted-value row per document
                example: |
                  "document_name","fieldOne","fieldTwo"
                  "invoice.pdf","valueOne","valueTwo"
        '400':
          description: Job ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job/{jobId}/cancel:
    parameters:
      - $ref: '#/components/parameters/JobId'

    post:
      summary: Cancel a job
      description: Cancel the specified job and stopping any further analysis from happening
      responses:
        '200':
          description: Returns the updated job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
        '400':
          description: Job ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job/{jobId}/archive:
    parameters:
      - $ref: '#/components/parameters/JobId'

    post:
      summary: Archive a job
      description: Marks the specified job as archived
      responses:
        '200':
          description: Successfully archived job
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: ID of the archived job
        '400':
          description: Job ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /job/{jobId}/document:
    parameters:
      - $ref: '#/components/parameters/JobId'

    get:
      summary: Get the documents for a job
      description: Retrieve all documents the specified job was run against
      responses:
        '200':
          description: List of documents
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Document'
        '400':
          description: Job ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /catalog:
    get:
      summary: Get all catalogs
      description: Retrieve all catalogs (collections of documents) for the user
      responses:
        '200':
          description: List of catalogs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Catalog'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      summary: Create a catalog
      description: Create a new catalog (collection of documents) for the user's account
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCatalogRequest'
      responses:
        '200':
          description: Successfully created catalog
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Catalog'
        '400':
          description: Data is invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: All users must be connected to an account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /catalog/{catalogId}:
    parameters:
      - $ref: '#/components/parameters/CatalogId'

    delete:
      summary: Delete a catalog
      description: >-
        Deletes the specified catalog. Also deletes all documents belonging to the catalog,
        including any underlying stored files.
      responses:
        '200':
          description: Successfully deleted catalog
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: ID of the deleted catalog
        '400':
          description: Catalog ID is not a valid UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /catalog/{catalogId}/document:
    parameters:
      - $ref: '#/components/parameters/CatalogId'

    get:
      summary: Get documents for a catalog
      description: Retrieve all documents belonging to the specified catalog
      responses:
        '200':
          description: List of documents
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Document'
        '400':
          description: Catalog ID is not UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      summary: Upload a file to the specified catalog
      description: Upload a file to the specified catalog. Files are capped at 100MB, and raw text files (such as .txt, .csv or .json) are capped at 10MB for analysis.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: >-
                    The file to upload. Supported extensions: .png, .jpg, .jpeg, .webp,
                    .heic, .heif, .tif, .tiff, .avif, .bmp, .pdf, .txt, .csv, .json,
                    .xml, .html, .log, .md, .yaml, .yml, .ini, .conf, .cfg, .sql, .svg,
                    .doc, .docx, .xls, .xlsx, .ppt, .pptx, .eml, .msg, .rtf, .mp3, .wav,
                    .m4a, .m4b, .ogg, .flac, .amr. If you require any other file types supported
                    please contact us at matt@stract-api.com with the request.
      responses:
        '200':
          description: Successfully uploaded document
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Document'
        '400':
          description: Catalog ID is not UUID || Data was invalid || The file extension is not supported || The file is too large (100MB maximum)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this catalog
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Insufficient credits for file upload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /catalog/{catalogId}/document/text:
    parameters:
      - $ref: '#/components/parameters/CatalogId'

    post:
      summary: Upload text as a document to the specified catalog
      description: >-
        Create a document in the specified catalog directly from text in the request body.
        No file upload is needed and the document is immediately ready for analysis.
        The request body is capped at 10MB.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UploadTextDocumentRequest'
      responses:
        '200':
          description: Successfully created document
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Document'
        '400':
          description: Catalog ID is not UUID || Document object is missing a required field || Document object field is not the correct type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /catalog/{catalogId}/document/{documentId}/text:
    parameters:
      - $ref: '#/components/parameters/CatalogId'
      - $ref: '#/components/parameters/DocumentId'

    get:
      summary: Get the extracted text of a document
      description: Retrieve the extracted text content of the specified document, if it has been processed
      responses:
        '200':
          description: Document text (null if the document has not yet been processed)
          content:
            application/json:
              schema:
                type: object
                required:
                  - text
                properties:
                  text:
                    type: string
                    nullable: true
                    description: Extracted text content of the document
        '400':
          description: Document ID is not UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this document
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /document:
    get:
      summary: Get all documents for the user
      description: Retrieve all documents belonging to the user's account, across all catalogs
      responses:
        '200':
          description: List of documents
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Document'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    post:
      summary: Upload a document
      description: >-
        Uploads a document. Files are capped at 100MB, and raw text files (such as .txt, .csv or .json) are capped at 10MB for analysis.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
                  description: >-
                    The file to upload. Supported extensions: .png, .jpg, .jpeg, .webp,
                    .heic, .heif, .tif, .tiff, .avif, .bmp, .pdf, .txt, .csv, .json,
                    .xml, .html, .log, .md, .yaml, .yml, .ini, .conf, .cfg, .sql, .svg,
                    .doc, .docx, .xls, .xlsx, .ppt, .pptx, .eml, .msg, .rtf, .mp3, .wav,
                    .m4a, .m4b, .ogg, .flac, .amr. If you require any other file types supported
                    please contact us at matt@stract-api.com with the request.
      responses:
        '200':
          description: Successfully uploaded document
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Document'
        '400':
          description: Data was invalid || The file extension is not supported || The file is too large (100MB maximum)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: You are not permitted to access this information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Insufficient credits for file upload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /document/text:
    post:
      summary: Upload text as a document
      description: >-
        Create a document directly from text in the request body. No file upload is needed and
        the document is immediately ready for analysis. The request body is capped at 10MB.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UploadTextDocumentRequest'
      responses:
        '200':
          description: Successfully created document
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Document'
        '400':
          description: Document object is missing a required field || Document object field is not the correct type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to perform this action
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /document/{documentId}/link:
    parameters:
      - $ref: '#/components/parameters/DocumentId'

    get:
      summary: Get a link to a document
      description: Retrieve a link to download the specified document
      responses:
        '200':
          description: Document link
          content:
            application/json:
              schema:
                type: object
                required:
                  - link
                properties:
                  link:
                    type: string
                    description: URL where the document can be downloaded
        '400':
          description: Document ID is not UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Not permitted to access this document
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'API key, included in every request as `authorization: bearer [apiKey]`'

  headers:
    StractDocumentId:
      schema:
        type: string
        format: uuid
      description: ID of the document created from the uploaded file. Use it to retrieve the document later.
      example: 3f2b8c1e-5d4a-4c7e-9b1a-2e6f8d0a7c11
    StractJobId:
      schema:
        type: string
        format: uuid
      description: ID of the job created for the uploaded document. Use it to retrieve the job and its output later.
      example: 9a7d1c42-6b3e-4f58-8e2d-0c5b1a9f3d76

  parameters:
    StructId:
      name: structId
      in: path
      required: true
      description: Unique identifier of the struct
      schema:
        type: string
        format: uuid
    CatalogId:
      name: catalogId
      in: path
      required: true
      description: Unique identifier of the catalog
      schema:
        type: string
        format: uuid
    DocumentId:
      name: documentId
      in: path
      required: true
      description: Unique identifier of the document
      schema:
        type: string
        format: uuid
    FieldId:
      name: fieldId
      in: path
      required: true
      description: Unique identifier of the field
      schema:
        type: string
        format: uuid
    TransactionId:
      name: transactionId
      in: path
      required: true
      description: Identifier of the payment transaction, as provided by the payment processor
      schema:
        type: string
    JobId:
      name: jobId
      in: path
      required: true
      description: Unique identifier of the job
      schema:
        type: string
        format: uuid
    JobDocId:
      name: jobDocId
      in: path
      required: true
      description: Unique identifier of the job document
      schema:
        type: string
        format: uuid

  schemas:
    LoginRequest:
      type: object
      required:
        - email
        - password
      properties:
        email:
          type: string
          format: email
          description: User's email address
          example: user@example.com
        password:
          type: string
          format: password
          description: User's password
          example: secretpassword

    LoginResponse:
      type: object
      required:
        - token
      properties:
        token:
          type: string
          description: JWT token for authentication
          example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

    User:
      type: object
      required:
        - id
        - is_active
        - email
        - first_name
        - last_name
        - dt_created
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the user
        is_active:
          type: boolean
          description: Whether the user's account is active
        email:
          type: string
          format: email
          description: User's email address
        first_name:
          type: string
          description: User's first name
        last_name:
          type: string
          description: User's last name
        dt_created:
          type: string
          format: date
          description: Date when the user was created

    EditMyUserRequest:
      type: object
      minProperties: 1
      properties:
        first_name:
          type: string
          description: User's first name
        last_name:
          type: string
          description: User's last name

    AccountUserRole:
      type: string
      enum:
        - admin
        - base
      description: The current user's role within the account

    Account:
      type: object
      required:
        - id
        - name
        - date_created
        - account_user_role
        - subscription_type
        - subscription_dt_started
        - subscription_billing_period_end
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the account
        name:
          type: string
          description: Name of the account
        date_created:
          type: string
          format: date
          description: Date when the account was created
        account_user_role:
          $ref: '#/components/schemas/AccountUserRole'
        subscription_type:
          type: string
          nullable: true
          enum:
            - team
            - enterprise
          description: The account's active subscription type, or null if the account has no active subscription
        subscription_dt_started:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when the account's active subscription started, or null if the account has no active subscription
        subscription_billing_period_end:
          type: string
          format: date-time
          nullable: true
          description: Timestamp when the account's current subscription billing period ends, or null if the account has no active subscription

    EditAccountRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: Name of the account
          example: Acme Inc

    CreateAccountUserRequest:
      type: object
      required:
        - email
        - first_name
        - last_name
        - account_user_role
      properties:
        email:
          type: string
          format: email
          description: Email address of the new user
          example: user@example.com
        first_name:
          type: string
          description: First name of the new user
          example: Jane
        last_name:
          type: string
          description: Last name of the new user
          example: Doe
        account_user_role:
          $ref: '#/components/schemas/AccountUserRole'

    AccountUser:
      type: object
      required:
        - id
        - account_id
        - suser_id
        - account_user_role
        - email
        - first_name
        - last_name
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the account user record
        account_id:
          type: string
          format: uuid
          description: ID of the account this user belongs to
        suser_id:
          type: string
          format: uuid
          description: ID of the user
        account_user_role:
          $ref: '#/components/schemas/AccountUserRole'
        email:
          type: string
          format: email
          description: User's email address
        first_name:
          type: string
          description: User's first name
        last_name:
          type: string
          description: User's last name

    AccountCreditCache:
      type: object
      required:
        - id
        - account_id
        - suser_id
        - cached_balance
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the account credit balance
        account_id:
          type: string
          format: uuid
          description: ID of the account this credit balance belongs to
        suser_id:
          type: string
          format: uuid
          description: ID of the user this credit balance belongs to
        cached_balance:
          type: number
          description: Credit balance for the account
          example: 42

    AccountCreditLedger:
      type: object
      required:
        - id
        - account_id
        - suser_id
        - spending_suser_id
        - amount
        - created_at
        - type
        - reference_id
        - idempotency_key
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the ledger entry
        account_id:
          type: string
          format: uuid
          description: ID of the account this ledger entry belongs to
        suser_id:
          type: string
          format: uuid
          nullable: true
          description: ID of the user account that was charged or null if charged to the organization account
        spending_suser_id:
          type: string
          format: uuid
          description: ID of the user who performed the action that created this ledger entry
        amount:
          type: number
          description: Change in credits for this entry (negative for credits spent, positive for credits added)
          example: 42
        created_at:
          type: string
          format: date-time
          description: Timestamp when the ledger entry was created
        type:
          type: string
          enum:
            - File Upload
            - Payment Received
            - File Download
            - Free Credits on Sign Up
            - etc...
          description: The kind of activity that produced this ledger entry
        reference_id:
          type: string
          description: ID of the object (found in reference_table) that this ledger entry relates to
        reference_table:
          type: string
          description: Object type where reference_id can be found
        idempotency_key:
          type: string
          description: Unique key used to prevent duplicate ledger entries

    ApiKey:
      type: object
      required:
        - id
        - key_last_four
        - account_id
        - suser_id
        - dt_created
        - dt_expired
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the API key
        key_last_four:
          type: string
          description: Last four characters of the API key, used to help identify the key
        account_id:
          type: string
          format: uuid
          description: ID of the account this API key belongs to
        suser_id:
          type: string
          format: uuid
          description: ID of the user who created this API key
        dt_created:
          type: string
          format: date-time
          description: Timestamp when the API key was created
        dt_expired:
          type: string
          format: date-time
          description: Timestamp when the API key expires

    Struct:
      type: object
      required:
        - id
        - name
        - account_id
        - suser_id
        - date_created
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the struct
        name:
          type: string
          description: Name of the struct
        account_id:
          type: string
          format: uuid
          description: ID of the account this struct belongs to
        suser_id:
          type: string
          format: uuid
          description: ID of the user who created the struct
        date_created:
          type: string
          format: date-time
          description: Timestamp when the struct was created

    CreateStructRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: Name of the new data structure
          example: Document Analysis

    FieldType:
      type: string
      enum:
        - string
        - boolean
        - number
        - date
        - datetime
        - enum
        - choose_from_list
      description: The data type of the field

    Field:
      type: object
      required:
        - id
        - struct_id
        - date_created
        - name
        - description
        - type
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the field
        struct_id:
          type: string
          format: uuid
          description: ID of the struct this field belongs to
        date_created:
          type: string
          format: date
          description: Date when the field was created
        name:
          type: string
          description: Name of the field
        description:
          type: string
          description: Description of the field
        type:
          $ref: '#/components/schemas/FieldType'
        enum_values:
          type: array
          nullable: true
          items:
            type: string
          description: Allowed values for the field. Required if type is enum.

    CreateFieldRequest:
      type: object
      required:
        - name
        - description
        - type
      properties:
        name:
          type: string
          description: Name of the field
          example: email
        description:
          type: string
          description: Description of the field
          example: Customer's email address
        type:
          $ref: '#/components/schemas/FieldType'
        enum_values:
          type: array
          nullable: true
          items:
            type: string
          description: Allowed values for the field, required if type is enum

    EditFieldRequest:
      type: object
      minProperties: 1
      properties:
        name:
          type: string
          description: Name of the field
          example: email
        description:
          type: string
          description: Description of the field
          example: Customer's email address
        type:
          $ref: '#/components/schemas/FieldType'
        enum_values:
          type: array
          nullable: true
          items:
            type: string
          description: Allowed values for the field, required if type is enum

    CreateCatalogRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: Name of the catalog
          example: Invoices 2026

    UploadTextDocumentRequest:
      type: object
      required:
        - name
        - text
      properties:
        name:
          type: string
          minLength: 2
          description: Name of the document
          example: Meeting notes
        text:
          type: string
          minLength: 2
          description: Text content of the document
          example: Discussed Q3 budget and hiring plans.

    Catalog:
      type: object
      required:
        - id
        - name
        - date_created
        - account_id
        - suser_id
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the catalog
        name:
          type: string
          description: Name of the catalog
        date_created:
          type: string
          format: date
          description: Date when the catalog was created
        account_id:
          type: string
          format: uuid
          description: ID of the account this catalog belongs to
        suser_id:
          type: string
          format: uuid
          description: ID of the user who created the catalog

    DocumentProcessingStatus:
      type: string
      enum:
        - not_started
        - complete
        - failed
      description: The current processing status of the document

    Document:
      type: object
      required:
        - id
        - name
        - catalog_id
        - catalog_name
        - extension
        - date_created
        - processing_status
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the document
        name:
          type: string
          description: Name of the document
        catalog_id:
          type: string
          format: uuid
          description: ID of the catalog this document belongs to
        catalog_name:
          type: string
          description: Name of the catalog this document belongs to
        text:
          type: string
          description: Text content of the document, if applicable
        extension:
          type: string
          description: File extension of the document
          example: .pdf
        date_created:
          type: string
          format: date
          description: Date when the document was created
        processing_status:
          $ref: '#/components/schemas/DocumentProcessingStatus'

    LlmModel:
      type: object
      required:
        - id
        - maker
        - name
        - credits_per_m_input
        - credits_per_m_output
        - can_do_images
        - can_do_audio
        - can_do_video
        - is_available
      properties:
        id:
          type: string
          description: Unique identifier of the model, used as the llm_model_id when creating a job
          example: google.gemma-3-27b-it
        maker:
          type: string
          description: Company that makes the model
          example: Google
        name:
          type: string
          description: Human-readable name of the model
          example: Gemma 3 27B
        credits_per_m_input:
          type: number
          description: Credits consumed per one million input tokens
        credits_per_m_output:
          type: number
          description: Credits consumed per one million output tokens
        can_do_images:
          type: boolean
          description: Whether the model can process image inputs
        can_do_audio:
          type: boolean
          description: Whether the model can process audio inputs
        can_do_video:
          type: boolean
          description: Whether the model can process video inputs
        is_available:
          type: boolean
          description: Whether the model is currently available for use

    CreateJobRequest:
      type: object
      required:
        - additional_instructions
      properties:
        additional_instructions:
          type: string
          description: Additional instructions to guide the data extraction, can be empty string
          example: Focus on extracting financial figures only
        catalog_id:
          type: string
          format: uuid
          description: ID of the catalog to run the job against (mutually exclusive with document_ids)
        document_ids:
          type: array
          items:
            type: string
            format: uuid
          description: IDs of specific documents to run the job against (mutually exclusive with catalog_id)
        llm_model_id:
          type: string
          description: ID of the LLM model to use for this job. Optional; if omitted, or not a recognized model ID, no specific model is set on the job.
          example: google.gemma-3-27b-it

    JobStatus:
      type: string
      enum:
        - not_started
        - in_progress
        - complete
        - error
        - cancelled
      description: The current status of the job

    Job:
      type: object
      required:
        - id
        - status
        - struct_id
        - struct_name
        - is_complete
        - dt_created
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the job
        status:
          $ref: '#/components/schemas/JobStatus'
        struct_id:
          type: string
          format: uuid
          description: ID of the struct this job belongs to
        struct_name:
          type: string
          description: Name of the struct this job belongs to
        is_complete:
          type: boolean
          description: Whether the job has completed
        dt_created:
          type: string
          format: date-time
          description: Timestamp when the job was created
        dt_completed:
          type: string
          format: date-time
          description: Timestamp when the job completed
        catalog_id:
          type: string
          format: uuid
          description: ID of the catalog this job was run against, if applicable
        catalog_name:
          type: string
          description: Name of the catalog this job was run against, if applicable
        document_ids:
          type: array
          items:
            type: string
            format: uuid
          description: IDs of the documents this job was run against, if applicable
        notes:
          type: string
          description: Notes about the job, e.g. an error message if the job failed
        credits_used:
          type: number
          description: Number of credits consumed by this job
        instructions:
          type: string
          description: Additional instructions provided to guide the data extraction
        llm_model_id:
          type: string
          description: ID of the LLM model used for this job
          example: google.gemma-3-27b-it

    JobDocument:
      type: object
      required:
        - id
        - job_id
        - document_id
        - status
        - is_complete
        - document_name
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the job document
        job_id:
          type: string
          format: uuid
          description: ID of the job this record belongs to
        document_id:
          type: string
          format: uuid
          description: ID of the document this record belongs to
        document_name:
          type: string
          description: Name of the document this record belongs to
        notes:
          type: string
          description: Notes about the job document, e.g. an error message if processing failed
        status:
          $ref: '#/components/schemas/JobStatus'
        is_complete:
          type: boolean
          description: Whether processing of this document has completed
        error_description:
          type: string
          description: Description of the error, if processing this document failed
        credits_used:
          type: number
          description: Number of credits consumed processing this document
        dt_started:
          type: string
          format: date-time
          description: Timestamp when processing of this document started
        dt_completed:
          type: string
          format: date-time
          description: Timestamp when processing of this document completed

    JobOutput:
      type: object
      required:
        - id
        - job_document_id
        - data
        - dt_created
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the job output
        job_document_id:
          type: string
          format: uuid
          description: ID of the job document this output belongs to
        data:
          type: object
          additionalProperties: true
          description: Extracted structured data for the document, keyed by field name
        dt_created:
          type: string
          format: date-time
          description: Timestamp when the output was created

    JobOutputRecord:
      type: object
      required:
        - document_name
      properties:
        document_name:
          type: string
          description: Name of the document this output belongs to
      additionalProperties: true
      description: Extracted structured data fields for the document, plus the document name
      example:
        document_name: invoice.pdf
        fieldOne: valueOne
        fieldTwo: valueTwo

    Error:
      type: string
