{
  "openapi": "3.1.0",
  "info": {
    "title": "AnythingMD API",
    "version": "1.0.0-preview",
    "description": "Convert PDFs, Office documents, spreadsheets and images into Markdown. Guides, pricing and limits: https://docs.anythingmd.com. Preview: available to workspaces that have purchased credits."
  },
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "servers": [
    {
      "url": "https://anythingmd.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Uploads",
      "description": "Stage a source document for conversion"
    },
    {
      "name": "Jobs",
      "description": "Create and observe async conversion work"
    },
    {
      "name": "Artifacts",
      "description": "Retrieve job outputs"
    },
    {
      "name": "Quotes",
      "description": "See what a conversion would cost before starting it."
    },
    {
      "name": "Receipts",
      "description": "What a job was charged. Receipts outlive the job."
    }
  ],
  "paths": {
    "/api/v1/uploads": {
      "post": {
        "operationId": "createUpload",
        "tags": [
          "Uploads"
        ],
        "summary": "Create a staged upload",
        "description": "Returns a documentId and a signed uploadUrl. PUT the file bytes to uploadUrl, then create a job with `source.type: \"document\"` and the documentId.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "If reused within the retention window, replay the original result instead of a second mutation"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUploadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing upload slot returned for a replayed idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateUploadResponse"
                }
              }
            }
          },
          "201": {
            "description": "Upload slot created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateUploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs": {
      "post": {
        "operationId": "createJob",
        "tags": [
          "Jobs"
        ],
        "summary": "Create a conversion job",
        "description": "Starts an asynchronous conversion. Credits for the estimated pages are reserved now and settled on the pages actually converted. Send an Idempotency-Key so a retry returns the same job instead of starting a second one. Returns 402 when the workspace does not have enough credits, and 413 when the document is over the page limit.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "If reused within the retention window, replay the original result instead of a second mutation"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateJobRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing job returned for a replayed idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateJobResponse"
                }
              }
            }
          },
          "201": {
            "description": "Job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateJobResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body carries topUpPath and optional requiredCredits/availableCredits. Quote is omitted unless a saved quote is attached; Job stays amount-free.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "413": {
            "description": "The document's estimated pages exceed the per-conversion ceiling (code: document_too_large; default 1000 pages). Refused before any credits are reserved; the job is kept as failed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentTooLargeError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs/{jobId}": {
      "get": {
        "operationId": "getJob",
        "tags": [
          "Jobs"
        ],
        "summary": "Get job status",
        "description": "Returns the job and moves it forward. Poll every 2 to 5 seconds until status is succeeded, failed or canceled.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Id of an async job"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current job state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body carries topUpPath and optional requiredCredits/availableCredits. Quote is omitted unless a saved quote is attached; Job stays amount-free.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs/{jobId}/cancel": {
      "post": {
        "operationId": "cancelJob",
        "tags": [
          "Jobs"
        ],
        "summary": "Cancel a job",
        "description": "Cancels a job that has not finished. Reserved credits are refunded. Requires the documents:delete scope.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Id of an async job"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "If reused within the retention window, replay the original result instead of a second mutation"
          }
        ],
        "responses": {
          "200": {
            "description": "Updated job (status canceled when cancellation succeeded)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelJobResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/jobs/{jobId}/artifacts": {
      "get": {
        "operationId": "listJobArtifacts",
        "tags": [
          "Artifacts"
        ],
        "summary": "List artifacts for a job",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Id of an async job"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Artifact list (empty while job is still running)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListArtifactsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/artifacts/{artifactId}": {
      "get": {
        "operationId": "getArtifact",
        "tags": [
          "Artifacts"
        ],
        "summary": "Get one artifact",
        "description": "Returns an artifact's metadata and either its inline text (small Markdown files) or a downloadUrl.",
        "parameters": [
          {
            "name": "artifactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Id of a job output artifact"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Artifact metadata / content hints",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Artifact"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/quotes": {
      "post": {
        "operationId": "createQuote",
        "tags": [
          "Quotes"
        ],
        "summary": "Create a quote",
        "description": "Returns the credits a conversion would reserve (maximumCredits) without starting it. Uploaded documents are quoted on their exact page count; URLs are quoted at the minimum because the file is not downloaded. A URL whose server does not report its size returns 422 size_unknown. Quotes can be fetched by id until expiresAt.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "description": "If reused within the retention window, replay the original result instead of a second mutation"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateQuoteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing quote returned for a replayed idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateQuoteResponse"
                }
              }
            }
          },
          "201": {
            "description": "Quote created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateQuoteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body carries topUpPath and optional requiredCredits/availableCredits. Quote is omitted unless a saved quote is attached; Job stays amount-free.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRequiredError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "422": {
            "description": "Cannot estimate credits: the external URL did not advertise a file size. Jobs may still start; the hold is priced after ingest measures bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/quotes/{quoteId}": {
      "get": {
        "operationId": "getQuote",
        "tags": [
          "Quotes"
        ],
        "summary": "Get a quote",
        "description": "Returns a saved quote. Expired or unknown quotes return 404.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "quoteId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Id of a quote"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved quote",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateQuoteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/receipts": {
      "get": {
        "operationId": "getReceiptByJobId",
        "tags": [
          "Receipts"
        ],
        "summary": "Get a receipt by job id",
        "description": "Returns the receipt for a job: the credits reserved, charged and refunded. Receipts stay available after the job itself has expired.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Id of an async job"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage receipt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/receipts/{receiptId}": {
      "get": {
        "operationId": "getReceipt",
        "tags": [
          "Receipts"
        ],
        "summary": "Get a receipt",
        "description": "Returns a receipt by id (rcpt_<jobId>).",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "receiptId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Id of a usage receipt"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage receipt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated, but the credential lacks the scope this operation requires (code: insufficient_scope). Reads need documents:read, uploads and job creation need documents:write, cancel needs documents:delete. Checked before the resource is looked up, so this never reveals whether the resource exists.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "Create a key under Settings → API Keys and send it as `Authorization: Bearer amd_live_…`. See https://docs.anythingmd.com/authentication."
      }
    },
    "schemas": {
      "ApiError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "User-facing error message"
          },
          "code": {
            "description": "Optional machine-readable error code (e.g. invalid_request)",
            "type": "string"
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "PaymentRequiredError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "User-facing error message"
          },
          "code": {
            "description": "Optional machine-readable error code (e.g. invalid_request)",
            "type": "string"
          },
          "quote": {
            "description": "Quote that must be funded before the mutation can proceed",
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "minLength": 1,
                "description": "Quote id"
              },
              "operation": {
                "type": "string",
                "enum": [
                  "convert"
                ]
              },
              "capabilityVersion": {
                "type": "string",
                "minLength": 1,
                "description": "Pinned version of this capability. Quotes, receipts, rate cards, and Skills key off operation + version."
              },
              "estimatedUsage": {
                "type": "object",
                "properties": {
                  "inputBytes": {
                    "description": "Source document size in bytes",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "discoveredPages": {
                    "description": "Pages detected in the source",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "ocrPages": {
                    "description": "Pages that required OCR",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "outputBytes": {
                    "description": "Produced artifact bytes",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "durationMs": {
                    "description": "Wall-clock processing time in milliseconds",
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  }
                },
                "additionalProperties": false,
                "description": "Estimated natural units; not a bill"
              },
              "estimatedCredits": {
                "type": "number",
                "minimum": 0,
                "description": "Expected credits if work matches the estimate"
              },
              "maximumCredits": {
                "type": "number",
                "minimum": 0,
                "description": "Credits that will be reserved when the job starts; the workspace needs at least this many"
              },
              "priceVersion": {
                "type": "string",
                "minLength": 1,
                "description": "Rate-card version this quote is pinned to"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                "description": "ISO-8601 quote expiration"
              },
              "createdAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
              }
            },
            "required": [
              "id",
              "operation",
              "capabilityVersion",
              "estimatedUsage",
              "estimatedCredits",
              "maximumCredits",
              "priceVersion",
              "expiresAt",
              "createdAt"
            ],
            "additionalProperties": false
          },
          "topUpPath": {
            "description": "Control-plane path or URL where the payer can add funds (not an amount)",
            "type": "string"
          },
          "requiredCredits": {
            "description": "Credits needed to start this operation (reserved, not the final charge)",
            "type": "number",
            "minimum": 0
          },
          "availableCredits": {
            "description": "Credits currently available to this account",
            "type": "number",
            "minimum": 0
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "DocumentTooLargeError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "User-facing error message"
          },
          "code": {
            "type": "string",
            "const": "document_too_large"
          },
          "maxPages": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "description": "Page ceiling per conversion"
          },
          "estimatedPages": {
            "description": "Pages estimated from the file before converting",
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991
          },
          "jobId": {
            "description": "The refused job, kept as failed with errorCode document_too_large",
            "type": "string"
          }
        },
        "required": [
          "error",
          "code",
          "maxPages"
        ],
        "additionalProperties": false
      },
      "CreateUploadRequest": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "minLength": 1,
            "description": "Original file name used for the object key and metadata"
          },
          "fileType": {
            "type": "string",
            "minLength": 1,
            "description": "MIME type of the file being uploaded"
          },
          "idempotencyKey": {
            "description": "If the same key is reused within the idempotency window, return the original upload slot instead of creating a duplicate",
            "type": "string",
            "minLength": 1
          },
          "content_hash": {
            "description": "Optional SHA-256 payload checksum (e.g. sha256:<hex>)",
            "type": "string",
            "minLength": 1
          },
          "contentHash": {
            "description": "Alias for content_hash",
            "type": "string",
            "minLength": 1
          }
        },
        "required": [
          "fileName",
          "fileType"
        ],
        "additionalProperties": false
      },
      "CreateUploadResponse": {
        "type": "object",
        "properties": {
          "documentId": {
            "type": "string",
            "minLength": 1,
            "description": "Id of an uploaded source document"
          },
          "uploadUrl": {
            "type": "string",
            "description": "Pre-signed URL for HTTP PUT of the file bytes"
          },
          "accessUrl": {
            "type": "string",
            "description": "Object URL the conversion worker will read after upload"
          },
          "objectKey": {
            "type": "string",
            "description": "Storage object key for the uploaded file"
          },
          "expiresAt": {
            "description": "ISO-8601 expiry of the pre-signed upload URL, if known",
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          }
        },
        "required": [
          "documentId",
          "uploadUrl",
          "accessUrl",
          "objectKey"
        ],
        "additionalProperties": false
      },
      "CreateJobRequest": {
        "type": "object",
        "properties": {
          "operation": {
            "default": "convert",
            "description": "Work to perform",
            "type": "string",
            "enum": [
              "convert"
            ]
          },
          "capabilityVersion": {
            "default": "1",
            "description": "Capability version to invoke; defaults to 1",
            "type": "string",
            "minLength": 1
          },
          "source": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "document"
                  },
                  "documentId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Id of an uploaded source document"
                  }
                },
                "required": [
                  "type",
                  "documentId"
                ],
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "external"
                  },
                  "fileUrl": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Caller-supplied URL for the server to fetch"
                  },
                  "fileName": {
                    "description": "Original file name; defaults to \"document\" if omitted",
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "fileUrl"
                ],
                "additionalProperties": false
              }
            ],
            "description": "Where the input document comes from"
          },
          "includeImages": {
            "default": false,
            "description": "If true, save image artifacts with download URLs; if false, skip image bodies",
            "type": "boolean"
          },
          "force_refresh": {
            "description": "If true, bypass document cache and perform a full conversion",
            "type": "boolean"
          },
          "forceRefresh": {
            "description": "Alias for force_refresh",
            "type": "boolean"
          },
          "content_hash": {
            "description": "Optional SHA-256 payload checksum (e.g. sha256:<hex>)",
            "type": "string",
            "minLength": 1
          },
          "contentHash": {
            "description": "Alias for content_hash",
            "type": "string",
            "minLength": 1
          },
          "idempotencyKey": {
            "description": "If the same key is reused within the idempotency window, return the original job instead of creating a duplicate",
            "type": "string",
            "minLength": 1
          },
          "webhookUrl": {
            "description": "Optional callback URL when the job reaches a terminal status (future; polling remains required)",
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "operation",
          "capabilityVersion",
          "source",
          "includeImages"
        ],
        "additionalProperties": false
      },
      "CreateJobResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Id of an async job"
          },
          "operation": {
            "type": "string",
            "enum": [
              "convert"
            ]
          },
          "capabilityVersion": {
            "type": "string",
            "minLength": 1,
            "description": "Pinned version of this capability. Quotes, receipts, rate cards, and Skills key off operation + version."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "input_required",
              "succeeded",
              "failed",
              "canceled",
              "expired"
            ]
          },
          "source": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "document"
                  },
                  "documentId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Id of an uploaded source document"
                  }
                },
                "required": [
                  "type",
                  "documentId"
                ],
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "external"
                  },
                  "fileUrl": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Caller-supplied URL for the server to fetch"
                  },
                  "fileName": {
                    "description": "Original file name; defaults to \"document\" if omitted",
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "fileUrl"
                ],
                "additionalProperties": false
              }
            ]
          },
          "fileSource": {
            "type": "string",
            "enum": [
              "managed",
              "external"
            ]
          },
          "includeImages": {
            "type": "boolean"
          },
          "cached": {
            "description": "True when results were returned from content-hash cache",
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "ISO-8601 creation time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "ISO-8601 last status change"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "error": {
            "description": "Present when status is failed",
            "type": "string"
          },
          "errorCode": {
            "description": "Stable machine code when status is failed. `stranded_running` means the worker or client disappeared; it is not a conversion failure.",
            "type": "string"
          },
          "idempotencyKey": {
            "type": "string"
          },
          "usage": {
            "description": "Natural usage units for this job; never credits or currency",
            "type": "object",
            "properties": {
              "inputBytes": {
                "description": "Source document size in bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "discoveredPages": {
                "description": "Pages detected in the source",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "ocrPages": {
                "description": "Pages that required OCR",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "outputBytes": {
                "description": "Produced artifact bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "durationMs": {
                "description": "Wall-clock processing time in milliseconds",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "additionalProperties": false
          },
          "stage": {
            "description": "Fine-grained phase within the current status",
            "type": "string",
            "enum": [
              "preparing",
              "converting",
              "finalizing",
              "complete",
              "error"
            ]
          },
          "stageProgress": {
            "description": "0–100 progress within the current stage",
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "message": {
            "description": "Human-readable status for display",
            "type": "string"
          }
        },
        "required": [
          "id",
          "operation",
          "capabilityVersion",
          "status",
          "source",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "CancelJobResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Id of an async job"
          },
          "operation": {
            "type": "string",
            "enum": [
              "convert"
            ]
          },
          "capabilityVersion": {
            "type": "string",
            "minLength": 1,
            "description": "Pinned version of this capability. Quotes, receipts, rate cards, and Skills key off operation + version."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "input_required",
              "succeeded",
              "failed",
              "canceled",
              "expired"
            ]
          },
          "source": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "document"
                  },
                  "documentId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Id of an uploaded source document"
                  }
                },
                "required": [
                  "type",
                  "documentId"
                ],
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "external"
                  },
                  "fileUrl": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Caller-supplied URL for the server to fetch"
                  },
                  "fileName": {
                    "description": "Original file name; defaults to \"document\" if omitted",
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "fileUrl"
                ],
                "additionalProperties": false
              }
            ]
          },
          "fileSource": {
            "type": "string",
            "enum": [
              "managed",
              "external"
            ]
          },
          "includeImages": {
            "type": "boolean"
          },
          "cached": {
            "description": "True when results were returned from content-hash cache",
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "ISO-8601 creation time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "ISO-8601 last status change"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "error": {
            "description": "Present when status is failed",
            "type": "string"
          },
          "errorCode": {
            "description": "Stable machine code when status is failed. `stranded_running` means the worker or client disappeared; it is not a conversion failure.",
            "type": "string"
          },
          "idempotencyKey": {
            "type": "string"
          },
          "usage": {
            "description": "Natural usage units for this job; never credits or currency",
            "type": "object",
            "properties": {
              "inputBytes": {
                "description": "Source document size in bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "discoveredPages": {
                "description": "Pages detected in the source",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "ocrPages": {
                "description": "Pages that required OCR",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "outputBytes": {
                "description": "Produced artifact bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "durationMs": {
                "description": "Wall-clock processing time in milliseconds",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "additionalProperties": false
          },
          "stage": {
            "description": "Fine-grained phase within the current status",
            "type": "string",
            "enum": [
              "preparing",
              "converting",
              "finalizing",
              "complete",
              "error"
            ]
          },
          "stageProgress": {
            "description": "0–100 progress within the current stage",
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "message": {
            "description": "Human-readable status for display",
            "type": "string"
          }
        },
        "required": [
          "id",
          "operation",
          "capabilityVersion",
          "status",
          "source",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Id of an async job"
          },
          "operation": {
            "type": "string",
            "enum": [
              "convert"
            ]
          },
          "capabilityVersion": {
            "type": "string",
            "minLength": 1,
            "description": "Pinned version of this capability. Quotes, receipts, rate cards, and Skills key off operation + version."
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "input_required",
              "succeeded",
              "failed",
              "canceled",
              "expired"
            ]
          },
          "source": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "document"
                  },
                  "documentId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Id of an uploaded source document"
                  }
                },
                "required": [
                  "type",
                  "documentId"
                ],
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "external"
                  },
                  "fileUrl": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Caller-supplied URL for the server to fetch"
                  },
                  "fileName": {
                    "description": "Original file name; defaults to \"document\" if omitted",
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "fileUrl"
                ],
                "additionalProperties": false
              }
            ]
          },
          "fileSource": {
            "type": "string",
            "enum": [
              "managed",
              "external"
            ]
          },
          "includeImages": {
            "type": "boolean"
          },
          "cached": {
            "description": "True when results were returned from content-hash cache",
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "ISO-8601 creation time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "ISO-8601 last status change"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "error": {
            "description": "Present when status is failed",
            "type": "string"
          },
          "errorCode": {
            "description": "Stable machine code when status is failed. `stranded_running` means the worker or client disappeared; it is not a conversion failure.",
            "type": "string"
          },
          "idempotencyKey": {
            "type": "string"
          },
          "usage": {
            "description": "Natural usage units for this job; never credits or currency",
            "type": "object",
            "properties": {
              "inputBytes": {
                "description": "Source document size in bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "discoveredPages": {
                "description": "Pages detected in the source",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "ocrPages": {
                "description": "Pages that required OCR",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "outputBytes": {
                "description": "Produced artifact bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "durationMs": {
                "description": "Wall-clock processing time in milliseconds",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "additionalProperties": false
          },
          "stage": {
            "description": "Fine-grained phase within the current status",
            "type": "string",
            "enum": [
              "preparing",
              "converting",
              "finalizing",
              "complete",
              "error"
            ]
          },
          "stageProgress": {
            "description": "0–100 progress within the current stage",
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "message": {
            "description": "Human-readable status for display",
            "type": "string"
          }
        },
        "required": [
          "id",
          "operation",
          "capabilityVersion",
          "status",
          "source",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false
      },
      "JobUsage": {
        "type": "object",
        "properties": {
          "inputBytes": {
            "description": "Source document size in bytes",
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "discoveredPages": {
            "description": "Pages detected in the source",
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "ocrPages": {
            "description": "Pages that required OCR",
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "outputBytes": {
            "description": "Produced artifact bytes",
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "durationMs": {
            "description": "Wall-clock processing time in milliseconds",
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          }
        },
        "additionalProperties": false
      },
      "Artifact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Id of a job output artifact"
          },
          "jobId": {
            "type": "string",
            "minLength": 1,
            "description": "Id of an async job"
          },
          "kind": {
            "type": "string",
            "enum": [
              "markdown",
              "image",
              "zip",
              "metadata"
            ]
          },
          "contentType": {
            "type": "string",
            "description": "MIME type, e.g. text/markdown or image/png"
          },
          "fileName": {
            "description": "Suggested download file name",
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "downloadUrl": {
            "description": "Time-limited URL to download the artifact bytes",
            "type": "string"
          },
          "text": {
            "description": "Inline text content when kind is markdown/metadata and small enough",
            "type": "string"
          },
          "contentHash": {
            "description": "SHA-256 of artifact bytes as sha256:<hex>. Omitted when bytes were not available to hash (e.g. external zip URL).",
            "type": "string"
          },
          "expiresAt": {
            "description": "When artifact metadata/bytes may be deleted (aligned with job retention)",
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          }
        },
        "required": [
          "id",
          "jobId",
          "kind",
          "contentType",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "ListArtifactsResponse": {
        "type": "object",
        "properties": {
          "jobId": {
            "type": "string",
            "minLength": 1,
            "description": "Id of an async job"
          },
          "artifacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "description": "Id of a job output artifact"
                },
                "jobId": {
                  "type": "string",
                  "minLength": 1,
                  "description": "Id of an async job"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "markdown",
                    "image",
                    "zip",
                    "metadata"
                  ]
                },
                "contentType": {
                  "type": "string",
                  "description": "MIME type, e.g. text/markdown or image/png"
                },
                "fileName": {
                  "description": "Suggested download file name",
                  "type": "string"
                },
                "sizeBytes": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 9007199254740991
                },
                "downloadUrl": {
                  "description": "Time-limited URL to download the artifact bytes",
                  "type": "string"
                },
                "text": {
                  "description": "Inline text content when kind is markdown/metadata and small enough",
                  "type": "string"
                },
                "contentHash": {
                  "description": "SHA-256 of artifact bytes as sha256:<hex>. Omitted when bytes were not available to hash (e.g. external zip URL).",
                  "type": "string"
                },
                "expiresAt": {
                  "description": "When artifact metadata/bytes may be deleted (aligned with job retention)",
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                }
              },
              "required": [
                "id",
                "jobId",
                "kind",
                "contentType",
                "createdAt"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "jobId",
          "artifacts"
        ],
        "additionalProperties": false
      },
      "CreateQuoteRequest": {
        "type": "object",
        "properties": {
          "operation": {
            "default": "convert",
            "description": "Work to price",
            "type": "string",
            "enum": [
              "convert"
            ]
          },
          "capabilityVersion": {
            "default": "1",
            "description": "Capability version the quote is pinned to",
            "type": "string",
            "minLength": 1
          },
          "source": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "document"
                  },
                  "documentId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Id of an uploaded source document"
                  }
                },
                "required": [
                  "type",
                  "documentId"
                ],
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "external"
                  },
                  "fileUrl": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Caller-supplied URL for the server to fetch"
                  },
                  "fileName": {
                    "description": "Original file name; defaults to \"document\" if omitted",
                    "type": "string"
                  }
                },
                "required": [
                  "type",
                  "fileUrl"
                ],
                "additionalProperties": false
              }
            ],
            "description": "Input the quote should estimate"
          },
          "idempotencyKey": {
            "description": "If the same key is reused within the window, return the original quote",
            "type": "string",
            "minLength": 1
          }
        },
        "required": [
          "operation",
          "capabilityVersion",
          "source"
        ],
        "additionalProperties": false
      },
      "CreateQuoteResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Quote id"
          },
          "operation": {
            "type": "string",
            "enum": [
              "convert"
            ]
          },
          "capabilityVersion": {
            "type": "string",
            "minLength": 1,
            "description": "Pinned version of this capability. Quotes, receipts, rate cards, and Skills key off operation + version."
          },
          "estimatedUsage": {
            "type": "object",
            "properties": {
              "inputBytes": {
                "description": "Source document size in bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "discoveredPages": {
                "description": "Pages detected in the source",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "ocrPages": {
                "description": "Pages that required OCR",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "outputBytes": {
                "description": "Produced artifact bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "durationMs": {
                "description": "Wall-clock processing time in milliseconds",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "additionalProperties": false,
            "description": "Estimated natural units; not a bill"
          },
          "estimatedCredits": {
            "type": "number",
            "minimum": 0,
            "description": "Expected credits if work matches the estimate"
          },
          "maximumCredits": {
            "type": "number",
            "minimum": 0,
            "description": "Credits that will be reserved when the job starts; the workspace needs at least this many"
          },
          "priceVersion": {
            "type": "string",
            "minLength": 1,
            "description": "Rate-card version this quote is pinned to"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "ISO-8601 quote expiration"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          }
        },
        "required": [
          "id",
          "operation",
          "capabilityVersion",
          "estimatedUsage",
          "estimatedCredits",
          "maximumCredits",
          "priceVersion",
          "expiresAt",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "Quote": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Quote id"
          },
          "operation": {
            "type": "string",
            "enum": [
              "convert"
            ]
          },
          "capabilityVersion": {
            "type": "string",
            "minLength": 1,
            "description": "Pinned version of this capability. Quotes, receipts, rate cards, and Skills key off operation + version."
          },
          "estimatedUsage": {
            "type": "object",
            "properties": {
              "inputBytes": {
                "description": "Source document size in bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "discoveredPages": {
                "description": "Pages detected in the source",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "ocrPages": {
                "description": "Pages that required OCR",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "outputBytes": {
                "description": "Produced artifact bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "durationMs": {
                "description": "Wall-clock processing time in milliseconds",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "additionalProperties": false,
            "description": "Estimated natural units; not a bill"
          },
          "estimatedCredits": {
            "type": "number",
            "minimum": 0,
            "description": "Expected credits if work matches the estimate"
          },
          "maximumCredits": {
            "type": "number",
            "minimum": 0,
            "description": "Credits that will be reserved when the job starts; the workspace needs at least this many"
          },
          "priceVersion": {
            "type": "string",
            "minLength": 1,
            "description": "Rate-card version this quote is pinned to"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
            "description": "ISO-8601 quote expiration"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          }
        },
        "required": [
          "id",
          "operation",
          "capabilityVersion",
          "estimatedUsage",
          "estimatedCredits",
          "maximumCredits",
          "priceVersion",
          "expiresAt",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "Receipt": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "description": "Receipt id (stable: rcpt_<jobId>)"
          },
          "jobId": {
            "type": "string",
            "minLength": 1,
            "description": "Id of an async job"
          },
          "quoteId": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Quote id when one was pinned"
          },
          "artifactIds": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Artifact ids produced by the job"
          },
          "holdId": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ]
          },
          "tenantId": {
            "type": "string",
            "minLength": 1
          },
          "actorPrincipalId": {
            "type": "string",
            "minLength": 1
          },
          "actorType": {
            "type": "string",
            "minLength": 1
          },
          "credentialId": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ]
          },
          "channel": {
            "type": "string",
            "minLength": 1
          },
          "usage": {
            "type": "object",
            "properties": {
              "inputBytes": {
                "description": "Source document size in bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "discoveredPages": {
                "description": "Pages detected in the source",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "ocrPages": {
                "description": "Pages that required OCR",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "outputBytes": {
                "description": "Produced artifact bytes",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "durationMs": {
                "description": "Wall-clock processing time in milliseconds",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "additionalProperties": false,
            "description": "Natural units; not a second bill"
          },
          "sourceFormat": {
            "type": [
              "string",
              "null"
            ]
          },
          "reservedCredits": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Credits reserved when the job started"
          },
          "settledCredits": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991,
            "description": "Credits actually captured; 0 when the hold was released"
          },
          "priceVersion": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ]
          },
          "tier": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Pricing tier the job was charged at, e.g. standard"
          },
          "fundingSource": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ]
          },
          "originalReceiptId": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "description": "Set on refund/correction receipts; null on the original"
          },
          "kind": {
            "type": "string",
            "enum": [
              "original",
              "refund",
              "correction"
            ]
          },
          "outcome": {
            "type": "string",
            "minLength": 1
          },
          "errorCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "metronomeEventId": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ]
          },
          "stripeInvoiceId": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ]
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
          }
        },
        "required": [
          "id",
          "jobId",
          "quoteId",
          "artifactIds",
          "holdId",
          "tenantId",
          "actorPrincipalId",
          "actorType",
          "credentialId",
          "channel",
          "usage",
          "sourceFormat",
          "reservedCredits",
          "settledCredits",
          "priceVersion",
          "tier",
          "fundingSource",
          "originalReceiptId",
          "kind",
          "outcome",
          "errorCode",
          "metronomeEventId",
          "stripeInvoiceId",
          "occurredAt",
          "createdAt"
        ],
        "additionalProperties": false
      }
    }
  }
}
