heruAPI
e.firma and CSD

Get a signature

PlannedDesigned and scheduled for the v1 API. The contract can still change; the route is not served yet.

GET
/signatures/{id}

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.

Authorization

oauth2 signatures:read
headerAuthorizationBearer <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:read

Path parameters

id*string

The signature id.

Match^sig_[0-7][0-9a-hjkmnp-tv-z]{25}$

Response body

OK

application/json
  1. response
id*string
Match^sig_[0-7][0-9a-hjkmnp-tv-z]{25}$
external_id*string

Your id, as you sent it.

status*string

awaiting_worker until the worker signs; signed once they did; rejected if they declined; expired when the signing link ran out unused.

Value in"awaiting_worker""signed""rejected""expired"
worker_id*string
Match^wrk_[0-7][0-9a-hjkmnp-tv-z]{25}$
purpose?string|null
signing*

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?|null
created_at*string
Formatdate-time
updated_at*string
Formatdate-time
curl -X GET 'https://api.dev.b2b.heru.app/v1/signatures/sig_01m4rcp7xvfrct34z0q3s0r2yb'
{  "id": "sig_01m4rcp7xvfrct34z0q3s0r2yb",  "external_id": "CTR-2026-000417",  "status": "signed",  "worker_id": "wrk_01m4ra8w0he5esnnsew0v9ffkv",  "purpose": "Contrato de prestación de servicios",  "signing": {    "url": null,    "expires_at": null  },  "signed_document": {    "url": "https://download.heru.app/signatures/sig_01m4rcp7xvfrct34z0q3s0r2yb/contrato-prestacion-servicios-DRV-000088213.pdf?Expires=1791993789&KeyName=b2b-files&Signature=Qz8vT3pLm2Kx7wN4cB9rY6dA1f",    "expires_at": "2026-10-12T16:18:09.000Z",    "content_type": "application/pdf",    "filename": "contrato-prestacion-servicios-DRV-000088213.pdf"  },  "certificate": {    "serial_number": "00001000000504465028",    "rfc": "HEGL900101K44",    "signed_at": "2026-10-12T16:03:09.584Z"  },  "created_at": "2026-10-12T15:46:20.731Z",  "updated_at": "2026-10-12T16:03:09.584Z"}

Sign a document with the worker's e.firmaPOST

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.

Issue an invoicePOST

Issues a CFDI 4.0. **Who issues it** - Your company: send nothing, or `issuer.company_id` to pick one of your companies. - A merchant: `issuer.merchant_id`. - A worker with their own CSD: `issuer.worker_id`. - heru, on a worker's behalf (the worker needs no CSD): `third_party.worker_id`. - Your company, on another taxpayer's behalf: `third_party` with their RFC. **Who receives it** - One of your companies, a worker or a merchant: `receiver.company_id`, `receiver.worker_id` or `receiver.merchant_id`. heru fills their SAT data. - Anyone else: `receiver` with their RFC, name, regime and postal code. **Which companies can issue.** It depends on the credential: see [Companies](/companies). **Files.** Get the XML or the PDF with `GET /invoices/{id}/download`, which needs the `invoices:download` scope. **Synchronous.** heru stamps the CFDI with the PAC before answering, usually in 2 to 5 seconds, and returns it with its folio fiscal. Wait up to 30 seconds. If the PAC or the SAT do not answer in time you get `503` and nothing is created: retry after `Retry-After` with the same `Idempotency-Key`. If the connection drops or you get another `5xx`, retry the same way: you get the CFDI that was already stamped, never a second one. Needs the `invoices:write` scope.

© 2026 Kuarto Inc. (heru)heru.appQuestions about your integration? Contact your heru account team.