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

# Create and send invoices to your customers

> Build itemized invoices with line items, taxes, and discounts, then send them to customers by email and track payment status through to settled.

Dubu Pay's invoicing API lets you create professional invoices, attach line items, and deliver them to customers directly by email. Invoices go through a clear status lifecycle — from `draft` through to `paid` — and payments can be collected via virtual bank accounts or checkout links. This guide covers the full flow from creation to delivery.

## Invoice statuses

| Status     | Meaning                                  |
| ---------- | ---------------------------------------- |
| `draft`    | Created but not yet sent to the customer |
| `pending`  | Sent; awaiting payment                   |
| `paid`     | Payment confirmed                        |
| `overdue`  | Past the due date with no payment        |
| `canceled` | Voided; no longer payable                |

## Create an invoice

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.dubupay.com/api/v1/invoices \
    -H "X-Api-Key: dubu_sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Web Design Services — November 2024",
      "customer_name": "Amara Okafor",
      "customer_email": "amara@example.com",
      "currency": "NGN",
      "issue_date": "2024-11-01",
      "due_date": "2024-11-15",
      "notes": "Payment is due within 14 days. Bank transfer only.",
      "line_items": [
        {
          "description": "Homepage design",
          "quantity": 1,
          "unit_price": 150000,
          "tax_type": "percentage",
          "tax_rate": 7.5
        },
        {
          "description": "Mobile responsive layout",
          "quantity": 1,
          "unit_price": 75000
        }
      ]
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://api.dubupay.com/api/v1/invoices", {
    method: "POST",
    headers: {
      "X-Api-Key": "dubu_sk_live_your_api_key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      title: "Web Design Services — November 2024",
      customer_name: "Amara Okafor",
      customer_email: "amara@example.com",
      currency: "NGN",
      issue_date: "2024-11-01",
      due_date: "2024-11-15",
      notes: "Payment is due within 14 days. Bank transfer only.",
      line_items: [
        {
          description: "Homepage design",
          quantity: 1,
          unit_price: 150000,
          tax_type: "percentage",
          tax_rate: 7.5,
        },
        {
          description: "Mobile responsive layout",
          quantity: 1,
          unit_price: 75000,
        },
      ],
    }),
  });
  const { data: invoice } = await response.json();
  ```
</CodeGroup>

**Request fields:**

| Field            | Type   | Required | Description                                          |
| ---------------- | ------ | -------- | ---------------------------------------------------- |
| `title`          | string | Yes      | Invoice title (max 255 chars)                        |
| `customer_name`  | string | Yes      | Recipient's display name                             |
| `customer_email` | string | Yes      | Recipient's email address                            |
| `customer_id`    | string | No       | Link to an existing Dubu customer record             |
| `currency`       | string | No       | `NGN` or `USD`. Defaults to `NGN`                    |
| `issue_date`     | string | No       | ISO date string (e.g. `2024-11-01`)                  |
| `due_date`       | string | No       | ISO date string                                      |
| `notes`          | string | No       | Freeform notes shown on the invoice (max 2000 chars) |
| `line_items`     | array  | Yes      | At least one line item is required                   |

**Line item fields:**

| Field           | Type    | Required | Description                      |
| --------------- | ------- | -------- | -------------------------------- |
| `description`   | string  | Yes      | Item description (max 500 chars) |
| `quantity`      | integer | Yes      | Must be a positive integer       |
| `unit_price`    | number  | Yes      | Price per unit (must be ≥ 0)     |
| `tax_type`      | string  | No       | `none`, `percentage`, or `fixed` |
| `tax_rate`      | number  | No       | Tax value (e.g. `7.5` for 7.5%)  |
| `discount_type` | string  | No       | `none`, `percentage`, or `fixed` |
| `discount`      | number  | No       | Discount value                   |
| `product_id`    | string  | No       | Optional product reference UUID  |

**Response:**

```json theme={null}
{
  "success": true,
  "data": {
    "id": "inv_01hx9ab2qr3st4uv5wx6kl",
    "invoice_number": "INV-0001",
    "title": "Web Design Services — November 2024",
    "status": "draft",
    "customer_name": "Amara Okafor",
    "customer_email": "amara@example.com",
    "currency": "NGN",
    "total_amount": "236250.00",
    "issue_date": "2024-11-01",
    "due_date": "2024-11-15",
    "created_at": "2024-11-01T11:00:00.000Z"
  }
}
```

<Note>
  Newly created invoices have `status: "draft"`. The customer cannot pay until you send the invoice.
</Note>

## Add line items after creation

You can add additional line items to a `draft` invoice at any time before sending it:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl/line-items \
    -H "X-Api-Key: dubu_sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "description": "SEO optimisation",
      "quantity": 1,
      "unit_price": 50000,
      "discount_type": "percentage",
      "discount": 10
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl/line-items",
    {
      method: "POST",
      headers: {
        "X-Api-Key": "dubu_sk_live_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        description: "SEO optimisation",
        quantity: 1,
        unit_price: 50000,
        discount_type: "percentage",
        discount: 10,
      }),
    }
  );
  const { data: lineItem } = await response.json();
  ```
</CodeGroup>

### Remove a line item

```bash cURL theme={null}
curl -X DELETE \
  "https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl/line-items/li_01hx9bb2qr3st4uv5wx6mn" \
  -H "X-Api-Key: dubu_sk_live_your_api_key"
```

## Send the invoice by email

Once you're satisfied with the invoice, send it to the customer's email address:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl/send \
    -H "X-Api-Key: dubu_sk_live_your_api_key"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl/send",
    {
      method: "POST",
      headers: { "X-Api-Key": "dubu_sk_live_your_api_key" },
    }
  );
  const { data } = await response.json();
  ```
</CodeGroup>

Sending the invoice transitions its status from `draft` to `pending`. The customer receives an email with a payment link and a summary of all line items.

## Update an invoice

You can update a `draft` or `pending` invoice. Once an invoice is `paid` or `canceled`, updates are not accepted.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH \
    https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl \
    -H "X-Api-Key: dubu_sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "due_date": "2024-11-22",
      "notes": "Extended deadline upon customer request."
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl",
    {
      method: "PATCH",
      headers: {
        "X-Api-Key": "dubu_sk_live_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        due_date: "2024-11-22",
        notes: "Extended deadline upon customer request.",
      }),
    }
  );
  const { data: updated } = await response.json();
  ```
</CodeGroup>

**Updatable fields:** `title`, `customer_name`, `customer_email`, `currency`, `issue_date`, `due_date`, `notes`, `status` (to `draft`, `pending`, or `canceled`)

## Delete an invoice

You can delete a `draft` invoice. Paid or canceled invoices cannot be deleted.

```bash cURL theme={null}
curl -X DELETE https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl \
  -H "X-Api-Key: dubu_sk_live_your_api_key"
```

## List invoices

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.dubupay.com/api/v1/invoices?status=pending&limit=20" \
    -H "X-Api-Key: dubu_sk_live_your_api_key"
  ```

  ```javascript Node.js theme={null}
  const params = new URLSearchParams({ status: "pending", limit: "20" });
  const response = await fetch(
    `https://api.dubupay.com/api/v1/invoices?${params}`,
    {
      headers: { "X-Api-Key": "dubu_sk_live_your_api_key" },
    }
  );
  const { data } = await response.json();
  ```
</CodeGroup>

Filter by `status` (`draft`, `pending`, `paid`, `overdue`, `canceled`) or `search` (matches customer name or email). Supports `page` and `limit` (max 100) for pagination.

## Retrieve a single invoice

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl \
    -H "X-Api-Key: dubu_sk_live_your_api_key"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.dubupay.com/api/v1/invoices/inv_01hx9ab2qr3st4uv5wx6kl",
    {
      headers: { "X-Api-Key": "dubu_sk_live_your_api_key" },
    }
  );
  const { data: invoice } = await response.json();
  ```
</CodeGroup>

<Tip>
  To collect payment on an invoice without building a custom checkout UI, create a [checkout link](/guides/checkout-links) linked to the invoice ID. Dubu Pay hosts the payment page for you.
</Tip>
