Canceled Invoices

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

Intro

This API signs in to the SAT portal with the taxpayer's own credentials and returns the CFDI cancellation requests linked to their RFC: which invoice was asked to be cancelled, who issued it and to whom, for how much, and the status of the request.
It is meant to check whether an invoice you were handed is in the middle of being cancelled before taking it as valid, and to review whether a taxpayer has cancellations waiting to be accepted or rejected.

A single endpoint serves both Personas Físicas and Personas Morales: the RFC you send decides which one it is.

Important Points

Mandatory Fields

All the fields in the body are mandatory and kiban cloud performs validations on the information sent to detect special characters or incorrect formats.

fieldtyperequiredlengthDescription
rfcAlphanumericYes12-13RFC of the taxpayer. 13 positions for a Persona Física, 12 for a Persona Moral.
passwordAlphanumericYes8The taxpayer's CIEC, the password they use to sign in to the SAT portal.

The query runs with the taxpayer's own credentials

Unlike the other SAT services, this one signs in to the portal as the taxpayer, so you need them to hand you their CIEC. Ask for it over a secure channel, and keep in mind that if they change it the query stops working until you update it.

The password is never stored in the clear: the execution keeps it masked, so the request you get back — here and in the detail — shows asterisks instead of the value you sent.

Wrong credentials do not fail the request

If the RFC or the CIEC are not correct you still get a 200 and an execution with status: SUCCESS. What changes is that there is no response object and errorMessage says the credentials are wrong. That call is billed like any other.

This matters because a credentials failure looks a lot like "the taxpayer has no cancellation requests": in both cases you find no invoices. Check errorMessage before reading response.total, or you will read a failed sign-in as a clean record.

Response times

This query is not resolved against a SAT API: it is resolved by navigating the portal, which requires solving a captcha to sign in. Expect seconds, not milliseconds, and give your HTTP client a generous timeout.

Test the service (test cases)

We have included a query parameter in Sandbox to enable you to query the test cases that we created for running tests. To get a response, fill the testCaseId parameter with any of the following cases:

NumIdNameDescription
168752a1b0000000000000001Respuesta exitosaIndicates one successful response with one cancellation request
268752a1b0000000000000002Sin solicitudes de cancelaciónIndicates one successful response with no cancellation requests
368752a1b0000000000000003Credenciales inválidasIndicates a response where the RFC or the CIEC are not correct

📘

Test your own test case

In case you want to test your own test case created in link, you can send in the testCaseId parameter the identifier of the test case you want to use.

For more information visit our knowledge center to know more about test cases

Successful response

Inside the response object you will get the next fields.

subfieldDescription
totalNumber of cancellation requests found.
invoicesOne entry per request. Empty when the taxpayer has none.

Each entry of invoices contains:

subfieldDescription
folioFiscalUUID of the CFDI the cancellation was requested for.
rfcEmisorRFC of whoever issued the invoice.
nombreEmisorName or company name of the issuer.
rfcReceptorRFC of whoever received the invoice.
nombreReceptorName or company name of the receiver.
fechaEmisionDate and time the CFDI was issued.
fechaCertificacionDate and time the PAC certified it.
fechaSolicitudDate and time the cancellation request was filed.
pacCertificoRFC of the authorized provider that certified the CFDI.
totalTotal amount of the invoice, as the portal prints it.
efectoComprobanteEffect of the receipt.
estatusSolicitudStatus of the cancellation, for example En proceso.
motivoCancellation reason stated in the request.
folioSustitucionUUID of the CFDI that replaces the cancelled one, when there is one.

Several fields arrive empty depending on the status of the request: while a cancellation is still in process there is no reason, effect or replacement folio yet.

{
    "id": "68752a1b0000000000000f01",
    "createdAt": "2026-07-14T15:40:11.204Z",
    "finishedAt": "2026-07-14T15:40:29.882Z",
    "duration": 18678,
    "status": "SUCCESS",
    "searchableBy": {
        "externalId": "solicitud-4821"
    },
    "request": {
        "rfc": "LIQ2209121V6",
        "password": "********",
        "externalId": "solicitud-4821"
    },
    "response": {
        "total": 1,
        "invoices": [
            {
                "folioFiscal": "FBF788D3-1681-4A63-BA32-C4B5951D1606",
                "rfcEmisor": "MRE2412175E4",
                "nombreEmisor": "MOTOS REGIAS",
                "rfcReceptor": "LIQ2209121V6",
                "nombreReceptor": "LIQUITECH",
                "fechaEmision": "2026-05-27T14:10:16.000-06:00",
                "fechaCertificacion": "2026-05-27T14:10:35.000-06:00",
                "fechaSolicitud": "2026-07-14T15:33:45.000-06:00",
                "pacCertifico": "SAT970701NN3",
                "total": "$65,498.99",
                "efectoComprobante": "",
                "estatusSolicitud": "En proceso",
                "motivo": "",
                "folioSustitucion": ""
            }
        ]
    }
}
{
    "id": "68752a1b0000000000000f02",
    "createdAt": "2026-07-14T15:44:02.118Z",
    "finishedAt": "2026-07-14T15:44:19.334Z",
    "duration": 17216,
    "status": "SUCCESS",
    "request": {
        "rfc": "LIQ2209121V6",
        "password": "********"
    },
    "response": {
        "total": 0,
        "invoices": []
    }
}

Listing the possible not success responses

Required fields

You will get a 400 bad request error when any of the required fields are not provided.

[
    {
        "code": "REQUIRED_FIELD_ERROR",
        "message": "EMPTY_ERROR; can't be empty",
        "field": "rfc"
    },
    {
        "code": "REQUIRED_FIELD_ERROR",
        "message": "EMPTY_ERROR; can't be empty",
        "field": "password"
    }
]

Invalid Format

The RFC does not comply with the expected format, or the CIEC is not exactly 8 characters long. The service will return a 400 bad request.

[
    {
        "code": "FORMAT_ERROR",
        "message": "must match ^([A-Z]{3,4})(\\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\\d|3[01]))([A-Z\\d]{3})$",
        "field": "rfc"
    },
    {
        "code": "LENGTH_ERROR",
        "message": "must be only 8 characters",
        "field": "password"
    }
]
🚧

Use v2 to get the error detail

The bodies above are the ones returned by v2. On v1 the same validation errors arrive as an object keyed by field name:

{
    "password": "LENGTH_ERROR; must be only 8 characters",
    "rfc": "REQUIRED_FIELD_ERROR; EMPTY_ERROR; can't be empty"
}

Invalid credentials

The RFC or the CIEC are not correct. The HTTP code is 200 and the execution status is SUCCESS — there is simply no response object, and errorMessage says what happened. Read errorMessage before reading response.

{
    "id": "68752a1b0000000000000f03",
    "createdAt": "2026-07-14T15:47:31.556Z",
    "finishedAt": "2026-07-14T15:47:48.019Z",
    "duration": 16463,
    "status": "SUCCESS",
    "errorMessage": "Error credentials wrong RFC or password",
    "request": {
        "rfc": "LIQ2209121V6",
        "password": "********"
    }
}

Unauthorized

It means that the provided API is incorrect and that you are not authorized to access it. You will not receive a body, only a 401 HTTP code.

Responses

Language
Credentials
Header
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json