{"id":29106,"date":"2026-10-19T19:19:23","date_gmt":"2026-10-19T17:19:23","guid":{"rendered":"https:\/\/staging.e-signature.eu\/?page_id=29106"},"modified":"2026-10-21T22:25:28","modified_gmt":"2026-10-21T20:25:28","slug":"documentacion-de-la-api-v3","status":"publish","type":"page","link":"https:\/\/staging.e-signature.eu\/es\/api-firma-electronica\/documentacion-de-la-api-v3\/","title":{"rendered":"Documentaci\u00f3n de la API V3"},"content":{"rendered":"<style>\n.esig-api{--ink:#1f2937;--muted:#6b7280;--line:#e5e7eb;--soft:#f8fafc;--brand:#1d4ed8;--code:#0f172a;\n font-family:inherit;color:var(--ink);line-height:1.6;max-width:1100px;margin:0 auto;font-size:16px}\n.esig-api h2{font-size:1.6em;margin:2.2em 0 .6em;padding-top:.6em;border-top:1px solid var(--line)}\n.esig-api h3{font-size:1.2em;margin:1.8em 0 .5em}\n.esig-api h4{font-size:1em;margin:1.4em 0 .4em;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}\n.esig-api p,.esig-api li{max-width:820px}\n.esig-api code{font-family:SFMono-Regular,Consolas,Menlo,monospace;font-size:.88em;background:#eef2ff;color:#1e3a8a;padding:.1em .35em;border-radius:4px;word-break:break-word}\n.esig-api pre{background:var(--code);color:#e2e8f0;padding:16px 18px;border-radius:8px;overflow-x:auto;font-size:13.5px;line-height:1.5;margin:.8em 0 1.4em}\n.esig-api pre code{background:none;color:inherit;padding:0;font-size:inherit;word-break:normal}\n.esig-api table{border-collapse:collapse;width:100%;margin:.8em 0 1.4em;font-size:.94em;display:block;overflow-x:auto}\n.esig-api th,.esig-api td{border:1px solid var(--line);padding:8px 10px;text-align:left;vertical-align:top}\n.esig-api th{background:var(--soft);font-weight:600}\n.esig-api{display:grid;grid-template-columns:230px minmax(0,1fr);gap:40px;max-width:1240px}\n.esig-api-main{min-width:0}\n.esig-api-nav{position:relative}\n.esig-api-nav-in{position:sticky;top:var(--esig-top,110px);z-index:20}\n.esig-api-nav-in.is-fixed{position:fixed}\n.esig-api-toc{max-height:calc(100vh - var(--esig-top,110px) - 20px);overflow-y:auto;background:var(--soft);border:1px solid var(--line);border-radius:8px;padding:14px 16px;font-size:.92em}\n.esig-api-toc strong{display:block;margin-bottom:.4em}\n.esig-api-toc ol{margin:0;padding-left:1.3em}.esig-api-toc li{margin:.3em 0;max-width:none}\n.esig-api-main a{color:var(--brand)!important;text-decoration:underline!important;text-underline-offset:2px;text-decoration-thickness:1px}.esig-api-main a:hover{text-decoration-thickness:2px}\n.esig-api-details{border:1px solid var(--line);border-radius:8px;padding:10px 16px;margin:.8em 0 1.4em;background:var(--soft)}.esig-api-details summary{cursor:pointer;font-weight:600;color:var(--brand)}.esig-api-details[open] summary{margin-bottom:.6em}.esig-api-details h4{margin:1em 0 .3em;text-transform:none;letter-spacing:0;color:var(--ink)}.esig-api-details ul{margin:.2em 0 .6em}\n.esig-api-toc a{text-decoration:none;color:var(--ink)}.esig-api-toc a:hover{color:var(--brand);text-decoration:underline}\n.esig-api-toc a.is-active{color:var(--brand);font-weight:600;background:#e8efff;border-radius:4px;padding:1px 5px;margin-left:-5px}.esig-api-toc li.is-active::marker{color:var(--brand);font-weight:600}\n.esig-api-toggle{position:absolute;opacity:0;pointer-events:none}\n.esig-api-toc-btn{display:none}\n.esig-api h2{scroll-margin-top:calc(var(--esig-top,110px) + 10px)}\n@media (max-width:900px){\n .esig-api{display:block}\n .esig-api-nav{margin:0 0 1.2em}\n .esig-api-nav-in{top:var(--esig-top,0px)}\n .esig-api-toc-btn{display:flex;align-items:center;justify-content:space-between;background:var(--soft);border:1px solid var(--line);border-radius:8px;padding:10px 14px;font-weight:600;cursor:pointer}\n .esig-api-toc-btn::after{content:\"\u25be\";font-size:1.1em}\n .esig-api-toggle:checked + .esig-api-toc-btn::after{content:\"\u25b4\"}\n .esig-api-toc{display:none;position:static;max-height:60vh;margin-top:6px;box-shadow:0 6px 16px rgba(0,0,0,.08);background:#fff}\n .esig-api-toc strong{display:none}\n .esig-api-toggle:checked ~ .esig-api-toc{display:block}\n .esig-api h2{scroll-margin-top:calc(var(--esig-top,0px) + 60px)}\n}\n.esig-api .ep{display:flex;flex-wrap:wrap;align-items:center;gap:10px;background:var(--soft);border:1px solid var(--line);border-radius:8px;padding:10px 14px;margin:.6em 0 1em;font-family:SFMono-Regular,Consolas,Menlo,monospace;font-size:.95em}\n.esig-api .m{font-weight:700;color:#fff;border-radius:4px;padding:2px 8px;font-size:.85em}\n.esig-api .GET{background:#059669}.esig-api .POST{background:#1d4ed8}.esig-api .PATCH{background:#d97706}.esig-api .DELETE{background:#dc2626}\n.esig-api .note{border-left:4px solid var(--brand);background:#eff6ff;padding:10px 14px;border-radius:0 6px 6px 0;margin:1em 0}\n.esig-api .warn{border-left:4px solid #d97706;background:#fffbeb;padding:10px 14px;border-radius:0 6px 6px 0;margin:1em 0}\n.esig-api .badge{display:inline-block;font-size:.75em;font-weight:700;background:#dbeafe;color:#1e40af;border-radius:999px;padding:1px 8px;margin-left:4px;vertical-align:middle}\n.esig-api .req{color:#dc2626;font-weight:700}\n<\/style>\n<div class=\"esig-api\">\n<nav class=\"esig-api-nav\" aria-label=\"\u00cdndice\">\n<div class=\"esig-api-nav-in\"><input type=\"checkbox\" id=\"esig-api-toc\" class=\"esig-api-toggle\"><label for=\"esig-api-toc\" class=\"esig-api-toc-btn\">\u00cdndice<\/label><\/p>\n<div class=\"esig-api-toc\"><strong>\u00cdndice<\/strong><\/p>\n<ol>\n<li><a href=\"#overview\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Presentaci\u00f3n<\/a><\/li>\n<li><a href=\"#auth\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Autenticaci\u00f3n<\/a><\/li>\n<li><a href=\"#conventions\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Convenciones<\/a><\/li>\n<li><a href=\"#credits\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Cr\u00e9ditos<\/a><\/li>\n<li><a href=\"#flow\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">C\u00f3mo funciona una solicitud de firma<\/a><\/li>\n<li><a href=\"#request\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Crear una solicitud de firma<\/a><\/li>\n<li><a href=\"#placement\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Colocaci\u00f3n de las firmas<\/a><\/li>\n<li><a href=\"#object\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">El objeto solicitud de firma<\/a><\/li>\n<li><a href=\"#endpoints\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Otros endpoints<\/a><\/li>\n<li><a href=\"#callbacks\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Callbacks (webhooks)<\/a><\/li>\n<li><a href=\"#errors\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Errores<\/a><\/li>\n<li><a href=\"#retention\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Conservaci\u00f3n<\/a><\/li>\n<li><a href=\"#changelog\" onclick=\"var t=document.getElementById('esig-api-toc');if(t)t.checked=false;\">Changelog<\/a><\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/nav>\n<div class=\"esig-api-main\">\n<p style=\"color:#6b7280;margin-top:0\">API REST de e-Signature.eu \u2014 firmas electr\u00f3nicas (SES, AES, QES)<\/p>\n<h2 id=\"overview\">1. Presentaci\u00f3n<\/h2>\n<p>La API REST de e-Signature.eu permite a su aplicaci\u00f3n enviar documentos para firma electr\u00f3nica (simple SES, avanzada AES o cualificada QES seg\u00fan eIDAS) sin pasar por nuestra web. Usted env\u00eda el PDF y los firmantes; nosotros gestionamos la verificaci\u00f3n de identidad, la firma y el seguimiento; usted recibe el documento firmado mediante la API o un callback.<\/p>\n<table style=\"display:table;width:100%\">\n<tbody>\n<tr>\n<td style=\"width:180px;min-width:140px;white-space:nowrap\">URL base<\/td>\n<td><code>https:\/\/api.e-signature.eu\/v3\/signature\/<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Esta documentaci\u00f3n describe la API <span class=\"badge\">v3<\/span>. \u00bfYa usa la API <span class=\"badge\">v2<\/span> (<code>https:\/\/api.e-signature.eu\/v2\/signature\/<\/code>)? Consulte el <a href=\"#changelog\">Changelog<\/a>.<\/p>\n<h2 id=\"auth\">2. Autenticaci\u00f3n<\/h2>\n<p>Sus credenciales est\u00e1n en <strong>Mi cuenta &gt; Firmas API<\/strong> una vez conectado en e-signature.eu:<\/p>\n<ul>\n<li><strong>User ID<\/strong>: en la URL, como par\u00e1metro <code>userid<\/code> de cada llamada;<\/li>\n<li><strong>API token<\/strong>: en la cabecera HTTP <code>x-api-key<\/code> de cada llamada.<\/li>\n<\/ul>\n<pre><code>curl -X GET \"https:\/\/api.e-signature.eu\/v3\/signature\/requestBalance?userid=123\" \\\n  -H \"x-api-key: YOUR_API_TOKEN\"<\/code><\/pre>\n<p>Mantenga su token en secreto: da acceso completo a su cuenta mediante la API. Las llamadas deben hacerse desde su servidor, nunca desde un navegador o una app m\u00f3vil.<\/p>\n<h2 id=\"conventions\">3. Convenciones<\/h2>\n<h3>Peticiones y respuestas<\/h3>\n<ul>\n<li>Solo HTTPS. Los cuerpos de las peticiones son JSON (<code>Content-Type: application\/json<\/code>).<\/li>\n<li>Cada respuesta es JSON, en una de estas dos formas:<\/li>\n<\/ul>\n<pre><code>{ \"success\": true,  \"result\": { ... } }\n{ \"success\": false, \"error\": \"Readable error message\" }<\/code><\/pre>\n<h3>L\u00edmites<\/h3>\n<table>\n<thead>\n<tr>\n<th>L\u00edmite<\/th>\n<th>Valor<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Peticiones<\/td>\n<td>10 por minuto por cuenta y direcci\u00f3n IP (por encima, HTTP 403; reintente tras un minuto)<\/td>\n<\/tr>\n<tr>\n<td>Documento<\/td>\n<td>Un PDF por solicitud, 30 MB como m\u00e1ximo, sin cifrar \/ sin contrase\u00f1a<\/td>\n<\/tr>\n<tr>\n<td>Descarga de documentos firmados<\/td>\n<td>30 d\u00edas tras la finalizaci\u00f3n (ver <a href=\"#retention\">Conservaci\u00f3n<\/a>)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"credits\">4. Cr\u00e9ditos<\/h2>\n<p>Las solicitudes se pagan con sus cr\u00e9ditos prepago de e-signature.eu. El precio de un m\u00e9todo se obtiene con <a href=\"#getMethods\"><code>getMethods<\/code><\/a> (tiene en cuenta sus precios espec\u00edficos). Su saldo lo devuelven <a href=\"#requestBalance\"><code>requestBalance<\/code><\/a> y cada objeto solicitud (<code>credits_balance<\/code>).<\/p>\n<h3 id=\"auto-recharge\">Recarga autom\u00e1tica de cr\u00e9ditos<\/h3>\n<p>Para no quedarse nunca sin cr\u00e9ditos, su cuenta puede recargarse autom\u00e1ticamente. Se configura una vez en <strong>Mi cuenta &gt; Firmas API<\/strong>, no mediante la API:<\/p>\n<ol>\n<li>Elija un <strong>umbral<\/strong> (en cr\u00e9ditos) y el <strong>paquete de cr\u00e9ditos<\/strong> que se pedir\u00e1.<\/li>\n<li>Guarde un m\u00e9todo de pago con nuestro proveedor de pagos Mollie (tarjeta, o adeudo directo SEPA mediante Bancontact, iDEAL\u2026). Se solicita una sola vez un pago de verificaci\u00f3n de 0,01 \u20ac.<\/li>\n<li>Cada vez que se descuentan cr\u00e9ditos y su saldo baja del umbral, se crea un pedido del paquete elegido y se paga autom\u00e1ticamente con el m\u00e9todo de pago guardado. La factura se le env\u00eda por email.<\/li>\n<\/ol>\n<table>\n<thead>\n<tr>\n<th><\/th>\n<th>Recarga autom\u00e1tica<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Activaci\u00f3n<\/td>\n<td>Un cargo de cr\u00e9ditos (p. ej. una nueva solicitud) que hace bajar el saldo por debajo del umbral<\/td>\n<\/tr>\n<tr>\n<td>Abono de los cr\u00e9ditos<\/td>\n<td>En cuanto se confirma el pago: inmediatamente con tarjeta, tras unos d\u00edas h\u00e1biles con adeudo directo SEPA<\/td>\n<\/tr>\n<tr>\n<td>Recargas en curso<\/td>\n<td>Una a la vez<\/td>\n<\/tr>\n<tr>\n<td>L\u00edmite de seguridad<\/td>\n<td>Un n\u00famero m\u00e1ximo de recargas autom\u00e1ticas por 30 d\u00edas<\/td>\n<\/tr>\n<tr>\n<td>Pago fallido<\/td>\n<td>El pedido se marca como fallido, la recarga autom\u00e1tica se desactiva y se le informa por email<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"note\">La recarga se activa con un cargo. Una solicitud que cuesta m\u00e1s que su saldo actual se rechaza (HTTP 403, <code>You do not have enough credits<\/code>) y no activa ninguna recarga: elija un umbral superior al coste de sus solicitudes m\u00e1s grandes y mantenga un margen si paga con adeudo directo SEPA. Su saldo est\u00e1 disponible en todo momento con <a href=\"#requestBalance\"><code>requestBalance<\/code><\/a> y <code>credits_balance<\/code>.<\/div>\n<h2 id=\"flow\">5. C\u00f3mo funciona una solicitud de firma<\/h2>\n<ol>\n<li>Usted crea la solicitud con el PDF, los firmantes y los m\u00e9todos de firma aceptados. Se descuentan los cr\u00e9ditos.<\/li>\n<li>Cada firmante recibe un email con un enlace de firma personal (o usted env\u00eda el <code>signature_link<\/code> cuando <code>send_email<\/code> es <code>false<\/code>).<\/li>\n<li>El firmante verifica su identidad con uno de los m\u00e9todos aceptados (itsme\u00ae, Evrotrust, Veriff, OTP\u2026) y firma.<\/li>\n<li>Cuando todos han firmado, la solicitud pasa a <code>finished<\/code>: el PDF firmado (PAdES) est\u00e1 disponible con <code>getRequest<\/code> y se env\u00eda en el callback.<\/li>\n<\/ol>\n<h3>Orden de firma<\/h3>\n<p>Por defecto, todos los firmantes firman en paralelo. Para definir un orden, indique <code>sign_first: true<\/code> en los firmantes del <strong>primer grupo<\/strong>: se les invita de inmediato, varios en paralelo si es necesario. Los dem\u00e1s firmantes solo se invitan cuando todo el primer grupo ha firmado. Dos grupos como m\u00e1ximo.<\/p>\n<h3>Dos modos de integraci\u00f3n<\/h3>\n<table>\n<thead>\n<tr>\n<th>Modo<\/th>\n<th>Funcionamiento<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Modo email<\/strong> (<code>send_email: true<\/code>, por defecto)<\/td>\n<td>Enviamos en su nombre a los firmantes las invitaciones, los recordatorios y los emails de finalizaci\u00f3n.<\/td>\n<\/tr>\n<tr>\n<td><strong>Modo integrado<\/strong> (<code>send_email: false<\/code>)<\/td>\n<td>No se env\u00eda ning\u00fan email al crear la solicitud: el <code>signature_link<\/code> de cada firmante se devuelve en la respuesta y usted redirige a sus usuarios desde su propia interfaz.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"note\">Incluso con <code>send_email: false<\/code>, un recordatorio o una cancelaci\u00f3n lanzados desde el panel en l\u00ednea env\u00edan un email a los firmantes pendientes.<\/div>\n<h3>No consulte la API en bucle<\/h3>\n<p>No llame a <code>getRequest<\/code> repetidamente para seguir el estado de una solicitud: utilice los <a href=\"#callbacks\">callbacks<\/a>, enviados autom\u00e1ticamente en cada cambio. Las llamadas excesivas activan una limitaci\u00f3n autom\u00e1tica que suspende temporalmente el tratamiento de sus peticiones.<\/p>\n<h2 id=\"request\">6. Crear una solicitud de firma<\/h2>\n<div class=\"ep\"><span class=\"m POST\">POST<\/span><span>\/v3\/signature\/request?userid={userid}<\/span><\/div>\n<pre><code>{\n  \"title\": \"Sales agreement 2026-114\",\n  \"lang\": \"en\",\n  \"methods\": [\n    \"itsme-qes-signature\",\n    \"evrotrust-signature\"\n  ],\n  \"signature_place\": \"position_auto\",\n  \"reminder\": 3,\n  \"send_email\": true,\n  \"email_notification\": false,\n  \"note_html\": \"Please sign the agreement before Friday.\",\n  \"signature_redirect\": \"https:\/\/www.example.com\/thank-you\",\n  \"external_reference\": \"QUOTE-2026-114\",\n  \"metadata\": {\n    \"crm_deal_id\": 8812\n  },\n  \"callback_url\": \"https:\/\/erp.example.com\/hooks\/esignature\",\n  \"signers\": [\n    {\n      \"firstname\": \"Ann\",\n      \"lastname\": \"Peeters\",\n      \"email\": \"ann.peeters@example.com\",\n      \"phone\": \"+32475111222\",\n      \"sign_first\": true\n    },\n    {\n      \"firstname\": \"Marc\",\n      \"lastname\": \"Dubois\",\n      \"email\": \"marc.dubois@example.com\",\n      \"sign_first\": false\n    }\n  ],\n  \"pdf_file_base64\": \"JVBERi0xLjcKJeLjz9MK...\"\n}<\/code><\/pre>\n<h3 id=\"methods\">M\u00e9todos de firma<\/h3>\n<table>\n<thead>\n<tr>\n<th>M\u00e9todo<\/th>\n<th>Nivel<\/th>\n<th>Cobertura<\/th>\n<th>Precio<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>itsme-qes-signature<\/code> \u2014 itsme\u00ae<\/td>\n<td>QES (cualificada)<\/td>\n<td>32 pa\u00edses europeos<\/td>\n<td>1 cr\u00e9dito \/ firmante<\/td>\n<\/tr>\n<tr>\n<td><code>evrotrust-signature<\/code> \u2014 Evrotrust<\/td>\n<td>QES (cualificada)<\/td>\n<td>69 pa\u00edses<\/td>\n<td>1 cr\u00e9dito \/ firmante<\/td>\n<\/tr>\n<tr>\n<td><code>veriff-advanced-signature<\/code> \u2014 Veriff<\/td>\n<td>AES (avanzada)<\/td>\n<td>198 pa\u00edses<\/td>\n<td>0,7 cr\u00e9ditos \/ firmante<\/td>\n<\/tr>\n<tr>\n<td><code>otp-email-non-qualified<\/code> \u2014 OTP por email o SMS<\/td>\n<td>SES (simple)<\/td>\n<td>Todo el mundo<\/td>\n<td>0,4 cr\u00e9ditos \/ firmante<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Son los precios est\u00e1ndar: <a href=\"#getMethods\"><code>getMethods<\/code><\/a> devuelve los m\u00e9todos disponibles y los precios de su cuenta. Solo una firma electr\u00f3nica cualificada (QES) equivale legalmente a una firma manuscrita seg\u00fan el Reglamento eIDAS. <code>otp-email-non-qualified<\/code> cubre email y SMS: el c\u00f3digo se env\u00eda por SMS si el firmante tiene <code>phone<\/code>, si no por email, al mismo precio.<\/p>\n<h3>Campos del cuerpo de la petici\u00f3n<\/h3>\n<table>\n<thead>\n<tr>\n<th>Campo<\/th>\n<th>Obligatorio<\/th>\n<th>Tipo<\/th>\n<th>Descripci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>title<\/code><\/td>\n<td><span class=\"req\">s\u00ed<\/span><\/td>\n<td>string<\/td>\n<td>Nombre del documento. Se conservan letras, cifras y guiones; si el nombre ya existe en su cuenta, se a\u00f1ade un sufijo <code>-1<\/code>, <code>-2<\/code>\u2026<\/td>\n<\/tr>\n<tr>\n<td><code>lang<\/code><\/td>\n<td><span class=\"req\">s\u00ed<\/span><\/td>\n<td>string<\/td>\n<td>Idioma de los emails y de las p\u00e1ginas de firma: <code>fr<\/code>, <code>nl<\/code>, <code>en<\/code>, <code>de<\/code>, <code>es<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>methods<\/code><\/td>\n<td><span class=\"req\">s\u00ed<\/span><\/td>\n<td>array<\/td>\n<td>M\u00e9todos de firma aceptados, ver <a href=\"#methods\">M\u00e9todos de firma<\/a>. Si se aceptan varios, cada firmante elige.<\/td>\n<\/tr>\n<tr>\n<td><code>signers<\/code><\/td>\n<td><span class=\"req\">s\u00ed<\/span><\/td>\n<td>array<\/td>\n<td>Firmantes, ver m\u00e1s abajo.<\/td>\n<\/tr>\n<tr>\n<td><code>pdf_file_base64<\/code><\/td>\n<td><span class=\"req\">s\u00ed<\/span><\/td>\n<td>string<\/td>\n<td>El PDF, codificado en base64. Un solo archivo, 30 MB como m\u00e1ximo, sin cifrar.<\/td>\n<\/tr>\n<tr>\n<td><code>signature_place<\/code><\/td>\n<td>no<\/td>\n<td>string<\/td>\n<td><code>position_auto<\/code> (por defecto) o <code>position_manual<\/code>, ver <a href=\"#placement\">Colocaci\u00f3n de las firmas<\/a>.<\/td>\n<\/tr>\n<tr>\n<td><code>reminder<\/code><\/td>\n<td>no<\/td>\n<td>number<\/td>\n<td>Recordatorio autom\u00e1tico cada N d\u00edas, de 0 a 14. Por defecto 0 (sin recordatorio).<\/td>\n<\/tr>\n<tr>\n<td><code>send_email<\/code><\/td>\n<td>no<\/td>\n<td>boolean<\/td>\n<td>Por defecto <code>true<\/code> (modo email). Con <code>false<\/code> (modo integrado) no se env\u00eda ning\u00fan email de invitaci\u00f3n ni de finalizaci\u00f3n: env\u00ede usted el <code>signature_link<\/code>. No compatible con <code>sign_first: true<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>email_notification<\/code><\/td>\n<td>no<\/td>\n<td>boolean<\/td>\n<td>Por defecto <code>false<\/code>. Con <code>true<\/code>, recibe un email en cada firma.<\/td>\n<\/tr>\n<tr>\n<td><code>note_html<\/code><\/td>\n<td>no<\/td>\n<td>string<\/td>\n<td>Mensaje a\u00f1adido a los emails enviados a los firmantes (modo email). Se aceptan etiquetas HTML, p. ej. <code>Note with &lt;strong&gt;HTML&lt;\/strong&gt;<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>signature_redirect<\/code><\/td>\n<td>no<\/td>\n<td>string (URL)<\/td>\n<td>P\u00e1gina mostrada al firmante tras la firma. Debe ser una URL v\u00e1lida (no se aceptan cadenas vac\u00edas). Por defecto: p\u00e1gina de confirmaci\u00f3n en e-signature.eu.<\/td>\n<\/tr>\n<tr>\n<td><code>external_reference<\/code><\/td>\n<td>no<\/td>\n<td>string<\/td>\n<td>Su propio identificador (presupuesto, contrato\u2026), 255 caracteres como m\u00e1ximo. Se devuelve en cada respuesta y callback.<\/td>\n<\/tr>\n<tr>\n<td><code>metadata<\/code><\/td>\n<td>no<\/td>\n<td>object<\/td>\n<td>Objeto JSON libre, 4 KB como m\u00e1ximo, devuelto tal cual.<\/td>\n<\/tr>\n<tr>\n<td><code>callback_url<\/code><\/td>\n<td>no<\/td>\n<td>string (URL)<\/td>\n<td>URL de callback solo para esta solicitud (HTTPS p\u00fablico). Por defecto: la URL de su cuenta.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Campos de un firmante<\/h3>\n<table>\n<thead>\n<tr>\n<th>Campo<\/th>\n<th>Obligatorio<\/th>\n<th>Tipo<\/th>\n<th>Descripci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>lastname<\/code><\/td>\n<td><span class=\"req\">s\u00ed<\/span><\/td>\n<td>string<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>email<\/code><\/td>\n<td><span class=\"req\">s\u00ed<\/span><\/td>\n<td>string<\/td>\n<td>Direcci\u00f3n de email v\u00e1lida<\/td>\n<\/tr>\n<tr>\n<td><code>firstname<\/code><\/td>\n<td>no<\/td>\n<td>string<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><code>phone<\/code><\/td>\n<td>no<\/td>\n<td>string<\/td>\n<td>Formato internacional que empieza por <code>+<\/code> y el prefijo del pa\u00eds (<code>+32\u2026<\/code>); se eliminan los espacios. Un n\u00famero no v\u00e1lido se ignora. Con el m\u00e9todo OTP, el c\u00f3digo se env\u00eda por SMS si se indica un n\u00famero, si no por email.<\/td>\n<\/tr>\n<tr>\n<td><code>sign_first<\/code><\/td>\n<td>no<\/td>\n<td>boolean<\/td>\n<td>Por defecto <code>false<\/code>. Ver <a href=\"#flow\">Orden de firma<\/a>.<\/td>\n<\/tr>\n<tr>\n<td><code>sign_page<\/code>, <code>sign_left<\/code>, <code>sign_bottom<\/code><\/td>\n<td>con <code>position_manual<\/code><\/td>\n<td>number<\/td>\n<td>Ver <a href=\"#placement\">Colocaci\u00f3n de las firmas<\/a>.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Coste<\/h3>\n<p>Precio del m\u00e9todo m\u00e1s caro de <code>methods<\/code> \u00d7 n\u00famero de firmantes. Los cr\u00e9ditos se descuentan al crear la solicitud. Los de los firmantes que no hayan firmado se reembolsan si la solicitud se cancela o se detiene.<\/p>\n<h3>Respuesta <code>201 Created<\/code><\/h3>\n<pre><code>{\n  \"success\": true,\n  \"result\": {\n    \"id_sign\": 4521,\n    \"lang\": \"en\",\n    \"doc_name\": \"Sales-agreement-2026-114\",\n    \"send_email\": true,\n    \"from_api\": true,\n    \"signature_redirect\": \"https:\/\/www.example.com\/thank-you\",\n    \"status_id\": \"pending\",\n    \"date_status\": \"2026-10-20 10:15:02\",\n    \"last_reminder\": null,\n    \"timezone\": \"Europe\/Brussels\",\n    \"credits\": 2,\n    \"credits_balance\": 38.4,\n    \"signers\": {\n      \"1\": {\n        \"firstname\": \"Ann\",\n        \"lastname\": \"Peeters\",\n        \"email\": \"ann.peeters@example.com\",\n        \"phone\": \"+32475111222\",\n        \"sign_first\": true,\n        \"status\": \"pending\",\n        \"signature_link\": \"https:\/\/www.e-signature.eu\/en\/sign\/?key=\u2026\"\n      },\n      \"2\": {\n        \"firstname\": \"Marc\",\n        \"lastname\": \"Dubois\",\n        \"email\": \"marc.dubois@example.com\",\n        \"sign_first\": false,\n        \"status\": \"pending\",\n        \"signature_link\": \"https:\/\/www.e-signature.eu\/en\/sign\/?key=\u2026\"\n      }\n    },\n    \"external_reference\": \"QUOTE-2026-114\",\n    \"metadata\": {\n      \"crm_deal_id\": 8812\n    }\n  }\n}<\/code><\/pre>\n<h2 id=\"placement\">7. Colocaci\u00f3n de las firmas<\/h2>\n<h3><code>position_auto<\/code> (por defecto)<\/h3>\n<p>Coloque los marcadores <code>#SIG01<\/code>, <code>#SIG02<\/code>\u2026 (tambi\u00e9n se acepta <code>#SIG01#<\/code>) como texto en su documento, donde cada firmante debe firmar (<code>#SIG01<\/code> = primer firmante del array <code>signers<\/code>). La firma se coloca arriba a la izquierda del marcador. Si un mismo marcador aparece varias veces, se usa su primera aparici\u00f3n. Un marcador se omite si su zona de firma cubrir\u00eda una firma ya colocada (o una firma existente): el firmante toma entonces el siguiente marcador libre. Un marcador tan cerca del borde de la p\u00e1gina que la firma deba desplazarse solo se usa como \u00faltimo recurso.<\/p>\n<div class=\"note\">Consejo: escriba los marcadores en <strong>texto blanco<\/strong> (sobre fondo blanco) para que sean invisibles en el PDF firmado. Deben seguir siendo texto real, no una imagen, para ser detectados.<\/div>\n<h4>Documento a\u00fan no firmado<\/h4>\n<p>Si el documento no contiene ning\u00fan marcador, o falta el marcador de un firmante, se a\u00f1ade al final del documento una <strong>p\u00e1gina de firmas con los marcadores<\/strong> y todas las firmas se colocan en esa p\u00e1gina (6 firmantes en la primera p\u00e1gina a\u00f1adida, luego 10 por p\u00e1gina adicional).<\/p>\n<h4>Documento ya firmado<\/h4>\n<p>No se puede a\u00f1adir ninguna p\u00e1gina a un PDF ya firmado electr\u00f3nicamente: invalidar\u00eda las firmas existentes. Con <code>position_auto<\/code>, las firmas se colocan en los <strong>marcadores libres<\/strong>, es decir, los marcadores cuya zona de firma no cubre ninguna firma existente. Los marcadores libres se asignan a los firmantes por orden (<code>#SIG01<\/code>, <code>#SIG02<\/code>\u2026).<\/p>\n<div class=\"warn\">Si el documento firmado no contiene suficientes marcadores libres para todos los firmantes, la solicitud se rechaza (HTTP 400): use <code>position_manual<\/code>.<\/div>\n<h3><code>position_manual<\/code><\/h3>\n<p>Indique la posici\u00f3n de la firma, en cent\u00edmetros, para cada firmante:<\/p>\n<table>\n<thead>\n<tr>\n<th>Campo<\/th>\n<th>Valor<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>sign_page<\/code><\/td>\n<td>N\u00famero de p\u00e1gina, a partir de 1 (entero)<\/td>\n<\/tr>\n<tr>\n<td><code>sign_left<\/code><\/td>\n<td>Distancia del borde izquierdo de la p\u00e1gina a la izquierda de la firma, en cm (se admiten decimales)<\/td>\n<\/tr>\n<tr>\n<td><code>sign_bottom<\/code><\/td>\n<td>Distancia del borde inferior de la p\u00e1gina a la parte superior de la firma, en cm (se admiten decimales)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre><code>{ \"lastname\": \"Peeters\", \"email\": \"ann.peeters@example.com\", \"sign_page\": 3, \"sign_left\": 2.5, \"sign_bottom\": 6 }<\/code><\/pre>\n<p><code>sign_left<\/code> y <code>sign_bottom<\/code> indican la <strong>esquina superior izquierda<\/strong> de la firma. La firma se coloca debajo y a la derecha de este punto.<\/p>\n<p>Los l\u00edmites dependen del tama\u00f1o real de la p\u00e1gina y del tama\u00f1o del sello visual: toda la firma debe quedar al menos a 2 cm de cada borde de la p\u00e1gina. Si se aceptan varios m\u00e9todos de firma, se toma el sello m\u00e1s grande. Si un valor est\u00e1 fuera de los l\u00edmites, el mensaje de error indica el rango permitido para esa p\u00e1gina.<\/p>\n<p>Una firma no puede cubrir otra firma de la solicitud, ni una firma existente si el documento ya est\u00e1 firmado.<\/p>\n<h2 id=\"object\">8. El objeto solicitud de firma<\/h2>\n<p>Devuelto por <code>request<\/code>, <code>getRequest<\/code>, <code>cancel<\/code>, <code>skip<\/code>, <code>remind<\/code>, <code>delete<\/code> y enviado en los callbacks.<\/p>\n<table>\n<thead>\n<tr>\n<th>Campo<\/th>\n<th>Descripci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>id_sign<\/code><\/td>\n<td>Identificador de la solicitud<\/td>\n<\/tr>\n<tr>\n<td><code>doc_name<\/code><\/td>\n<td>Nombre del documento<\/td>\n<\/tr>\n<tr>\n<td><code>status_id<\/code><\/td>\n<td><code>pending<\/code> en curso \u00b7 <code>finished<\/code> firmado por todos \u00b7 <code>skipped<\/code> detenido, firmado parcialmente \u00b7 <code>cancelled<\/code> \u00b7 <code>deleted<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>signers<\/code><\/td>\n<td>Objeto de los firmantes, por clave (<code>\"1\"<\/code>, <code>\"2\"<\/code>\u2026) \u2014 ver m\u00e1s abajo<\/td>\n<\/tr>\n<tr>\n<td><code>lang<\/code>, <code>send_email<\/code>, <code>signature_redirect<\/code>, <code>timezone<\/code><\/td>\n<td>Tal como se definieron al crear<\/td>\n<\/tr>\n<tr>\n<td><code>from_api<\/code><\/td>\n<td><code>true<\/code> si la solicitud se cre\u00f3 mediante la API<\/td>\n<\/tr>\n<tr>\n<td><code>date_status<\/code><\/td>\n<td>Fecha del \u00faltimo cambio de estado (zona horaria de la solicitud)<\/td>\n<\/tr>\n<tr>\n<td><code>last_reminder<\/code><\/td>\n<td>Fecha del \u00faltimo recordatorio, o <code>null<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>credits<\/code><\/td>\n<td>Cr\u00e9ditos de la solicitud (reservados mientras est\u00e1 en curso, consumidos al finalizar)<\/td>\n<\/tr>\n<tr>\n<td><code>credits_balance<\/code><\/td>\n<td>Saldo actual de su cuenta<\/td>\n<\/tr>\n<tr>\n<td><code>pdf_file_base64<\/code><\/td>\n<td>PDF firmado, cuando la solicitud ya no est\u00e1 en curso<\/td>\n<\/tr>\n<tr>\n<td><code>external_reference<\/code>, <code>metadata<\/code><\/td>\n<td>Tal como se enviaron al crear<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Firmante<\/h3>\n<table>\n<thead>\n<tr>\n<th>Campo<\/th>\n<th>Descripci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>firstname<\/code>, <code>lastname<\/code>, <code>email<\/code>, <code>phone<\/code>, <code>sign_first<\/code><\/td>\n<td>Tal como se enviaron al crear<\/td>\n<\/tr>\n<tr>\n<td><code>status<\/code><\/td>\n<td><code>pending<\/code> \u00b7 <code>signed<\/code> \u00b7 <code>skipped<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>signature_link<\/code><\/td>\n<td>Enlace de firma personal, mientras el firmante no haya firmado<\/td>\n<\/tr>\n<tr>\n<td><code>signing_time<\/code>, <code>signing_method<\/code><\/td>\n<td>Tras la firma: fecha y m\u00e9todo utilizado<\/td>\n<\/tr>\n<tr>\n<td><code>verified_firstname<\/code>, <code>verified_lastname<\/code><\/td>\n<td>Tras la firma: identidad verificada por el m\u00e9todo de firma<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<pre><code>{\n  \"1\": {\n    \"firstname\": \"Ann\",\n    \"lastname\": \"Peeters\",\n    \"email\": \"ann.peeters@example.com\",\n    \"status\": \"signed\",\n    \"signing_time\": \"2026-10-20 11:02:47\",\n    \"signing_method\": \"itsme-qes-signature\",\n    \"verified_firstname\": \"Ann\",\n    \"verified_lastname\": \"Peeters\"\n  }\n}<\/code><\/pre>\n<h2 id=\"endpoints\">9. Otros endpoints<\/h2>\n<p>Todos los endpoints reciben <code>userid<\/code> en la URL y <code>x-api-key<\/code> en las cabeceras. <code>id_sign<\/code> se pasa en la URL.<\/p>\n<h3 id=\"list\">Listar las solicitudes<\/h3>\n<div class=\"ep\"><span class=\"m GET\">GET<\/span><span>\/v3\/signature\/list?userid={userid}&amp;status_id=pending<\/span><\/div>\n<p><code>status_id<\/code> (opcional): <code>pending<\/code>, <code>finished<\/code> o <code>skipped<\/code>. <code>external_reference<\/code> (opcional): solo las solicitudes con esta referencia.<\/p>\n<pre><code>{\n  \"success\": true,\n  \"result\": [\n    {\n      \"id_sign\": 4521,\n      \"status_id\": \"pending\",\n      \"external_reference\": \"QUOTE-2026-114\"\n    },\n    {\n      \"id_sign\": 4498,\n      \"status_id\": \"finished\"\n    }\n  ]\n}<\/code><\/pre>\n<h3 id=\"getRequest\">Obtener una solicitud<\/h3>\n<div class=\"ep\"><span class=\"m GET\">GET<\/span><span>\/v3\/signature\/getRequest?userid={userid}&amp;id_sign=4521<\/span><\/div>\n<p>Devuelve el <a href=\"#object\">objeto solicitud de firma<\/a>, con el PDF firmado una vez finalizada la solicitud. Para seguir el estado, use los <a href=\"#callbacks\">callbacks<\/a> en lugar de llamadas repetidas.<\/p>\n<h3 id=\"remind\">Enviar un recordatorio<\/h3>\n<div class=\"ep\"><span class=\"m PATCH\">PATCH<\/span><span>\/v3\/signature\/remind?userid={userid}&amp;id_sign=4521<\/span><\/div>\n<p>Env\u00eda un email de recordatorio a los firmantes con <code>status: pending<\/code> del grupo invitado actualmente (primero el grupo <code>sign_first<\/code>). Solo solicitudes <code>pending<\/code>. Funciona tambi\u00e9n con solicitudes creadas con <code>send_email: false<\/code>.<\/p>\n<h3 id=\"skip\">Detener una solicitud (conservando las firmas ya realizadas)<\/h3>\n<div class=\"ep\"><span class=\"m PATCH\">PATCH<\/span><span>\/v3\/signature\/skip?userid={userid}&amp;id_sign=4521<\/span><\/div>\n<p>Posible cuando al menos un firmante ha firmado y al menos otro no. La solicitud pasa a <code>skipped<\/code>, el PDF firmado parcialmente est\u00e1 disponible y se reembolsan los cr\u00e9ditos de los firmantes que no firmaron.<\/p>\n<h3 id=\"cancel\">Cancelar una solicitud<\/h3>\n<div class=\"ep\"><span class=\"m DELETE\">DELETE<\/span><span>\/v3\/signature\/cancel?userid={userid}&amp;id_sign=4521<\/span><\/div>\n<p>Posible mientras nadie haya firmado; para terminar una solicitud firmada parcialmente, use <a href=\"#skip\"><code>skip<\/code><\/a>. La respuesta contiene la solicitud con <code>status_id: cancelled<\/code>; despu\u00e9s, la solicitud y su documento se eliminan de su panel, los enlaces de firma dejan de funcionar y se reembolsan los cr\u00e9ditos.<\/p>\n<h3 id=\"delete\">Eliminar una solicitud<\/h3>\n<div class=\"ep\"><span class=\"m DELETE\">DELETE<\/span><span>\/v3\/signature\/delete?userid={userid}&amp;id_sign=4521<\/span><\/div>\n<p>Solo solicitudes <code>finished<\/code> o <code>skipped<\/code>. Elimina los documentos y la solicitud. La respuesta contiene la solicitud una \u00faltima vez, con <code>status_id: deleted<\/code>: descargue el PDF firmado antes de eliminar.<\/p>\n<h3 id=\"requestAuditTrail\">Descargar el audit trail<\/h3>\n<div class=\"ep\"><span class=\"m GET\">GET<\/span><span>\/v3\/signature\/requestAuditTrail?userid={userid}&amp;id_sign=4521<\/span><\/div>\n<p>No disponible mientras la solicitud est\u00e1 en curso (HTTP 412). Devuelve el objeto solicitud con <code>audit_trail_base64<\/code>: un PDF con el historial de la solicitud (fechas, m\u00e9todos, identidades verificadas).<\/p>\n<h3 id=\"requestBalance\">Obtener el saldo de cr\u00e9ditos<\/h3>\n<div class=\"ep\"><span class=\"m GET\">GET<\/span><span>\/v3\/signature\/requestBalance?userid={userid}<\/span><\/div>\n<pre><code>{ \"success\": true, \"result\": { \"credits_balance\": 38.4 } }<\/code><\/pre>\n<h3 id=\"getMethods\">Listar los m\u00e9todos de firma<\/h3>\n<div class=\"ep\"><span class=\"m GET\">GET<\/span><span>\/v3\/signature\/getMethods?userid={userid}&amp;lang=en<\/span><\/div>\n<p>M\u00e9todos aceptados en <code>methods<\/code>, con el precio en cr\u00e9ditos por firmante <strong>para su cuenta<\/strong>. <code>lang<\/code> (opcional) traduce las etiquetas.<\/p>\n<pre><code>{\n  \"success\": true,\n  \"result\": [\n    {\n      \"id\": \"itsme-qes-signature\",\n      \"label\": \"itsme\u00ae | QES\",\n      \"credits\": 1\n    },\n    {\n      \"id\": \"evrotrust-signature\",\n      \"label\": \"Evrotrust | QES\",\n      \"credits\": 1\n    },\n    {\n      \"id\": \"veriff-advanced-signature\",\n      \"label\": \"Veriff | AES\",\n      \"credits\": 0.7\n    },\n    {\n      \"id\": \"otp-email-non-qualified\",\n      \"label\": \"OTP by Email\/SMS | SES\",\n      \"credits\": 0.4\n    }\n  ]\n}<\/code><\/pre>\n<h2 id=\"callbacks\">10. Callbacks (webhooks)<\/h2>\n<p>Defina su URL de callback en <strong>Mi cuenta &gt; Firmas API<\/strong> (HTTPS, accesible p\u00fablicamente). Tambi\u00e9n puede indicar una <code>callback_url<\/code> por solicitud. El callback es un <code>POST<\/code> con un cuerpo JSON que contiene el estado completo actual de la solicitud (mismo formato que <code>getRequest<\/code>), enviado para las solicitudes creadas mediante la API.<\/p>\n<h3>Campos del evento<\/h3>\n<table>\n<thead>\n<tr>\n<th>Campo<\/th>\n<th>Descripci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>event<\/code><\/td>\n<td>Tipo de evento (ver m\u00e1s abajo)<\/td>\n<\/tr>\n<tr>\n<td><code>event_id<\/code><\/td>\n<td>Identificador \u00fanico del evento (<code>evt_\u2026<\/code>). <strong>Id\u00e9ntico en cada reintento<\/strong> del mismo evento: \u00faselo para ignorar duplicados.<\/td>\n<\/tr>\n<tr>\n<td><code>event_at<\/code><\/td>\n<td>Fecha del evento (UTC, ISO 8601)<\/td>\n<\/tr>\n<tr>\n<td><code>changes<\/code><\/td>\n<td>Cambios de estado de los firmantes, p. ej. <code>[{\"signer_key\": 1, \"from\": \"pending\", \"to\": \"signed\"}]<\/code> (solo si un firmante cambi\u00f3)<\/td>\n<\/tr>\n<tr>\n<td><code>external_reference<\/code>, <code>metadata<\/code><\/td>\n<td>Tal como se enviaron al crear la solicitud<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Tipos de eventos<\/h3>\n<table>\n<thead>\n<tr>\n<th>Evento<\/th>\n<th>Cu\u00e1ndo<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>signer.signed<\/code><\/td>\n<td>Un firmante ha firmado, la solicitud sigue en curso<\/td>\n<\/tr>\n<tr>\n<td><code>signer.declined<\/code>, <code>signer.skipped<\/code>, <code>signer.expired<\/code><\/td>\n<td>Un firmante rechaz\u00f3, fue omitido o expir\u00f3<\/td>\n<\/tr>\n<tr>\n<td><code>request.completed<\/code><\/td>\n<td>Todos los firmantes han firmado: el PDF firmado est\u00e1 incluido (<code>pdf_file_base64<\/code>)<\/td>\n<\/tr>\n<tr>\n<td><code>request.stopped<\/code><\/td>\n<td>La solicitud se detuvo: el PDF firmado parcialmente est\u00e1 incluido<\/td>\n<\/tr>\n<tr>\n<td><code>request.cancelled<\/code><\/td>\n<td>La solicitud fue cancelada<\/td>\n<\/tr>\n<tr>\n<td><code>request.deleted<\/code><\/td>\n<td>La solicitud fue eliminada<\/td>\n<\/tr>\n<tr>\n<td><code>request.expired<\/code><\/td>\n<td>La solicitud expir\u00f3<\/td>\n<\/tr>\n<tr>\n<td><code>request.declined<\/code><\/td>\n<td>Correo certificado rechazado por el destinatario<\/td>\n<\/tr>\n<tr>\n<td><code>request.updated<\/code><\/td>\n<td>Cualquier otro cambio: recordatorio enviado, firmante modificado, nuevos enlaces de firma\u2026<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>El cuerpo contiene siempre el estado completo actual: su integraci\u00f3n puede basarse en <code>status_id<\/code> y en el estado de cada firmante en lugar de solo en el tipo de evento.<\/p>\n<h3>Cabeceras<\/h3>\n<table>\n<thead>\n<tr>\n<th>Cabecera<\/th>\n<th>Ejemplo<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>X-Esig-Api-Version<\/code><\/td>\n<td><code>3<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>X-Esig-Event<\/code><\/td>\n<td><code>signer.signed<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>X-Esig-Event-Id<\/code><\/td>\n<td><code>evt_4f0c2b9e1d7a3c55e8b1a2f0<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>X-Esig-Delivery-Attempt<\/code><\/td>\n<td><code>1<\/code>, <code>2<\/code>, \u2026<\/td>\n<\/tr>\n<tr>\n<td><code>X-Esig-Signature<\/code><\/td>\n<td><code>t=1792407600,v1=5d41402abc4b2a76b9719d911017c592\u2026<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Verificar la firma<\/h3>\n<p>Su secreto de firma aparece en <strong>Mi cuenta &gt; Firmas API<\/strong>, donde tambi\u00e9n puede regenerarlo. <code>v1<\/code> es el HMAC-SHA256 de <code>\"&lt;t&gt;.&lt;raw request body&gt;\"<\/code> con su secreto, codificado en hexadecimal. Use el cuerpo <strong>bruto<\/strong>, antes de cualquier lectura JSON, y rechace los callbacks de m\u00e1s de 5 minutos.<\/p>\n<h4>PHP<\/h4>\n<pre><code>$body   = file_get_contents( 'php:\/\/input' );\n$header = $_SERVER['HTTP_X_ESIG_SIGNATURE'] ?? '';\npreg_match( '\/t=(\\d+),v1=([a-f0-9]{64})\/', $header, $m );\n$valid = $m\n    &amp;&amp; abs( time() - (int) $m[1] ) &lt;= 300\n    &amp;&amp; hash_equals( hash_hmac( 'sha256', $m[1] . '.' . $body, $secret ), $m[2] );<\/code><\/pre>\n<h4>Node.js<\/h4>\n<pre><code>const crypto = require('crypto');\nfunction verify(rawBody, header, secret) {\n  const m = \/t=(\\d+),v1=([a-f0-9]{64})\/.exec(header || '');\n  if (!m || Math.abs(Date.now() \/ 1000 - Number(m[1])) &gt; 300) return false;\n  const expected = crypto.createHmac('sha256', secret).update(`${m[1]}.${rawBody}`).digest('hex');\n  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(m[2]));\n}<\/code><\/pre>\n<h4>C# (.NET)<\/h4>\n<pre><code>using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions;\nstatic bool Verify(string rawBody, string header, string secret) {\n    var m = Regex.Match(header ?? \"\", @\"t=(\\d+),v1=([a-f0-9]{64})\");\n    if (!m.Success || Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - long.Parse(m.Groups[1].Value)) &gt; 300) return false;\n    using var h = new HMACSHA256(Encoding.UTF8.GetBytes(secret));\n    var expected = Convert.ToHexString(h.ComputeHash(Encoding.UTF8.GetBytes(m.Groups[1].Value + \".\" + rawBody))).ToLowerInvariant();\n    return CryptographicOperations.FixedTimeEquals(Encoding.ASCII.GetBytes(expected), Encoding.ASCII.GetBytes(m.Groups[2].Value));\n}<\/code><\/pre>\n<h3>Respuestas y reintentos<\/h3>\n<ul>\n<li>Responda <strong>HTTP 2xx<\/strong> en cuanto reciba el callback y tr\u00e1telo de forma as\u00edncrona si es necesario.<\/li>\n<li>En caso de error de red, tiempo agotado (30 s), HTTP 429 o 5xx, el callback se reenv\u00eda cada hora con el mismo <code>event_id<\/code>, hasta 24 intentos. Las dem\u00e1s respuestas 4xx se consideran definitivas. Si la solicitud vuelve a cambiar antes de una entrega correcta, el siguiente callback lleva un nuevo evento y el estado completo actual. El estado actual sigue disponible en todo momento con <code>getRequest<\/code>.<\/li>\n<li>Se siguen las redirecciones (se mantiene el m\u00e9todo <code>POST<\/code>). No se pueden usar <code>localhost<\/code> ni direcciones privadas.<\/li>\n<\/ul>\n<h2 id=\"errors\">11. Errores<\/h2>\n<p>Los errores se devuelven con <code>\"success\": false<\/code> y un mensaje <code>error<\/code> legible. Base su l\u00f3gica en el c\u00f3digo HTTP: los mensajes pueden mejorar con el tiempo.<\/p>\n<table>\n<thead>\n<tr>\n<th>C\u00f3digo HTTP<\/th>\n<th>Significado<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>200 \/ 201<\/td>\n<td>OK \/ solicitud creada<\/td>\n<\/tr>\n<tr>\n<td>400<\/td>\n<td>Campo ausente o no v\u00e1lido (el mensaje indica el campo)<\/td>\n<\/tr>\n<tr>\n<td>400<\/td>\n<td><code>id_sign<\/code> ausente, o filtro <code>status_id<\/code> no v\u00e1lido<\/td>\n<\/tr>\n<tr>\n<td>401<\/td>\n<td><code>userid<\/code> o <code>x-api-key<\/code> no v\u00e1lidos<\/td>\n<\/tr>\n<tr>\n<td>403<\/td>\n<td>Cr\u00e9ditos insuficientes, o l\u00edmite de peticiones alcanzado (10 por minuto)<\/td>\n<\/tr>\n<tr>\n<td>404<\/td>\n<td><code>id_sign<\/code> desconocido para esta cuenta<\/td>\n<\/tr>\n<tr>\n<td>412<\/td>\n<td>Acci\u00f3n no posible en el estado actual (p. ej. cancelar tras una firma, eliminar una solicitud en curso)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"errors-by-endpoint\">Errores por endpoint<\/h3>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>C\u00f3digo HTTP<\/th>\n<th>Mensaje<\/th>\n<th>Causa<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Todos los endpoints<\/td>\n<td>401<\/td>\n<td><code>Please provide a valid x-api-key in headers &amp; userid in url parameters.<\/code><\/td>\n<td><code>userid<\/code> o <code>x-api-key<\/code> no v\u00e1lidos<\/td>\n<\/tr>\n<tr>\n<td>Todos los endpoints<\/td>\n<td>403<\/td>\n<td><code>Rate limit exceeded: 10 requests per minute is allowed. Please try again after a minute.<\/code><\/td>\n<td>M\u00e1s de 10 peticiones por minuto<\/td>\n<\/tr>\n<tr>\n<td><code>request<\/code><\/td>\n<td>400<\/td>\n<td>Ver <a href=\"#validation\">Mensajes de validaci\u00f3n<\/a><\/td>\n<td>Campo, PDF o posici\u00f3n ausente o no v\u00e1lido<\/td>\n<\/tr>\n<tr>\n<td><code>request<\/code><\/td>\n<td>403<\/td>\n<td><code>You do not have enough credits<\/code><\/td>\n<td>Saldo inferior al coste de la solicitud<\/td>\n<\/tr>\n<tr>\n<td><code>list<\/code><\/td>\n<td>400<\/td>\n<td><code>Incorrect value for status_id.<\/code><\/td>\n<td>Filtro <code>status_id<\/code> desconocido<\/td>\n<\/tr>\n<tr>\n<td><code>getRequest<\/code>, <code>remind<\/code>, <code>skip<\/code>, <code>cancel<\/code>, <code>delete<\/code>, <code>requestAuditTrail<\/code><\/td>\n<td>400<\/td>\n<td><code>please provide id_sign parameter.<\/code><\/td>\n<td><code>id_sign<\/code> ausente<\/td>\n<\/tr>\n<tr>\n<td><code>getRequest<\/code>, <code>remind<\/code>, <code>skip<\/code>, <code>cancel<\/code>, <code>delete<\/code>, <code>requestAuditTrail<\/code><\/td>\n<td>404<\/td>\n<td><code>invalid id_sign value.<\/code><\/td>\n<td><code>id_sign<\/code> desconocido para esta cuenta<\/td>\n<\/tr>\n<tr>\n<td><code>remind<\/code><\/td>\n<td>412<\/td>\n<td><code>request can not be remind to user(s): wrong status<\/code><\/td>\n<td>La solicitud no est\u00e1 en curso<\/td>\n<\/tr>\n<tr>\n<td><code>skip<\/code><\/td>\n<td>412<\/td>\n<td><code>request can not be skipped: wrong status<\/code><\/td>\n<td>Nadie ha firmado todav\u00eda, todos han firmado, o la solicitud ya no est\u00e1 en curso<\/td>\n<\/tr>\n<tr>\n<td><code>cancel<\/code><\/td>\n<td>412<\/td>\n<td><code>request can not be cancelled: someone already signed the PDF<\/code><\/td>\n<td>Al menos un firmante ha firmado<\/td>\n<\/tr>\n<tr>\n<td><code>delete<\/code><\/td>\n<td>412<\/td>\n<td><code>request can not be deleted: wrong status_id<\/code><\/td>\n<td>La solicitud sigue en curso<\/td>\n<\/tr>\n<tr>\n<td><code>requestAuditTrail<\/code><\/td>\n<td>412<\/td>\n<td><code>Can not download Audit Trail while the signature request is pending<\/code><\/td>\n<td>La solicitud sigue en curso<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3 id=\"validation\">Mensajes de validaci\u00f3n al crear (<code>request<\/code>, HTTP 400)<\/h3>\n<p>El mensaje indica el campo o el problema; <code>\u2026<\/code> representa un valor de su petici\u00f3n. Base su c\u00f3digo en el c\u00f3digo HTTP y muestre el mensaje para ayudar a corregir la petici\u00f3n.<\/p>\n<details class=\"esig-api-details\">\n<summary>Mostrar todos los mensajes de validaci\u00f3n<\/summary>\n<h4>Cuerpo de la petici\u00f3n<\/h4>\n<ul>\n<li><code>Request body can not be empty<\/code><\/li>\n<\/ul>\n<h4><code>title<\/code>, <code>lang<\/code><\/h4>\n<ul>\n<li><code>Field 'title' must be of type string and can not be empty<\/code><\/li>\n<li><code>Field 'lang' is an invalid language code<\/code><\/li>\n<\/ul>\n<h4><code>signers<\/code><\/h4>\n<ul>\n<li><code>field 'signers' is omitted or is empty<\/code><\/li>\n<li><code>Firstname, Lastname &amp; email address must be of type string and can not be empty<\/code><\/li>\n<li><code>\u2026 is not an email address<\/code><\/li>\n<li><code>field 'sign_first' is not a boolean value<\/code><\/li>\n<li><code>field 'sign_first' can not be 'true' when field 'send_email' is 'false'<\/code><\/li>\n<\/ul>\n<h4><code>methods<\/code><\/h4>\n<ul>\n<li><code>You must set at least one signing method<\/code><\/li>\n<li><code>\u2026 is not a valid method<\/code><\/li>\n<\/ul>\n<h4>Opciones<\/h4>\n<ul>\n<li><code>Field 'reminder' should be of type numeric between 0 &amp; 14 (days)<\/code><\/li>\n<li><code>Field 'send_email' should be of type boolean<\/code><\/li>\n<li><code>Field 'email_notification' should be of type boolean<\/code><\/li>\n<li><code>Field 'note_html' should be of type string<\/code><\/li>\n<li><code>Field 'signature_redirect' is not a valid url<\/code><\/li>\n<\/ul>\n<h4><code>external_reference<\/code>, <code>metadata<\/code>, <code>callback_url<\/code><\/h4>\n<ul>\n<li><code>Field 'external_reference' must be a string<\/code><\/li>\n<li><code>Field 'external_reference' can not exceed 255 characters<\/code><\/li>\n<li><code>Field 'metadata' must be a JSON object<\/code><\/li>\n<li><code>Field 'metadata' can not exceed 4096 bytes<\/code><\/li>\n<li><code>Field 'callback_url' must be a publicly reachable HTTPS URL<\/code><\/li>\n<\/ul>\n<h4>PDF<\/h4>\n<ul>\n<li><code>Field 'pdf_file_base64' should be of type string and not empty<\/code><\/li>\n<li><code>Field 'pdf_file_base64' doesn't contains a base64 encoded string<\/code><\/li>\n<li><code>Field 'pdf_file_base64' doesn't contains a base64 encoded PDF file<\/code><\/li>\n<li><code>Your file is too big &gt; 30 MB<\/code><\/li>\n<li><code>Couldn't load your PDF document<\/code><\/li>\n<li><code>PDF file is encrypted and password protected. Please unprotected your PDF file.<\/code><\/li>\n<li><code>Couldn't get pages from PDF document<\/code><\/li>\n<\/ul>\n<h4>Colocaci\u00f3n de las firmas<\/h4>\n<ul>\n<li><code>field 'signature_place' is incorrect<\/code><\/li>\n<li><code>field 'sign_page' is empty or is not an integer<\/code><\/li>\n<li><code>field 'sign_left' is empty or is not a number (cm)<\/code><\/li>\n<li><code>field 'sign_bottom' is empty or is not a number (cm)<\/code><\/li>\n<li><code>Field 'sign_left' for signer \u2026 must be between \u2026 and \u2026 cm (page \u2026 is \u2026 x \u2026 cm, signature \u2026 x \u2026 cm, margin \u2026 cm)<\/code><\/li>\n<li><code>Field 'sign_bottom' for signer \u2026 must be between \u2026 and \u2026 cm (\u2026)<\/code><\/li>\n<li><code>Field 'sign_page' for signer \u2026 is too big: the document has \u2026 page(s)<\/code><\/li>\n<li><code>Page \u2026 is too small for the signature of \u2026 (\u2026)<\/code><\/li>\n<li><code>The signature of \u2026 on page \u2026 overlaps an existing signature of the document (\u2026)<\/code><\/li>\n<li><code>The signatures of \u2026 and \u2026 overlap on page \u2026 (\u2026)<\/code><\/li>\n<li><code>The existing signatures of the document could not be read: the position of the signature of \u2026 can not be checked<\/code><\/li>\n<\/ul>\n<h4>Documento ya firmado (<code>position_auto<\/code>)<\/h4>\n<ul>\n<li><code>Your PDF file is already signed: pages can not be added without invalidating the existing signatures. It contains \u2026 free marker(s) for \u2026 signer(s): place the signatures manually (signature_place: position_manual).<\/code><\/li>\n<li><code>Your PDF file is already signed: pages can not be added without invalidating the existing signatures. The free markers could not be determined: place the signatures manually (signature_place: position_manual).<\/code><\/li>\n<\/ul>\n<h4>Procesamiento<\/h4>\n<ul>\n<li><code>Couldn't extract markers from PDF document: \u2026<\/code><\/li>\n<li><code>Unknown error: Request could not be saved into the Database<\/code><\/li>\n<li>Mensaje de error devuelto por el proveedor de firma (eID Easy)<\/li>\n<\/ul>\n<\/details>\n<h2 id=\"retention\">12. Conservaci\u00f3n<\/h2>\n<p>Los documentos firmados pueden descargarse durante <strong>30 d\u00edas<\/strong> tras la finalizaci\u00f3n, con <code>getRequest<\/code> o el callback <code>request.completed<\/code>. El audit trail se conserva durante el periodo definido en nuestro <a href=\"https:\/\/www.e-signature.eu\/en\/dpa\/\">DPA<\/a>. Archive el documento firmado y el audit trail por su parte en un plazo de 30 d\u00edas.<\/p>\n<h2 id=\"changelog\">13. Changelog<\/h2>\n<h3>API <span class=\"badge\">v3<\/span> \u2014 diferencias con la API <span class=\"badge\">v2<\/span><\/h3>\n<p>La API <span class=\"badge\">v2<\/span> (<code>https:\/\/api.e-signature.eu\/v2\/signature\/<\/code>) sigue disponible y sin cambios. Los endpoints, par\u00e1metros y la autenticaci\u00f3n son id\u00e9nticos en ambas versiones: para pasar a la API <span class=\"badge\">v3<\/span>, sustituya la URL base por <code>https:\/\/api.e-signature.eu\/v3\/signature\/<\/code>. Puede migrar endpoint por endpoint.<\/p>\n<p class=\"note\">Las URL anteriores (<code>https:\/\/www.e-signature.eu\/wp-json\/signature\/<\/code> para la API <span class=\"badge\">v2<\/span> y <code>https:\/\/www.e-signature.eu\/wp-json\/esig\/v3\/signature\/<\/code> para la API <span class=\"badge\">v3<\/span>) siguen siendo v\u00e1lidas. Recomendamos utilizar las URL de <code>api.e-signature.eu<\/code>.<\/p>\n<table>\n<thead>\n<tr>\n<th>Tema<\/th>\n<th>API <span class=\"badge\">v2<\/span><\/th>\n<th>API <span class=\"badge\">v3<\/span><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>URL base<\/td>\n<td><code>\/v2\/signature\/<\/code><\/td>\n<td><code>\/v3\/signature\/<\/code><\/td>\n<\/tr>\n<tr>\n<td>Sus propias referencias<\/td>\n<td>\u2014<\/td>\n<td>Nuevos campos <code>external_reference<\/code> y <code>metadata<\/code>, devueltos en cada respuesta y callback; filtro <code>list<\/code> por <code>external_reference<\/code><\/td>\n<\/tr>\n<tr>\n<td>URL de callback<\/td>\n<td>Una URL por cuenta<\/td>\n<td>Tambi\u00e9n por solicitud (<code>callback_url<\/code>)<\/td>\n<\/tr>\n<tr>\n<td>Contenido del callback<\/td>\n<td>Estado completo de la solicitud<\/td>\n<td>Estado completo de la solicitud + <code>event<\/code>, <code>event_id<\/code>, <code>event_at<\/code>, <code>changes<\/code><\/td>\n<\/tr>\n<tr>\n<td>Seguridad del callback<\/td>\n<td>\u2014<\/td>\n<td>Firma HMAC-SHA256 en la cabecera <code>X-Esig-Signature<\/code><\/td>\n<\/tr>\n<tr>\n<td>Reintentos del callback<\/td>\n<td>Cada hora en caso de error de red, hasta su recepci\u00f3n<\/td>\n<td>Cada hora en caso de error de red, tiempo agotado, HTTP 429 o 5xx, hasta 24 intentos, mismo <code>event_id<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>id_sign<\/code> ausente, filtro <code>status_id<\/code> no v\u00e1lido<\/td>\n<td>HTTP 401<\/td>\n<td>HTTP 400<\/td>\n<\/tr>\n<tr>\n<td><code>id_sign<\/code> desconocido<\/td>\n<td>HTTP 401<\/td>\n<td>HTTP 404<\/td>\n<\/tr>\n<tr>\n<td>Audit trail de una solicitud en curso<\/td>\n<td>HTTP 401<\/td>\n<td>HTTP 412<\/td>\n<\/tr>\n<tr>\n<td>Colocaci\u00f3n manual: <code>sign_left<\/code> \/ <code>sign_bottom<\/code><\/td>\n<td>L\u00edmites fijos para una p\u00e1gina A4 vertical (0 a 15 cm \/ 4 a 28,7 cm), altura de firma 2,5 cm<\/td>\n<td>L\u00edmites calculados seg\u00fan el tama\u00f1o real de la p\u00e1gina y del sello de los m\u00e9todos aceptados, margen de 2 cm; se admiten decimales; el mensaje de error indica el rango permitido<\/td>\n<\/tr>\n<tr>\n<td>Colocaci\u00f3n manual: solapamientos<\/td>\n<td>No se comprueban<\/td>\n<td>Rechazado si una firma cubre otra firma de la solicitud o una firma existente del documento<\/td>\n<\/tr>\n<tr>\n<td>Colocaci\u00f3n manual: <code>sign_page<\/code><\/td>\n<td>No se rechazaba un n\u00famero de p\u00e1gina superior en uno a la \u00faltima p\u00e1gina<\/td>\n<td>Se rechaza cualquier p\u00e1gina inexistente<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Los callbacks siguen la versi\u00f3n usada para <strong>crear<\/strong> la solicitud: una solicitud creada con la API <span class=\"badge\">v2<\/span> sigue recibiendo callbacks de la API <span class=\"badge\">v2<\/span>.<\/p>\n<\/div>\n<\/div>\n<p><script data-no-optimize=\"1\" data-no-defer=\"1\" data-no-minify=\"1\" data-cfasync=\"false\" nowprocket>\n(function(){\n  var root=document.querySelector('.esig-api'); if(!root) return;\n  var nav=root.querySelector('.esig-api-nav'), box=root.querySelector('.esig-api-nav-in');\n  function headerBottom(){\n    \/* empile les \u00e9l\u00e9ments fixes du haut (barre d'admin WordPress, en-t\u00eate collant\u2026) *\/\n    var b=0, xs=[Math.round(window.innerWidth\/2), 40, window.innerWidth-40];\n    for(var k=0; k<6; k++){\n      var y=b+2, found=0;\n      xs.forEach(function(x){\n        (document.elementsFromPoint?document.elementsFromPoint(x,y):[]).forEach(function(el){\n          for(var n=el; n; n=n.parentElement){\n            if(n===document.body||n===document.documentElement||n===root) break;\n            var p=getComputedStyle(n).position;\n            if(p==='fixed'||p==='sticky'){\n              var r=n.getBoundingClientRect();\n              if(r.top<=y){ if(r.bottom>b){ if(r.bottom<window.innerHeight\/2){ b=r.bottom; found=1; } } }\n              break;\n            }\n          }\n        });\n      });\n      if(!found) break;\n    }\n    return Math.round(b);\n  }\n  \/* section en cours de lecture surlign\u00e9e dans le sommaire *\/\n  var toc=root.querySelector('.esig-api-toc'), links=[].slice.call(root.querySelectorAll('.esig-api-toc a'));\n  var heads=links.map(function(a){ return document.getElementById((a.getAttribute('href')||'').slice(1)); });\n  var current=-1;\n  function spy(top){\n    var cur=0;\n    var line=top+(window.innerHeight-top)*0.3; \/* titre pass\u00e9 au-dessus du premier tiers de l'\u00e9cran *\/\n    heads.forEach(function(h,i){ if(h){ if(h.getBoundingClientRect().top<=line) cur=i; } });\n    if(window.innerHeight+window.scrollY>=document.documentElement.scrollHeight-2) cur=links.length-1;\n    if(cur===current) return;\n    current=cur;\n    links.forEach(function(a,i){ a.classList.toggle('is-active',i===cur); a.parentNode.classList.toggle('is-active',i===cur); });\n    var a=links[cur];\n    if(a){ if(toc.scrollHeight>toc.clientHeight){\n      var y=a.getBoundingClientRect().top-toc.getBoundingClientRect().top+toc.scrollTop;\n      if(y<toc.scrollTop+20) toc.scrollTop=y-20;\n      else if(y>toc.scrollTop+toc.clientHeight-40) toc.scrollTop=y-toc.clientHeight+40;\n    } }\n  }\n  function reset(){box.classList.remove('is-fixed');box.style.left=box.style.width=box.style.top='';nav.style.minHeight='';}\n  var ticking=false;\n  function update(){\n    ticking=false;\n    var mobile=window.innerWidth<=900, gap=mobile?0:20, top=headerBottom()+gap;\n    root.style.setProperty('--esig-top',top+'px');\n    spy(top);\n    reset();\n    var n=nav.getBoundingClientRect(), b=box.getBoundingClientRect(), end=root.getBoundingClientRect().bottom;\n    if(n.top>=top) return;                       \/* pas encore atteint : position normale *\/\n    if(mobile) nav.style.minHeight=b.height+'px'; \/* garde la place du bouton *\/\n    var y=Math.min(top, end-b.height);           \/* s'arr\u00eate en bas de la documentation *\/\n    box.classList.add('is-fixed'); box.style.top=y+'px'; box.style.left=n.left+'px'; box.style.width=n.width+'px';\n    \/* parent avec transform (animations Elementor\u2026) : position:fixed relative \u00e0 ce parent \u2192 correction *\/\n    var f=box.getBoundingClientRect(), dy=f.top-y, dx=f.left-n.left;\n    if(Math.abs(dy)>1||Math.abs(dx)>1){ box.style.top=(y-dy)+'px'; box.style.left=(n.left-dx)+'px'; }\n  }\n  function req(){ if(!ticking){ticking=true;requestAnimationFrame(update);} }\n  window.addEventListener('scroll',req,{passive:true}); window.addEventListener('resize',req);\n  document.addEventListener('change',function(e){ if(e.target){ if(e.target.id==='esig-api-toc') req(); } });\n  update(); window.addEventListener('load',update); setTimeout(update,1500);\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00cdndice \u00cdndice Presentaci\u00f3n Autenticaci\u00f3n Convenciones Cr\u00e9ditos C\u00f3mo funciona una solicitud de firma Crear una solicitud de firma Colocaci\u00f3n de las&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":21414,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-29106","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/pages\/29106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/comments?post=29106"}],"version-history":[{"count":4,"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/pages\/29106\/revisions"}],"predecessor-version":[{"id":29171,"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/pages\/29106\/revisions\/29171"}],"up":[{"embeddable":true,"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/pages\/21414"}],"wp:attachment":[{"href":"https:\/\/staging.e-signature.eu\/es\/wp-json\/wp\/v2\/media?parent=29106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}