{
  "info": {
    "name": "Identik API — v1 y v2 estable",
    "description": "Integración de documentos y plantillas en Firma Digital y Firma Electrónica.\n\n## Versiones y entornos\nLas primeras solicitudes conservan el flujo v1: crear JSON → PUT de PDF a uploadUrl → campos → enviar. La descarga v1 devuelve JSON con downloadUrl; descargá después esa URL. Las carpetas V2 usan multipart payload+file sin PUT y descargas PDF directas. El contrato v2 de documentos/plantillas es estable; confirmá el release y spec del ambiente antes de usar nuevas opciones. /api/v2-beta sigue disponible, sin retiro anunciado.\n\nConfigurá baseUrl/apiToken para v1 y v2BaseUrl/v2ApiToken para v2. Cada token pertenece a su plataforma/ambiente. V2 comienza en electronica-dev; también admite firma-dev y producción firma/electronica. No publiques tokens, signingUrls ni URLs prefirmadas. Los ejemplos de identidad deben reemplazarse o quitarse: Digital requiere CUIL real del SIGNER al enviar; Electrónica no usa CUIL. No se generan certificados ni se firman documentos automáticamente.\n\n## Ejecutar v2\n1. Elegí ambiente y token privado. Completá email, CUIL Digital y teléfono E.164, o eliminá phone si no lo usás.\n2. Ejecutá cada solicitud después de revisar el ambiente y los IDs. Las carpetas opcionales contienen operaciones independientes y eliminación; no ejecutarlas como un flujo automático.\n3. Elegí un PDF local en file; payload es JSON. Postman agrega el boundary: no escribas Content-Type manual en multipart.\n4. Seguí el flujo principal. Sus IDs se guardan en variables de colección; un Environment del mismo nombre los sobreescribe, evitá duplicarlos.\n5. Antes de archivar el PDF final, consultá status=COMPLETED. La constancia de DRAFT/PENDING responde 409 DOCUMENT_NOT_COMPLETE. COMPLETED o REJECTED permiten constancia; en REJECTED acredita el rechazo, no firmas completas.\n\n## Envíos y créditos\nTodos los ejemplos v2 usan distributionMethod=NONE, emailSettings completos en false y canales/biometría en false. No basta con omitir emailSettings: sus eventos tienen defaults habilitados. Distribuir consume crédito de documento según el plan, incluso sin notificaciones. Los borradores no lo consumen, pero crear requiere saldo/cupo disponible. Biometría y WhatsApp tienen saldos/reglas propios. La facturación y el cupo mensual dependen del plan.\n\n## Contrato y errores\nincludeSigningUrls se solicita dentro de payload en create, en query para GET y en JSON raíz para distribute. Omitido o false no agrega enlaces. Query acepta sólo true/false; JSON usa booleanos. Template/use lleva flags en override, no meta: false desactiva, omitido hereda. Identidad omitida/null hereda de la plantilla; recipient/update null borra y omitido conserva.\n\nAcciones: JSON message/code/data. Descargas: PDF en 200; error/code cuando fallan. 400 validación/cupo/saldo, 401 token o acceso, 403 permisos/origen, 404 no disponible, 409 estado, 429 límite. Cada versión admite 100 requests/minuto/IP en la aplicación: X-RateLimit-Limit/Remaining/Reset (Unix segundos); en 429 respetá Retry-After. La capa de acceso puede responder antes sin esos headers. No reintentes mutaciones a ciegas después de un timeout: no se promete una clave de idempotencia.\n\n## Referencia\n/api/docs (guía), /api/docs/openapi-v2.json (contrato seleccionado), /api/v2/openapi.json (spec completo), /api/v1/openapi.json (v1), /api/docs/postman.json (esta colección).",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://electronica.identik.me",
      "description": "https://firma.identik.me (digital) o https://electronica.identik.me (electrónica)"
    },
    {
      "key": "apiToken",
      "value": "api_XXXXXXXXXXXX",
      "description": "Tu token (te lo entrega Identik). Va como Authorization: Bearer."
    },
    {
      "key": "documentId",
      "value": "",
      "description": "Se completa solo al correr el paso 1."
    },
    {
      "key": "uploadUrl",
      "value": "",
      "description": "Se completa solo al correr el paso 1."
    },
    {
      "key": "recipientId1",
      "value": "",
      "description": "recipientId del firmante 1 (lo setea el paso 1)."
    },
    {
      "key": "recipientId2",
      "value": "",
      "description": "recipientId del firmante 2 (lo setea el paso 1)."
    },
    {
      "key": "envelopeId",
      "value": "",
      "type": "string"
    },
    {
      "key": "v2BaseUrl",
      "value": "https://electronica-dev.identik.me",
      "type": "string",
      "description": "Elegí https://firma.identik.me o https://electronica.identik.me, o sus hosts firma-dev/electronica-dev para pruebas. Sin slash final. El token debe pertenecer a ese ambiente."
    },
    {
      "key": "v2ApiToken",
      "value": "",
      "type": "string",
      "description": "Token API del ambiente seleccionado. Usá un Environment privado o Vault; no exportes el secreto."
    },
    {
      "key": "v2DocumentId",
      "value": "",
      "type": "string",
      "description": "ID numérico guardado por el create v2."
    },
    {
      "key": "v2EnvelopeId",
      "value": "",
      "type": "string",
      "description": "ID envelope_ guardado por el create v2."
    },
    {
      "key": "v2RecipientId",
      "value": "",
      "type": "string",
      "description": "ID numérico guardado por el create v2."
    },
    {
      "key": "v2SignerEmail",
      "value": "signer@example.invalid",
      "type": "string",
      "description": "Reemplazá por una cuenta de prueba controlada si vas a firmar."
    },
    {
      "key": "v2SignerCuil",
      "value": "",
      "type": "string",
      "description": "Digital: CUIL real del firmante. En dev podés usar el CUIL demo del proveedor; nunca usar identidad ficticia en producción. Electrónica: eliminá la propiedad cuil o dejala vacía."
    },
    {
      "key": "v2TemplateId",
      "value": "",
      "type": "string",
      "description": "ID numérico de una plantilla propia del ambiente seleccionado; se guarda al crear la plantilla."
    },
    {
      "key": "v2TemplateRecipientId",
      "value": "",
      "type": "string",
      "description": "ID del destinatario dentro de la plantilla; se guarda al consultar la plantilla."
    },
    {
      "key": "v2ExtraRecipientId",
      "value": "",
      "type": "string",
      "description": "ID de destinatario opcional para ejemplos agregar/eliminar."
    },
    {
      "key": "v2FieldId",
      "value": "",
      "type": "string",
      "description": "ID de campo opcional para ejemplos editar/eliminar."
    }
  ],
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiToken}}",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "name": "1 · Crear documento",
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "const j = pm.response.json();",
              "pm.test('201/200 y documentId presente', () => pm.expect(j.documentId).to.be.a('number'));",
              "pm.collectionVariables.set('documentId', j.documentId);",
              "pm.collectionVariables.set('uploadUrl', j.uploadUrl);",
              "if (j.recipients?.[0]) pm.collectionVariables.set('recipientId1', j.recipients[0].recipientId);",
              "if (j.recipients?.[1]) pm.collectionVariables.set('recipientId2', j.recipients[1].recipientId);",
              "console.log('signingUrls:', (j.recipients||[]).map(r => r.signingUrl));"
            ]
          }
        }
      ],
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/api/v1/documents",
        "description": "Crea el documento y declara los firmantes.\n\n- `title`: nombre del documento (aparece en emails y en la constancia).\n- `recipients[]`: `name`, `email` y — SOLO en la plataforma digital — `cuil` (11 dígitos; se aceptan guiones/espacios).\n\nRespuesta: `documentId`, `uploadUrl` (subí el PDF ahí en el paso 2) y `recipients[]` con `recipientId`, `token` y `signingUrl` de cada firmante.\n\n⚠️ Si tu plan mensual está completo, acá recibís 400 con el mensaje de cupo.",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"title\": \"Contrato de servicios\",\n  \"recipients\": [\n    { \"name\": \"Juan Pérez\", \"email\": \"juan@cliente.com.ar\" },\n    { \"name\": \"María Gómez\", \"email\": \"maria@cliente.com.ar\" }\n  ]\n}\n\n// Plataforma DIGITAL (firma.identik.me): agregá el CUIL a cada firmante:\n// { \"name\": \"Juan Pérez\", \"email\": \"juan@...\", \"cuil\": \"20-33111349-3\" }\n\n// Plataforma ELECTRÓNICA (electronica.identik.me): para exigir verificación\n// biométrica (DNI + prueba de vida) antes de firmar, agregá:\n//   \"meta\": { \"requireBiometricId\": true }\n// y fijá la identidad esperada en cada firmante (recomendado — la verificación\n// se valida CONTRA estos datos; nombre y apellido van POR SEPARADO):\n//   { \"name\": \"...\", \"email\": \"...\", \"idDocumentNumber\": \"33111349\",\n//     \"firstName\": \"Juan\", \"lastName\": \"Pérez\" }\n// Consume 1 crédito prepago por verificación; sin créditos, se firma normalmente."
        }
      }
    },
    {
      "name": "2 · Subir el PDF (PUT a uploadUrl)",
      "request": {
        "method": "PUT",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/pdf"
          }
        ],
        "url": "{{uploadUrl}}",
        "description": "Subí el PDF con un PUT **binario** a la URL prefirmada del paso 1 (Body → binary → seleccioná el archivo).\n\n- La URL ya está autenticada: NO agregues el header Authorization (Postman lo hereda de la colección — desactivalo en Auth → No Auth para este request).\n- Respuesta esperada: 200 sin cuerpo.",
        "auth": {
          "type": "noauth"
        },
        "body": {
          "mode": "file",
          "file": {}
        }
      }
    },
    {
      "name": "3a · Campo de firma — firmante 1",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/api/v1/documents/{{documentId}}/fields",
        "description": "Coloca el campo de firma del firmante 1 en la página.\n\nCoordenadas en **porcentaje de la página** (origen arriba-izquierda):\n- `pageNumber`: 1-based.\n- `pageX`/`pageY`: esquina superior izquierda del campo (%).\n- `pageWidth`/`pageHeight`: tamaño del campo (%).\n\nEl dibujo de la firma queda EXACTAMENTE en esas coordenadas en el PDF final.",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"recipientId\": {{recipientId1}},\n  \"type\": \"SIGNATURE\",\n  \"pageNumber\": 1,\n  \"pageX\": 18,\n  \"pageY\": 55,\n  \"pageWidth\": 24,\n  \"pageHeight\": 6\n}"
        }
      }
    },
    {
      "name": "3b · Campo de firma — firmante 2",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/api/v1/documents/{{documentId}}/fields",
        "description": "Igual que 3a, para el segundo firmante (otra posición para que no se pisen).",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"recipientId\": {{recipientId2}},\n  \"type\": \"SIGNATURE\",\n  \"pageNumber\": 1,\n  \"pageX\": 18,\n  \"pageY\": 72,\n  \"pageWidth\": 24,\n  \"pageHeight\": 6\n}"
        }
      }
    },
    {
      "name": "4 · Enviar a firmar",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{baseUrl}}/api/v1/documents/{{documentId}}/send",
        "description": "Dispara el envío.\n\n- `sendEmail: true` → Identik le manda a cada firmante el email con su enlace único.\n- `sendEmail: false` → no se manda nada: distribuís vos los `signingUrl` del paso 1 (por tu propio canal).\n\nEn la plataforma ELECTRÓNICA el firmante abre el enlace, revisa y confirma (menos de 2 minutos). En la DIGITAL, además autoriza con su CUIL + PIN + OTP ante el certificador.",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"sendEmail\": true\n}"
        }
      }
    },
    {
      "name": "5 · Consultar estado",
      "request": {
        "method": "GET",
        "url": "{{baseUrl}}/api/v1/documents/{{documentId}}",
        "description": "Estado del documento: `PENDING` (esperando firmas) → `COMPLETED` (todos firmaron y el PDF quedó sellado).\n\nMejor que polling: configurá un **webhook** `DOCUMENT_COMPLETED` (Configuración del equipo → Webhooks) y recibís el aviso con el documento apenas se completa."
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "const j = pm.response.json();",
              "pm.test('200 y status presente', () => pm.expect(j.status).to.be.a('string'));",
              "// El envelopeId solo aparece anidado en fields[]: es lo que piden los endpoints v2.",
              "const envelopeId = j.fields?.[0]?.envelopeId;",
              "if (envelopeId) { pm.collectionVariables.set('envelopeId', envelopeId); }",
              "else { console.warn('Sin campos todavia: el envelopeId no esta disponible (paso 8 va a fallar).'); }",
              "console.log('status:', j.status, '| firmantes:', (j.recipients||[]).map(r => r.email + ':' + r.signingStatus));"
            ]
          }
        }
      ]
    },
    {
      "name": "6 · Descargar el PDF firmado",
      "request": {
        "method": "GET",
        "url": "{{baseUrl}}/api/v1/documents/{{documentId}}/download",
        "description": "Devuelve la URL de descarga del PDF firmado y sellado.\n\nLa **Constancia de firma** (cada firmante, marcas temporales y hash SHA-256): en **electrónica** va integrada como última página del PDF; en **digital** NO va dentro del PDF (agregarle páginas invalidaría la firma cualificada) — llega como adjunto aparte (`Constancia de firma.pdf`) en el email de completado y se descarga por API con el **paso 9**. Cualquiera puede verificar el documento en `{{baseUrl}}/validar`."
      }
    },
    {
      "name": "7 · Descargar el PDF (bytes directos, v2)",
      "request": {
        "method": "GET",
        "url": "{{baseUrl}}/api/v2/document/{{documentId}}/download?version=signed",
        "description": "Alternativa al paso 6: devuelve directamente los **bytes del PDF** (`application/pdf`) en lugar de una URL de descarga. Suele ser mas comodo para guardar el archivo desde el backend sin un segundo salto.\n\n`version=signed` (por defecto) trae el documento firmado; `version=original`, el PDF tal como se subio.\n\nAcepta **tanto el `id` numerico** del documento (igual que v1) **como su `envelopeId`** (`envelope_...`) en el mismo lugar de la URL. Funciona con documentos creados por esta API.\n\nPasado el plazo de resguardo el archivo ya no existe y responde `410`."
      }
    },
    {
      "name": "8 · Traza de auditoria (v2)",
      "request": {
        "method": "GET",
        "url": "{{baseUrl}}/api/v2/envelope/{{envelopeId}}/audit-log?page=1&perPage=50",
        "description": "Devuelve la traza de auditoria en JSON: creacion, envio, apertura, firma de cada campo, rechazo y finalizacion, con fecha, IP y dispositivo. Sirve para archivar la evidencia de forma estructurada, ademas del PDF.\n\n⚠️ Identifica el documento con el **`envelopeId`** (`envelope_...`), NO con el `id` numerico: mandarle el numero devuelve `400 Invalid envelope ID`. El paso 5 lo captura automaticamente desde `fields[].envelopeId`."
      }
    },
    {
      "name": "9 · Descargar la constancia de firma (v2, PDF aparte)",
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test('200 y PDF', () => {",
              "  pm.response.to.have.status(200);",
              "  pm.expect(pm.response.headers.get('Content-Type')).to.include('application/pdf');",
              "});",
              "if (pm.response.code === 409) console.warn('El documento todavia no esta COMPLETED: la constancia se emite cuando firman todos.');"
            ]
          }
        }
      ],
      "request": {
        "method": "GET",
        "url": "{{baseUrl}}/api/v2/document/{{documentId}}/certificate",
        "description": "Devuelve constancia como PDF separado (application/pdf) con estado COMPLETED o REJECTED. En REJECTED acredita el rechazo, no firmas completas. DRAFT/PENDING responde 409 con code DOCUMENT_NOT_COMPLETE. En Digital archivala junto al PDF firmado; Electrónica también la incorpora al PDF completado. Acepta ID numérico o envelopeId y requiere el token API del ambiente."
      }
    },
    {
      "name": "V2 · Documentos — flujo principal",
      "description": "Flujo estable: crear PDF y firmante → editar → enviar sin avisos → consultar → descargar. Elegí ambiente explícitamente. Los ejemplos no firman automáticamente; distribuir sí aplica crédito. Esperá COMPLETED para el PDF final.",
      "auth": {
        "type": "bearer",
        "bearer": [
          {
            "key": "token",
            "value": "{{v2ApiToken}}",
            "type": "string"
          }
        ]
      },
      "item": [
        {
          "name": "V2 · 1 Crear con PDF (multipart)",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/create",
            "description": "Seleccioná un PDF de una página en file. payload es JSON de texto; no fijes Content-Type manualmente porque Postman agrega el boundary. includeSigningUrls va dentro de payload. Identidad/teléfono son opcionales. Biometría y avisos están desactivados para evitar contactar terceros. Digital necesita CUIL válido para crear y al enviar.",
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "payload",
                  "type": "text",
                  "value": "{\n  \"title\": \"Prueba API v2\",\n  \"includeSigningUrls\": true,\n  \"recipients\": [\n    {\n      \"name\": \"Persona de prueba\",\n      \"email\": \"{{v2SignerEmail}}\",\n      \"role\": \"SIGNER\",\n      \"cuil\": \"{{v2SignerCuil}}\",\n      \"phone\": null,\n      \"idDocumentCountry\": \"AR\",\n      \"idDocumentNumber\": \"00000001\",\n      \"idDocumentType\": \"DNI\",\n      \"firstName\": \"Persona\",\n      \"lastName\": \"Prueba\",\n      \"fields\": [\n        {\n          \"type\": \"SIGNATURE\",\n          \"pageNumber\": 1,\n          \"pageX\": 10,\n          \"pageY\": 60,\n          \"width\": 30,\n          \"height\": 10,\n          \"fieldMeta\": {\n            \"type\": \"signature\"\n          }\n        }\n      ]\n    }\n  ],\n  \"meta\": {\n    \"requireBiometricId\": false,\n    \"sendViaWhatsapp\": false,\n    \"sendViaSms\": false,\n    \"requireWhatsappOtp\": false,\n    \"emailSettings\": {\n      \"recipientSigningRequest\": false,\n      \"recipientRemoved\": false,\n      \"recipientSigned\": false,\n      \"documentPending\": false,\n      \"documentCompleted\": false,\n      \"documentDeleted\": false,\n      \"ownerDocumentCompleted\": false,\n      \"ownerRecipientExpired\": false,\n      \"ownerDocumentCreated\": false\n    },\n    \"distributionMethod\": \"NONE\"\n  }\n}"
                },
                {
                  "key": "file",
                  "type": "file",
                  "src": []
                }
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('200', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const j = pm.response.json();",
                  "  pm.collectionVariables.set('v2DocumentId', j.id);",
                  "  pm.collectionVariables.set('v2EnvelopeId', j.envelopeId);",
                  "  if (j.recipients?.[0]) pm.collectionVariables.set('v2RecipientId', j.recipients[0].id);",
                  "  pm.test('enlace optativo', () => pm.expect(j.recipients[0].signingUrl).to.be.a('string'));",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "V2 · 2 Actualizar configuración",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/update",
            "description": "data edita el documento; meta edita configuración. Flags omitidos conservan su valor; false desactiva. Mantener avisos desactivados durante la prueba. Las reglas de estado no cambian.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"documentId\": {{v2DocumentId}},\n  \"data\": {\n    \"title\": \"Prueba API v2 — revisada\"\n  },\n  \"meta\": {\n    \"distributionMethod\": \"NONE\",\n    \"requireBiometricId\": false,\n    \"sendViaWhatsapp\": false,\n    \"sendViaSms\": false,\n    \"requireWhatsappOtp\": false,\n    \"emailSettings\": {\n      \"recipientSigningRequest\": false,\n      \"recipientRemoved\": false,\n      \"recipientSigned\": false,\n      \"documentPending\": false,\n      \"documentCompleted\": false,\n      \"documentDeleted\": false,\n      \"ownerDocumentCompleted\": false,\n      \"ownerRecipientExpired\": false,\n      \"ownerDocumentCreated\": false\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "V2 · 3 Actualizar destinatario sin borrar identidad",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/recipient/update",
            "description": "Un update parcial omite CUIL, teléfono e identidad: conserva lo guardado. Para limpiar teléfono/identidad usar null explícito. No se permite cambiar a quien ya interactuó con el documento.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"documentId\": {{v2DocumentId}},\n  \"recipient\": {\n    \"id\": {{v2RecipientId}},\n    \"name\": \"Persona de prueba actualizada\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "V2 · 4 Consultar con enlaces",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/document/{{v2DocumentId}}?includeSigningUrls=true",
            "description": "includeSigningUrls es query parameter. Devuelve signingUrl por destinatario y documentMeta con requireBiometricId/sendViaWhatsapp/sendViaSms/requireWhatsappOtp. Sin el parámetro no se agregan URLs. No implica enviar avisos."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('200', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const j = pm.response.json();",
                  "  pm.test('enlace optativo', () => pm.expect(j.recipients[0].signingUrl).to.be.a('string'));",
                  "  ['requireBiometricId','sendViaWhatsapp','sendViaSms','requireWhatsappOtp'].forEach(k => pm.test(k, () => pm.expect(j.documentMeta[k]).to.be.a('boolean')));",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "V2 · 5 Enviar sin invitaciones (consume crédito)",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/distribute",
            "description": "Cambia DRAFT a PENDING y consume crédito de documento según el plan. includeSigningUrls va al nivel superior. recipientSigningRequest=false evita invitaciones; los canales y los demás emails están apagados. Para OTP en Electrónica, activarlo sólo con teléfonos y saldos según el plan controlados; todos los SIGNER deben tener E.164.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"documentId\": {{v2DocumentId}},\n  \"includeSigningUrls\": true,\n  \"meta\": {\n    \"distributionMethod\": \"NONE\",\n    \"requireBiometricId\": false,\n    \"sendViaWhatsapp\": false,\n    \"sendViaSms\": false,\n    \"requireWhatsappOtp\": false,\n    \"emailSettings\": {\n      \"recipientSigningRequest\": false,\n      \"recipientRemoved\": false,\n      \"recipientSigned\": false,\n      \"documentPending\": false,\n      \"documentCompleted\": false,\n      \"documentDeleted\": false,\n      \"ownerDocumentCompleted\": false,\n      \"ownerRecipientExpired\": false,\n      \"ownerDocumentCreated\": false\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "V2 · 6 Consultar sin expansión",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/document/{{v2DocumentId}}?includeSigningUrls=false",
            "description": "Consulta de compatibilidad: no se agregan signingUrl. Los flags de documento y la identidad guardada sí son legibles."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200) {",
                  "  const j = pm.response.json();",
                  "  pm.test('sin enlaces adicionales', () => j.recipients.forEach(r => pm.expect(r).not.to.have.property('signingUrl')));",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "V2 · Listar documentos",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/document?page=1&perPage=10",
            "description": "Respuesta paginada data. Filtros opcionales: status, templateId, source, folderId; orden por createdAt."
          }
        },
        {
          "name": "V2 · 7 Descargar original",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/document/{{v2EnvelopeId}}/download?version=original",
            "description": "Acepta ID numérico o envelope_. Respuesta binaria application/pdf. version=signed devuelve el archivo vigente: verificar status=COMPLETED antes de considerarlo final."
          }
        },
        {
          "name": "V2 · 8 Constancia (409 en DRAFT/PENDING)",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/document/{{v2DocumentId}}/certificate",
            "description": "200 application/pdf con COMPLETED o REJECTED. En REJECTED acredita el rechazo, no firmas completas. DRAFT/PENDING: 409 DOCUMENT_NOT_COMPLETE. Este ejemplo no firma documentos."
          }
        },
        {
          "name": "V2 · Descargar PDF vigente",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/document/{{v2DocumentId}}/download?version=signed",
            "description": "Bytes application/pdf, no downloadUrl. Verificá COMPLETED antes de tratarlo como final. signed devuelve el archivo vigente incluso antes de terminar."
          }
        },
        {
          "name": "V2 · Auditoría",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/envelope/{{v2EnvelopeId}}/audit-log?page=1&perPage=10",
            "description": "Requiere envelopeId textual, no el ID numérico. Datos de auditoría del documento autorizado; no registrarlos en logs públicos."
          }
        }
      ]
    },
    {
      "name": "V2 · Plantillas — flujo principal",
      "description": "Crear con PDF, consultar IDs, actualizar y usar sin distribución. Elegí un PDF y reemplazá identidad de ejemplo.",
      "auth": {
        "type": "bearer",
        "bearer": [
          {
            "key": "token",
            "value": "{{v2ApiToken}}",
            "type": "string"
          }
        ]
      },
      "item": [
        {
          "name": "Crear plantilla con PDF",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/template/create",
            "description": "Multipart payload+file. Seleccioná el PDF; devuelve id y envelopeId sin uploadUrl. Meta contiene flags y emailSettings.",
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "payload",
                  "type": "text",
                  "value": "{\n  \"title\": \"Plantilla de integración\",\n  \"recipients\": [\n    {\n      \"name\": \"Persona de prueba\",\n      \"email\": \"{{v2SignerEmail}}\",\n      \"role\": \"SIGNER\",\n      \"cuil\": \"{{v2SignerCuil}}\",\n      \"phone\": null,\n      \"idDocumentCountry\": \"AR\",\n      \"idDocumentNumber\": \"00000001\",\n      \"idDocumentType\": \"DNI\",\n      \"firstName\": \"Persona\",\n      \"lastName\": \"Prueba\",\n      \"fields\": [\n        {\n          \"type\": \"SIGNATURE\",\n          \"pageNumber\": 1,\n          \"pageX\": 10,\n          \"pageY\": 60,\n          \"width\": 30,\n          \"height\": 10,\n          \"fieldMeta\": {\n            \"type\": \"signature\"\n          }\n        }\n      ]\n    }\n  ],\n  \"meta\": {\n    \"requireBiometricId\": false,\n    \"sendViaWhatsapp\": false,\n    \"sendViaSms\": false,\n    \"requireWhatsappOtp\": false,\n    \"emailSettings\": {\n      \"recipientSigningRequest\": false,\n      \"recipientRemoved\": false,\n      \"recipientSigned\": false,\n      \"documentPending\": false,\n      \"documentCompleted\": false,\n      \"documentDeleted\": false,\n      \"ownerDocumentCompleted\": false,\n      \"ownerRecipientExpired\": false,\n      \"ownerDocumentCreated\": false\n    },\n    \"distributionMethod\": \"NONE\"\n  }\n}"
                },
                {
                  "key": "file",
                  "type": "file",
                  "src": []
                }
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('200', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) pm.collectionVariables.set('v2TemplateId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Listar plantillas",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/template?page=1&perPage=10",
            "description": "Lista paginada data; plantillas autorizadas."
          }
        },
        {
          "name": "Consultar plantilla y guardar destinatario",
          "request": {
            "method": "GET",
            "url": "{{v2BaseUrl}}/api/v2/template/{{v2TemplateId}}",
            "description": "templateMeta contiene configuración; recipients contiene IDs para template/use."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200) { const j=pm.response.json(); if (j.recipients?.length) pm.collectionVariables.set('v2TemplateRecipientId', j.recipients[0].id); }"
                ]
              }
            }
          ]
        },
        {
          "name": "Actualizar plantilla",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/template/update",
            "description": "data actualiza título, meta actualiza configuración; omitir flags conserva su valor. En template/use se usa override.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"templateId\": {{v2TemplateId}}, \"data\": { \"title\": \"Plantilla revisada\" }, \"meta\": { \"distributionMethod\": \"NONE\", \"sendViaWhatsapp\": false, \"sendViaSms\": false, \"requireBiometricId\": false, \"requireWhatsappOtp\": false } }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Crear borrador desde plantilla",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/template/use",
            "description": "Usa el id del destinatario en la plantilla. Identidad omitida/null hereda; flags en override, false desactiva. distributeDocument es booleano false. El nuevo documento queda DRAFT y no se envían avisos.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"templateId\": {{v2TemplateId}},\n  \"recipients\": [\n    {\n      \"id\": {{v2TemplateRecipientId}},\n      \"name\": \"Persona de prueba\",\n      \"email\": \"{{v2SignerEmail}}\",\n      \"cuil\": \"{{v2SignerCuil}}\",\n      \"phone\": null,\n      \"idDocumentCountry\": \"AR\",\n      \"idDocumentNumber\": \"00000001\",\n      \"idDocumentType\": \"DNI\",\n      \"firstName\": \"Persona\",\n      \"lastName\": \"Prueba\"\n    }\n  ],\n  \"distributeDocument\": false,\n  \"override\": {\n    \"distributionMethod\": \"NONE\",\n    \"title\": \"Prueba desde plantilla\",\n    \"requireBiometricId\": false,\n    \"sendViaWhatsapp\": false,\n    \"sendViaSms\": false,\n    \"requireWhatsappOtp\": false,\n    \"emailSettings\": {\n      \"recipientSigningRequest\": false,\n      \"recipientRemoved\": false,\n      \"recipientSigned\": false,\n      \"documentPending\": false,\n      \"documentCompleted\": false,\n      \"documentDeleted\": false,\n      \"ownerDocumentCompleted\": false,\n      \"ownerRecipientExpired\": false,\n      \"ownerDocumentCreated\": false\n    }\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('200', () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) { const j = pm.response.json(); pm.collectionVariables.set('v2DocumentId', j.id); pm.collectionVariables.set('v2EnvelopeId', j.envelopeId); if (j.recipients?.length) pm.collectionVariables.set('v2RecipientId', j.recipients[0].id); }"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "V2 · Operaciones opcionales — revisar antes de ejecutar",
      "description": "Ejemplos independientes para borradores propios. Incluye eliminaciones. No ejecutar toda la carpeta como flujo automático.",
      "auth": {
        "type": "bearer",
        "bearer": [
          {
            "key": "token",
            "value": "{{v2ApiToken}}",
            "type": "string"
          }
        ]
      },
      "item": [
        {
          "name": "Reenviar invitación (opcional)",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/redistribute",
            "description": "Usa IDs de destinatarios pendientes. El ejemplo creado por el flujo principal tiene recipientSigningRequest=false y no manda correo; con ese evento habilitado esta operación sí envía invitaciones. Revisá la configuración antes de usarla en otro documento. Puede renovar el vencimiento de los destinatarios.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"documentId\": {{v2DocumentId}}, \"recipients\": [{{v2RecipientId}}] }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Agregar destinatario",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/recipient/create",
            "description": "Sólo sobre borrador propio. Agrega un segundo SIGNER; colocá su campo antes del envío. Identidad y CUIL deben corresponder a la persona.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"documentId\": {{v2DocumentId}}, \"recipient\": { \"name\": \"Segundo firmante\", \"email\": \"second@example.invalid\", \"role\": \"SIGNER\", \"cuil\": \"{{v2SignerCuil}}\" } }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200) pm.collectionVariables.set('v2ExtraRecipientId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Limpiar teléfono e identidad",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/recipient/update",
            "description": "Ejemplo de null explícito; no usar si necesitás OTP/biometría antes de volver a completar datos.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"documentId\": {{v2DocumentId}}, \"recipient\": { \"id\": {{v2RecipientId}}, \"phone\": null, \"idDocumentNumber\": null } }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Quitar destinatario opcional",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/recipient/delete",
            "description": "Elimina el destinatario v2ExtraRecipientId. Ejecutá en un borrador propio; no cambia el firmante principal.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"recipientId\": {{v2ExtraRecipientId}} }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Agregar campo de firma opcional",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/field/create",
            "description": "Coordenadas y dimensiones en % de página: width/height, no pageWidth/pageHeight de v1. El flujo principal ya trae un campo: este ejemplo agrega otro.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"documentId\": {{v2DocumentId}}, \"field\": { \"recipientId\": {{v2RecipientId}}, \"type\": \"SIGNATURE\", \"pageNumber\": 1, \"pageX\": 10, \"pageY\": 75, \"width\": 30, \"height\": 10, \"fieldMeta\": { \"type\": \"signature\" } } }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200) pm.collectionVariables.set('v2FieldId', pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "Agregar varios campos",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/field/create-many",
            "description": "Alternativa a create individual; no ejecutar ambos si no querés campos duplicados.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"documentId\": {{v2DocumentId}}, \"fields\": [{ \"recipientId\": {{v2RecipientId}}, \"type\": \"SIGNATURE\", \"pageNumber\": 1, \"pageX\": 10, \"pageY\": 75, \"width\": 30, \"height\": 10, \"fieldMeta\": { \"type\": \"signature\" } }] }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Actualizar campo opcional",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/field/update",
            "description": "Actualiza posición/dimensiones del campo guardado; conserva su tipo SIGNATURE.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"documentId\": {{v2DocumentId}}, \"field\": { \"id\": {{v2FieldId}}, \"type\": \"SIGNATURE\", \"pageX\": 15, \"width\": 25, \"fieldMeta\": { \"type\": \"signature\" } } }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Quitar campo opcional",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/field/delete",
            "description": "Elimina sólo el campo indicado.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"fieldId\": {{v2FieldId}} }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Eliminar documento propio",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/document/delete",
            "description": "Operación destructiva; revisá el ID. Usá un borrador creado para esta prueba, con todos los avisos apagados. No ejecutar sobre documentos reales por accidente.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"documentId\": {{v2DocumentId}} }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        },
        {
          "name": "Eliminar plantilla propia",
          "request": {
            "method": "POST",
            "url": "{{v2BaseUrl}}/api/v2/template/delete",
            "description": "Revisá templateId; elimina la plantilla indicada. Operación opcional y destructiva.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{ \"templateId\": {{v2TemplateId}} }",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          }
        }
      ]
    }
  ]
}