Sign a document with the worker's e.firma
PlannedDesigned and scheduled for the v1 API. The contract can still change; the route is not served yet.
For digital contracts. You send the PDF; the worker reviews and signs it with their e.firma on a hosted page. You get the signed document and the certificate data.
Needs the signatures:write scope.
oauth2 signatures:writeAuthorizationBearer <token>OAuth 2.0 client credentials. Exchange your client_id and client_secret at /oauth/token of the environment for a bearer token valid for one hour. The playground of every operation asks for your own client and keeps it in your browser tab only.
Scope: signatures:write
Idempotency-Key*stringUnique per operation. Retrying with the same key returns the original result for 24 hours.
length <= 255application/json- body
external_id*stringYour id for this document, e.g. your contract number. Echoed back in every response and webhook.
length <= 128worker_id*stringThe worker who signs, with the e.firma they uploaded at enrollment.
^wrk_[0-7][0-9a-hjkmnp-tv-z]{25}$document*purpose?stringWhat the document is. The worker sees it on the signing page.
Created
application/json- response
id*string^sig_[0-7][0-9a-hjkmnp-tv-z]{25}$external_id*stringYour id, as you sent it.
status*stringawaiting_worker until the worker signs; signed once they did; rejected if they declined; expired when the signing link ran out unused.
"awaiting_worker""signed""rejected""expired"worker_id*string^wrk_[0-7][0-9a-hjkmnp-tv-z]{25}$purpose?string|nullsigning*Where the worker reviews and signs the document with their e.firma.
signed_document?|Signed link to download the signed PDF, valid for 15 minutes. heru creates a new one every time you get the signature. Null until status is signed.
certificate?|nullcreated_at*stringdate-timeupdated_at*stringdate-timecurl -X POST 'https://api.dev.b2b.heru.app/v1/signatures' \ -H 'Idempotency-Key: try-it-0001' \ -H 'Content-Type: application/json' \ -d '{ "external_id": "CTR-2026-000417", "worker_id": "wrk_01m4ra8w0he5esnnsew0v9ffkv", "document": { "filename": "contrato-prestacion-servicios-DRV-000088213.pdf", "content_base64": "JVBERi0xLjcKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+" }, "purpose": "Contrato de prestación de servicios"}'{ "id": "sig_01m4rcp7xvfrct34z0q3s0r2yb", "external_id": "CTR-2026-000417", "status": "awaiting_worker", "worker_id": "wrk_01m4ra8w0he5esnnsew0v9ffkv", "purpose": "Contrato de prestación de servicios", "signing": { "url": "https://sign.heru.app/s/Wq4nT8vK2xLp7RzM3cYb?expires=1791992780&signature=6d1a9c3e72", "expires_at": "2026-10-19T15:46:20.731Z" }, "signed_document": null, "certificate": null, "created_at": "2026-10-12T15:46:20.731Z", "updated_at": "2026-10-12T15:46:20.731Z"}Request the worker's CSDPOST
Requests the worker's Certificado de Sello Digital from the SAT using their e.firma, so they can issue invoices directly. Needs consent and an active e.firma. Asynchronous; `worker.updated` fires when it is ready. Never call it twice for the same worker: the SAT issues a new certificate each time. Needs the `workers:csd` scope.
Get a signatureGET
Returns the signature request. Once the worker signs, `signed_document` carries a signed link to the signed PDF, valid for 15 minutes, and `certificate` the e.firma they used. Get the signature again for a new link. Needs the `signatures:read` scope.