For agents
One-page summary, ready for a system prompt — the cold start, the six scopes, the handoff pattern and the MCP server.
Facturia is Chile's multi-company e-invoicing API: issuing DTEs (facturas, boletas, credit and debit notes), receiving suppliers' documents, the tax suite (RCV, F29), and signed webhooks, with an MCP server so an agent can operate it directly. Sandbox free forever, no card, no certificate.
The path in five steps
1. Cold start, one call. POST /account/register with bootstrap.sandbox_key and optionally
bootstrap.empresa returns, in the same response, the account, an sk_test_ key, and data.next —
the exact call that follows, with method, URL and headers. Confirming an e-mail is never required to
get this far. Full contract: https://docs.facturia.cl/openapi-bootstrap.yaml.
2. Emit in the sandbox. POST /v1/documents with Authorization: Bearer sk_test_… and
Facturia-Empresa: <rut> creates a document without touching the SII: folio: null, accepted in
under a second, PDF and XML on the spot. The bootstrap key carries the six scopes that carry this
whole path: documents:read, documents:write, empresas:read, empresas:write, webhooks:read,
webhooks:write. keys:write is separate (a root key, mints other keys only), and the four
go-live scopes (mandato:write, mandato:attest, onboarding:write, onboarding:attest) never
come by default: they are requested explicitly when they are actually needed.
3. Production is a state machine you read with a GET.
GET /v1/empresas/{empresa_id}/onboarding always answers with the list of remaining steps and, if
the next one needs a person, a pending_action. There is no need to guess the whole flow: every read
names the one next step.
4. The handoff pattern. When pending_action shows up, it names who
(performed_by.role: representante_legal, usuario_administrador, titular_certificado or
titular_cuenta — a role, never a person), where (action_url, or link.mint with
{method, url, body} if the link has to be minted first), what to do (instructions[], in
Chilean Spanish, verbatim — do not paraphrase it) and how we find out
(verification.recheck: call it once the person is done, and we check again). Relay the whole
object to your principal; never summarize it or invent a field that was not there.
5. Over MCP. https://mcp.facturia.cl/mcp exposes the same capabilities as tools, with OAuth for
the connection and explicit per-scope consent. Discovery lives at
/.well-known/oauth-protected-resource.
The two rules
- Follow
next(orpending_action/link.mint/recheck), never build the URL by hand. Every response carries the exact call that follows — method, absolute URL, headers and sometimes a body — and that is the only thing to execute. Guessing a route or inventing a field is exactly the mistake this pattern exists to prevent. - Relay
pending_actionverbatim. Thetitle, theinstructions[]and theperformed_by.roleare the communication with a real person who is about to do something in front of the SII; summarizing them, over-translating them, or handing the wrong role gives that person a different instruction from the one we actually know to be correct.
To go further
- OpenAPI 3.1 — cold start: the contract for step 1.
- OpenAPI 3.1 — /v1: the full contract.
- Quickstart: steps 1 and 2, with the full responses.
- From sandbox to production: steps 3 and 4, with every handoff documented.
- MCP server: what an agent connecting over MCP sees.
- Error dictionary: every code, its cause, and
whether retrying is worth it. The API serves the same dictionary at
GET /v1/error_codes. - All of the above in one file: quickstart, production, authentication and MCP, without the ~200 error-code pages.