Contract Signing API — v4 (4.0)

Download OpenAPI specification:Download

INTRODUCTION

REST integration API for sending contracts and documents for electronic signature from your applications. This is version 4 (v4), fully compatible with requests in the previous v3 format, but extended with the following new capabilities:



Summary of v4 new features:
1. Omnichannel channels in cascade: instead of a single notification channel (SMS/Email/SMS-cert), you can now define an ordered list of channels (SMS, Email, RCS, WhatsApp). The system will try the first one and, if it fails, automatically move to the next, giving you maximum delivery reliability. Each time you force the contracting process to continue, the system will additionally rotate the channels in order to ensure deliveries and maximize reliability.
2. Sequential authorization groups: documents the signer must review and accept before reaching the contract to sign (accept NDA, GDPR, etc. before signing the contract). Up to 3 sequential groups (Group 1 → Group 2 → Group 3 → Contract). The system will generate one certificate per authorization group, another for the contract that make up the signer copies, and a global one including all evidence, interactions and documents (copy for the sender).
3. Multiple boxes per document: up to 10 signature boxes of Signer type and 10 of Sender type per PDF, distributed throughout the document as you wish, not just one as in v3.
4. OTP per specific channel: the OTP code can be sent through the channel you choose (SMS, Email, RCS or WhatsApp), not only SMS. Also alternately, if the first channel does not reach the signer for any reason (for example WhatsApp is selected and the signer does not have it installed) the system will continue with the next configured channel.
5. Multi-send: in a single request you can create N independent contracts, each with its own list of signers and its own variables (useful for personalized bulk sending).



Legacy compatibility: if your current integration sends v3 requests to this v4 endpoint, they will work exactly the same without modifications. The system automatically detects the format and applies the appropriate behavior. This lets you migrate to v4 whenever you wish, without rush or only if you need any of the new features.

COMPATIBILITY AND VERSIONS


Version 1.0 – 1.7: Last updated 2017. Unsupported versions. Contact support for migration help.
Version 2.0 – 2.55: Last updated 2021. Functional but migrating to v3 or higher is recommended.
Version 3.0 – 3.1: Last updated 2023. Full support. Coexists with v4.
Version 4.0: This version (2026). Adds omnichannel channels, sequential authorizations, multiple boxes, OTP per selectable channel and multi-send. 100% backward compatible with v3.

AUTHENTICATION

In your user account you will find the API User and the API Token, both required to make REST requests. Requests, for security, must be made via POST over HTTPS (TLS ≥ 1.2).



To use HTTP Basic Authentication you must include a header of the type:
Authorization: Basic Base64StringAPI
where Base64StringAPI is the Base64 encoding of the string UsuarioAPI:APIToken. You can find your API User and API Token in your user account under Your Data → Configure Account.



To generate the Base64-encoded string, simply concatenate UsuarioApi:APIToken and encode it with any base64_encode function.

REQUEST FORMAT

All requests to this API are made via POST . It supports two formats for the parameters and will accept them in both formats:

1.- You can make them in JSON format in the body. The header must include Content-Type: application/json. 2.- You can make them as Form Data. In this case the header must include Content-Type: application/x-www-form-urlencoded.



The RESP parameter indicates the response format. Possible values: JSON (recommended), XML or TXT. If not specified, TXT is assumed for compatibility with old versions of the API.

KEY CONCEPTS — YOU MUST READ THIS BEFORE INTEGRATING

1. Notification channels (CANALESFIRMA)

A channel is a medium through which the system sends the signing link to the signer. The supported channels are:
  • SMS: text message to the signer's mobile.
  • EMAIL: email to the signer's email. You can use the default domain or your own domain validated in your account under the 'Transactional Email' section.
  • RCS: RCS (Rich Communication Services) message to the signer's mobile. Requires an RCS agent and template configured in the panel.
  • WHATSAPP: WhatsApp message to the signer's mobile. Requires a WhatsApp Business account (WABA) and a template configured in the panel.

Cascade: the CANALESFIRMA array is an ordered list. The system will try the first channel; if the send fails (deactivated phone, invalid number, rejected template, etc.), it will automatically move to the next. If all fail, the send is marked as failed and can be retried manually or wait for the reminder.

Rotating reminders: if you configure automatic reminders, each one will use the next channel in the cascade (not the same one already used previously). This maximizes the probability of reaching the signer.


Replaceable variables in messages and templates (all these formats are equivalent, you can use the one you prefer): {{LINK}}, [LINK], (LINK), ###LINK###. The available variables are:
    {{LINK}} — unique signing link for that signer.
    {{NOMBRE}} — signer's name.
    {{NIF}} — signer's NIF.
    {{EMAIL}} — signer's email.
    {{MOVIL}} — signer's mobile.
    {{TIPODOCUMENTO}} — the value you pass in TIPODOCUMENTO (default 'contract').

2. OTP channels (CANALESOTP)

If TIPOFIRMA=OTP, the system will send the signer a one-time code (5-digit PIN) that must be entered before signing. By default it is sent via SMS to the signer's mobile (legacy v3 API behavior). In v4 you can configure CANALESOTP with the same structure as CANALESFIRMA to send the OTP through the channel/template you prefer.


The replaceable variable specific to the PIN is: {{CODE}}. The template for the channels configured for OTP must contain it mandatorily.

3. Documents (TIPODOC + GRUPOAUT)

The contract documents can be of two types:
  • CONTRATO (default): the main document to sign. Accepts signature boxes for the signer and the sender.
  • AUTORIZACION: a document the signer must review and accept before reaching the contract to sign. They are grouped into up to 3 sequential groups through GRUPOAUT (1, 2 or 3). The signer must first accept all of those in Group 1, then those of Group 2, then those of Group 3 and, finally, sign the document of type CONTRATO.

4. Multiple boxes per document (STAMPFIRMASFIRMANTE / STAMPFIRMASEMISOR)

In v3 each PDF accepted a single signature box per document for the signer (STAMPFIRMAFIRMANTE) and another for the sender (STAMPFIRMAEMISOR). In v4 you can define up to 10 boxes of each type in each document through the new plural parameters STAMPFIRMASFIRMANTE and STAMPFIRMASEMISOR (arrays of strings with the same format as the singular: pag,x,y,tamx,tamy,H|V).


If you only need one box, keep using the legacy singulars. If you send both (singular and plural) the plural prevails.

5. Multi-send (ENVIOS)

In a single request you can generate multiple independent contracts, each with their own signers and customizable variables. Useful for sending the same document to N people with individualized data without having to make N requests to the API.


If the JSON includes the ENVIOS field (array of objects), the root-level FIRMANTES and PERSONALIZACION fields are ignored and each object in ENVIOS generates an independent contract. The response returns a Contratos array with one object per contract created.

6. Sender certification data (CERTIFICACION)

Designed for companies that send signing requests on behalf of their clients. If you include the CERTIFICACION object with EMPRESA, CIF, TELEFONO and/or LOGO, that data replaces — only in that contract — the certification data configured in your account: the Company and the CIF appear as 'Contract sender' in the PDF certificate and in the signing process, the Phone is shown to the signer during the process, and the Logo (https URL to svg/png) takes priority over the logo in your configuration on the signing page.


All fields are optional: send only the ones you want to override; the rest still comes from your account configuration.

IMPORTANT NOTES

Empty connections: A repeated erroneous connection will be treated by the system as spam and may end up temporarily blocking the connection. Avoid making repeated connections with erroneous data or fast 'empty' connections (without sends) with the same data to obtain the number of credits or the same report.

To obtain reports optimally in real time, configuring the API in the panel to receive them in a script on your website (webhooks) is recommended.


Response of requests: Most functions have a RESP parameter that defines the response format (JSON, XML or TXT). Always defining it as JSON for maximum clarity is recommended. If not defined, functions respond by default in TXT format for compatibility with old versions.


Recommended workflow:
- PROCESS 1: Send a signing request with the /EnviarContrato function.
- PROCESS 2: Automatic reception of status changes on your website (configurable in the panel — see the 'Automatic event reception' section in this document).

basicAuth

HTTP Basic authentication. Use your API User as the username and your API Token as the password (you will find them in your panel, under Your Data → Configure Account). The resulting header is Authorization: Basic base64(APIUser:APIToken). Most HTTP libraries build it automatically (curl -u, requests auth=, Ruby's basic_auth, etc.) without needing to encode the base64 by hand.

Security Scheme Type: HTTP
HTTP Authorization Scheme: basic

Send Signing Request (v4 omnichannel)

/EnviarContrato

Main function of the API. Creates a contract (or several, if you use ENVIOS) and sends the signing request to the signer(s) through the configured channels.

This is the most complete function of the API. It supports both the legacy v3 format (a single channel defined by MEDIOCOMUNICACION, singular boxes, a single send) and the new v4 format (omnichannel cascade with CANALESFIRMA/CANALESOTP, multiple boxes, authorizations by groups, multi-send).

The system automatically detects which format the client uses and applies the appropriate behavior. It is perfectly valid to mix legacy and new parameters in the same request (for example: send modern CANALESFIRMA but keep using singular STAMPFIRMAFIRMANTE).

ATTENTION: review the event reception section at the end if you want to receive the status of contracts and signer interactions in real time in a script on your server.

Authorizations:
basicAuth
query Parameters
Firmantes
Array of arrays
Example: Firmantes=[{"Nombre":"Pedro Pérez","NIF":"00000000T","Email":"destinatario@eldominio.com","Telefono":"34600000001","Orden":1}]

JSON array with the signers' data. Use this parameter when you are only going to send ONE contract. To send several contracts in a single request, use ENVIOS instead (see below).

Each element of the array must contain:
Nombre : (Required if VERIFICACIONIDENTIDAD=NO) Signer's first and last name.
NIF : (Required if VERIFICACIONIDENTIDAD=NO) Signer's NIF/DNI.
Email : (Optional but required if Telefono is not included) Signer's email.
Telefono : (Optional but required if Email is not included) Signer's mobile with international prefix without '+', e.g. '34600000001'.
Orden : (Optional) Signing order when there are several signers. The signer with the lowest Orden signs first.



If VERIFICACIONIDENTIDAD=SI, the Nombre and NIF fields are filled in automatically with the data verified during the identification process, so they can be omitted.



Example with two signers:


                      {"FIRMANTES": [
                          {
                            "Nombre":   "Pedro Aicart",
                            "NIF":      "00000000T",
                            "Email":    "pedro@dominio.com",
                            "Telefono": "34600000002",
                            "Orden":    1
                          },
                          {
                            "Nombre":   "Ana Aguado",
                            "NIF":      "00000001E",
                            "Telefono": "34600000001",
                            "Orden":    2
                          }
                        ]}
Envios
Array of strings
Example: Envios=[{"Firmantes":[{"Nombre":"Juan","NIF":"11111111H","Telefono":"34611111111","Email":"juan@a.com","Orden":1}],"Variables":{"importe":"100€"}}]

NEW in v4. JSON array to create multiple independent contracts in a single request. Each object in the array generates a contract.



Use this parameter instead of FIRMANTES + PERSONALIZACION when you need to send the same document to several people with different personalized variables. If you send ENVIOS, the root-level FIRMANTES and PERSONALIZACION fields are ignored.



Each object in the array must contain:
Firmantes : (Required) Array of signers for this contract (same structure as the root-level FIRMANTES parameter).
Variables : (Optional) Object with key/value pairs of replaceable variables in templates and messages for this specific contract. The keys are normalized to lowercase and accessed in templates as {{nombrevariable}}.



Example: two contracts with different variables


                      {"ENVIOS": [
                          {
                            "Firmantes": [
                              { "Nombre":"Juan García", "NIF":"11111111H", "Telefono":"34611111111", "Email":"juan@a.com", "Orden":1 }
                            ],
                            "Variables": { "importe":"100€", "plazo":"30 días" }
                          },
                          {
                            "Firmantes": [
                              { "Nombre":"Ana Pérez", "NIF":"22222222J", "Telefono":"34622222222", "Email":"ana@a.com", "Orden":1 }
                            ],
                            "Variables": { "importe":"250€", "plazo":"60 días" }
                          }
                        ]}



The response when using ENVIOS contains a Contratos array with one object per contract created (with ContratoId, ReportID, Firmantes, Documentos).

Flujotrabajo
string
Example: Flujotrabajo=238754787

Identifier of a workflow previously saved in your panel. It has predefined documents, templates, signature type, etc. and you just need to define the signers in the request.

The request variables prevail over those of the workflow (e.g. if the workflow has TIPOFIRMA=ACEPTACION and the request sends TIPOFIRMA=BIOMETRICA, BIOMETRICA is used). Exception: DOCUMENTOS and FIRMASEMISOR are cumulative (those of the workflow are added to those of the request).

Firmasemisor
Array of arrays
Example: Firmasemisor=[{"ID":1865998}]

JSON array with the sender signatures (yours) saved in your account that you want to stamp on the signed documents. The system adds your signature and certificates to the document at the end of the process, completing the legal document. The boxes where they are stamped are defined with STAMPFIRMAEMISOR/STAMPFIRMASEMISOR in each PDF document.



Each element of the array must contain:
ID: Identifier of the handwritten or certified signature saved in your account. You can find it in the panel.

Documentos
Array of arrays
Example: Documentos=[{"Tipo":"PDF","Nombre":"Contrato","Contenido":"JVBERi0xLj...","Aceptacion":"SI","TipoDoc":"CONTRATO","StampFirmaFirmante":"1,80,500,180,80,H"}]

JSON array with the list of contract documents. Each element represents a PDF, a panel template or a checkbox.



Supported types (Tipo field):
  PLANTILLA : Template created in your panel. Requires Plantilla, Nombre, Aceptacion.
  PDF : PDF file in base64. Requires Contenido, Nombre, Aceptacion. Optionally StampFirmaEmisor/StampFirmaFirmante (legacy singular) or StampFirmasEmisor/StampFirmasFirmante (NEW v4 plural).
  CHECKBOX : Question to the signer (GDPR, etc.). Requires Texto, Inicial, Final.



Common fields:
Tipo : PLANTILLA | PDF | CHECKBOX (Required)
Nombre : Name visible to the signer (PLANTILLA and PDF).
TipoDoc : NEW v4. CONTRATO (default) or AUTORIZACION.
GrupoAut : NEW v4. 1, 2 or 3. Only valid if TipoDoc=AUTORIZACION; indicates in which sequential group this document must be reviewed before the contract.



Fields for PLANTILLA:
Plantilla : ID of the panel template. Format {idUsuario}-{idPlantilla}.
Aceptacion : SI (the signer must reach the end by scrolling) | NO (can sign without scrolling).



Fields for PDF:
Contenido : PDF content in base64.
Aceptacion : SI | NO (same as PLANTILLA).
StampFirmaEmisor : (Legacy singular) ONE box for the sender's signature. Format: pag,x,y,tamx,tamy,H|V. E.g. 1,80,580,220,110,H.
StampFirmaFirmante : (Legacy singular) ONE box for the signer's signature. Same format.
StampFirmasEmisor : NEW v4. Array of strings — up to 10 sender boxes with the same format as the singular.
StampFirmasFirmante : NEW v4. Array of strings — up to 10 signer boxes.



Box format pag,x,y,tamx,tamy,H|V:
  pag : page (1-based).
  x : X coordinate of the left edge (0 = left edge of the page).
  y : Y coordinate of the top edge (0 = top edge of the page).
  tamx : box width.
  tamy : box height.
  H | V : page orientation. V (vertical, default A4): max width 595, max height 841. H (horizontal A4): max width 841, max height 595.



Fields for CHECKBOX:
Texto : The question or phrase the signer will see. It supports HTML links <a href="https://...">texto</a> (only http/https); standalone URLs are also linked automatically. Links open in a window within the signing process, without the signer leaving it. E.g.: Acepto la <a href="https://tudominio.com/politica-de-privacidad">Política de privacidad</a>.
Inicial : OFF (unchecked on load) | ON (checked on load).
Final : OFF (must remain unchecked to sign) | ON (must remain checked) | LIBRE (the signer decides).



Example: 2 authorizations (Group 1 and Group 2) + contract with 2 signer boxes


                          {"DOCUMENTOS": [
                              {
                                "Tipo":     "PDF",
                                "Nombre":   "NDA Confidencialidad",
                                "Contenido":"JVBERi0xLj...",
                                "TipoDoc":  "AUTORIZACION",
                                "GrupoAut": 1
                              },
                              {
                                "Tipo":     "PDF",
                                "Nombre":   "Política de Privacidad RGPD",
                                "Contenido":"JVBERi0xLj...",
                                "TipoDoc":  "AUTORIZACION",
                                "GrupoAut": 2
                              },
                              {
                                "Tipo":       "PDF",
                                "Nombre":     "Contrato Principal",
                                "Contenido":  "JVBERi0xLj...",
                                "TipoDoc":    "CONTRATO",
                                "Aceptacion": "SI",
                                "StampFirmasFirmante": [
                                  "1,80,500,180,80,H",
                                  "2,80,500,180,80,H"
                                ],
                                "StampFirmasEmisor": [
                                  "1,320,500,180,80,H"
                                ]
                              }
                            ]}
Documentossolicitados
Array of arrays
Example: Documentossolicitados=[{"Texto":"Adjunte copia del DNI","Firmante":0}]

JSON array with documents the signer must ATTACH when signing (e.g. ID copy, receipt, etc.). Each element defines a descriptive text and which signer it is requested from.



Each element must contain:
Texto : Description of the requested document (e.g. 'Attach a copy of your DNI, both sides').
Firmante : 0 = all signers; 1, 2, ... = the signer with that index (1-based).

Personalizacion
string
Example: Personalizacion={"importe":"100€","plazo":"30 días"}

Replaceable variables in templates and messages. It must be a JSON string with a flat object of key/value pairs. The keys are normalized to lowercase and accessed in templates as {{nombrevariable}} (or equivalents [nombrevariable], (nombrevariable), ###nombrevariable###).



If you use ENVIOS (multi-send), define the variables in Variables within each send instead of here.

Tipofirma
string
Enum: 1 2 3 4
Example: Tipofirma=BIOMETRICA

Type of signature to apply. IMPORTANT: you must use the TEXT, not the number.



ACEPTACION : Signature by explicit acceptance (Accept/Reject button).
OTP : Signature with a one-time OTP code. If you do not send CANALESOTP, the OTP will go via SMS to the signer's mobile.
BIOMETRICA : Biometric handwritten signature (default).
CERTIFICADO : Signature with the signer's electronic certificate or electronic DNI.

Plantillafirma
string
Enum: 0 1
Example: Plantillafirma=UNIFICADO

NEW. Environment/template of the signing process that the signer sees.



CLASICO : The usual signing process, step by step in full screen (default).
UNIFICADO : Single mobile-style page with numbered steps: the signer reads and accepts each document (with a full-screen viewer and full-read control), checks the consent boxes and signs at the end. The links in the legal text and in the boxes open in a modal window without leaving the process. The page texts and the corporate color are customizable per sender (request it from support).



The UNIFICADO environment covers: TIPOFIRMA ACEPTACION, OTP or BIOMETRICA, PDF/PLANTILLA documents (including authorizations with groups) and CHECKBOX boxes. If the request uses TIPOFIRMA=CERTIFICADO, VERIFICACIONIDENTIDAD=SI or DOCUMENTOSSOLICITADOS, the CLASICO environment will be applied.

Remitente
string
Example: Remitente=FIRMA

Sender identifier (3-11 alphanumeric characters). Used in legacy SMS and as a fallback if you do not specify REMITENTE in each SMS channel.

Mensaje
string
Example: Mensaje=Hello [NOMBRE], sign the [TIPODOCUMENTO] here: [LINK]

Legacy v3. SMS/Email text when MEDIOCOMUNICACION is used and CANALESFIRMA is NOT sent. Ignored if you use CANALESFIRMA (each channel carries its own message). Replaceable variables: [NOMBRE], [NIF], [LINK], [TIPODOCUMENTO].

Mediocomunicacion
string
Enum: 1 2 3
Example: Mediocomunicacion=SMS

Legacy v3. Single notification channel. Ignored if you send CANALESFIRMA; instead use CANALESFIRMA to define one or several channels.



SMS : Send via SMS to the signer's mobile.
EMAIL : Send via email (default domain).
SMSCERTIFICADO : SMS with delivery certification.

Tipodocumento
string
Example: Tipodocumento=Contrato

Document type (free text, max 50 chars). It is substituted in the [TIPODOCUMENTO] placeholder of legacy messages. Default: 'Contrato'.

Verificacionidentidad
string
Enum: "NO" "SI"
Example: Verificacionidentidad=NO

SI activates the online identity verification before signing (video + ID). Option with extra cost. Requires your account to be validated by support. If SI, the Nombre and NIF fields of FIRMANTES are optional (they are filled in after verification).

Minparecidoverificacion
integer
Referenciausuario
string
Example: Referenciausuario=PEDIDO-2026-00123

Integrator's internal reference (max 200 chars). It is returned in the reports and allows associating the contract with your external system. Accepts letters, digits, spaces and the characters . - _ ,

Accesible
string
Enum: "NO" "SI"
Example: Accesible=SI

SI leaves the contract accessible for future download after signing; NO blocks future access after certification. Default: SI.

Alternamedios
string
Enum: "NO" "SI"
Example: Alternamedios=SI

SI allows reminders to alternate channels (SMS and Email) if the signer has both defined; NO always uses the same channel. In v4 with CANALESFIRMA, the rotation is automatic among all the channels in the array, regardless of this parameter.

Recordatorios
integer
Example: Recordatorios=3

Number of automatic reminders to send to the signer if they have not signed (1-10). Each reminder uses the next channel in the cascade (rotation).

Fechalimite
string
Example: Fechalimite=2026-12-31 23:59

Signing deadline date in format YYYY-MM-DD HH:mm. Minimum: today + 1 hour. Maximum: today + 45 days. Default: next month, same day. After this date the contract expires without signature (status 150).

Idioma
string
Enum: "es" "pt" "en"
Example: Idioma=es

Language of the interface the signer will see on the signing screen. es (Spanish, default) | pt (Portuguese) | en (English).

Minimocheck
integer
Example: Minimocheck=0

If there are CHECKBOXES in DOCUMENTOS, the minimum number of boxes the signer must check in order to sign. Between 0 and the total number of checkboxes.

Maximocheck
integer
Example: Maximocheck=10

If there are CHECKBOXES in DOCUMENTOS, the maximum number of boxes the signer can check. Must be ≥ MINIMOCHECK.

Mensajeautorizacion
string
Example: Mensajeautorizacion=Antes de firmar el contrato debe revisar y aceptar los documentos de autorización.

NEW v4. Informative message (max 1000 chars) shown to the signer in a popup window when reaching the first authorization document. Useful to explain to the signer what they are going to review before signing the contract. Ignored if there are no documents with TipoDoc=AUTORIZACION.

Validarcanales
string
Enum: "NO" "SI"
Example: Validarcanales=NO

NEW v4. Activates the deep validation of the channels (CANALESFIRMA and CANALESOTP) before creating the contract. Possible values:
  NO (default, recommended in PRODUCTION): only the fast structural validation is done (types, IDs present, sender format). The system does NOT query external services.
  SI (recommended in PREPRODUCTION): in addition to the structural one, it validates each channel against external sources:
    • EMAIL: checks that the email template exists in the DB and that its HTML contains {{LINK}} (signature) or {{CODE}} (OTP).
    • RCS: verifies the RCS template in the DB and that it contains the required placeholder.
    • WHATSAPP: calls Meta/Facebook to confirm that the template is approved in your WABA account, that the URL button points to https://firma.ws/ (signature), or that the BODY literally contains {{CODE}} (OTP).

⚠️ IMPORTANT NOTICE:
1. This validation adds significant latency (especially WhatsApp due to the external call to Meta). In bulk sends it can translate into extra seconds per contract.
2. If you launch bulk sends with VALIDARCANALES=SI, the high volume of requests to third-party services could cause those services to temporarily block your connection (rate limiting). Therefore, when you confirm that the channel configuration is correct, go back to NO.
3. Use SI only during integration or preproduction testing to detect errors in the channel configuration (non-existent templates, no placeholders, not approved, etc.) before going to production.

🛡️ Protection rate limit: to prevent the accidental use of SI in production from bringing down your access to Meta/RCS, the API imposes a limit of 10 requests with VALIDARCANALES=SI per minute and per user. If you exceed it, the API returns Res=-29 with the fields Reintentar (seconds remaining until the counter resets) and Limite (requests allowed per minute). Your requests with VALIDARCANALES=NO do not count in this counter and continue to work normally.

If the deep validation detects a problem, the API responds with Res=-24 and an Error field describing exactly which channel and which problem it has.

Resp
string
Enum: "TXT" "JSON" "XML"
Example: Resp=JSON

Type of response to return as the result of the call.
JSON - The response will be returned in JSON
XML - The response will be returned in XML
TXT - The response will be returned in Text format

Canalesfirma
Array of strings
Example: Canalesfirma=[{"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Firma: {{LINK}}"}]

NEW in v4. JSON array with the ordered list of channels through which to send the signing request. The system will try the first one; if it fails, it will move to the next automatically (cascade). If you configure reminders, each one will use the next available channel (rotation).



If you do NOT include CANALESFIRMA, the system internally builds a single channel from the legacy parameters MEDIOCOMUNICACION, MENSAJE and REMITENTE (v3 compat). That is, it is not required to keep your current v3 integration.



Each element of the array must carry the TIPO field and the fields specific to that type:



SMS — fields:
  TIPO: "SMS"
  REMITENTE: (Optional) SMS sender identifier, max 11 alphanumeric chars (default: 'FIRMA').
  MENSAJE: (Required) SMS text. It must contain {{LINK}} (or [LINK]) which will be replaced by the signing link.



EMAIL — fields:
  TIPO: "EMAIL"
  DOMINIO: (Required) It has two modes:
    (A) Own domain — e.g. su-dominio.com. To use it, it is ESSENTIAL that this domain is registered and validated in the Transactional Email service of your panel (DNS + verification process). If the domain is not validated the send will fail with code -25. This option allows the recipient to receive the email from your brand and improves deliverability.
    (B) Default domain — literal token pordefecto. Uses the generic domain configured by the system. It does NOT require prior validation or configuration. Use it when you do not want/cannot validate your own domain.
  REMITENTE: (Required if DOMINIO is an own domain, e.g. su-dominio.com) Full email of the sender; the part after @ MUST match DOMINIO EXACTLY. E.g. if DOMINIO=su-dominio.com, REMITENTE must be algo@su-dominio.com. (Optional if DOMINIO=pordefecto: if you omit it, the system uses the default sender.)
  IDPLANTILLA: (Required if DOMINIO is an own domain) Numeric ID of the transactional email template created in the panel; it must contain {{LINK}}. (Optional with pordefecto: if you omit it, the system's default template is used with the body of MENSAJEEMAIL.)
  ASUNTOEMAIL: (Optional) Email subject.
  MENSAJEEMAIL: (Optional, recommended only if DOMINIO=pordefecto without a template) Free email body when not using a user template.



⚠ Important reminder about the Email domain: ALWAYS use the pordefecto token for the generic domain. Do NOT use other internal tokens — they are deprecated for new integrators and exist only for compatibility with old data. If you are going to send from your own domain (su-dominio.com), validate it first in your panel » Transactional Email » Domains.



RCS — fields:
  TIPO: "RCS"
  IDAGENTE: (Required) ID of the RCS agent configured in the panel.
  IDPLANTILLA: (Required) ID of the RCS template; it must contain {{LINK}}.
  REMITENTE: (Optional) Commercial name shown to the recipient.



WHATSAPP — fields:
  TIPO: "WHATSAPP"
  IDTELEFONO: (Required) WhatsApp Business Phone Number ID configured in the panel.
  IDPLANTILLA: (Required) Name/ID of the WhatsApp template approved in Meta. The template MUST include a URL button pointing to https://firma.ws/.
  VARSCUSTOM: (Optional) Object with custom variables that the WhatsApp template expects (e.g. image header, etc.).



Cascade example SMS → Email (validated own domain) → WhatsApp
Here su-dominio.com must be previously validated in your Transactional Email panel. If you do NOT have it validated and only want to send from the system's generic domain, replace the EMAIL block with the one in the following example (with pordefecto).


                      {"CANALESFIRMA": [
                          {
                            "TIPO":      "SMS",
                            "REMITENTE": "FIRMA",
                            "MENSAJE":   "Hello {{NOMBRE}}, sign here: {{LINK}}"
                          },
                          {
                            "TIPO":         "EMAIL",
                            "DOMINIO":      "su-dominio.com",
                            "REMITENTE":    "contratos@su-dominio.com",
                            "IDPLANTILLA":  12345,
                            "ASUNTOEMAIL":  "Signature request"
                          },
                          {
                            "TIPO":        "WHATSAPP",
                            "IDTELEFONO":  "123456789012345",
                            "IDPLANTILLA": "firma_contrato_es"
                          }
                        ]}


In the EMAIL block: DOMINIO is your own domain (it must be validated), the part after the @ of REMITENTE must match DOMINIO, and the template IDPLANTILLA (from the panel) must contain {{LINK}}.



Variant with default domain (system's generic domain, does not require DNS validation):


                          {
                            "TIPO":         "EMAIL",
                            "DOMINIO":      "__pordefecto__",
                            "ASUNTOEMAIL":  "Signature request",
                            "MENSAJEEMAIL": "Click here to sign: {{LINK}}"
                          }
Canalesotp
Array of strings
Example: Canalesotp=[{"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Código: {{CODE}}"}]

NEW in v4. JSON array with the channels through which to send the OTP code (5-digit PIN) when TIPOFIRMA=OTP. The structure is identical to CANALESFIRMA: each element carries TIPO and the specific fields.



Key difference: in templates and messages use {{CODE}} instead of {{LINK}}. The email/RCS/WhatsApp template for OTP must contain {{CODE}}.



If TIPOFIRMA=OTP and you do NOT include CANALESOTP, the system automatically builds an SMS channel to the signer's mobile with the message 'Your verification code is: {{CODE}}'. This is the legacy v3 behavior (the OTP was always sent via SMS).



If you want the OTP to arrive via Email/RCS/WhatsApp instead of SMS, define CANALESOTP explicitly.



Example: OTP via SMS and Email (validated own domain) simultaneously
The EMAIL block uses su-dominio.com: that domain MUST be validated in your Transactional Email panel. If you do not have it validated, replace it with pordefecto (see variant below).


                      {"CANALESOTP": [
                          {
                            "TIPO":      "SMS",
                            "REMITENTE": "FIRMA",
                            "MENSAJE":   "Your OTP code is: {{CODE}}"
                          },
                          {
                            "TIPO":         "EMAIL",
                            "DOMINIO":      "su-dominio.com",
                            "REMITENTE":    "otp@su-dominio.com",
                            "IDPLANTILLA":  67890,
                            "ASUNTOEMAIL":  "Your OTP code"
                          }
                        ]}


In the EMAIL block: DOMINIO is your own domain (it must be validated), the part after the @ of REMITENTE must match DOMINIO, and the template IDPLANTILLA (from the panel) must contain {{CODE}}.



Variant with default domain (generic domain, without validation):


                          {
                            "TIPO":         "EMAIL",
                            "DOMINIO":      "__pordefecto__",
                            "ASUNTOEMAIL":  "Your OTP code",
                            "MENSAJEEMAIL": "Your code is {{CODE}}"
                          }
Certificacion
object
Example: Certificacion={"EMPRESA":"Inmobiliaria Cliente Final SL","CIF":"B00000000","TELEFONO":"+34910000000","LOGO":"https://www.clientefinal.com/img/logo.svg"}

NEW in v4. JSON object with the sender certification data, designed for companies that send signing requests on behalf of their clients. The data sent here replaces — only in this contract — the certification data configured in your account (Your Data → Configure Account).



Object fields (all optional — send only the ones you want to override; the rest comes from your configuration):
EMPRESA : Name of the company issuing the contract (max 150 chars). Appears as 'Contract sender' in the PDF certificate and as the sender's identity in the signing process.
CIF : CIF/NIF of the issuing company (max 30 chars). Accompanies the Company in the PDF certificate and in the signing process.
TELEFONO : Sender's contact phone (max 30 chars, allows '+' prefix). Shown to the signer in the signing process. Does not appear in the PDF certificate.
LOGO : https URL to the sender's logo image, ending in .svg, .png, .jpg, .jpeg or .webp. During the signing process this logo takes priority over the one configured in your account (which in turn keeps its fallback to the default logo). The logo is NOT embedded in the PDF certificate. If the URL does not meet the format, the API returns Res=-3 with the detail in Error.



Example: sending on behalf of a client


                      {"CERTIFICACION": {
                          "EMPRESA":  "Inmobiliaria Cliente Final SL",
                          "CIF":      "B00000000",
                          "TELEFONO": "+34910000000",
                          "LOGO":     "https://www.clientefinal.com/img/logo.svg"
                        }}


It accepts the JSON object directly (requests with JSON body) or as a JSON string (form-encoded requests), just like CANALESFIRMA.

Request Body schema:

Parameters are sent in the body of the POST request, either as a JSON object (Content-Type application/json, RECOMMENDED) or as an application/x-www-form-urlencoded form. In the form format, array or object parameters are sent as a JSON-encoded string. Parameter names are case-insensitive. The detailed description of each parameter is in the parameters section of this operation.

Firmantes
Array of any
Envios
Array of any
Flujotrabajo
string
Firmasemisor
Array of any
Documentos
Array of any
Documentossolicitados
Array of any
Personalizacion
string
Tipofirma
string
Plantillafirma
string
Remitente
string
Mensaje
string
Mediocomunicacion
string
Tipodocumento
string
Verificacionidentidad
string
Minparecidoverificacion
integer
Referenciausuario
string
Accesible
string
Alternamedios
string
Recordatorios
integer
Fechalimite
string
Idioma
string
Minimocheck
integer
Maximocheck
integer
Mensajeautorizacion
string
Validarcanales
string
Resp
string
Canalesfirma
Array of any
Canalesotp
Array of any
Certificacion
object

Responses

Response Schema:
Array
Res
required
integer <int32>

Result of the operation.


1 Correct.
-1 Authentication error or unauthorized IP.
-2 Insufficient credits (includes the fields Necesarios and Cred).
-3 Parameter error (includes Error with description).
-4 to -6 General error in contract INSERT.
-7 to -9 General error in signers INSERT.
-10 to -14 General error in documents INSERT.
-15 For ACEPTACION=SI there must be exactly ONE PDF.
-16 The specified attached PDF does not exist.
-20 to -22 Error inserting requested documents.
-23 NEW v4. Invalid channel structure/type in CANALESFIRMA or CANALESOTP.
-24 NEW v4. Template without {{LINK}} (signature) or without {{CODE}} (OTP) depending on the case.
-25 NEW v4. Email domain not validated for the user.
-26 NEW v4. WhatsApp WABA not configured in the account.
-27 NEW v4. Invalid GRUPOAUT (must be 1-3 and only applicable if TipoDoc=AUTORIZACION).

ContratoId
string

Contract identifier (CSV — Secure Verification Code). Together with ReportID it is used for subsequent calls to other API functions. It also arrives in the real-time events.

ReportId
integer

Internal reports identifier. Together with ContratoID it is used for subsequent calls (e.g. download of the certified PDF, force resend, etc.).

Cred
integer

Credits remaining in the account after the send.

Firmantes
integer

Number of signers of the contract.

Documentos
integer

Number of documents sent (TEMPLATES + PDFs + CHECKBOXES).

Contratos
Array of arrays

NEW v4. Only present if you used ENVIOS with more than one send. Array with one object per contract created, each with its ContratoId, ReportID, Firmantes and Documentos.

Request samples

Content type
"{\n \"RESP\": \"JSON\",\n \"TIPOFIRMA\": \"BIOMETRICA\",\n \"REFERENCIAUSUARIO\": \"PEDIDO-2026-00123\",\n \"CERTIFICACION\": {\n \"EMPRESA\": \"Inmobiliaria Cliente Final SL\",\n \"CIF\": \"B00000000\",\n \"TELEFONO\": \"+34910000000\",\n \"LOGO\": \"https://www.clientefinal.com/img/logo.svg\"\n },\n \"CANALESFIRMA\": [\n {\"TIPO\": \"SMS\", \"REMITENTE\": \"FIRMA\", \"MENSAJE\": \"Hello {{NOMBRE}}, sign your contract: {{LINK}}\"},\n {\"TIPO\": \"EMAIL\", \"DOMINIO\": \"__pordefecto__\", \"ASUNTOEMAIL\": \"Signature request\", \"MENSAJEEMAIL\": \"Click to sign your contract: {{LINK}}\"}\n ],\n \"FIRMANTES\": [\n {\"Nombre\": \"Pedro Aicart\", \"NIF\": \"00000000T\", \"Email\": \"pedro@dominio.com\", \"Telefono\": \"34600000002\", \"Orden\": 1}\n ],\n \"DOCUMENTOS\": [\n {\"Tipo\": \"PDF\", \"Nombre\": \"Contrato de servicio\", \"Contenido\": \"JVBERi0xLjQK_BASE64_DEL_PDF_AQUI\", \"StampFirmasFirmante\": [\"1,80,500,180,80,V\"]}\n ]\n}\n"

Response samples

Content type
[
  • {
    }
]

Automatic event reception

https://{SuDominio}/path/de/su/script/de/recepción/de/reports

REAL-TIME RECEPTION OF THE STATUS OF EACH CONTRACT IN A SCRIPT ON YOUR SERVER.

By activating the option to receive reports in real time in a script on your server from your user panel, you will receive a POST request with the indicated format each time each sent contract changes status.

You can configure receiving the requests with basic authentication and in JSON or FORM-DATA format

Authorizations:
basicAuth
Request Body schema:

Parámetros recibidos en su script en petición POST con la configuración especificada en su panel de usuario/configuración API.

Servicio
required
string

Report type. For this API you will receive CONTRATACION.

ContratoID
string

Contract identifier (CSV).

ReportID
integer

Internal reports identifier.

Resultado
required
integer

Contract status. Possible statuses:

STATUSDESCRIPTIONMEANING
0In processContract accepted, waiting for the first signer.
100CertifyingProcess finished, generating certificate.
101Signed and CertifiedCertificate available for download.
150ExpiredThe contract expired without signature.
151CancelledCancelled by the user before signing.
1014Signed and CertifiedSynonym of 101.
1050ExpiredSynonym of 150.
FechaEnvio
string

Date on which the contract was sent.

FechaFirma
string

Date on which the contract was signed (if it has been signed).

NumFirmantes
required
string

Number of signers of the contract.

NumFirmados
string

Number of signers who have already signed.

Referencia
string

REFERENCIAUSUARIO you sent in the original request.

TipoFirma
integer

Signature type of the contract (numeric):
1: ACEPTACION
2: OTP
3: BIOMETRICA
4: CERTIFICADO

CanalUsado
string

NEW v4. Channel through which the last message was sent to the signer. Possible: sms, email, rcs, whatsapp. Useful to audit which channel of the cascade worked.

Request samples

Content type
{
  • "Servicio": "CONTRATACION",
  • "ContratoID": "ASYYFRE5492-HN776TFD",
  • "ReportID": "299846332",
  • "Resultado": "11",
  • "FechaEnvio": "2026-05-03 10:10",
  • "FechaFirma": "2026-05-03 11:30",
  • "NumFirmantes": "2",
  • "NumFirmados": "1",
  • "Referencia": "PEDIDO-2026-00123",
  • "TipoFirma": "3",
  • "CanalUsado": "sms"
}

Force resend to the next signer

/ForzarRecomunicacionCONTRATO

Forces the immediate continuation of the signing flow. Its typical use is to resend the request to the current signer when they do not respond. If you configured a channel cascade in CANALESFIRMA, this resend will use the NEXT channel in the cascade (rotation). Limited to 2 executions per day per signing process.

Authorizations:
basicAuth
query Parameters
Contratoid
required
string
Example: Contratoid=ASYYFRE5492-HN776TFD

ContratoID returned in the send function.

Reportid
required
integer
Example: Reportid=1283876988

ReportID returned in the send function.

Resp
string
Enum: "TXT" "JSON" "XML"
Example: Resp=JSON

Response format: JSON | XML | TXT.

Request Body schema:

Parameters are sent in the body of the POST request, either as a JSON object (Content-Type application/json, RECOMMENDED) or as an application/x-www-form-urlencoded form. In the form format, array or object parameters are sent as a JSON-encoded string. Parameter names are case-insensitive. The detailed description of each parameter is in the parameters section of this operation.

Contratoid
required
string
Reportid
required
integer
Resp
string

Responses

Response Schema:
Array
Res
required
integer <int32>

0 The contract is already signed.
1 Resend performed correctly.
-1 Authentication error.
-2 Incorrect data.
-3 Parameter error (includes Error).

Cred
integer

Remaining credits.

CanalUsado
string

NEW v4. Channel through which the resend was attempted.

Request samples

Content type
{
  • "Contratoid": "ASYYFRE5492-HN776TFD",
  • "Reportid": "1283876988",
  • "Resp": "JSON"
}

Response samples

Content type
[
  • {
    }
]

Download the Contract Certificate

/GetCertificadoCONTRATO

Downloads the certificate of the signed contract or the signer copy. It is normally executed in response to the reception of the report with status 101/1014 (Signed and Certified).

Type of file returned depending on DOC:

  • DOC=CERTIFICADO → ALWAYS returns a PDF (certificado_S.pdf) with the complete evidence of the process. Content-Type: application/pdf, suggested name contrato.pdf.
  • DOC=FIRMANTE → can return PDF or ZIP depending on the contract:
    • If there are NO authorization groups → PDF (copiafirmantes.pdf), a single document with the signed contract. Content-Type: application/pdf, name contrato.pdf.
    • If there ARE authorization groups → ZIP (copiafirmantes.zip) with one PDF per authorization group (grupo_autorizacion_N_certificado.pdf) plus the contract PDF (contrato_certificado.pdf). Content-Type: application/zip, name contrato.zip.
Detection by the integrator: check the Content-Type header of the response to know whether you received application/pdf or application/zip and process accordingly. The API client must be prepared for both formats.
Authorizations:
basicAuth
query Parameters
Contratoid
required
string
Example: Contratoid=ASYYFRE5492-HN776TFD

ContratoID returned in the send function.

Reportid
required
integer
Example: Reportid=1283876988

ReportID returned in the send function.

Doc
string
Enum: "CERTIFICADO" "FIRMANTE"
Example: Doc=CERTIFICADO

Type of document to download:
CERTIFICADO — Complete certified document with all events (always PDF).
FIRMANTE — Copy for signers (only the signed document with stamped signatures). PDF if the contract has no authorization groups; ZIP if it has them (with one PDF per group + the contract PDF).

Resp
string
Enum: "TXT" "JSON" "XML"
Example: Resp=JSON

Response format when there is an error: JSON | XML | TXT. On success the file is downloaded directly (PDF or ZIP).

Request Body schema:

Parameters are sent in the body of the POST request, either as a JSON object (Content-Type application/json, RECOMMENDED) or as an application/x-www-form-urlencoded form. In the form format, array or object parameters are sent as a JSON-encoded string. Parameter names are case-insensitive. The detailed description of each parameter is in the parameters section of this operation.

Contratoid
required
string
Reportid
required
integer
Doc
string
Resp
string

Responses

Response Schema:
string

Request samples

Content type
{
  • "Contratoid": "ASYYFRE5492-HN776TFD",
  • "Reportid": "1283876988",
  • "Doc": "CERTIFICADO",
  • "Resp": "JSON"
}

Response samples

Content type
PDF (certificate or signer copy without groups).

Credits Query

/GetCreditos

Returns the number of credits in the account. Occasional function since most functions return the balance in the response.

Authorizations:
basicAuth
query Parameters
Resp
string
Enum: "TXT" "JSON" "XML"
Example: Resp=JSON

Response format: JSON | XML | TXT.

Request Body schema:

Parameters are sent in the body of the POST request, either as a JSON object (Content-Type application/json, RECOMMENDED) or as an application/x-www-form-urlencoded form. In the form format, array or object parameters are sent as a JSON-encoded string. Parameter names are case-insensitive. The detailed description of each parameter is in the parameters section of this operation.

Resp
string

Responses

Response Schema:
Array
Res
required
integer <int32>

1 Function completed successfully.
-1 Authentication error.

Cred
required
double

Credits remaining in the account.

Request samples

Content type
{
  • "Resp": "JSON"
}

Response samples

Content type
[
  • {
    }
]

Migration v3 → v4

Full compatibility

The v4 API is 100% backward compatible with v3 requests. If your current integration sends requests to the v3 endpoint and redirects them to v4, everything will keep working without changes.

Decision: do I migrate to v4 or stay on v3?

We keep both endpoints active so you can migrate whenever it suits you.

Minimal changes to enable v4 capabilities

  • Channel cascade: add the CANALESFIRMA field with an array of channels instead of or in addition to MEDIOCOMUNICACION.
  • Authorizations: add TipoDoc:'AUTORIZACION' and GrupoAut: 1|2|3 to the relevant documents.
  • Multiple boxes: change StampFirmaFirmante (singular) to StampFirmasFirmante (array of strings).
  • Multi-send: use ENVIOS instead of FIRMANTES + PERSONALIZACION.
  • OTP per specific channel: add CANALESOTP when you use TIPOFIRMA=OTP.
  • Sending on behalf of your clients: add CERTIFICACION with {EMPRESA, CIF, TELEFONO, LOGO} so the contract is certified with your client's identity instead of the one configured in your account.

Quick equivalence table

v3v4
MEDIOCOMUNICACION:'SMS' + MENSAJE + REMITENTECANALESFIRMA:[{TIPO:'SMS', REMITENTE:'...', MENSAJE:'... {{LINK}}'}]
STAMPFIRMAFIRMANTE:'1,80,500,180,80,H'STAMPFIRMASFIRMANTE:['1,80,500,180,80,H']
Only the direct contract could be signedTipoDoc:'AUTORIZACION' + GrupoAut:1 adds prior steps

Credits calculation

Complete formula

créditos = PRECIO_FIJO_CONTRATO (11)
         + nFirmantes × FIRMANTE (3)
         + nFirmantesConVerifica × VERIFICAR_IDENTIDAD (20)
         + nCheckboxes × CHECKBOX (1)
         + (hayDocumentosSolicitados ? PRECIO_FIJO_SOLICITUD_DOCUMENTOS (11) : 0)
         + nGruposAutorizacionDistintos × PRECIO_FIJO_AUTORIZACIONES (7)
         + extras según MEDIOCOMUNICACION (legacy):
              SMS:            PRO_CREDITOS_MENSAJE
              EMAIL:          0
              SMSCERTIFICADO: CREDITOS_CERTIFICADO + CREDITOS_PARTE_CERTIFICADO

Practical example

A contract with 2 signers, 1 PDF, 2 checkboxes, no identity verification, no requested documents, no authorizations, sent via legacy SMS:
11 + 2×3 + 0 + 2×1 + 0 + 0 + 2×PRO_CREDITOS_MENSAJE = 19 + 2×SMS

A contract with 1 signer, 1 PDF, 0 checkboxes, with authorizations from Group 1 and Group 3 (2 different groups), without legacy SMS (uses CANALESFIRMA):
11 + 1×3 + 0 + 0 + 0 + 2×7 = 28 credits. Each channel in the cascade is charged when it is sent (not when creating the contract).

Error codes

Complete table of Res codes

CodeMeaningWhen
1OKSuccessful operation.
-1Auth/IPInvalid credentials or unauthorized IP.
-2No creditsThe Necesarios field indicates how many are needed.
-3ParametersThe Error field describes the specific problem.
-4 a -6INSERT contractInternal error on insert (contact support).
-7 a -9INSERT signersInternal error inserting signers.
-10 a -14INSERT documentsInternal error inserting documents.
-15ACEPTACION=SI requires 1 PDFIf you activate acceptance scroll, there must be exactly ONE PDF.
-16Non-existent PDFThe referenced PDF does not exist in your account.
-20 a -22INSERT requestsError inserting documents requested from the signer.
-23NEW v4 Invalid channelStructure/type of a channel in CANALESFIRMA or CANALESOTP is incorrect. The Error field details which one.
-24NEW v4 Deep channel validation failedOnly if VALIDARCANALES=SI. Indicates that a channel passed the structural validation but failed when validating against external sources (template non-existent in DB, without {{LINK}}/{{CODE}}, WhatsApp template not approved in Meta, etc.). The Error field says which channel and which specific problem.
-25NEW v4 Email domain not validatedThe DOMINIO of an Email channel is not DNS-validated in your account.
-26NEW v4 WABA not configuredWhatsApp Business is not configured in your account.
-27NEW v4 Invalid GRUPOAUTGrupoAut must be 1, 2 or 3 and only applies with TipoDoc=AUTORIZACION.
-29NEW v4 VALIDARCANALES rate limitOnly if VALIDARCANALES=SI. You have exceeded 10 requests per minute and per user. The response includes Reintentar (seconds until you can retry) and Limite (requests/min allowed). Go back to VALIDARCANALES=NO for bulk sends.

Examples by scenario

1. Simple legacy SMS (v3 compat)

{
  "RESP": "JSON",
  "TIPOFIRMA": "BIOMETRICA",
  "MEDIOCOMUNICACION": "SMS",
  "REMITENTE": "FIRMA",
  "MENSAJE": "Firma aquí: [LINK]",
  "FIRMANTES": [{"Nombre":"Juan","NIF":"00000000T","Telefono":"34600000001","Email":"j@a.com","Orden":1}],
  "DOCUMENTOS": [{"Tipo":"CHECKBOX","Texto":"Acepto","Inicial":"OFF","Final":"ON"}]
}

2a. Cascade SMS → Email (validated own domain)

Important: the domain su-dominio.com must be registered and validated in your Transactional Email panel. If you do not have it validated the send will fail with Res=-25; in that case use example 2b with __pordefecto__.

{
  "RESP": "JSON",
  "TIPOFIRMA": "BIOMETRICA",
  "CANALESFIRMA": [
    {"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Firma: {{LINK}}"},
    {"TIPO":"EMAIL","DOMINIO":"su-dominio.com","REMITENTE":"contratos@su-dominio.com","IDPLANTILLA":12345,"ASUNTOEMAIL":"Firma"}
  ],
  "FIRMANTES": [{"Nombre":"Juan","NIF":"00000000T","Telefono":"34600000001","Email":"j@a.com","Orden":1}],
  "DOCUMENTOS": [{"Tipo":"PDF","Nombre":"Contrato","Contenido":"JVBERi0xLj...","Aceptacion":"SI","StampFirmaFirmante":"1,80,500,180,80,H"}]
}

2b. Cascade SMS → Email (default domain, without validation)

Use the __pordefecto__ token when you do NOT have a validated own domain. The system will send from the generic domain (it does not require DNS/prior validation).

{
  "RESP": "JSON",
  "TIPOFIRMA": "BIOMETRICA",
  "CANALESFIRMA": [
    {"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Firma: {{LINK}}"},
    {"TIPO":"EMAIL","DOMINIO":"__pordefecto__","ASUNTOEMAIL":"Firma","MENSAJEEMAIL":"Click {{LINK}}"}
  ],
  "FIRMANTES": [{"Nombre":"Juan","NIF":"00000000T","Telefono":"34600000001","Email":"j@a.com","Orden":1}],
  "DOCUMENTOS": [{"Tipo":"PDF","Nombre":"Contrato","Contenido":"JVBERi0xLj...","Aceptacion":"SI","StampFirmaFirmante":"1,80,500,180,80,H"}]
}

3. Authorizations in 2 groups + contract

{
  "RESP": "JSON",
  "TIPOFIRMA": "BIOMETRICA",
  "MENSAJEAUTORIZACION": "Antes de firmar revise NDA y RGPD.",
  "CANALESFIRMA": [{"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Firma: {{LINK}}"}],
  "FIRMANTES": [{"Nombre":"Juan","NIF":"00000000T","Telefono":"34600000001","Email":"j@a.com","Orden":1}],
  "DOCUMENTOS": [
    {"Tipo":"PDF","Nombre":"NDA","Contenido":"JVBERi0xLj...","TipoDoc":"AUTORIZACION","GrupoAut":1},
    {"Tipo":"PDF","Nombre":"RGPD","Contenido":"JVBERi0xLj...","TipoDoc":"AUTORIZACION","GrupoAut":2},
    {"Tipo":"PDF","Nombre":"Contrato","Contenido":"JVBERi0xLj...","TipoDoc":"CONTRATO","Aceptacion":"SI","StampFirmaFirmante":"1,80,500,180,80,H"}
  ]
}

4. OTP via SMS and Email (validated own domain)

Reminder: the domain su-dominio.com must be validated in your Transactional Email panel. If it is not, replace the EMAIL block with {"TIPO":"EMAIL","DOMINIO":"__pordefecto__","ASUNTOEMAIL":"OTP","MENSAJEEMAIL":"Your code is {{CODE}}"} to use the generic domain.

{
  "RESP": "JSON",
  "TIPOFIRMA": "OTP",
  "CANALESFIRMA": [{"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Firma: {{LINK}}"}],
  "CANALESOTP": [
    {"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Your code: {{CODE}}"},
    {"TIPO":"EMAIL","DOMINIO":"su-dominio.com","REMITENTE":"otp@su-dominio.com","IDPLANTILLA":67890,"ASUNTOEMAIL":"OTP"}
  ],
  "FIRMANTES": [{"Nombre":"Juan","NIF":"00000000T","Telefono":"34600000001","Email":"j@a.com","Orden":1}],
  "DOCUMENTOS": [{"Tipo":"CHECKBOX","Texto":"Acepto","Inicial":"OFF","Final":"ON"}]
}

5. Multi-send with own variables

{
  "RESP": "JSON",
  "TIPOFIRMA": "BIOMETRICA",
  "CANALESFIRMA": [{"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Hello {{NOMBRE}}: {{LINK}}"}],
  "ENVIOS": [
    {"Firmantes":[{"Nombre":"Juan","NIF":"11111111H","Telefono":"34611111111","Email":"j@a.com","Orden":1}],"Variables":{"importe":"100€"}},
    {"Firmantes":[{"Nombre":"Ana","NIF":"22222222J","Telefono":"34622222222","Email":"a@a.com","Orden":1}],"Variables":{"importe":"250€"}}
  ],
  "DOCUMENTOS": [{"Tipo":"PLANTILLA","Plantilla":"1234-5678","Nombre":"Contrato","Aceptacion":"SI"}]
}

The response of example 5 will contain a Contratos field with 2 objects (one per contract created).

6. Sending on behalf of a client (CERTIFICACION)

An agency sends the contract on behalf of its client 'Inmobiliaria Cliente Final SL': the PDF certificate and the signing process show the client's identity and logo instead of the ones configured in the agency's account.

{
  "RESP": "JSON",
  "TIPOFIRMA": "BIOMETRICA",
  "CANALESFIRMA": [{"TIPO":"SMS","REMITENTE":"FIRMA","MENSAJE":"Firma: {{LINK}}"}],
  "CERTIFICACION": {
    "EMPRESA":  "Inmobiliaria Cliente Final SL",
    "CIF":      "B00000000",
    "TELEFONO": "+34910000000",
    "LOGO":     "https://www.clientefinal.com/img/logo.svg"
  },
  "FIRMANTES": [{"Nombre":"Juan","NIF":"00000000T","Telefono":"34600000001","Email":"j@a.com","Orden":1}],
  "DOCUMENTOS": [{"Tipo":"PLANTILLA","Plantilla":"1234-5678","Nombre":"Contrato","Aceptacion":"SI"}]
}