> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fleetit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Driver Billing Overview

> How billing plans, driver invoices, and credit notes fit together.

Driver billing turns a driver's tolls (and other chargeable events) into
invoices, then lets you finalize, collect, adjust, and credit them. Three
resources are involved:

* **Billing Plans** — the rate rules (`charges`) applied to an agreement's
  tickets.
* **Driver Invoices** — a billed statement for an agreement over a period.
* **Credit Notes** — a credit issued against a finalized invoice.

## Routing & scope

All endpoints live under `/v2/` and are scoped to the authenticated user's
fleet. Routes derive the fleet from the authenticated user; you cannot request
another fleet's data.

## Conventions

* **Money / quantities** are decimal *strings* (`"12.50"`), not floats.
* **Timestamps** are ISO-8601 (`2026-05-16T14:03:00Z`); dates are `YYYY-MM-DD`.
* **IDs** are integers.
* **Pagination** is limit/offset (`limit`, `offset`); list responses are wrapped
  in `{ "count", "next", "previous", "results" }`.
* **Errors** use the DRF format: field errors `{"field": ["message"]}`, general
  errors `{"detail": "message"}`.

## Invoice lifecycle

Every invoice starts as a `DRAFT` and moves to one of two terminal statuses:

| Status      | Meaning                                                                                     |
| ----------- | ------------------------------------------------------------------------------------------- |
| `DRAFT`     | Working state. `draft_total` holds the running total; `total` is `null`. Fees are editable. |
| `FINALIZED` | Locked and immutable. `total` is set; PDF generation is triggered. Terminal.                |
| `VOID`      | Cancelled. Terminal.                                                                        |

`FINALIZED` and `VOID` are terminal. (Voiding a `FINALIZED` invoice is planned
but not yet implemented — today only `DRAFT` invoices are voided.)

### How invoices are created

The `trigger` records why an invoice was created. Every type starts as a
`DRAFT`.

| Trigger           | Created when                                                                                                                                                                                 |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MANUAL`          | You call `generate` for an agreement. It captures the agreement's not-yet-invoiced tolls at that moment; it does **not** pick up tolls that arrive afterward.                                |
| `PROGRESSIVE`     | Automatically, off the plan's `progressive_billing_threshold`. Each incoming toll compares the agreement's running total against the threshold; crossing it generates a progressive invoice. |
| `AGREEMENT_ENDED` | Automatically, when an agreement ends.                                                                                                                                                       |
| `LATE_TICKET`     | After an `AGREEMENT_ENDED` invoice is finalized, tolls that arrive later accumulate onto a late-ticket invoice.                                                                              |

### DRAFT stage

While `DRAFT`:

* **Fees are editable** via [adjust fee](/api-reference/driver-invoices/adjust-fee).
  Tickets are not directly editable.
* **Refresh** ([refresh](/api-reference/driver-invoices/refresh)) recalculates
  fees and pulls in any unbilled tickets. It is called before finalizing.
* For `AGREEMENT_ENDED` invoices only, tickets that arrive while the invoice is
  in `DRAFT` are swallowed into it automatically.

### Finalization

* **Automatic** finalization waits for the plan's grace period to end.
* You can **finalize manually at any time** as an override, before the grace
  period ends.

Finalizing locks the invoice (immutable), sets `total`, and triggers PDF
generation.

### Payment status

`payment_status` (`PENDING`, `SUCCEEDED`, `FAILED`) is set manually via the
[payment status](/api-reference/driver-invoices/payment-status) endpoint — there
is no payment integration. `is_overdue` is a marker only; being overdue has no
automatic consequence.

### Plan snapshot

On creation, the invoice freezes a copy of the plan and its charges in
`plan_snapshot`. Fees are computed from this snapshot, not the live plan, so
later plan edits don't change an existing invoice. Fee adjustments reference a
charge by its 0-based `charge_snapshot_index` into `plan_snapshot.charges`.

## Credit notes

A credit note credits a **finalized** invoice. The total must be greater than 0
and no more than the invoice balance (`total − credited_amount`). Create one via
the invoice sub-route (`POST /driver-invoices/{id}/credit-notes/`); the resource
itself supports read, `void`, and `download`.

## Documents (PDF)

Invoice and credit-note PDFs are generated **asynchronously**. Poll the
`download` action:

| `pdf_status`              | HTTP  | Body                                    | Action                           |
| ------------------------- | ----- | --------------------------------------- | -------------------------------- |
| `null` (never requested)  | `202` | `{"detail": "PDF is being generated."}` | Enqueues generation. Poll again. |
| `PENDING` / `IN_PROGRESS` | `202` | `{"detail": "PDF is being generated."}` | Poll again.                      |
| `COMPLETE`                | `200` | `{"url": "https://…"}`                  | Fetch the file at `url`.         |

The `download` action is the safe entry point because it triggers generation on
the first call. Once `pdf_status` is `COMPLETE`, the `pdf_file` field on the
object holds the same (time-limited) URL.

## CSV export

`GET /driver-invoices/export/?channel=email` emails a CSV export (invoices,
fees, tickets) in the background. `channel` must be `email`. All current list
filters are honored, so the export mirrors the list query. It returns `200`
immediately; the files are emailed, not returned in the response.
