Fac-360
Documents

Get a tenant-owned document and its canonical state

GET
/api/v2/documents/{id}

Authorization

bearerAuth
AuthorizationBearer <token>

Tenant-bound, scoped and expiring Apifact credential. Migrated legacy credentials are accepted only on deprecated v1 writes and tenant-scoped v2 read, poll and download routes. Each operation names the single scope it requires in x-required-scope; the scope array of the security requirement itself is empty because OpenAPI 3.0 requires it to be for a non-oauth2 scheme.

In: header

Path Parameters

id*string
Formatuuid

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/v2/documents/497f6eca-6276-4993-bfeb-53cbbbba6f08" \  -H "Authorization: Bearer apf_v2_tu_credencial"
{  "schemaVersion": "2.0",  "requestId": "d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6",  "documentId": "4704590c-004e-410d-adf7-acb7ca0a7052",  "environment": "BETA",  "documentType": "01",  "series": "string",  "number": "string",  "state": "RECEIVED",  "fiscalState": "ISSUED",  "stateVersion": 1,  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "responseCode": "string",  "responseMessage": "string",  "sunat": {    "severity": "ACCEPTED",    "standing": "REGISTERED",    "action": "NONE",    "guidance": "string",    "catalogVersion": "string"  }}

Ask what POST /api/v2/documents would answer, without creating anything POST POST

The development tool. It runs every check the create route runs and then throws the result away: no comprobante, no correlativo, no operation, no outbox event, no quota. Free, and rate limited to 60 requests per 60 seconds per credential — a limit about how OFTEN you ask, never about what you sent, which is why it is a 429 with an error envelope and never a verdict. IT CANNOT WRITE. Not 'it does not': the route holds a repository class with no writing method, and that method runs inside a PostgreSQL READ ONLY transaction, so every INSERT, UPDATE and DELETE inside it — including one a trigger would fire — is refused by the server. A dry-run flag on the create route was rejected for the obvious reason: the day somebody leaves it set, a real comprobante exists. IT ANSWERS 200 EVEN WHEN THE DOCUMENT IS INVALID. The verdict is `valid`, in the body, and the status says only whether the service could answer. That is the opposite of the rest of this API and it is on purpose: this is the one route you call in a loop while programming, where 'invalid' is the expected result, and most HTTP clients turn a 4xx into a thrown exception you would then have to catch and unwrap to read the list you asked for. findings[0] IS THE ERROR THE CREATE ROUTE WOULD ANSWER WITH — same code, same status, same details, because both routes read one implementation of the taxonomy. The remaining findings are the problems it would only have reported on your NEXT attempt; collecting them is what removes the round trips. `totals` is present whenever the arithmetic closes, so you can compare the IGV, the payable amount, the detraction split and the derived Cuota identifiers against your own before you issue anything. NO Idempotency-Key. There is nothing to replay. THE TWO THINGS IT DOES NOT ANSWER. It does not tell you whether YOUR CREDENTIAL may create the document: a credential holding only documents:validate is told valid: true here and refused with 403 there, which is the point of the separate scope. And two of the rules it reports are snapshots of shared state — the accumulated credit on the affected comprobante, and whether that comprobante already has a cancellation note — so a note created by another request between this answer and yours moves them. That is a race, not a disagreement.

Durably request document submission POST POST

Creates an idempotent operation and outbox event. Factura, boleta and the restricted 07 and 08 note profiles are admitted only when their independent tenant capabilities are enabled: the capabilities are evaluated when the request arrives, and a request that does not meet them is REFUSED with 409 TENANT_CAPABILITY_DISABLED naming the exact capability column, never accepted and held. A 202 therefore means the submission is queued for the private SUNAT Workflow and will reach a terminal state; it never means the request is waiting for a capability to be turned on. A note profile is pinned per type and not per reason, so a 07 that voids its factura and a 07 that credits part of it are dispatched on identical terms. Successful admission does not imply SUNAT acceptance. An accepted or observed submission of any of these document types produces signed XML, submission ZIP, CDR, QR PNG and the A4 and ticket representations; a note prints its own series-number and amounts and names the document it modifies with its catalog 09/10 reason.