API Reference
Issue, consult and cancel documents
The stackin API issues, consults, and cancels Brazilian fiscal documents (NF-e and NFS-e) on your behalf.
JSON over HTTPS
Requests and responses are JSON, authenticated with a Bearer API key.
Scoped to one company
Every request is scoped to one company — the issuer's UF, address, and digital certificate are resolved server-side from the API key, so a request only needs the business fields (buyer, items, amounts).
Just getting started?
Create a free account, generate an SDK key, and issue your first document in homologation — it's free and unlimited, no card required.
https://api.stackin.io/api/v1CopyAll API endpoints are relative to this base URL.
Authentication
The API authenticates with an API key — same mechanism as the SDK, just with its context set to . No login, no JWT — one Bearer header on every request.
Getting an API key
- 1Sign up and log in at .
- 2Create a company — this is required before a key.
- 3Go to Settings → API key in the dashboard, and set context to
api. - 4Name the key and choose its environment (
homologationorproduction, defaults tohomologation) — this is fixed for the key's whole lifetime, it can't be changed later. - 5Copy the key immediately — it's shown , at creation time, and can't be retrieved again. Losing it means revoking it and creating a new one.
curl https://api.stackin.io/api/v1/invoices \
-H "Authorization: Bearer $STACKIN_API_KEY"A missing or invalid token gets a 401 — see below.
Environments
Every API key is created for exactly one environment — or or — chosen when you generate it, and fixed for that key's lifetime.
There's no environment field in API requests: the key decides where the document goes.
Free and unlimited — it's the real SEFAZ/ADN test environment, not a mock — so integrate and test fully before switching to production.
For real documents. Make sure everything works in homologation before switching.
A company can hold keys for both environments at once (up to 3 total).
Pagination
GET /invoices is paginated with and and query params (default query params (default , max , max ).
The response envelope always includes:
- total
- integertotal rows matching the filters.
- total_pages
- integer
- next_page / prev_page
- integer | null
- data
- arraythe page's rows.
Errors
The API uses standard HTTP status codes. In most cases the response carries a detail object. SEFAZ or ADN rejections return extra information about the authorizer.
Example response
{
"detail": "This company has no state set — required for NFe. Set it via PATCH /companies/{id}."
}| HTTP | Error | When | Learn more |
|---|---|---|---|
| 400 | Invalid configuration | The issuer's configuration (certificate, address, fiscal fields) is missing or invalid. | |
| 401 | Unauthorized | The Bearer token is missing, expired, invalid, or wasn't created for the host you're calling (api.stackin.io vs sdk.stackin.io). | See details |
| 402 | Quota reached | The company's plan quota for production invoices was reached and the plan has no overage price (trial). | |
| 409 | Operation conflict | The requested operation doesn't apply to that document_type (e.g. an nfse-only operation on an nfe). | |
| 422 | Validation error | The request body failed validation — a required field is missing or malformed. | |
| 501 | Not implemented | Signing for that document type/country isn't implemented on the server yet. | |
| 502 | Authorizer rejectedAuthorizer rejection | The authorizer (SEFAZ/state or ADN) rejected the request. detail.message carries the authorizer's own error, and detail.invoice_id (issuance only) lets you look the rejected attempt up. | See details |
Invoices
Issues a new document. items[].product.br (ncm, cfop) is required for , ignored for , ignored for — a service has no tax classification code, so nfse only reads description and amount off each item.
Lists the company's issuance history, paginated (see Pagination above). Filter with document_type and and (issued, rejected, cancelled).
Looks up a document's current status directly at the authorizer by its access key. Requires as a query param.
Cancels a previously authorized document. must be at least 15 characters for nfe (the authorizer's xJust field requires it). Cancelling doesn't refund plan quota — the authorizer capacity was already spent on issuance.
Retries a failed submission by the document's local `id` (not its access key — a rejected invoice doesn't have one). Useful for retrying after fixing a configuration problem or an authorizer outage. Consumes credit like a fresh issuance, since it's a new transmission.