# Firmar con e.firma Fuente: /sign-via-api/sign-with-efirma/ **e.firma** (antes Firma Electrónica Avanzada) es el certificado digital personal que emite el SAT. En Verificamex Firma, un firmante puede usarlo para firmar un documento directamente con su propio certificado, sin pasar por el flujo guiado de validación de identidad. > **Precaución** > > Para que un firmante pueda usar e.firma, el documento debe haberse creado con `"EFIRMA"` incluido en `allow_type_signatures`. Si el documento no lo permite, el endpoint responde con *"El documento no permite firmas de este tipo"*. Ver [configuración de `allow_type_signatures`](/document-management/create-document#allow_type_signatures-qué-certificados-se-aceptan). ## Endpoint **Método:** POST `https://api.digitafirma.com/v1/sign/{signatureId}` #### Encabezados de la Solicitud | Encabezado | Valor | Descripción | | :- | :- | :- | | `X-Api-Key` | `{id}:{secret}` | Tu API Key, ver [Uso de tokens](/authentication/using-token). | | `Content-Type` | `multipart/form-data` | El certificado y la llave se envían como archivos binarios. | #### Parámetros de Form-Data | Campo | Tipo | Requerido | Descripción | | :- | :- | :- | :- | | `cer` | `file` | Sí\* | Certificado público de la e.firma (`.cer`). | | `key` | `file` | Sí\* | Llave privada de la e.firma (`.key`). | | `pfx` | `file` | Sí\* | Alternativa a `cer` + `key`: certificado en formato PKCS12 (`.pfx`). | | `password` | `string` | Sí | Contraseña de la llave privada. | \* Envía **`cer` + `key`**, o bien **`pfx`** — no es necesario enviar los tres. Si no envías ninguna de las dos combinaciones completas, el endpoint responde con error de validación. > **Nota** > > No existe un campo para indicar "esto es e.firma". El sistema lee el certificado y detecta el tipo automáticamente según quién lo emitió (`SERVICIO DE ADMINISTRACION TRIBUTARIA` → e.firma). El mismo mecanismo reconoce certificados de FIREL y TEPJF, que se envían con los mismos campos. ## Ejemplo **cURL** ```bash curl --location 'https://api.digitafirma.com/v1/sign/ac110005-9d7a-148c-819d-9cdca24f033e' \ --header 'X-Api-Key: TU_ID:TU_SECRET' \ --form 'cer=@"/ruta/a/certificado.cer"' \ --form 'key=@"/ruta/a/llave.key"' \ --form 'password=contraseña_de_la_llave' ``` **Respuesta Exitosa (200)** ```json { "data": [ { "type": "signatures", "id": "ac110005-9d7a-148c-819d-9cdca24f033e", "links": { "self": "/signatures/ac110005-9d7a-148c-819d-9cdca24f033e" }, "attributes": { "name": "JUAN PEREZ LOPEZ", "rfc": "PELJ800101ABC", "curp": "PELJ800101HDFRPN01", "email": "juanperez@gmail.com", "sign_status": "SIGNED", "certificate_serial_number": "3A2B1C...", "certificate_issuer_name": "SERVICIO DE ADMINISTRACION TRIBUTARIA", "signed_at": "2026-04-17T13:20:45.128Z", "signature": "MIIF...", "redirect_url": null, "allowed_signature_methods": null } } ] } ``` ## Cómo firmar correctamente 1. **El certificado debe ser una e.firma personal, no un CSD.** Un Certificado de Sello Digital (el que se usa para timbrar facturas) tiene un campo `OU` que la e.firma personal no tiene. Si subes un CSD por error, la firma se rechaza. 2. **El certificado debe estar vigente.** El sistema valida las fechas de vigencia del propio certificado antes de firmar. Un certificado vencido o aún no vigente se rechaza. 3. **El RFC o CURP debe coincidir con el firmante registrado**, si al crear el documento le asignaste un `rfc` a ese firmante. El sistema extrae el RFC y el CURP directamente del certificado y los compara; si no coinciden con el firmante esperado, la firma se rechaza. Si no le asignaste un RFC al firmante, esta validación se omite. 4. **La contraseña debe corresponder exactamente a la llave privada enviada.** Una contraseña incorrecta impide abrir la llave y la firma falla. 5. **En producción, el certificado no debe estar revocado.** El sistema consulta al SAT (OCSP) para confirmar que la e.firma sigue vigente y no fue revocada antes de aplicar la firma. ## Errores comunes | Código | Mensaje | Causa | | :- | :- | :- | | 400 | `El formato ingresado pertenece a un CSD, favor de ingresar una e.firma (FIEL)` | Se envió un Certificado de Sello Digital en vez de una e.firma personal. | | 400 | `El certificado digital no está vigente` | El certificado está vencido o su vigencia aún no inicia. | | 400 | `El RFC o CURP asignado a este firmante no coincide con el certificado digital esperado` | El firmante fue registrado con un RFC distinto al que trae el certificado. | | 400 | `El certificado digital no es soportado` | El emisor del certificado no es reconocido (no es SAT, Judicatura Federal, TEPJF ni Verificamex). | | 400 | `El documento no permite firmas de este tipo` | El documento no incluyó `"EFIRMA"` en `allow_type_signatures` al crearse. | | 400 | `El documento ya ha sido firmado` | Ese `signatureId` ya está en estatus `SIGNED` o `REJECTED`. | > **Consejo** > > Todos estos errores llegan con status HTTP `400` (o `401` si el problema es de autenticación) dentro de `errors[0].detail`, siguiendo el mismo formato de respuesta que el resto de la API.