{
  "info": {
    "_postman_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "name": "OCR Platform API v1",
    "description": "Colección para probar la API pública `/v1` de OCR Platform.\n\n## Antes de empezar\n1. Lee la guía pública en `/docs` de tu instancia.\n2. Solicita una API Key al equipo de plataforma (integradores externos no tienen acceso al admin).\n3. Importa el entorno `OCR-Platform-Railway.postman_environment.json` o `OCR-Platform-Local.postman_environment.json`.\n4. Configura `base_url` y `api_key` en el entorno.\n5. Para **POST /documents**, selecciona un archivo PDF en el campo `file` (form-data).\n\n## Scopes requeridos\n- `documents:create` — crear y cancelar documentos\n- `documents:read` — listar y consultar documentos\n- `results:read` — obtener resultado OCR\n- `extractions:create` — crear extracciones\n- `extractions:read` — consultar extracciones\n- `usage:read` — consultar consumo del proyecto\n\n## Flujo recomendado\n1. Health Live\n2. Crear documento → guarda `document_id`\n3. Consultar documento (repetir hasta `completed` o `partial_success`)\n4. Obtener resultado OCR\n5. Crear extracción → guarda `extraction_id`\n6. Consultar extracción / resultado",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "X-API-Key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{api_key}}",
        "type": "string"
      },
      {
        "key": "in",
        "value": "header",
        "type": "string"
      }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "pm.request.headers.upsert({ key: 'Accept', value: 'application/json' });",
          "if (!pm.request.headers.get('X-Request-ID')) {",
          "    pm.request.headers.upsert({ key: 'X-Request-ID', value: pm.variables.replaceIn('{{$guid}}') });",
          "}"
        ]
      }
    }
  ],
  "item": [
    {
      "name": "Health",
      "item": [
        {
          "name": "Health Live",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/health/live",
              "host": ["{{base_url}}"],
              "path": ["health", "live"]
            },
            "description": "Sin autenticación. Debe responder `{\"status\":\"ok\"}`."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "pm.test('status ok', () => pm.expect(pm.response.json().status).to.eql('ok'));"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Documents",
      "item": [
        {
          "name": "Crear documento (upload)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "type": "text"
              }
            ],
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "file",
                  "type": "file",
                  "src": [],
                  "description": "Selecciona un PDF o imagen (jpeg/png)"
                },
                {
                  "key": "profile",
                  "value": "{{profile}}",
                  "type": "text",
                  "description": "ine_document | csf_document | cfdi_invoice | curp_document | proof_of_address | bank_statement | passport | birth_certificate | contract | general_document"
                },
                {
                  "key": "output_formats[]",
                  "value": "markdown",
                  "type": "text"
                },
                {
                  "key": "output_formats[]",
                  "value": "json",
                  "type": "text"
                },
                {
                  "key": "output_formats[]",
                  "value": "text",
                  "type": "text"
                },
                {
                  "key": "languages[]",
                  "value": "es",
                  "type": "text"
                },
                {
                  "key": "external_reference",
                  "value": "postman-test-001",
                  "type": "text"
                },
                {
                  "key": "priority",
                  "value": "normal",
                  "type": "text",
                  "description": "normal | high"
                }
              ]
            },
            "url": {
              "raw": "{{base_url}}/v1/documents",
              "host": ["{{base_url}}"],
              "path": ["v1", "documents"]
            },
            "description": "Sube un archivo para OCR. Requiere scope `documents:create` y header `Idempotency-Key` (mín. 16 caracteres)."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Aceptado (202)', () => pm.expect(pm.response.code).to.be.oneOf([200, 202]));",
                  "const json = pm.response.json();",
                  "if (json.data && json.data.id) {",
                  "    pm.environment.set('document_id', json.data.id);",
                  "    console.log('document_id guardado:', json.data.id);",
                  "}",
                  "pm.test('Tiene request_id', () => pm.expect(json.meta.request_id).to.be.a('string'));"
                ]
              }
            }
          ]
        },
        {
          "name": "Listar documentos",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/documents?page=1&per_page=25",
              "host": ["{{base_url}}"],
              "path": ["v1", "documents"],
              "query": [
                { "key": "status", "value": "processing", "disabled": true },
                { "key": "profile", "value": "{{profile}}", "disabled": true },
                { "key": "external_reference", "value": "postman-test-001", "disabled": true },
                { "key": "page", "value": "1" },
                { "key": "per_page", "value": "25" }
              ]
            },
            "description": "Scope: `documents:read`"
          },
          "response": []
        },
        {
          "name": "Detalle documento",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/documents/{{document_id}}",
              "host": ["{{base_url}}"],
              "path": ["v1", "documents", "{{document_id}}"]
            },
            "description": "Consulta estado (`queued`, `processing`, `completed`, etc.). Usa `document_id` del paso anterior."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', () => pm.response.to.have.status(200));",
                  "const status = pm.response.json().data.status;",
                  "console.log('Estado documento:', status);"
                ]
              }
            }
          ]
        },
        {
          "name": "Resultado OCR documento",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/documents/{{document_id}}/result?format={{result_format}}&download=false",
              "host": ["{{base_url}}"],
              "path": ["v1", "documents", "{{document_id}}", "result"],
              "query": [
                {
                  "key": "format",
                  "value": "{{result_format}}",
                  "description": "markdown | json | text (debe coincidir con output_formats del documento)"
                },
                {
                  "key": "download",
                  "value": "false",
                  "description": "false = contenido inline. true requiere Wasabi (URL firmada)."
                }
              ]
            },
            "description": "Scope: `results:read`. Requiere query `format`. Solo cuando el documento está `completed` o `partial_success`."
          },
          "response": []
        },
        {
          "name": "Cancelar documento",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/documents/{{document_id}}/cancel",
              "host": ["{{base_url}}"],
              "path": ["v1", "documents", "{{document_id}}", "cancel"]
            },
            "description": "Scope: `documents:create`. Solo antes de enviarse a Docling."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Extractions",
      "item": [
        {
          "name": "Crear extracción",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"document_id\": \"{{document_id}}\",\n  \"custom_instruction\": \"Extrae el total, la fecha y el nombre del emisor del documento.\",\n  \"input_result_type\": \"markdown\",\n  \"response_schema\": {\n    \"type\": \"object\",\n    \"additionalProperties\": false,\n    \"required\": [\"total\", \"date\", \"issuer\"],\n    \"properties\": {\n      \"total\": { \"type\": [\"number\", \"null\"] },\n      \"date\": { \"type\": [\"string\", \"null\"] },\n      \"issuer\": { \"type\": [\"string\", \"null\"] }\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/extractions",
              "host": ["{{base_url}}"],
              "path": ["v1", "extractions"]
            },
            "description": "Scope: `extractions:create`. El documento debe ser de la misma API Key y estar `completed` o `partial_success`; si sigue en proceso, la extracción queda en `waiting_for_document`."
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Aceptado', () => pm.expect(pm.response.code).to.be.oneOf([200, 202]));",
                  "const json = pm.response.json();",
                  "if (json.data && json.data.id) {",
                  "    pm.environment.set('extraction_id', json.data.id);",
                  "    console.log('extraction_id guardado:', json.data.id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Listar extracciones",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/extractions?page=1&per_page=25",
              "host": ["{{base_url}}"],
              "path": ["v1", "extractions"],
              "query": [
                { "key": "document_id", "value": "{{document_id}}", "disabled": true },
                { "key": "status", "value": "completed", "disabled": true },
                { "key": "page", "value": "1" },
                { "key": "per_page", "value": "25" }
              ]
            },
            "description": "Scope: `extractions:read`"
          },
          "response": []
        },
        {
          "name": "Detalle extracción",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/extractions/{{extraction_id}}",
              "host": ["{{base_url}}"],
              "path": ["v1", "extractions", "{{extraction_id}}"]
            }
          },
          "response": []
        },
        {
          "name": "Resultado extracción",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/extractions/{{extraction_id}}/result",
              "host": ["{{base_url}}"],
              "path": ["v1", "extractions", "{{extraction_id}}", "result"]
            },
            "description": "JSON validado contra `response_schema` cuando status es `completed`."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Usage",
      "item": [
        {
          "name": "Consumo del proyecto",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{base_url}}/v1/usage?from=2026-06-01&to=2026-06-30",
              "host": ["{{base_url}}"],
              "path": ["v1", "usage"],
              "query": [
                { "key": "from", "value": "2026-06-01" },
                { "key": "to", "value": "2026-06-30" }
              ]
            },
            "description": "Scope: `usage:read`. Tokens, costo estimado y volumen OCR por proyecto. `from`/`to` opcionales (por defecto el mes en curso)."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Auth tests",
      "item": [
        {
          "name": "Sin API Key (401)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/documents",
              "host": ["{{base_url}}"],
              "path": ["v1", "documents"]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('401 invalid_api_key', () => pm.response.to.have.status(401));",
                  "pm.test('error code', () => pm.expect(pm.response.json().error.code).to.eql('invalid_api_key'));"
                ]
              }
            }
          ]
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "base_url",
      "value": "https://TU-APP.up.railway.app"
    },
    {
      "key": "api_key",
      "value": ""
    },
    {
      "key": "profile",
      "value": "cfdi_invoice"
    },
    {
      "key": "document_id",
      "value": ""
    },
    {
      "key": "result_format",
      "value": "markdown"
    },
    {
      "key": "extraction_id",
      "value": ""
    }
  ]
}
