# The HTTP API

uninvoice.app exposes an HTTP API so you can create entities (clients and suppliers), draft and issue invoices, download their PDFs, and read your company configuration from your own tools and integrations. The same API powers the web app.

This section covers authentication and the conventions shared by every endpoint. The full list of endpoints is in the **[Endpoint reference](https://docs.uninvoice.app/api/reference)**. If you drive the API from an AI agent, see the **[MCP server](https://docs.uninvoice.app/api/mcp)**, which exposes the same operations over the Model Context Protocol.

## Base URL

The API is versioned under `/v1`:

| Environment | Base URL                    |
| ----------- | --------------------------- |
| Production  | `https://api.uninvoice.app` |

Every path in the reference is relative to this base, for example `GET /v1/invoices`.

## Authentication

All API requests authenticate with a **Bearer token** in the `Authorization` header:

```
Authorization: Bearer <token> 
```

The token is an **API token**: a long-lived UUID that identifies a user acting within a company. API tokens do **not** expire; they stay valid until you delete them. Use one for anything running outside a browser: integrations, scripts, and MCP clients.

Requests with no token, an unknown token, or a deleted token receive `401 Unauthorized`.

### Creating an API token

Create and manage your API tokens from **[the Company section of your settings](https://app.uninvoice.app/company#api-keys)** in the web app. There you can issue a new token, give it a description, see the tokens already active, and revoke any you no longer need.

A token's value is shown **once**, at creation: copy it then and store it securely; treat it like a password. It looks like `3f2b1c9a-...-a1b2c3d4e5f6`; send it as the Bearer credential on every request.

A token is scoped to **one user within one company**. Every call it makes acts as that user in that company; there is no way to switch company on an API token.

### Acting as a human or as an AI

By default an API token is treated as an **AI**: its mutating requests (creating or issuing an invoice, deleting a proforma, …) don't run immediately: they are held for a person to approve through **[AI Audit](https://docs.uninvoice.app/api/ai-audit)**, and the API replies `202 pending_approval`.

When you create a **standard** token you also receive a one-time **human proof** secret (`humanProof`). Presenting it in the `X-Human-Proof` header asserts that a human is driving the request, so it **runs immediately and is not audited**. Use it for automations a person genuinely supervises. A token created for an **MCP client** is AI-driven and gets no human proof, so it is always gated. See **[AI Audit](https://docs.uninvoice.app/api/ai-audit)** for the full flow.

## Conventions every endpoint follows

These conventions apply across all endpoints.

### JSON

Requests and responses are JSON. Field names use `snake_case` (e.g. `recipient_id`, `unit_price`), except for a small number of metadata fields that are explicitly camelCased (e.g. `createdAt`).

### Money

Monetary amounts are **integers in the currency's minor unit (cents)**, never floats. `unit_price`, `subtotal`, `tax_amount`, and invoice `total` are all in cents. For example, `€1,250.00` is `125000`. Currencies are ISO 4217 codes (`currency_code`, e.g. `EUR`).

### Dates and times

Timestamps are RFC 3339 / ISO 8601 in UTC (e.g. `2026-07-03T10:00:00Z`).

### Errors

Errors use standard HTTP status codes. Most carry a plain-text message body:

| Status                      | Meaning                                                                            |
| --------------------------- | ---------------------------------------------------------------------------------- |
| `400 Bad Request`           | The request is malformed or fails a business rule. The body describes what to fix. |
| `401 Unauthorized`          | Missing, invalid, or revoked token.                                                |
| `403 Forbidden`             | Authenticated, but not allowed to perform this action.                             |
| `404 Not Found`             | The resource does not exist, or is not visible to your company.                    |
| `500 Internal Server Error` | Unexpected server error.                                                           |

Some `403` responses that require a specific follow-up action return a **JSON body** with a machine-readable `error` code and a human `message`, for example:

```
{  
    "error" :   "verifactu_authorization_required" ,  
    "message" :   "You must authorize uninvoice.app to report on your behalf before issuing invoices." ,  
    "requiresAuthorizationUrl" :   "/verifactu/authorization"  
  } 
```

Codes you may encounter: `company_not_settled` (finish company onboarding first), `agreement_required` (accept the current legal terms first), `verifactu_authorization_required` (give uninvoice.app your [Veri\*Factu authorization](https://docs.uninvoice.app/verifactu/authorize) first).

## What a token can and cannot do

An API token can read and write the resources of its company: entities, invoices, proformas, taxes, company configuration, and the Veri\*Factu authorization status.

Continue to the **[Endpoint reference](https://docs.uninvoice.app/api/reference)**.
