> ## Documentation Index
> Fetch the complete documentation index at: https://docs.newinvoice.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Constancia de situación fiscal

> Get a taxpayer's constancia de situación fiscal as a PDF, using only their RFC and a saved CIEC.

Get a taxpayer's constancia de situación fiscal as a PDF, using only their RFC and a saved CIEC. You
don't need a FIEL.

The **constancia de situación fiscal** is the SAT document that states a taxpayer's registered fiscal
details. The **CIEC** is the password the taxpayer uses to sign in to the SAT portal.

> **Test mode is simulated.** With a `sk_test_` key, or on the sandbox issuer, nothing reaches the
> SAT and any password is accepted. The PDF you get is clearly marked as not being a SAT document.
> The steps below work as written with a test key.

## From request to PDF

Set `$API_KEY` to your key and `$FP_ID` to a fiscal profile in the same mode.

**1. Save the CIEC.** Skip this if the profile already has a `verified` credential. With a live key,
wait for `verified` first, as described in [SAT credentials](https://docs.newinvoice.dev/guides/sat-credentials.md).

```bash theme={null}
curl -s -X POST https://api.newinvoice.dev/v1/fiscal_profiles/$FP_ID/sat_credential \
  -H "authorization: Bearer $API_KEY" -H 'content-type: application/json' \
  -d '{ "password": "any-password-in-test-mode" }' | jq .status
```

**2. Request the constancia.** You get an answer right away, and the work continues in the background.

```bash theme={null}
DOC_ID=$(curl -s -X POST https://api.newinvoice.dev/v1/fiscal_documents \
  -H "authorization: Bearer $API_KEY" -H 'content-type: application/json' \
  -d "{ \"fiscal_profile_id\": \"$FP_ID\", \"type\": \"constancia\" }" | jq -r .id)
```

The response is a `pending` document:

```json theme={null}
{
  "id": "fdoc_06GVX7CK6V7ZE7VV5TBNPT72",
  "status": "pending",
  "livemode": false,
  "deadline": "2026-11-09T06:42:40.310Z",
  "pdf_url": null,
  "error": null
}
```

**3. Wait for it.** Subscribe to the `fiscal_document.ready` [webhook](https://docs.newinvoice.dev/guides/webhooks.md), or poll. A live
request can take several minutes; in test mode it takes about 15 seconds.

```bash theme={null}
until STATUS=$(curl -s https://api.newinvoice.dev/v1/fiscal_documents/$DOC_ID \
  -H "authorization: Bearer $API_KEY" | jq -r .status); \
  [ "$STATUS" != "pending" ] && [ "$STATUS" != "processing" ]; do sleep 10; done
echo $STATUS
```

A finished document also carries the PDF's location, checksum and deletion date:

```json theme={null}
{
  "status": "ready",
  "sha256": "6c3cbe364c840b0b27eba153a02d4e53376fea5a0f1b210be21e0b5e26501463",
  "size_bytes": 910,
  "pdf_url": "/v1/fiscal_documents/fdoc_06GVX7CK6V7ZE7VV5TBNPT72/pdf",
  "pdf_expires_at": "2026-12-09T04:42:55.423Z"
}
```

**4. Download the PDF** once the status is `ready`.

```bash theme={null}
curl -s https://api.newinvoice.dev/v1/fiscal_documents/$DOC_ID/pdf \
  -H "authorization: Bearer $API_KEY" -o constancia.pdf
```

In live mode, one constancia per RFC is free each calendar quarter (Mexico City time). Only a
delivered PDF uses it up; test mode is never limited.

We keep the PDF encrypted for **30 days**, then delete it (`pdf_expires_at`). Store your own copy, or
request a new one. A live constancia that reaches `ready` is recorded in `GET /v1/usage` as
`sat_constancia`; failed requests are free.

## Statuses

| `status` | What it means | What to do |
| - | - | - |
| `pending`, `processing` | Still working, up to `deadline` (at most 2 hours). | Wait. |
| `ready` | The PDF is available. | Download it. |
| `needs_action`, `failed` | It stopped: someone needs to look at it, or it did not complete. | Follow `error.remediation`. |
| `cancelled`, `expired` | Cancelled, or the PDF was deleted after 30 days. | Create a new request. |

## Common errors

| Code | What to do |
| - | - |
| `fiscal_document.credential_missing` (422) | [Save the CIEC](https://docs.newinvoice.dev/guides/sat-credentials.md) on the profile. |
| `fiscal_document.credential_pending` (422) | Wait until the credential is `verified`. |
| `fiscal_document.credential_unverified` (422) | Confirm the RFC and password with the taxpayer, then save them again. |
| `fiscal_document.credential_expired` (422) | Ask the taxpayer for the password and save it again. |
| `fiscal_document.free_quota_exceeded` (402) | This RFC used this quarter's free one. The error says when the next is available. |
| `sat_service.credential_rejected` (in `error`) | The SAT refused the password. Save the right one; we won't retry it for you. |

The [error reference](https://docs.newinvoice.dev/concepts/errors.md) lists every code. To try a failure in test mode, see
[Testing](https://docs.newinvoice.dev/guides/testing.md#exercising-each-lifecycle-branch).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.