# Create a draft invoice

> The invoices.create operation: POST /api/v1/invoices in the REST API and the invoices_create tool in the MCP server.

Creates a draft invoice for a customer of the brand, outside any subscription: setup fees, consulting,
enterprise contracts billed by bank transfer (spec §16.15). A draft has no number yet: edit it, add or remove
items (`invoice_items.create`, `invoice_items.delete`), then finalize it (`invoices.finalize`: number, tax
quoted at that moment, PDF) and send it (`invoices.send`).

- **Items:** each an active one-time price (`priceId`), or a product with a `unitAmount` (`productId`), with a
  `quantity`. Amounts are integer micros in whole minor units; every item is in the invoice's currency.
  `includePendingItems` also bills the customer's pending invoice items in that currency.
- **Collection:** `send_invoice` (default) emails the invoice with a due date, `daysUntilDue` after the issue
  date (default 14) or a fixed `dueDate`, and the entity's bank transfer details. `charge_automatically` charges
  the customer's default payment method.

Tax isn't computed on a draft: `draft.subtotal` is before tax.

**Business customers without a valid VAT ID** are taxed as consumers: only a `valid` tax ID makes the sale
business-to-business. In the EU a consumer's country needs two pieces of location evidence that agree, so a
customer created through the API with only its billing address (one evidence item) can't be invoiced:
`invoices.finalize` refuses with `evidence_conflict`. Add its VAT ID first (`customers.tax_ids.add`; once the
register confirms it, the billing address is enough), or finalize after the customer bought once through a
hosted checkout, whose IP address and card country are stored as evidence.

## At a glance

- **REST:** `POST /api/v1/invoices`
- **MCP tool:** `invoices_create`
- **Operation ID:** `invoices.create`
- **Scope:** Brand
- **Permission:** `invoices:write`
- **Risk tier:** `write`
- **Dry run:** Supported (send `Ownrecord-Dry-Run: true`)
- **Idempotency:** `Idempotency-Key` required
- **Modes:** Test and live
- **Authentication:** API key with the `invoices:write` scope
- **Since:** M5

## Request

### Body

A JSON object (`Content-Type: application/json`):

| Field                         | Type                                          | Required | Description                                                                                                                                                                      |
| ----------------------------- | --------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `customerId`                  | `cus_…` ID                                    | Yes      | The customer (`cus_…`).                                                                                                                                                          |
| `collectionMethod`            | one of `charge_automatically`, `send_invoice` | No       | `send_invoice`: emailed with a due date and bank transfer details, paid by bank transfer (spec §16.9). `charge_automatically`: the customer's default payment method is charged. |
| `daysUntilDue`                | integer (0 to 365)                            | No       | send_invoice: days from the issue date to the due date, 0 to 365 (default 14).                                                                                                   |
| `dueDate`                     | string                                        | No       | send_invoice: a fixed due date instead of `daysUntilDue`.                                                                                                                        |
| `currency`                    | string                                        | No       | The invoice's currency. Required without `items`; with items it must be theirs.                                                                                                  |
| `items`                       | array of object                               | No       | The invoice's items, 0 to 100 (add more later with `invoice_items.create`).                                                                                                      |
| `items[].priceId`             | `price_…` ID                                  | No       | An active one-time price with a fixed amount: its product, amount, currency and tax behavior.                                                                                    |
| `items[].productId`           | `prod_…` ID                                   | No       | Instead of a price: the product (its tax category and revenue account), with `unitAmount`.                                                                                       |
| `items[].unitAmount`          | object                                        | No       | With `productId`: the price of one unit.                                                                                                                                         |
| `items[].unitAmount.amount`   | string                                        | Yes      | Integer micros as a string (12500000 = 12.50), in whole minor units of the currency.                                                                                             |
| `items[].unitAmount.currency` | string                                        | Yes      | ISO 4217 currency code.                                                                                                                                                          |
| `items[].taxBehavior`         | one of `exclusive`, `inclusive`               | No       | With `productId`: whether `unitAmount` includes tax (default `exclusive`).                                                                                                       |
| `items[].quantity`            | integer (1 to 1000000)                        | No       | Whole units, 1 to 1000000 (default 1).                                                                                                                                           |
| `items[].description`         | string                                        | No       | The line's text on the invoice (default: the product's name, and the price's nickname).                                                                                          |
| `includePendingItems`         | boolean                                       | No       | Also bill the customer's pending invoice items in this currency (not a subscription's).                                                                                          |
| `metadata`                    | object                                        | No       | Your own key-value pairs (at most 50 keys, values of at most 500 characters).                                                                                                    |

## Response

`201 Created` with a JSON object:

| Field                             | Type                                                                                                   | Description                                                                                                                                                                                                                                                         |
| --------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                              | `inv_…` ID                                                                                             |                                                                                                                                                                                                                                                                     |
| `object`                          | `"invoice"`                                                                                            |                                                                                                                                                                                                                                                                     |
| `livemode`                        | boolean                                                                                                |                                                                                                                                                                                                                                                                     |
| `entityId`                        | `ent_…` ID                                                                                             |                                                                                                                                                                                                                                                                     |
| `brandId`                         | `brd_…` ID                                                                                             |                                                                                                                                                                                                                                                                     |
| `number`                          | string or null                                                                                         | The invoice number: gap-free per legal entity, mode, brand series and year (§18.2). Null for a draft: the number is taken at finalization.                                                                                                                          |
| `numbering`                       | object or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `customerId`                      | `cus_…` ID or null                                                                                     |                                                                                                                                                                                                                                                                     |
| `subscriptionId`                  | `sub_…` ID or null                                                                                     |                                                                                                                                                                                                                                                                     |
| `collectionMethod`                | one of `charge_automatically`, `send_invoice`                                                          |                                                                                                                                                                                                                                                                     |
| `kind`                            | one of `invoice`, `receipt` or null                                                                    | `invoice` (business customers) or `receipt` (the receipt-invoice consumers get); null for a draft.                                                                                                                                                                  |
| `status`                          | one of 9 values, e.g. `draft`, `pending_registration`, `issued` (all in the OpenAPI document)          | `draft` → `open` (finalized) → `paid`, `void` or `uncollectible`. Checkout invoices are `issued` (paid at once), or `pending_registration`: a full invoice charged before the tax registration exists; the receipt went out and the formal invoice follows (§18.1). |
| `language`                        | one of `en`, `de`, `fr`, `hr`, `it`, `es` or null                                                      |                                                                                                                                                                                                                                                                     |
| `issuedAt`                        | date-time or null                                                                                      |                                                                                                                                                                                                                                                                     |
| `issueDate`                       | string or null                                                                                         | The issue date in the seller's time zone.                                                                                                                                                                                                                           |
| `taxPoint`                        | date-time or null                                                                                      |                                                                                                                                                                                                                                                                     |
| `taxPointDate`                    | string or null                                                                                         | The date of supply in the seller's time zone.                                                                                                                                                                                                                       |
| `daysUntilDue`                    | integer or null                                                                                        | send_invoice: days from the issue date to the due date.                                                                                                                                                                                                             |
| `dueDate`                         | string or null                                                                                         | send_invoice: when payment is due (fixed at finalization).                                                                                                                                                                                                          |
| `seller`                          | object or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `buyer`                           | object or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `currency`                        | string                                                                                                 |                                                                                                                                                                                                                                                                     |
| `lines`                           | array of object                                                                                        |                                                                                                                                                                                                                                                                     |
| `lines[].id`                      | string                                                                                                 | The tax quote's line ID.                                                                                                                                                                                                                                            |
| `lines[].description`             | string                                                                                                 |                                                                                                                                                                                                                                                                     |
| `lines[].productId`               | `prod_…` ID or null                                                                                    |                                                                                                                                                                                                                                                                     |
| `lines[].priceId`                 | `price_…` ID or null                                                                                   |                                                                                                                                                                                                                                                                     |
| `lines[].quantity`                | integer                                                                                                |                                                                                                                                                                                                                                                                     |
| `lines[].taxCategoryId`           | one of 9 values, e.g. `electronically_supplied_service`, `saas`, `ebook` (all in the OpenAPI document) |                                                                                                                                                                                                                                                                     |
| `lines[].taxBehavior`             | one of `inclusive`, `exclusive`                                                                        |                                                                                                                                                                                                                                                                     |
| `lines[].unitAmount`              | money                                                                                                  | The net price of one unit (may be finer than the minor unit).                                                                                                                                                                                                       |
| `lines[].net`                     | money                                                                                                  |                                                                                                                                                                                                                                                                     |
| `lines[].tax`                     | object                                                                                                 |                                                                                                                                                                                                                                                                     |
| `lines[].tax.ratePpm`             | string                                                                                                 | Parts per million as a string (19% = "190000").                                                                                                                                                                                                                     |
| `lines[].tax.amount`              | money                                                                                                  |                                                                                                                                                                                                                                                                     |
| `lines[].tax.jurisdictionId`      | string or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `lines[].tax.regimeId`            | string or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `lines[].tax.decision`            | one of `charge`, `reverse_charge`, `exempt`, `not_taxable`, `out_of_scope`, `not_collected`, `blocked` | What happened to the tax: `charge`, `reverse_charge`, `exempt`, `not_taxable`, `out_of_scope`, `not_collected`.                                                                                                                                                     |
| `lines[].tax.rateKind`            | one of `standard`, `reduced`, `super_reduced`, `parking`, `zero`, `exempt`, `not_taxable` or null      |                                                                                                                                                                                                                                                                     |
| `lines[].tax.rateId`              | string or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `lines[].tax.pendingRegistration` | boolean                                                                                                |                                                                                                                                                                                                                                                                     |
| `lines[].gross`                   | money                                                                                                  |                                                                                                                                                                                                                                                                     |
| `lines[].kind`                    | one of `licensed`, `metered`, `late_usage`, `proration`, `invoice_item` or null                        | Where the line came from (§16.3 order); null on checkout invoices.                                                                                                                                                                                                  |
| `lines[].period`                  | object or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `lines[].subscriptionItemId`      | string or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `lines[].invoiceItemId`           | `ii_…` ID or null                                                                                      |                                                                                                                                                                                                                                                                     |
| `lines[].discount`                | money or null                                                                                          | What discounts took off the line before tax.                                                                                                                                                                                                                        |
| `lines[].meteredQuantity`         | string or null                                                                                         | A metered line's usage (its quantity is 1).                                                                                                                                                                                                                         |
| `totals`                          | object or null                                                                                         |                                                                                                                                                                                                                                                                     |
| `taxCurrencyTotals`               | object or null                                                                                         | The tax in the seller's tax currency when the invoice is in another one (§18.3).                                                                                                                                                                                    |
| `creditApplied`                   | money or null                                                                                          | Taken from the customer's credit balance at finalization (§16.11).                                                                                                                                                                                                  |
| `amountDue`                       | money or null                                                                                          | What the customer pays: the gross total less the credit applied. Null on checkout invoices.                                                                                                                                                                         |
| `notes`                           | array of object                                                                                        |                                                                                                                                                                                                                                                                     |
| `notes[].code`                    | one of `reverse_charge`, `exempt`, `out_of_scope`, `registration_pending`, `oss_scheme`                |                                                                                                                                                                                                                                                                     |
| `notes[].text`                    | string                                                                                                 | The note as printed.                                                                                                                                                                                                                                                |
| `fieldCheck`                      | object or null                                                                                         | What the knowledge base's invoicing rules ask for that the invoice lacks (`missing`), and requirements Ownrecord can't check yet (`unchecked`).                                                                                                                     |
| `pendingRegistration`             | boolean                                                                                                | A full invoice with a line charged before the registration exists (§18.1).                                                                                                                                                                                          |
| `paymentIds`                      | array of `pay_…` ID                                                                                    |                                                                                                                                                                                                                                                                     |
| `creditNoteIds`                   | array of `cn_…` ID                                                                                     |                                                                                                                                                                                                                                                                     |
| `ledgerTxnIds`                    | array of `txn_…` ID                                                                                    |                                                                                                                                                                                                                                                                     |
| `quoteId`                         | `tq_…` ID or null                                                                                      | The tax quote the invoice shows (null for a draft).                                                                                                                                                                                                                 |
| `quoteIds`                        | array of `tq_…` ID                                                                                     | Every quote of the invoice: lines taxed at another date (prorations) have their own quote.                                                                                                                                                                          |
| `pdf`                             | object or null                                                                                         | Null for a draft: the PDF is rendered at finalization.                                                                                                                                                                                                              |
| `finalizedAt`                     | date-time or null                                                                                      |                                                                                                                                                                                                                                                                     |
| `paidAt`                          | date-time or null                                                                                      |                                                                                                                                                                                                                                                                     |
| `payment`                         | object or null                                                                                         | How the invoice was paid: `bank_transfer` (marked paid), `processor` (a card or debit payment) or `credit_balance`.                                                                                                                                                 |
| `voidedAt`                        | date-time or null                                                                                      |                                                                                                                                                                                                                                                                     |
| `markedUncollectibleAt`           | date-time or null                                                                                      |                                                                                                                                                                                                                                                                     |
| `emailedAt`                       | date-time or null                                                                                      |                                                                                                                                                                                                                                                                     |
| `sentAt`                          | date-time or null                                                                                      | When `invoices.send` last emailed the invoice.                                                                                                                                                                                                                      |
| `draft`                           | object or null                                                                                         | A draft's lines before tax (tax is quoted at finalization); null once finalized.                                                                                                                                                                                    |
| `metadata`                        | object                                                                                                 |                                                                                                                                                                                                                                                                     |
| `version`                         | integer                                                                                                | Pass it as `expectedVersion` to refuse a change if the invoice changed. Rendering the PDF and emailing the invoice change it too.                                                                                                                                   |
| `createdAt`                       | date-time                                                                                              |                                                                                                                                                                                                                                                                     |
| `updatedAt`                       | date-time                                                                                              |                                                                                                                                                                                                                                                                     |

## Examples

### Two consulting days for a business customer, sent for payment

```http
POST /api/v1/invoices
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json

{
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf47ym",
  "items": [
    {
      "productId": "prod_01m4tx5nj8emwbyf7y9vcf47yr",
      "unitAmount": {
        "amount": "600000000",
        "currency": "EUR"
      },
      "quantity": 2,
      "description": "Implementation workshop (days)"
    }
  ],
  "metadata": {
    "contract": "ENT-2026-07"
  }
}
```

Response (`201`):

```json
{
  "id": "inv_01m4tx5nj8emwbyf7y9vcf47yk",
  "object": "invoice",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "number": null,
  "numbering": null,
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf47ym",
  "subscriptionId": null,
  "collectionMethod": "send_invoice",
  "kind": null,
  "status": "draft",
  "language": null,
  "issuedAt": null,
  "issueDate": null,
  "taxPoint": null,
  "taxPointDate": null,
  "daysUntilDue": 14,
  "dueDate": null,
  "seller": null,
  "buyer": null,
  "currency": "EUR",
  "lines": [],
  "totals": null,
  "taxCurrencyTotals": null,
  "creditApplied": null,
  "amountDue": null,
  "notes": [],
  "fieldCheck": null,
  "pendingRegistration": false,
  "paymentIds": [],
  "creditNoteIds": [],
  "ledgerTxnIds": [],
  "quoteId": null,
  "quoteIds": [],
  "pdf": null,
  "finalizedAt": null,
  "paidAt": null,
  "payment": null,
  "voidedAt": null,
  "markedUncollectibleAt": null,
  "emailedAt": null,
  "sentAt": null,
  "draft": {
    "lines": [
      {
        "kind": "invoice_item",
        "description": "Implementation workshop (days)",
        "quantity": "2",
        "amount": {
          "amount": "1200000000",
          "currency": "EUR"
        },
        "discount": {
          "amount": "0",
          "currency": "EUR"
        },
        "subtotal": {
          "amount": "1200000000",
          "currency": "EUR"
        },
        "taxBehavior": "exclusive",
        "taxCategoryId": "consulting_remote",
        "productId": "prod_01m4tx5nj8emwbyf7y9vcf47yr",
        "priceId": null,
        "invoiceItemId": "ii_01m4tx5nj8emwbyf7y9vcf47ys",
        "period": null
      }
    ],
    "subtotal": {
      "amount": "1200000000",
      "currency": "EUR"
    }
  },
  "metadata": {
    "contract": "ENT-2026-07"
  },
  "version": 1,
  "createdAt": "2026-10-20T08:30:00.000Z",
  "updatedAt": "2026-10-20T08:30:00.000Z"
}
```

### An empty draft, items added later

```http
POST /api/v1/invoices
Authorization: Bearer or_test_…
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json

{
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf47ym",
  "currency": "EUR",
  "daysUntilDue": 30
}
```

Response (`201`):

```json
{
  "id": "inv_01m4tx5nj8emwbyf7y9vcf47yk",
  "object": "invoice",
  "livemode": false,
  "entityId": "ent_01m4tx5nj8emwbyf7y9vcf47x2",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "number": null,
  "numbering": null,
  "customerId": "cus_01m4tx5nj8emwbyf7y9vcf47ym",
  "subscriptionId": null,
  "collectionMethod": "send_invoice",
  "kind": null,
  "status": "draft",
  "language": null,
  "issuedAt": null,
  "issueDate": null,
  "taxPoint": null,
  "taxPointDate": null,
  "daysUntilDue": 30,
  "dueDate": null,
  "seller": null,
  "buyer": null,
  "currency": "EUR",
  "lines": [],
  "totals": null,
  "taxCurrencyTotals": null,
  "creditApplied": null,
  "amountDue": null,
  "notes": [],
  "fieldCheck": null,
  "pendingRegistration": false,
  "paymentIds": [],
  "creditNoteIds": [],
  "ledgerTxnIds": [],
  "quoteId": null,
  "quoteIds": [],
  "pdf": null,
  "finalizedAt": null,
  "paidAt": null,
  "payment": null,
  "voidedAt": null,
  "markedUncollectibleAt": null,
  "emailedAt": null,
  "sentAt": null,
  "draft": {
    "lines": [],
    "subtotal": {
      "amount": "0",
      "currency": "EUR"
    }
  },
  "metadata": {},
  "version": 1,
  "createdAt": "2026-10-20T08:30:00.000Z",
  "updatedAt": "2026-10-20T08:30:00.000Z"
}
```

## Errors

| Code                                                                                                       | HTTP status | When                                                                                                                                                                                                                  | What to do                                                                                                                                                                                 |
| ---------------------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`validation_failed`](https://ownrecord.io/docs/reference/errors.md#validation_failed)                     | 400         | A field is missing or malformed: both `daysUntilDue` and `dueDate`, no currency without items, an item with both or neither of `priceId` and `productId`, an archived product, amounts that aren't whole minor units. | Fix the fields listed in `details.issues` and send the request again.                                                                                                                      |
| [`resource_not_found`](https://ownrecord.io/docs/reference/errors.md#resource_not_found)                   | 404         | The customer, a price or a product isn't this brand's in this mode (`param` names it).                                                                                                                                | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode.                                                                                       |
| [`customer_deleted`](https://ownrecord.io/docs/reference/errors.md#customer_deleted)                       | 400         | The customer was deleted.                                                                                                                                                                                             | Create a new customer for this buyer. Deleted customers stay readable for the records they belong to, but can't be changed.                                                                |
| [`invoice_item_price_unusable`](https://ownrecord.io/docs/reference/errors.md#invoice_item_price_unusable) | 400         | A price is archived, recurring, a credit pack or a custom amount (use a product with `unitAmount`).                                                                                                                   | Use an active one-time price with a fixed amount, or give the product (`productId`) and a `unitAmount` instead. Recurring prices are billed by subscriptions and credit packs by checkout. |
| [`invoice_currency_mismatch`](https://ownrecord.io/docs/reference/errors.md#invoice_currency_mismatch)     | 400         | An item's currency isn't the invoice's.                                                                                                                                                                               | Every item of an invoice is in the invoice's currency (`details.invoice_currency`). Create a separate draft for the other currency.                                                        |
| [`idempotency_key_reused`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_reused)           | 409         | The idempotency key was used before for another request.                                                                                                                                                              | Use a new Idempotency-Key for a different request, or resend the original request unchanged.                                                                                               |
| [`scope_required`](https://ownrecord.io/docs/reference/errors.md#scope_required)                           | 400         | The request names no brand (an org or entity key without `Ownrecord-Brand`).                                                                                                                                          | Call the operation with credentials or a target at its level: an organization, a legal entity, a brand or the platform (`details.required_scope`).                                         |
| [`permission_denied`](https://ownrecord.io/docs/reference/errors.md#permission_denied)                     | 403         | You can't change this brand's invoices (`invoices:write`: finance, owners and admins).                                                                                                                                | Ask an organization owner or admin for a role or scope that allows this action.                                                                                                            |
| [`livemode_not_allowed`](https://ownrecord.io/docs/reference/errors.md#livemode_not_allowed)               | 403         | You have no live-mode access, so you can't use live invoices.                                                                                                                                                         | Use test mode, or credentials for the target's mode. Developers need live access granted by an organization owner or admin.                                                                |

It can also return these [common errors](https://ownrecord.io/docs/reference.md#common-errors): [`api_version_unsupported`](https://ownrecord.io/docs/reference/errors.md#api_version_unsupported), [`invalid_json`](https://ownrecord.io/docs/reference/errors.md#invalid_json), [`unsupported_media_type`](https://ownrecord.io/docs/reference/errors.md#unsupported_media_type), [`authentication_required`](https://ownrecord.io/docs/reference/errors.md#authentication_required), [`api_key_invalid`](https://ownrecord.io/docs/reference/errors.md#api_key_invalid), [`idempotency_key_required`](https://ownrecord.io/docs/reference/errors.md#idempotency_key_required), [`idempotency_in_progress`](https://ownrecord.io/docs/reference/errors.md#idempotency_in_progress), [`approval_required`](https://ownrecord.io/docs/reference/errors.md#approval_required), [`approval_rejected`](https://ownrecord.io/docs/reference/errors.md#approval_rejected), [`approval_expired`](https://ownrecord.io/docs/reference/errors.md#approval_expired), [`stale_approval`](https://ownrecord.io/docs/reference/errors.md#stale_approval), [`approval_policy_denied`](https://ownrecord.io/docs/reference/errors.md#approval_policy_denied), [`rate_limited`](https://ownrecord.io/docs/reference/errors.md#rate_limited), [`internal_error`](https://ownrecord.io/docs/reference/errors.md#internal_error).
