{
  "openapi": "3.1.0",
  "info": {
    "title": "Markovo Conversion API",
    "version": "2026-07-30",
    "description": "Account-metered file-to-Markdown conversion. Prices and capability status are discovered at runtime; failed jobs spend no Credits."
  },
  "servers": [{ "url": "https://markovo.net" }],
  "tags": [
    { "name": "Discovery" },
    { "name": "Conversion" },
    { "name": "Account" }
  ],
  "paths": {
    "/v1/capabilities": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "listCapabilities",
        "responses": { "200": { "description": "Authoritative capability catalog", "content": { "application/json": { "schema": { "type": "object" } } } } }
      }
    },
    "/v1/catalog": {
      "get": {
        "tags": ["Discovery"],
        "operationId": "getCatalog",
        "responses": { "200": { "description": "Authoritative plan, pack, and Credit contract", "content": { "application/json": { "schema": { "type": "object" } } } } }
      }
    },
    "/v1/estimates": {
      "post": {
        "tags": ["Conversion"],
        "operationId": "createEstimate",
        "security": [{ "bearerAuth": [] }, {}],
        "requestBody": { "$ref": "#/components/requestBodies/ConversionUpload" },
        "responses": {
          "201": { "description": "Bounded estimate", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Estimate" } } } },
          "400": { "$ref": "#/components/responses/Error" },
          "413": { "$ref": "#/components/responses/Error" },
          "422": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/url-estimates": {
      "post": {
        "tags": ["Conversion"],
        "operationId": "createUrlEstimate",
        "description": "Fetch one public HTTPS page in the isolated no-credential sandbox after explicit caller consent, then return a bounded Credit v2 estimate.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": ["url", "accept_remote_fetch"],
                "properties": {
                  "url": { "type": "string", "format": "uri", "maxLength": 2048, "pattern": "^https://" },
                  "accept_remote_fetch": { "type": "boolean", "const": true }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Sanitized public-page estimate", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Estimate" } } } },
          "400": { "$ref": "#/components/responses/Error" },
          "401": { "$ref": "#/components/responses/Error" },
          "403": { "$ref": "#/components/responses/Error" },
          "413": { "$ref": "#/components/responses/Error" },
          "422": { "$ref": "#/components/responses/Error" },
          "503": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/jobs": {
      "get": {
        "tags": ["Conversion"],
        "operationId": "listJobs",
        "security": [{ "bearerAuth": [] }],
        "responses": { "200": { "description": "Jobs owned by the current organization and project", "content": { "application/json": { "schema": { "type": "object", "properties": { "jobs": { "type": "array", "items": { "$ref": "#/components/schemas/Job" } } } } } } } }
      },
      "post": {
        "tags": ["Conversion"],
        "operationId": "confirmEstimate",
        "security": [{ "bearerAuth": [] }, { "jobToken": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobConfirmation" } } } },
        "responses": {
          "200": { "description": "Idempotent replay of an already confirmed job", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConfirmedJob" } } } },
          "201": { "description": "New job queued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConfirmedJob" } } } },
          "402": { "$ref": "#/components/responses/Error" },
          "409": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/convert": {
      "post": {
        "tags": ["Conversion"],
        "operationId": "convertWithCompatibilityShortcut",
        "security": [{ "bearerAuth": [] }, {}],
        "requestBody": { "$ref": "#/components/requestBodies/ConversionUploadWithMaximum" },
        "responses": {
          "200": { "description": "One or more jobs queued", "content": { "application/json": { "schema": { "type": "object" } } } },
          "207": { "description": "Only a subset of files were queued; unqueued files spend no Credits", "content": { "application/json": { "schema": { "type": "object" } } } },
          "400": { "$ref": "#/components/responses/Error" },
          "402": { "$ref": "#/components/responses/Error" },
          "413": { "$ref": "#/components/responses/Error" },
          "422": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/jobs/{job_id}": {
      "parameters": [{ "$ref": "#/components/parameters/JobId" }],
      "get": {
        "tags": ["Conversion"],
        "operationId": "getJob",
        "security": [{ "bearerAuth": [] }, { "jobToken": [] }],
        "responses": { "200": { "description": "Owned job", "content": { "application/json": { "schema": { "type": "object", "properties": { "job": { "$ref": "#/components/schemas/Job" } } } } } }, "404": { "$ref": "#/components/responses/Error" } }
      },
      "delete": {
        "tags": ["Conversion"],
        "operationId": "deleteJob",
        "security": [{ "bearerAuth": [] }, { "jobToken": [] }],
        "responses": { "204": { "description": "Deleted" }, "404": { "$ref": "#/components/responses/Error" }, "409": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/jobs/{job_id}/download": {
      "parameters": [{ "$ref": "#/components/parameters/JobId" }],
      "get": {
        "tags": ["Conversion"],
        "operationId": "downloadResult",
        "security": [{ "bearerAuth": [] }, { "jobToken": [] }],
        "parameters": [{ "name": "format", "in": "query", "schema": { "type": "string", "enum": ["md", "zip"], "default": "md" } }],
        "responses": { "200": { "description": "Markdown or verified bundle", "content": { "text/markdown": {}, "application/zip": {} } }, "404": { "$ref": "#/components/responses/Error" }, "409": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/v1/jobs/{job_id}/assets": {
      "parameters": [{ "$ref": "#/components/parameters/JobId" }],
      "get": {
        "tags": ["Conversion"],
        "operationId": "listJobAssets",
        "security": [{ "bearerAuth": [] }, { "jobToken": [] }],
        "responses": {
          "200": { "description": "Manifest-verified Bundle image assets", "content": { "application/json": { "schema": { "type": "object", "required": ["job_id", "assets"], "properties": { "job_id": { "type": "string" }, "assets": { "type": "array", "items": { "$ref": "#/components/schemas/BundleAsset" } } } } } } },
          "404": { "$ref": "#/components/responses/Error" },
          "409": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/jobs/{job_id}/asset-grants": {
      "parameters": [{ "$ref": "#/components/parameters/JobId" }],
      "post": {
        "tags": ["Conversion"],
        "operationId": "createAssetGrant",
        "security": [{ "bearerAuth": [] }, { "jobToken": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AssetGrantInput" } } } },
        "responses": {
          "201": { "description": "Revocable short-lived asset URL", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AssetGrant" } } } },
          "400": { "$ref": "#/components/responses/Error" },
          "404": { "$ref": "#/components/responses/Error" },
          "409": { "$ref": "#/components/responses/Error" },
          "410": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/jobs/{job_id}/asset-grants/{grant_id}": {
      "parameters": [
        { "$ref": "#/components/parameters/JobId" },
        { "name": "grant_id", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^ag_[a-f0-9]{32}$" } }
      ],
      "delete": {
        "tags": ["Conversion"],
        "operationId": "revokeAssetGrant",
        "security": [{ "bearerAuth": [] }, { "jobToken": [] }],
        "responses": {
          "204": { "description": "Asset grant revoked" },
          "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/asset-grants/{token}": {
      "parameters": [
        { "name": "token", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^mk_asset_[a-f0-9]{64}$" } }
      ],
      "get": {
        "tags": ["Conversion"],
        "operationId": "readAssetGrant",
        "security": [],
        "description": "Bearer capability URL. It expires in at most 10 minutes, can be revoked, and must not be logged or forwarded.",
        "responses": {
          "200": { "description": "Private Bundle image", "content": { "image/png": {}, "image/jpeg": {}, "image/webp": {}, "image/tiff": {}, "image/bmp": {}, "image/svg+xml": {} } },
          "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/v1/jobs/{job_id}/quality-report": {
      "parameters": [{ "$ref": "#/components/parameters/JobId" }],
      "get": { "tags": ["Conversion"], "operationId": "getQualityReport", "security": [{ "bearerAuth": [] }, { "jobToken": [] }], "responses": { "200": { "description": "Versioned Markovo quality evidence", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/QualityReport" } } } }, "404": { "$ref": "#/components/responses/Error" }, "409": { "$ref": "#/components/responses/Error" } } }
    },
    "/v1/jobs/{job_id}/delivery-check": {
      "parameters": [{ "$ref": "#/components/parameters/JobId" }],
      "get": { "tags": ["Conversion"], "operationId": "getDeliveryCheck", "security": [{ "bearerAuth": [] }, { "jobToken": [] }], "responses": { "200": { "description": "Versioned Bundle delivery verification", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DeliveryCheck" } } } }, "404": { "$ref": "#/components/responses/Error" }, "409": { "$ref": "#/components/responses/Error" } } }
    },
    "/v1/jobs/{job_id}/result-feedback": {
      "parameters": [{ "$ref": "#/components/parameters/JobId" }],
      "get": { "tags": ["Conversion"], "operationId": "getResultFeedback", "security": [{ "bearerAuth": [] }, { "jobToken": [] }], "responses": { "200": { "description": "Current actor rating", "content": { "application/json": { "schema": { "type": "object", "properties": { "feedback": { "anyOf": [{ "$ref": "#/components/schemas/ResultFeedback" }, { "type": "null" }] } } } } } }, "404": { "$ref": "#/components/responses/Error" } } },
      "put": { "tags": ["Conversion"], "operationId": "putResultFeedback", "security": [{ "bearerAuth": [] }, { "jobToken": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResultFeedbackInput" } } } }, "responses": { "200": { "description": "Rating saved", "content": { "application/json": { "schema": { "type": "object" } } } }, "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }, "409": { "$ref": "#/components/responses/Error" }, "429": { "$ref": "#/components/responses/Error" } } },
      "delete": { "tags": ["Conversion"], "operationId": "deleteResultFeedback", "security": [{ "bearerAuth": [] }, { "jobToken": [] }], "responses": { "204": { "description": "Rating removed" }, "404": { "$ref": "#/components/responses/Error" }, "429": { "$ref": "#/components/responses/Error" } } }
    },
    "/v1/account/usage": {
      "get": { "tags": ["Account"], "operationId": "getUsage", "security": [{ "bearerAuth": [] }], "responses": { "200": { "description": "Integer and decimal Credit balance", "content": { "application/json": { "schema": { "type": "object" } } } }, "401": { "$ref": "#/components/responses/Error" } } }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "Markovo API key" },
      "jobToken": { "type": "apiKey", "in": "header", "name": "x-markovo-job-token" }
    },
    "parameters": {
      "JobId": { "name": "job_id", "in": "path", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 128 } }
    },
    "requestBodies": {
      "ConversionUpload": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": ["file"], "properties": { "file": { "type": "string", "format": "binary" }, "capability_id": { "type": "string" }, "mode": { "type": "string", "enum": ["fast", "accurate"], "default": "fast" }, "layout_fidelity": { "type": "string", "enum": ["standard", "formula"], "default": "standard", "description": "Formula is a signed-in PDF Beta. Detected formula regions render as LaTeX; compare every equation with the original PDF. Each detected region adds 700 credit_units (0.7 Credit)." } } } } } },
      "ConversionUploadWithMaximum": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": ["file"], "properties": { "file": { "type": "array", "items": { "type": "string", "format": "binary" } }, "capability_id": { "type": "string" }, "mode": { "type": "string", "enum": ["fast", "accurate"], "default": "fast" }, "max_credit_units": { "type": "integer", "minimum": 1 }, "max_credits": { "oneOf": [{ "type": "number", "multipleOf": 0.001 }, { "type": "string", "pattern": "^[0-9]+(?:\\.[0-9]{1,3})?$" }] } } } } } }
    },
    "responses": {
      "Error": { "description": "Machine-readable safe error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } } }
    },
    "schemas": {
      "Estimate": { "type": "object", "required": ["upload_id", "credit_scale", "credit_model_version", "rate_card_version", "estimated_credit_units"], "properties": { "upload_id": { "type": "string" }, "job_token": { "type": "string" }, "credit_scale": { "const": 1000 }, "credit_model_version": { "type": "string" }, "rate_card_version": { "type": "string" }, "estimated_credit_units": { "type": "integer", "minimum": 0 }, "estimated_credits": { "type": "number", "minimum": 0 }, "layout_fidelity": { "type": "string", "enum": ["standard", "formula"] }, "formula_detection": { "type": "object", "additionalProperties": false, "required": ["requested", "applied", "reason", "additional_credit_units"], "properties": { "requested": { "const": true }, "applied": { "const": false }, "reason": { "const": "no_formula_regions" }, "additional_credit_units": { "const": 0 } }, "description": "Present when formula enhancement was requested but local preflight found no formula region. The estimate automatically uses standard conversion and adds no formula charge." }, "formula_candidate_pages": { "type": "array", "maxItems": 8, "uniqueItems": true, "items": { "type": "integer", "minimum": 0 } }, "formula_regions": { "type": "array", "maxItems": 32, "items": { "type": "object", "additionalProperties": false, "required": ["region_id", "page_index", "bbox"], "properties": { "region_id": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$" }, "page_index": { "type": "integer", "minimum": 0 }, "bbox": { "type": "array", "minItems": 4, "maxItems": 4, "items": { "type": "number", "minimum": 0 } } } }, "description": "Regions detected during unpaid formula preflight; the estimate shows the region count and maximum price before conversion." }, "external_processing": { "type": "object", "additionalProperties": false, "properties": { "required": { "type": "boolean" }, "transfer_scope": { "type": "string" } }, "description": "When required, only the detected formula region is transferred to a third-party service; the scope is disclosed before conversion." }, "billing_metrics": { "type": "object", "additionalProperties": { "oneOf": [{ "type": "number" }, { "type": "array", "uniqueItems": true, "items": { "type": "integer", "minimum": 0 } }] } } } },
      "JobConfirmation": { "type": "object", "required": ["upload_id"], "properties": { "upload_id": { "type": "string" }, "max_credit_units": { "type": "integer", "minimum": 1 }, "max_credits": { "oneOf": [{ "type": "number", "multipleOf": 0.001 }, { "type": "string", "pattern": "^[0-9]+(?:\\.[0-9]{1,3})?$" }] } }, "anyOf": [{ "required": ["max_credit_units"] }, { "required": ["max_credits"] }] },
      "ConfirmedJob": { "type": "object", "required": ["job_id", "status", "capability_id", "estimated_credits", "credit_scale", "credit_model_version", "rate_card_version", "estimated_credit_units"], "properties": { "job_id": { "type": "string" }, "status": { "type": "string", "enum": ["queued", "running", "succeeded", "failed", "cancelled"] }, "capability_id": { "type": "string" }, "estimated_credits": { "type": "number", "minimum": 0 }, "credit_scale": { "const": 1000 }, "credit_model_version": { "type": "string" }, "rate_card_version": { "type": "string" }, "estimated_credit_units": { "type": "integer", "minimum": 0 }, "job_token": { "type": "string", "description": "Returned only for an anonymous guest job." } } },
      "Job": { "type": "object", "required": ["id", "status", "credit_scale", "credit_model_version", "rate_card_version"], "properties": { "id": { "type": "string" }, "status": { "type": "string", "enum": ["queued", "running", "succeeded", "failed", "cancelled"] }, "capability_id": { "type": "string" }, "credit_scale": { "const": 1000 }, "credit_model_version": { "type": "string" }, "rate_card_version": { "type": "string" }, "estimated_credit_units": { "type": "integer", "minimum": 0 }, "actual_credit_units": { "type": ["integer", "null"], "minimum": 0 }, "estimated_credits": { "type": "number", "minimum": 0 }, "actual_credits": { "type": ["number", "null"], "minimum": 0 }, "deliverable": { "type": ["integer", "boolean", "null"] }, "billing_metrics": { "type": ["object", "null"], "additionalProperties": { "type": "number" } } } },
      "BundleAsset": { "type": "object", "required": ["path", "bytes", "sha256", "content_type"], "properties": { "path": { "type": "string", "pattern": "^assets/" }, "bytes": { "type": "integer", "minimum": 0 }, "sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "content_type": { "type": "string", "enum": ["image/png", "image/jpeg", "image/webp", "image/tiff", "image/bmp", "image/svg+xml"] } } },
      "QualityReport": {"type":"object","additionalProperties":false,"required":["schema_version","document_score","pages_low_confidence","review_required","page_scores","summary"],"properties":{"schema_version":{"const":"markovo.quality-report.v1"},"document_score":{"type":"number","minimum":0,"maximum":1},"pages_low_confidence":{"type":"array","items":{"type":"integer","minimum":1}},"review_required":{"type":"boolean"},"page_scores":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["page_index","score","confidence","review_required"],"properties":{"page_index":{"type":"integer","minimum":1},"score":{"type":"number","minimum":0,"maximum":1},"confidence":{"type":"number","minimum":0,"maximum":1},"review_required":{"type":"boolean"}}}},"summary":{"type":"object","additionalProperties":false,"required":["pages_total","pages_low_confidence","pages_with_errors","average_page_score"],"properties":{"pages_total":{"type":"integer","minimum":0},"pages_low_confidence":{"type":"integer","minimum":0},"pages_with_errors":{"type":"integer","minimum":0},"average_page_score":{"type":"number","minimum":0,"maximum":1}}}}},
      "DeliveryCheck": { "type": "object", "additionalProperties": true, "required": ["schema_version", "version", "status", "deliverable", "summary", "checks", "metrics", "policy", "next_actions"], "properties": { "schema_version": { "const": "markovo.delivery-check.v1" }, "version": { "type": "string" }, "status": { "type": "string", "enum": ["deliverable", "review_required", "blocked"] }, "deliverable": { "type": "boolean" }, "summary": { "type": "object" }, "checks": { "type": "array", "items": { "type": "object" } }, "metrics": { "type": "object" }, "policy": { "type": "object" }, "next_actions": { "type": "array", "items": { "type": "string" } } } },
      "AssetGrantInput": { "type": "object", "additionalProperties": false, "required": ["asset_path"], "properties": { "asset_path": { "type": "string", "pattern": "^assets/", "maxLength": 512 }, "expires_in_seconds": { "type": "integer", "minimum": 60, "maximum": 600, "default": 300 } } },
      "AssetGrant": { "type": "object", "required": ["grant_id", "job_id", "asset_path", "url", "expires_at", "expires_in_seconds"], "properties": { "grant_id": { "type": "string", "pattern": "^ag_[a-f0-9]{32}$" }, "job_id": { "type": "string" }, "asset_path": { "type": "string", "pattern": "^assets/" }, "url": { "type": "string", "format": "uri" }, "expires_at": { "type": "string", "format": "date-time" }, "expires_in_seconds": { "type": "integer", "minimum": 0, "maximum": 600 } } },
      "ResultFeedbackInput": { "type": "object", "required": ["rating"], "properties": { "rating": { "type": "string", "enum": ["up", "down"] }, "reason_code": { "type": "string", "enum": ["missing_content", "reading_order", "table_formula", "garbled_text", "layout_assets", "other"] }, "comment": { "type": "string", "maxLength": 1000 } }, "additionalProperties": false },
      "ResultFeedback": { "type": "object", "required": ["rating", "created_at", "updated_at"], "properties": { "rating": { "type": "string", "enum": ["up", "down"] }, "reason_code": { "type": ["string", "null"] }, "comment": { "type": ["string", "null"], "maxLength": 1000 }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } },
      "ErrorEnvelope": { "type": "object", "required": ["error"], "properties": { "error": { "type": "object", "required": ["code", "message", "request_id", "retryable", "docs_url"], "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "request_id": { "type": "string", "format": "uuid" }, "retryable": { "type": "boolean" }, "docs_url": { "type": "string", "format": "uri" } } } } }
    }
  }
}
