{
  "consumer": "scribex",
  "audience": "maipass-api",
  "contract_version": "2026-05-12.v6-stable-request-id-ready-artifacts",
  "base_path": "/v1",
  "auth": {
    "bearer": "Minosse service session returned by /api/v1/service/login",
    "required_headers": {
      "Authorization": "Bearer <minosse_service_session>",
      "X-Maipass-Consumer": "scribex",
      "X-Maipass-Owner": "<minosse_username>",
      "X-Maipass-Request-Id": "<request_id>"
    },
    "rules": [
      "Scribex runtime uses only Minosse service sessions.",
      "MAIPASS_ADMIN_API_TOKEN must never be exposed to the browser.",
      "Scribex persists one stable maipass_request_id per local document and reuses it for X-Maipass-Request-Id on all document-scoped Maipass calls.",
      "Scribex must not orchestrate Pandoc, PaddleOCR, deduplication, page overlap or chunk overlap."
    ]
  },
  "capabilities": [
    "maipass.documents.ingest",
    "maipass.documents.read",
    "maipass.documents.editorial.analyze",
    "maipass.files.read",
    "maipass.prompts.read",
    "maipass.messaging.send"
  ],
  "implemented_endpoints": [
    {
      "key": "documents_ingest",
      "method": "POST",
      "path": "/v1/documents/ingest",
      "capability": "maipass.documents.ingest",
      "content_type": "multipart/form-data",
      "request_parts": {
        "file": "pdf/docx/txt/md/png/jpeg/webp",
        "system_prompt": "Final OCR/editorial prompt composed by Scribex",
        "message": "optional short upload note",
        "prompt_slug": "optional Maipass prompt slug used as base prompt",
        "workflow_profile": "document-ingestion-flow.v2"
      },
      "response": {
        "ok": true,
        "document_id": "uuid/string",
        "status": "queued|processing|ready|failed",
        "manifest_path": "ingestion/{document_id}/manifest.json"
      }
    },
    {
      "key": "documents_get",
      "method": "GET",
      "path": "/v1/documents/{document_id}",
      "capability": "maipass.documents.read",
      "response": {
        "ok": true,
        "document_id": "uuid/string",
        "status": "queued|processing|ready|failed",
        "status_message": "optional human-readable status"
      }
    },
    {
      "key": "documents_artifacts",
      "method": "GET",
      "path": "/v1/documents/{document_id}/artifacts",
      "capability": "maipass.documents.read",
      "canonical_artifacts": {
        "ocr_raw_markdown": "ingestion/{document_id}/outputs/ocr-raw.md",
        "ocr_raw_batches_jsonl": "ingestion/{document_id}/outputs/ocr-raw-batches.jsonl",
        "ocr_doubts_json": "ingestion/{document_id}/outputs/ocr-doubts.json",
        "transcription_markdown": "ingestion/{document_id}/outputs/transcription.md",
        "source_markdown": "ingestion/{document_id}/outputs/source.md",
        "editorial_analysis_markdown": "ingestion/{document_id}/outputs/editorial-analysis.md",
        "diff_markdown": "ingestion/{document_id}/outputs/diff.md",
        "reader_manifest_json": "ingestion/{document_id}/outputs/reader-manifest.json",
        "presentation_sidecar_json": "ingestion/{document_id}/outputs/presentation-sidecar.json",
        "editorial_analysis_json": "ingestion/{document_id}/outputs/editorial-analysis.json",
        "diff_json": "ingestion/{document_id}/outputs/diff.json",
        "footnotes_markdown": "ingestion/{document_id}/outputs/footnotes.md",
        "footnote_map_json": "ingestion/{document_id}/outputs/footnote-map.json",
        "semantic_tags_json": "ingestion/{document_id}/outputs/semantic-tags.json",
        "page_structure_jsonl": "ingestion/{document_id}/outputs/page-structure.jsonl",
        "stitching_jsonl": "ingestion/{document_id}/outputs/stitching-windows.jsonl"
      },
      "artifact_paths": [
        "ocr_raw_markdown",
        "ocr_raw_batches_jsonl",
        "ocr_doubts_json",
        "transcription_markdown",
        "source_markdown",
        "editorial_analysis_markdown",
        "diff_markdown",
        "reader_manifest_json",
        "presentation_sidecar_json",
        "editorial_analysis_json (if available)",
        "diff_json (if available)",
        "footnotes_markdown (if available)",
        "footnote_map_json (if available)",
        "semantic_tags_json (if available)",
        "page_structure_jsonl (if available)",
        "stitching_jsonl (if available)"
      ],
      "response": {
        "ok": true,
        "document_id": "uuid/string",
        "status": "queued|postprocessed|editorial_analyzed",
        "artifact_paths": {
          "ocr_raw_markdown": "ingestion/{document_id}/outputs/ocr-raw.md",
          "ocr_raw_batches_jsonl": "ingestion/{document_id}/outputs/ocr-raw-batches.jsonl",
          "ocr_doubts_json": "ingestion/{document_id}/outputs/ocr-doubts.json",
          "transcription_markdown": "ingestion/{document_id}/outputs/transcription.md",
          "source_markdown": "ingestion/{document_id}/outputs/source.md",
          "editorial_analysis_markdown": "ingestion/{document_id}/outputs/editorial-analysis.md",
          "diff_markdown": "ingestion/{document_id}/outputs/diff.md",
          "reader_manifest_json": "ingestion/{document_id}/outputs/reader-manifest.json",
          "presentation_sidecar_json": "ingestion/{document_id}/outputs/presentation-sidecar.json",
          "editorial_analysis_json": "ingestion/{document_id}/outputs/editorial-analysis.json",
          "diff_json": "ingestion/{document_id}/outputs/diff.json",
          "footnote_map_json": "ingestion/{document_id}/outputs/footnote-map.json",
          "page_structure_jsonl": "ingestion/{document_id}/outputs/page-structure.jsonl",
          "stitching_jsonl": "ingestion/{document_id}/outputs/stitching-windows.jsonl"
        },
        "artifacts": [
          {
            "role": "transcription_markdown",
            "path": "ingestion/{document_id}/outputs/transcription.md",
            "content_type": "text/markdown; charset=utf-8",
            "size": 1234,
            "sha256": "string",
            "updated_at": "2026-05-08T12:34:56Z"
          }
        ],
        "readiness": {
          "consumer_ready": false,
          "next_required_action": "document.editorial_analyze|operator_review|..."
        },
        "manual_review": {
          "state": "required|blocked|none",
          "reason": "optional reason"
        }
      }
    },
    {
      "key": "documents_reader_manifest",
      "method": "GET",
      "path": "/v1/documents/{document_id}/reader-manifest",
      "capability": "maipass.documents.read",
      "response": {
        "schema": "maipass.document-reader-manifest.v1",
        "document_id": "uuid/string",
        "headings": "outline array with stable ids (id + title + level)",
        "appendices": "appendix blocks with anchors",
        "page_markers": "array",
        "analysis_sections": "array",
        "analysis_annotations": "array",
        "diff_hunks": "array",
        "footnote_map": "maps editorial_ref/editorial_ref_id to stable source footnote_id",
        "provenance": "ingestion + routing + source provenance",
        "artifact_paths": "same map of canonical artifact paths"
      }
    },
    {
      "key": "documents_editorial_analyze",
      "method": "POST",
      "path": "/v1/documents/editorial/analyze",
      "capability": "maipass.documents.editorial.analyze",
      "request": {
        "document_id": "uuid/string",
        "prompt": "string",
        "system_prompt_append": "string",
        "deploy": false
      },
      "response": {
        "ok": true,
        "document_id": "uuid/string",
        "status": "processing|queued",
        "status_message": "optional"
      }
    },
    {
      "key": "documents_regenerate",
      "method": "POST",
      "path": "/v1/documents/{document_id}/actions/regenerate",
      "capability": "maipass.documents.editorial.analyze",
      "usage": "Preferred granular regenerate action for Scribex UI.",
      "request": {
        "action": "full|ocr|preprocess|analysis|tags|notes",
        "prompt": "optional Scribex/user editorial instruction",
        "system_prompt_append": "same Scribex system prompt when relevant",
        "deploy": false,
        "force": true,
        "reason": "manual_scribex_regenerate"
      },
      "response": {
        "ok": true,
        "document_id": "uuid/string",
        "status": "queued|processing|postprocessed|editorial_queued"
      }
    },
    {
      "key": "documents_approved",
      "method": "POST",
      "path": "/v1/documents/{document_id}/actions/approved",
      "capability": "maipass.documents.editorial.analyze",
      "usage": "Final compaction/cleanup after Scribex review approval. Call dry_run first, then confirm.",
      "request": {
        "dry_run": true,
        "confirm": false
      },
      "confirm_request": {
        "dry_run": false,
        "confirm": true
      }
    },
    {
      "key": "documents_unlink",
      "method": "POST",
      "path": "/v1/documents/{document_id}/unlink",
      "capability": "maipass.documents.read",
      "usage": "Called before Scribex deletes a local document so Maipass can mark the ingestion unlinked for retention cleanup.",
      "request": {
        "consumer": "scribex",
        "owner_username": "<owner_username>",
        "local_document_id": "<scribex_document_id>",
        "reason": "user_deleted",
        "deleted_at": "RFC3339"
      },
      "response": {
        "ok": true,
        "document_id": "uuid/string",
        "consumer": "scribex",
        "owner_username": "<owner_username>",
        "retention_state": "unlinked"
      }
    },
    {
      "key": "files_download",
      "method": "GET",
      "path": "/v1/files/download?path={path}",
      "capability": "maipass.files.read",
      "usage": "Download the canonical markdown artifact path returned by /v1/documents/{document_id}/artifacts."
    },
    {
      "key": "prompts_list",
      "method": "GET",
      "path": "/v1/prompts",
      "capability": "maipass.prompts.read",
      "usage": "Populate the Scribex system prompt dropdown with title/label text and slug as value."
    },
    {
      "key": "prompts_get",
      "method": "GET",
      "path": "/v1/prompts/{slug}",
      "capability": "maipass.prompts.read",
      "usage": "Read the selected prompt body before Scribex appends its local document/language/user notes."
    },
    {
      "key": "messaging_smtp_send",
      "method": "POST",
      "path": "/v1/messaging/smtp/send",
      "capability": "maipass.messaging.send",
      "usage": "Optional notification after Scribex has copied the ready artifact locally."
    }
  ],
  "scribex_prompt_composition": [
    "FINAL_PROMPT = SYSTEM_PROMPT + DOCUMENT_TYPE_PROMPT + LANGUAGE_PROMPT + NOTES_PROMPT + USER_OPERATIVE_NOTES",
    "SYSTEM_PROMPT comes from Maipass prompt slug.",
    "DOCUMENT_TYPE_PROMPT, LANGUAGE_PROMPT and NOTES_PROMPT come from apps/scribex/docs/prompt-appendix.",
    "USER_OPERATIVE_NOTES are the modal textarea content."
  ],
  "polling": {
    "interval_seconds": 30,
    "sequence": [
      "GET /v1/documents/{document_id} only until readiness.consumer_ready is true",
      "Do not call document.editorial_analyze during normal polling",
      "Use POST /v1/documents/editorial/analyze only for explicit Rigenera/Riprova actions",
      "When readiness.consumer_ready is true, call GET /v1/documents/{document_id}/artifacts",
      "After consumer_ready, GET /v1/documents/{document_id}/reader-manifest when available",
      "After consumer_ready, GET /v1/files/download?path=<artifact_path> for paths returned by artifact_paths or artifacts[] only",
      "Never treat planned outputs as downloadable artifact paths"
    ]
  }
}
