Validation results
Every outcome of a fiscal or social security validation, as its webhook and GET deliver it.
Fiscal and social security validations run in the background. The request answers 202 with a receipt, and the outcome arrives later in the webhook and in GET. These outcomes are not HTTP errors: they are the answer of the SAT, RENAPO or the IMSS, or the report that heru could not get one.
How to read an outcome
status | Meaning | Webhook |
|---|---|---|
completed without code | The authority answered with the full profile or the NSS. | *.completed |
completed with code | The authority answered, and its answer is that there is no profile or NSS to return: the CURP does not exist, the person has no NSS, they must go in person. It is final; validating again gives the same answer until the person fixes it. | *.completed |
partially_completed | Some sources did not answer yet. What arrived is final; heru keeps retrying the rest. | fiscal_validation.completed, and another one when it completes |
failed | heru could not finish the query after every retry. Nothing is known about the person. | *.failed |
code is stable: branch on it. message explains it in plain words and can change. result is null whenever there is a code, except with SAT_SOURCES_PENDING, where it holds what already arrived.
{
"id": "evt_01m4ra8x08eq7vth7a13qb5y8n",
"type": "social_security_validation.completed",
"created_at": "2026-10-12T15:04:41.203Z",
"data": {
"id": "ssv_01m4ra8vtnepvrtmxdf6v3atq2",
"external_id": "SSV-2026-001213",
"status": "completed",
"code": "IN_PERSON_VALIDATION_REQUIRED",
"message": "The IMSS requires the person to validate in person at their subdelegación.",
"result": null,
"created_at": "2026-10-12T15:04:05.115Z",
"updated_at": "2026-10-12T15:04:41.203Z"
}
}Fiscal validation
The webhook is fiscal_validation.completed for completed and partially_completed, and fiscal_validation.failed for failed.
| Code | Status | message | What to do |
|---|---|---|---|
| (none) | completed | null | Use the profile: invoice with its name, postal code and regime. result has the full profile. |
CURP_NOT_FOUND | completed | The CURP is not registered with RENAPO. | Ask the person to check their CURP. Do not issue on their behalf. |
RFC_NOT_FOUND | completed | The RFC is not registered with the SAT, so the validation could not get the name. | You sent only the RFC: ask for the CURP, or check the RFC, and validate again. |
NAME_MISMATCH | completed | The name sent does not match the name registered for this RFC. | Validate with the CURP, or send the name exactly as registered with the SAT. |
SAT_SOURCES_PENDING | partially_completed | Validation was interrupted because some SAT sources did not answer. heru retries automatically and sends another webhook. | Nothing: wait for the next webhook, with completed or failed. The sections in pending are null in result. |
RETRIES_EXHAUSTED | failed | Every retry with the SAT was exhausted without a complete answer. | Validate again later with a new request. |
A suspended RFC is not a code: the validation completes with result.rfc_active false and no regimes, because that is the person's situation with the SAT.
Social security validation
The webhook is social_security_validation.completed for completed, and social_security_validation.failed for failed.
| Code | Status | message | What to do |
|---|---|---|---|
| (none) | completed | null | Use the NSS. result has the NSS and the IMSS documents. |
IN_PERSON_VALIDATION_REQUIRED | completed | The IMSS requires the person to validate in person at their subdelegación. | Tell the person to go to their IMSS subdelegación. It cannot be solved online. |
REGISTRATION_REQUIRED | completed | The person has no NSS. Send register_if_missing with their postal code to start the registration. | Validate again with register_if_missing and postal_code. |
CURP_NOT_FOUND | completed | The CURP is not registered with RENAPO. | Ask the person to check their CURP. |
RETRIES_EXHAUSTED | failed | The IMSS did not answer after every retry. | Validate again later with a new request. |
While a registration started with register_if_missing is in progress, the validation stays processing; it completes with the new NSS.
The webhook reference and GET of each validation have an example of every outcome.