heruAPI
Request errors

State conflicts

The resource is not in a state that allows the operation.

link: https://developers.heru.app/errors/conflict · status 409 or 410

The request is valid, but the resource it acts on does not allow it right now: an invoice already cancelled, a charge that expired. 409 means the state may still change, so read the resource to see where it is. 410 means the resource can no longer be used.

409 Conflict
{
  "code": "INVOICE_ALREADY_CANCELLED",
  "status": 409,
  "message": "The invoice is already cancelled.",
  "link": "https://developers.heru.app/errors/conflict",
  "request_id": "req_01m4ra8x59ehp870crwjcypejt"
}
StatusCodeOperationsWhat to do
409WORKER_REMOVEDOperations on a worker removed with DELETE /workers/{id}Register the person again with POST /workers if you work with them again.
409WORKER_CSD_ALREADY_ACTIVEPOST /workers/{id}/csdNothing: the worker already has a CSD. The SAT issues a new one on every request, so heru never requests a second.
409WORKER_CSD_IN_PROGRESSPOST /workers/{id}/csdWait for worker.updated.
409INVOICE_CANCELLATION_IN_PROGRESSDELETE /invoices/{id}Wait for invoice.cancelled: the receiver has not answered yet.
409INVOICE_ALREADY_CANCELLEDDELETE /invoices/{id}Nothing: it is cancelled.
409EXTERNAL_ID_ALREADY_USEDPOST /retention-certificatesNothing was issued: you already have a certificate with this external_id. Read it with the id in the message, or use a new external_id for a new certificate.
409RETENTION_CERTIFICATE_CANCELLATION_IN_PROGRESSDELETE /retention-certificates/{id}Wait for retention_certificate.cancelled: the SAT is confirming it.
409RETENTION_CERTIFICATE_ALREADY_CANCELLEDDELETE /retention-certificates/{id}Nothing: it is cancelled.
409BATCH_NOT_READYPOST /batches/{id}/processIn awaiting_upload or validating, wait for ready. A batch that is invalid, cancelling, cancelled or done never gets there: do not retry. Read report_url if it has one, and upload the file to a new batch for what is left; what was stamped comes back duplicate.
409BATCH_EXCEEDS_CAPACITYPOST /batches/{id}/processThe batch is ready, but fits_lifetime is false: at the pace available to your company it is estimated not to finish in its 20 days. Nothing was stamped. Split the file into several batches, or ask your account team for more capacity. To start it anyway, send {"allow_partial": true}: heru stamps what fits and cancels what is pending at 20 days. While emission is paused for maintenance it can answer this for a batch that would otherwise fit, until emission resumes. See a batch that will not finish.
409BATCH_INVALID_STATEPOST /batches/{id}/pause, /resume, /cancelNothing changed. Read the batch and act on its status: see what each status allows. Retrying only helps if the status changes.
409WEBHOOK_LIMIT_REACHEDPOST /webhooksThe company already has 10 subscriptions, the maximum. Delete one with DELETE /webhooks/{id} before creating another.
409DELIVERY_NOT_REPLAYABLEPOST /deliveries/{id}/replayThe delivery is still in progress, its event left the 30-day retention, or its subscription was deleted. Wait for it to finish, or trigger the event again.
409MERCHANT_SLUG_TAKENPOST /merchantsSend another slug, or leave it out and heru builds one.
409MERCHANT_ONBOARDING_NOT_NEEDEDPOST /merchants/{id}/onboardingNothing: the merchant is active and its CSD is not expiring.
409CHARGE_ALREADY_INVOICEDPOST /charges/{id}/voidCancel the invoice with DELETE /invoices/{id} instead.
410CHARGE_EXPIREDPOST /charges/{id}/voidNothing to void: the sale can go into the merchant's global invoice.
410CHARGE_VOIDEDPOST /charges/{id}/voidNothing: it was already voided.
© 2026 Kuarto Inc. (heru)heru.appQuestions about your integration? Contact your heru account team.