{
  "info": {
    "name": "Factumel API v1 — ejemplos seguros",
    "description": "Referencia para integradores. Lecturas y operaciones separadas. Los POST fiscales están bloqueados sin API key TEST; emisión y envío son acciones manuales, nunca se ejecutan automáticamente por la colección. No incluye secretos.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "01 · Consultas (lectura)",
      "item": [
        {
          "name": "Empresas",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/companies?limit=50",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "companies"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "50"
                }
              ]
            },
            "description": "OpenAPI: GET /api/v1/companies\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Numeración CAE",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/companies/{{COMPANY_ID}}/cae?documentType=111&limit=50",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "companies",
                "{{COMPANY_ID}}",
                "cae"
              ],
              "query": [
                {
                  "key": "documentType",
                  "value": "111"
                },
                {
                  "key": "limit",
                  "value": "50"
                }
              ]
            },
            "description": "OpenAPI: GET /api/v1/companies/{id}/cae\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Preparación fiscal",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/companies/{{COMPANY_ID}}/issuance-readiness?documentType=111",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "companies",
                "{{COMPANY_ID}}",
                "issuance-readiness"
              ],
              "query": [
                {
                  "key": "documentType",
                  "value": "111"
                }
              ]
            },
            "description": "OpenAPI: GET /api/v1/companies/{id}/issuance-readiness\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Comprobantes",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents?companyId={{COMPANY_ID}}&limit=50",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents"
              ],
              "query": [
                {
                  "key": "companyId",
                  "value": "{{COMPANY_ID}}"
                },
                {
                  "key": "limit",
                  "value": "50"
                }
              ]
            },
            "description": "OpenAPI: GET /api/v1/documents\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Recuperación por externalId",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents/lookup?companyId={{COMPANY_ID}}&externalId={{EXTERNAL_ID}}",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents",
                "lookup"
              ],
              "query": [
                {
                  "key": "companyId",
                  "value": "{{COMPANY_ID}}"
                },
                {
                  "key": "externalId",
                  "value": "{{EXTERNAL_ID}}"
                }
              ]
            },
            "description": "OpenAPI: GET /api/v1/documents/lookup\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Detalle comprobante",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents/{{DOCUMENT_ID}}",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents",
                "{{DOCUMENT_ID}}"
              ]
            },
            "description": "OpenAPI: GET /api/v1/documents/{id}\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "XML firmado",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents/{{DOCUMENT_ID}}/xml",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents",
                "{{DOCUMENT_ID}}",
                "xml"
              ]
            },
            "description": "OpenAPI: GET /api/v1/documents/{id}/xml\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "PDF firmado",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents/{{DOCUMENT_ID}}/pdf",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents",
                "{{DOCUMENT_ID}}",
                "pdf"
              ]
            },
            "description": "OpenAPI: GET /api/v1/documents/{id}/pdf\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Padrón de emisores",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/uy/electronic-issuers?companyId={{COMPANY_ID}}&rut={{RUT_RECEPTOR}}",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "uy",
                "electronic-issuers"
              ],
              "query": [
                {
                  "key": "companyId",
                  "value": "{{COMPANY_ID}}"
                },
                {
                  "key": "rut",
                  "value": "{{RUT_RECEPTOR}}"
                }
              ]
            },
            "description": "OpenAPI: GET /api/v1/uy/electronic-issuers\nScope: documents:read. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "CFE recibidos — listado",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/received-documents?companyId={{COMPANY_ID}}&limit=50",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "received-documents"
              ],
              "query": [
                {
                  "key": "companyId",
                  "value": "{{COMPANY_ID}}"
                },
                {
                  "key": "limit",
                  "value": "50"
                }
              ]
            },
            "description": "OpenAPI: GET /api/v1/received-documents\nScope: received:read"
          }
        },
        {
          "name": "CFE recibido — detalle",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/received-documents/{{RECEIVED_DOCUMENT_ID}}",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "received-documents",
                "{{RECEIVED_DOCUMENT_ID}}"
              ]
            },
            "description": "OpenAPI: GET /api/v1/received-documents/{id}\nScope: received:read"
          }
        },
        {
          "name": "CFE recibido — XML original",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/received-documents/{{RECEIVED_DOCUMENT_ID}}/xml",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "received-documents",
                "{{RECEIVED_DOCUMENT_ID}}",
                "xml"
              ]
            },
            "description": "OpenAPI: GET /api/v1/received-documents/{id}/xml\nScope: received:read"
          }
        }
      ]
    },
    {
      "name": "02 · Operaciones fiscales — SOLO TEST, ejecución manual",
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "// Para evitar un CFE real desde una colección de ejemplos, bloqueamos todo POST salvo TEST.",
              "const key = pm.variables.replaceIn('{{FACTUMEL_API_KEY}}');",
              "if (!/^fmk_test_[A-Za-z0-9_-]+$/.test(key)) {",
              "  throw new Error('Operaciones fiscales deshabilitadas: configurar una API key fmk_test_ de TEST.');",
              "}",
              "const origin = pm.variables.replaceIn('{{BASE_URL}}');",
              "if (!/^https:\\/\\//.test(origin)) throw new Error('La API requiere HTTPS.');"
            ]
          }
        }
      ],
      "item": [
        {
          "name": "Crear borrador",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents"
              ]
            },
            "description": "OpenAPI: POST /api/v1/documents\nScope: documents:write. Los filtros/ambiente los determina la API key.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"companyId\": \"{{COMPANY_ID}}\",\n  \"externalId\": \"{{EXTERNAL_ID}}\",\n  \"documentType\": \"111\",\n  \"currencyCode\": \"UYU\",\n  \"items\": [\n    {\n      \"description\": \"Servicio en ambiente TEST\",\n      \"quantity\": 1,\n      \"unitPrice\": 1000,\n      \"taxRate\": 22\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 201 || pm.response.code === 200) {",
                  "  const body = pm.response.json();",
                  "  if (body.data?.id) pm.collectionVariables.set('DOCUMENT_ID', body.data.id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Firmar (reserva CAE)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents/{{DOCUMENT_ID}}/issue",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents",
                "{{DOCUMENT_ID}}",
                "issue"
              ]
            },
            "description": "OpenAPI: POST /api/v1/documents/{id}/issue\nScope: documents:issue. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Enviar a DGI (sólo TEST)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents/{{DOCUMENT_ID}}/submit",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents",
                "{{DOCUMENT_ID}}",
                "submit"
              ]
            },
            "description": "OpenAPI: POST /api/v1/documents/{id}/submit\nScope: documents:submit. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Consultar estado DGI",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents/{{DOCUMENT_ID}}/status",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents",
                "{{DOCUMENT_ID}}",
                "status"
              ]
            },
            "description": "OpenAPI: POST /api/v1/documents/{id}/status\nScope: documents:status. Los filtros/ambiente los determina la API key."
          }
        },
        {
          "name": "Crear, firmar y enviar en una llamada — SOLO TEST",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/documents/issue-and-submit",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "documents",
                "issue-and-submit"
              ]
            },
            "description": "OpenAPI: POST /api/v1/documents/issue-and-submit\nScope: documents:write + documents:submit",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"companyId\": \"{{COMPANY_ID}}\",\n  \"externalId\": \"{{EXTERNAL_ID}}\",\n  \"documentType\": \"111\",\n  \"currencyCode\": \"UYU\",\n  \"items\": [\n    {\n      \"description\": \"Servicio test\",\n      \"quantity\": 1,\n      \"unitPrice\": 1000,\n      \"taxRate\": 22\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200 || pm.response.code === 202) {",
                  "  const data = pm.response.json();",
                  "  if (data.documentId) pm.collectionVariables.set('DOCUMENT_ID', data.documentId);",
                  "}"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "03 · Administración de webhooks (sólo TEST en ejemplos)",
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "// Protección extra sólo para esta colección de ejemplos: no administrar webhooks reales accidentalmente.",
              "const key = pm.variables.replaceIn('{{FACTUMEL_API_KEY}}');",
              "if (!/^fmk_test_[A-Za-z0-9_-]+$/.test(key)) {",
              "  throw new Error('Usar exclusivamente API keys TEST para ejemplos de administración de webhooks.');",
              "}"
            ]
          }
        }
      ],
      "item": [
        {
          "name": "Listar destinos",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/webhooks",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks"
              ]
            },
            "description": "OpenAPI: GET /api/v1/webhooks\nScope: webhooks:manage. Sólo clave organizacional."
          }
        },
        {
          "name": "Crear destino seguro",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/webhooks",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks"
              ]
            },
            "description": "OpenAPI: POST /api/v1/webhooks\nScope: webhooks:manage. Sólo clave organizacional.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"url\": \"{{WEBHOOK_URL}}\",\n  \"events\": [\n    \"document.accepted\",\n    \"document.rejected\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 201) {",
                  "  const response = pm.response.json();",
                  "  if (response.data?.id) pm.collectionVariables.set('WEBHOOK_ID', response.data.id);",
                  "  // El secreto generado debe guardarse en el servidor receptor y nunca registrarse aquí.",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Obtener destino",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/webhooks/{{WEBHOOK_ID}}",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                "{{WEBHOOK_ID}}"
              ]
            },
            "description": "OpenAPI: GET /api/v1/webhooks/{id}\nScope: webhooks:manage. Sólo clave organizacional."
          }
        },
        {
          "name": "Actualizar destino",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/webhooks/{{WEBHOOK_ID}}",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                "{{WEBHOOK_ID}}"
              ]
            },
            "description": "OpenAPI: PATCH /api/v1/webhooks/{id}\nScope: webhooks:manage. Sólo clave organizacional.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"active\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Archivar destino",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/webhooks/{{WEBHOOK_ID}}",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                "{{WEBHOOK_ID}}"
              ]
            },
            "description": "OpenAPI: DELETE /api/v1/webhooks/{id}\nScope: webhooks:manage. Sólo clave organizacional."
          }
        },
        {
          "name": "Rotar secreto HMAC",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{FACTUMEL_API_KEY}}",
                "type": "text"
              },
              {
                "key": "Accept",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "{{BASE_URL}}/api/v1/webhooks/{{WEBHOOK_ID}}/rotate-secret",
              "host": [
                "{{BASE_URL}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                "{{WEBHOOK_ID}}",
                "rotate-secret"
              ]
            },
            "description": "OpenAPI: POST /api/v1/webhooks/{id}/rotate-secret\nScope: webhooks:manage. Sólo clave organizacional."
          }
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "BASE_URL",
      "value": "https://factumel.com",
      "type": "string"
    },
    {
      "key": "FACTUMEL_API_KEY",
      "value": "fmk_test_CONFIGURAR_CLAVE_REAL",
      "type": "string"
    },
    {
      "key": "COMPANY_ID",
      "value": "REEMPLAZAR_COMPANY_ID",
      "type": "string"
    },
    {
      "key": "DOCUMENT_ID",
      "value": "REEMPLAZAR_DOCUMENT_ID",
      "type": "string"
    },
    {
      "key": "EXTERNAL_ID",
      "value": "pedido-test-001",
      "type": "string"
    },
    {
      "key": "RUT_RECEPTOR",
      "value": "RUT_REAL_DE_PRUEBA",
      "type": "string"
    },
    {
      "key": "WEBHOOK_URL",
      "value": "https://example.com/factumel-webhook",
      "type": "string"
    },
    {
      "key": "WEBHOOK_ID",
      "value": "REEMPLAZAR_WEBHOOK_ID",
      "type": "string"
    },
    {
      "key": "RECEIVED_DOCUMENT_ID",
      "value": "REEMPLAZAR_ID_CFE_RECIBIDO",
      "type": "string"
    }
  ]
}
