# Documents and status

Read the status of a sales document you submitted through Unify: its state, whether processing has finished, and what the tax authority or the Peppol network returned.

## Endpoint

```http title="Get a sales document"
GET https://prod.gets.complyance.io/api/v3/documents/{documentId}?type=sales
```

Use the `documentId` from the [submit response](https://docs.complyance.io/api-reference/unify/submit-and-retrieve/#response). The same request with `type=purchases` returns a received invoice; see [Get a purchase invoice](https://docs.complyance.io/api-reference/purchases/get/).

`GET /api/v3/documents/{documentId}/status` returns the same status object. When the document is compliant, it also returns the invoice PDF, Base64-encoded, in `pdfBase64`, which is `null` if the PDF could not be produced. Use either one; the examples in these docs use `?type=sales`.

## Authentication

Send `Authorization: Bearer YOUR_API_KEY` with a key from the workspace that submitted the document. See [Authentication](https://docs.complyance.io/api-reference/authentication/).

## Parameters

| Parameter | Location | Required | Description |
| - | - | - | - |
| `documentId` | Path | Yes | The identifier returned when the document was submitted |
| `type` | Query | Yes | `sales` |

```bash title="Check the status"
curl "https://prod.gets.complyance.io/api/v3/documents/${DOCUMENT_ID}?type=sales" \
  --header "Authorization: Bearer ${COMPLYANCE_API_KEY}" \
  --header 'Accept: application/json'
```

## Response

HTTP `200` returns `success: true` and the document’s status in `data`.

```json title="Compliant UAE invoice — HTTP 200 (shortened)"
{
  "success": true,
  "data": {
    "documentId": "01K5EXAMPLE00000000000142",
    "documentNumber": "INV-2026-000184",
    "country": "AE",
    "environment": "sandbox",
    "state": "final_valid",
    "isTerminal": true,
    "lastUpdatedAt": "2026-09-22T10:00:04.000Z",
    "errors": [],
    "compliance": {
      "uuid": "6f1c2a9e-3b4d-4e8f-9a7b-1c2d3e4f5a6b",
      "ftaApprovedStatus": "APPROVED",
      "businessProcessIdentifier": "urn:peppol:bis:billing",
      "specificationIdentifier": "urn:peppol:pint:billing-1@ae-1"
    },
    "validationResults": {
      "status": "Valid",
      "validationSteps": [
        { "name": "Validation Passed", "status": "Valid", "error": null },
        { "name": "Queue Admitted", "status": "Valid", "error": null },
        { "name": "Delivery Processing Started", "status": "Valid", "error": null },
        { "name": "Final Valid", "status": "Valid", "error": null }
      ]
    }
  }
}
```

This example leaves out `government` and `artifacts`.

| Field | Type | Description |
| - | - | - |
| `documentId` | string | The document’s identifier |
| `documentNumber` | string or null | The number from your payload |
| `country` | string | The document’s country |
| `environment` | string | `sandbox` or `production` |
| `state` | string | Where the document is. See [States](https://docs.complyance.io/api-reference/unify/documents/#states). |
| `isTerminal` | boolean | `true` when processing has finished and `state` will not change on its own |
| `lastUpdatedAt` | string | When the status last changed, in UTC (ISO 8601) |
| `errors` | object\[] | What went wrong, when something did. Each has a `code`, a `message`, a `path` to the field as a list of names, and a `source`: `validation`, `delivery` or `government`. Can be empty while the document is in progress. |
| `government` | object or null | What the tax authority or the Peppol network returned. See [The government object](https://docs.complyance.io/api-reference/unify/documents/#the-government-object). |
| `artifacts` | object or null | The e-invoice: `invoiceXmlBase64`, the XML Base64-encoded, with `invoiceXmlEncoding` set to `base64`. For the UAE, also `tddXmlBase64`, the tax data document reported to the Federal Tax Authority, when it exists. `null` before the XML is produced. |
| `compliance` | object | UAE, Belgium and Germany only. See [Compliance](https://docs.complyance.io/api-reference/unify/documents/#compliance). |
| `validationResults` | object | `status` (`Valid`, `Invalid` or `Pending`) and `validationSteps`, the steps the document has passed so far |

Each validation step has a `name`, a `status` (`Valid`, `Invalid`, `Pending` or `null` for a step not reached) and an `error` with a `code` and `message`, or `null`. The steps are **Validation Passed** (or **Validation Failed**), **Queue Admitted**, **Delivery Processing Started**, then **Delivery Success**, **Delivery Failed**, **Final Valid** or **Final Invalid**.

## States

| `state` | What it means | `isTerminal` | In the Invoice Portal | What to do |
| - | - | - | - | - |
| `submitted` | The document passed validation and is waiting for delivery to start. | `false` | **Draft** or **Ready** | Check again later. |
| `processing` | Delivery has started, or the authority’s answer is awaited. | `false` | **Processing** | Check again later. |
| `delivery_success` | The document was delivered. The final result is still to come. | `false` | — | Check again later. |
| `delivery_failed` | A delivery attempt did not succeed. This is not the final result. | `false` | — | Read `errors`, and keep checking. Do not send the invoice again under a new number: that creates a second invoice. If the state does not change, email <support@complyance.io> with the `documentId`. |
| `final_valid` | The document was accepted as compliant. | `true` | **Compliant** | Record the outcome. |
| `final_invalid` | The tax authority or the network rejected the document, or it was cancelled or rejected by the buyer. | `true` | **Non-Compliant** | Read `errors` for the reason. Fix the data and send it as a new document with a new `documentNumber`. The same number is refused with `GETS-HEAD-010`. |
| `rejected` | The document failed validation and was stored as **Needs Correction**. | `true` | **Needs Correction** | Fix the fields in `errors`, then send the document again with the same `documentNumber`. See [Retries and duplicates](https://docs.complyance.io/api-reference/unify/submit-and-retrieve/#retries-and-duplicates). |

In Saudi Arabia, a `delivery_success` the authority reports as cleared or reported becomes `final_valid`, and a `delivery_failed` it rejected becomes `final_invalid`.

## How often to check

While `isTerminal` is `false`, wait before checking again, and make each wait longer than the last, for example by doubling it. Stop when `isTerminal` is `true`. Complyance does not send webhooks for sales documents, so this request is how you learn the outcome.

A successful sandbox result shows that the document passed in sandbox. It does not confirm a production registration or acceptance of a live invoice.

## The government object

`government` is the tax authority’s or the Peppol network’s own record of the document. Its fields differ by country and change as delivery moves on, so use it to show or log the authority’s answer, not to decide what to do next. Act on `state` and `isTerminal`.

| Country | What `government` holds |
| - | - |
| Saudi Arabia | ZATCA’s result, such as `CLEARED` for a cleared invoice or `REPORTED` for a reported one. |
| Malaysia | The MyInvois result. |
| UAE, Belgium and Germany | The Peppol delivery record. For the outcome in a fixed form, read `compliance.ftaApprovedStatus`. |

Once a final result is recorded, `government.status` can be `VALID` or `INVALID`.

## Compliance

For the UAE, Belgium and Germany, `compliance` gives the outcome in a fixed form:

| Field | Description |
| - | - |
| `ftaApprovedStatus` | `APPROVED` when `state` is `final_valid`, `REJECTED` when it is `final_invalid` or `rejected`, `PENDING` otherwise |
| `uuid` | The identifier in the e-invoice: its UUID when it has one, otherwise its number |
| `businessProcessIdentifier` | The e-invoice’s profile, such as `urn:peppol:bis:billing`, or `null` |
| `specificationIdentifier` | The specification the e-invoice follows, such as `urn:peppol:pint:billing-1@ae-1`, or `null` |

## Errors

| HTTP / code | Meaning | What to do |
| - | - | - |
| `401` | The key is missing or not valid | Check the `Authorization` header. See [authentication failures](https://docs.complyance.io/api-reference/authentication/#authentication-failures). |
| `404 NOT_FOUND` | No document with this identifier in your workspace | Check the `documentId` and use a key from the workspace that submitted it. |
| `422` | `type` is missing or is not `sales` or `purchases` | Add `type=sales`. The body lists the checks that failed in its own format. |
| `500 INTERNAL_ERROR` | The document could not be read | Check again after a short wait, then with longer waits. |

```json title="Document not found — HTTP 404"
{
  "success": false,
  "code": "NOT_FOUND",
  "message": "Document not found"
}
```

`/status` returns `Document status not found` as the message for the same `404`.

Source: https://docs.complyance.io/api-reference/unify/documents/
