---
title: "Create invoice header and line items"
method: POST
path: "/invoices"
tags: ["invoices"]
---

# Create invoice header and line items

`POST /invoices`

Creates an invoice along with its line items. The invoice header and items are created in separate transactions.

### Features
- Create invoice header fields (date, amount, vendor, notes, etc.)
- Create new line items.
- Attach custom metadata fields to invoice header and line items (requires account-level custom field spec configuration).

### Use Cases
- Programmatic invoice creation from external systems.

## Headers

- `Authorization` string, required
- `X-Api-Key` string, required
- `X-API-Version` string
- `Idempotency-Key` string

## Request body

- object
  - `upload_id` string, required — A mandatory unique identifier for creating an invoice.
  - `ottimate_location_id` integer, required — The ID of the location for this invoice.
  - `erp_vendor_id` string — The ERP ID of the vendor for this invoice.
  - `invoice_number` string
  - `invoice_date` string, date
  - `due_date` string, date
  - `posting_date` string, date
  - `total_amount` number, double
  - `total_tax` number, double
  - `purchase_order` string
  - `notes` string
  - `currency` string
  - `type` 'invoice' | 'credit_memo' — Type of document.
  - `dimensions` InvoicesPostRequestBodyContentApplicationJsonSchemaDimensions — Header-level dimension mappings. Keys are dimension types (e.g., 'DEPARTMENT', 'CLASS') and values are `erp_dimension_id` strings from the `GET /dimensions` endpoint. If omitted, no dimensions are set. Invalid dimension types or IDs return a `400` error.
  - `custom_fields` InvoicesPostRequestBodyContentApplicationJsonSchemaCustomFields — Header-level custom metadata fields for this invoice. Keys and value types are validated against the custom field spec configured for your account in Ottimate. **Requirements**: Custom fields must be configured for your account before use. Sending `custom_fields` when no spec is configured returns a `400` error. Unrecognised keys return a `400` error. **Behaviour**: Omitted keys are filled with their configured default values
  - `items` InvoicesPostRequestBodyContentApplicationJsonSchemaItemsItems[] — Line items to create for the invoice.
    - `name` string, required
    - `sku` string
    - `quantity` number, double, required
    - `price` number, double, required
    - `is_taxed` boolean
    - `dimensions` InvoicesPostRequestBodyContentApplicationJsonSchemaItemsItemsDimensions — Item-level dimension mappings. Same format as header-level dimensions: keys are dimension types and values are `erp_dimension_id` strings. If omitted, no item-level dimensions are set.
    - `custom_fields` InvoicesPostRequestBodyContentApplicationJsonSchemaItemsItemsCustomFields — Item-level custom metadata fields. Keys and value types are validated against the invoice item custom field spec configured for your account in Ottimate. **Requirements**: Invoice item custom fields must be configured for your account before use. Returns a `400` error if no spec is found or if unrecognised keys are sent. **Behaviour**: Omitted keys are filled with their configured default values.
  - `image_urls` string[] — List of HTTPS image URLs to download and attach to the invoice. Supported formats: PDF, JPG, JPEG, PNG.
  - `raw_images` InvoicesPostRequestBodyContentApplicationJsonSchemaRawImagesItems[] — List of base64-encoded images to attach to the invoice. Supported formats: PDF, JPG, JPEG, PNG.
    - `filename` string, required — Original filename including extension (e.g. invoice.png). Used to determine file format.
    - `data` string, required — Base64-encoded image content.
  - `status` 'archived' | 'verified' — Optional. Only needed when ingesting invoices that are already fully processed elsewhere (e.g. historical backfills or invoices already coded/posted in your ERP) and should skip Ottimate's normal approval workflow. Omit for standard invoice ingestion. `archived` creates the invoice already approved, exported, and filed as a historical/inactive record (with relaxed dimension/GL validation appropriate for backfilled data). `verified` creates the invoice already approved and exported, but keeps it as a normal active invoice. Note: this is a write-only request field, distinct from the `status` field returned in the response.

## Response `200`

Invoice created successfully. Check if 'errors' are present in the response to identify any issues during creation. For 'items' creation errors, the invoice will be created but items may be missing or incomplete. Refer to 'items' for details.

- InvoicesPostInvoicesRootResponse200
  - `version` string — The API version of the response.
  - `id` string — The ID of the created invoice.
  - `status` string — The status of the created invoice (e.g., 'incomplete', 'processing').
  - `conflicting_invoice_id` string — The ID of a conflicting invoice, if one was detected.
  - `items` InvoicesPostResponsesContentApplicationJsonSchemaItems — The status of the line item ingestion process.
    - `success` InvoicesPostResponsesContentApplicationJsonSchemaItemsSuccess — An object mapping original item indexes to newly created item IDs for successful items.
    - `failure` InvoicesPostResponsesContentApplicationJsonSchemaItemsFailure — An object mapping original item indexes to error messages for failed items.
    - `status` string — The overall status of the item ingestion ('success', 'partial_success', 'failure').
  - `errors` string[] — A list of validation errors or warnings related to the invoice creation.
  - `images` InvoicesPostResponsesContentApplicationJsonSchemaImagesItems[] — Attached invoice images. Only present if image_urls or raw_images were provided.
    - `id` integer
    - `url` string, uri
  - `image_errors` InvoicesPostResponsesContentApplicationJsonSchemaImageErrorsItems[] — Errors from individual image uploads. The invoice is still created even if images fail.
    - `source` string
    - `error` string

## Other responses

- `400` — Bad request - Invalid parameters or request format
- `403` — Forbidden - Access denied or insufficient permissions
- `500` — Internal server error - Server-side processing error

---

[API](https://skmtc.dev/ottimate/apis/api-reference.md) · [All operations](https://skmtc.dev/ottimate/apis/api-reference/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/ottimate/api-reference/revisions/ba91ff4c6969/schema)
