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

# Credit notes

> Issue, retrieve, and void credit notes against paid invoices.

A credit note is an immutable accounting document that adjusts an already-issued invoice. Unlike a refund, which moves money, a credit note records the adjustment — it can pair with a refund, an out-of-band settlement, or both.

On Node, `npm install @ionicfi/sdk` gives you typed calls for every request
below; the [server SDK](/sdks/server) guide has details. Each example also
shows raw curl.

## How credit notes work

<Steps>
  <Step title="Preview the credit note">
    Call `POST /v1/credit_notes/preview` with the invoice and amount to confirm the creditable remaining before committing. The preview returns the computed totals without persisting anything.
  </Step>

  <Step title="Issue the credit note">
    Call `POST /v1/credit_notes` with an `Idempotency-Key`. Provide either explicit `lines` or a shorthand `amount`. Specify how the credit is settled: via a linked refund, an out-of-band payment, or both. The settlement amounts must sum to the credit total.
  </Step>

  <Step title="Retrieve and distribute">
    Retrieve the credit note by ID or fetch its PDF for your buyer. The credit note is immutable once issued — only `void` changes its state.
  </Step>
</Steps>

## Preview a credit note

Preview the computed totals before issuing. The response shows how much of the invoice can still be credited and whether your requested amount would exceed it.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { Ionic } from "@ionicfi/sdk";

  const ionic = new Ionic({ token: process.env.IONIC_SECRET_KEY });

  const preview = await ionic.creditNotes.preview({
    body: {
      invoice: "inv_000000000000000000000000",
      amount: 5400,
    },
  });
  ```

  ```bash curl theme={null}
  curl -X POST https://api.ionicfi.com/v1/credit_notes/preview \
    -H "Authorization: Bearer sk_v1_test_..." \
    -H "Content-Type: application/json" \
    -d '{
      "invoice": "inv_000000000000000000000000",
      "amount": 5400
    }'
  ```
</CodeGroup>

The preview response includes:

| Field                  | Type    | Notes                                                                          |
| ---------------------- | ------- | ------------------------------------------------------------------------------ |
| `invoice_total`        | integer | Total amount of the invoice in minor units.                                    |
| `already_credited`     | integer | Sum of all previously issued credit notes against this invoice.                |
| `creditable_remaining` | integer | Maximum amount still available to credit (`invoice_total − already_credited`). |
| `would_exceed`         | boolean | `true` if the requested amount exceeds `creditable_remaining`.                 |

## Issue a credit note

Always send an `Idempotency-Key` — issuing a credit note can trigger a refund, and a double POST creates a double refund.

<CodeGroup>
  ```ts TypeScript theme={null}
  const creditNote = await ionic.creditNotes.create({
    "Idempotency-Key": "cn_order_123_adjustment",
    body: {
      invoice: "inv_000000000000000000000000",
      amount: 5400,
      refund: "rf_000000000000000000000000",
      reason: "order_change",
      memo: "Partial credit for cancelled add-on",
    },
  });
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/credit_notes \
    -H "Authorization: Bearer sk_v1_test_..." \
    -H "Idempotency-Key: cn_order_123_adjustment" \
    -H "Content-Type: application/json" \
    -d '{
      "invoice": "inv_000000000000000000000000",
      "amount": 5400,
      "refund": "rf_000000000000000000000000",
      "reason": "order_change",
      "memo": "Partial credit for cancelled add-on"
    }'
  ```
</CodeGroup>

### Request fields

| Field                | Type    | Notes                                                                                                            |
| -------------------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| `invoice`            | string  | Required. ID of the paid invoice to credit.                                                                      |
| `lines`              | array   | Itemized lines to credit. Use instead of `amount` when crediting specific invoice lines or adding a custom line. |
| `amount`             | integer | Shorthand credit amount in minor units. Use instead of `lines` when crediting the invoice generically.           |
| `amount_refunded`    | integer | Portion settled by returning funds to the original payment method. Requires a linked `refund`.                   |
| `refund`             | string  | ID of an already-issued refund (`rf_`) to link.                                                                  |
| `out_of_band_amount` | integer | Portion settled outside Ionic (cash, check, or wire).                                                            |
| `reason`             | string  | Optional. One of `duplicate`, `fraudulent`, `order_change`, `product_unsatisfactory`, `adjustment`.              |
| `memo`               | string  | Optional. Customer-visible note on the credit note document.                                                     |
| `effective_at`       | integer | Optional. Accounting date as a Unix timestamp. Defaults to the time of creation.                                 |
| `metadata`           | object  | Optional. Key-value data attached to the credit note.                                                            |

<Note>
  `amount_refunded` and `out_of_band_amount` must sum to the credit total. If you supply only `out_of_band_amount`, the full settlement is recorded as out-of-band with no money movement initiated by Ionic.
</Note>

### Lines vs. amount

Use `lines` when you need to credit specific invoice line items or add a custom adjustment line:

<CodeGroup>
  ```ts TypeScript theme={null}
  const creditNote = await ionic.creditNotes.create({
    "Idempotency-Key": "cn_order_123_lines",
    body: {
      invoice: "inv_000000000000000000000000",
      lines: [
        {
          type: "invoice_line_item",
          invoice_line_item: "il_000000000000000000000000",
          quantity: 1,
          description: "Full credit for line item",
          amount: 10000,
        },
        {
          type: "custom_line_item",
          description: "Goodwill adjustment",
          quantity: 1,
          unit_amount: 1000,
          amount: 1000,
        },
      ],
      out_of_band_amount: 11000,
      reason: "product_unsatisfactory",
    },
  });
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/credit_notes \
    -H "Authorization: Bearer sk_v1_test_..." \
    -H "Idempotency-Key: cn_order_123_lines" \
    -H "Content-Type: application/json" \
    -d '{
      "invoice": "inv_000000000000000000000000",
      "lines": [
        {
          "type": "invoice_line_item",
          "invoice_line_item": "il_000000000000000000000000",
          "quantity": 1,
          "description": "Full credit for line item",
          "amount": 10000
        },
        {
          "type": "custom_line_item",
          "description": "Goodwill adjustment",
          "quantity": 1,
          "unit_amount": 1000,
          "amount": 1000
        }
      ],
      "out_of_band_amount": 11000,
      "reason": "product_unsatisfactory"
    }'
  ```
</CodeGroup>

#### Line item fields

| Field               | Type    | Notes                                                                                                     |
| ------------------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `type`              | string  | `invoice_line_item` to credit an existing invoice line; `custom_line_item` for a new freeform adjustment. |
| `invoice_line_item` | string  | Required when `type` is `invoice_line_item`. ID of the invoice line being credited.                       |
| `quantity`          | integer | Quantity credited on this line.                                                                           |
| `amount`            | integer | Required. Credit amount for the line in minor units, excluding tax.                                       |
| `description`       | string  | Required. Displayed on the credit note document.                                                          |
| `unit_amount`       | integer | Required when `type` is `custom_line_item`. Per-unit amount in minor units.                               |

## Retrieve a credit note

<CodeGroup>
  ```ts TypeScript theme={null}
  const creditNote = await ionic.creditNotes.retrieve({
    id: "cn_000000000000000000000000",
  });
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/credit_notes/cn_000000000000000000000000 \
    -H "Authorization: Bearer sk_v1_test_..."
  ```
</CodeGroup>

## List credit notes

<CodeGroup>
  ```ts TypeScript theme={null}
  const creditNotes = await ionic.creditNotes.list({
    invoice: "inv_000000000000000000000000",
    limit: 20,
  });
  ```

  ```bash curl theme={null}
  curl "https://api.ionicfi.com/v1/credit_notes?invoice=inv_000000000000000000000000&limit=20" \
    -H "Authorization: Bearer sk_v1_test_..."
  ```
</CodeGroup>

The list endpoint accepts `invoice`, `customer`, and `status` as filters, plus `limit` and `offset` for pagination.

## Void a credit note

Voiding marks a credit note as `void` and retains its number in the gapless sequence. Use this only when a credit note was issued in error.

<CodeGroup>
  ```ts TypeScript theme={null}
  const voided = await ionic.creditNotes.void({
    id: "cn_000000000000000000000000",
    "Idempotency-Key": "void_cn_000000000000000000000000",
  });
  ```

  ```bash curl theme={null}
  curl -X POST https://api.ionicfi.com/v1/credit_notes/cn_000000000000000000000000/void \
    -H "Authorization: Bearer sk_v1_test_..." \
    -H "Idempotency-Key: void_cn_000000000000000000000000"
  ```
</CodeGroup>

<Warning>
  Voiding a credit note does not reverse a linked refund. If money was already returned to the buyer, reverse it separately before voiding.
</Warning>

## Fetch the PDF

<CodeGroup>
  ```ts TypeScript theme={null}
  const pdf = await ionic.creditNotes.retrievePdf({
    id: "cn_000000000000000000000000",
  });
  const pdfBytes = await pdf.arrayBuffer();
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/credit_notes/cn_000000000000000000000000/pdf \
    -H "Authorization: Bearer sk_v1_test_..."
  ```
</CodeGroup>

The response streams the rendered PDF inline (`Content-Type: application/pdf`). Credit notes in test mode are labeled `TEST-CN-` in the document number.

## Statuses

| Status   | Meaning                                                                    |
| -------- | -------------------------------------------------------------------------- |
| `issued` | The credit note is active. Financial fields are immutable.                 |
| `void`   | Issued in error; no longer valid. The number is retained and never reused. |

## Webhooks

Ionic emits the following events for credit notes. See [Webhook events](/webhooks/events) for the full catalog.

| Event                 | Fired when                                                              |
| --------------------- | ----------------------------------------------------------------------- |
| `credit_note.created` | A credit note is successfully issued. `data.object` is the credit note. |
| `credit_note.voided`  | A credit note is voided. `data.object` is the credit note.              |

<Tip>
  Ionic auto-issues a credit note when you refund a charge that is linked to an invoice. The event handler is idempotent on `refund_id` — a credit note is never duplicated if the same refund triggers both a webhook and an explicit API call.
</Tip>

## Operational guidance

* Always call `POST /v1/credit_notes/preview` first when building a support or finance UI. Use `would_exceed` to gate the submit button before the user commits.
* Send an `Idempotency-Key` on every `POST /v1/credit_notes` call. Use a key derived from your invoice ID and the reason for the adjustment so retries after network failures are safe.
* Store your ticket or approval ID in `metadata`. That gives your finance team a join key between Ionic credit notes and your CRM or ERP records.
* `issued` credit notes are immutable. If a credit note amount is wrong, void it and issue a corrected one — do not attempt to edit financial fields.
* For VAT or audit purposes, the `number` field (`CN-XXXXXX`) is the document reference. In test mode it is prefixed `TEST-CN-` to distinguish from live records.
