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

# About Transactions

> Learn how transactions are recorded and processed in Blnk

export const CtaCallout = props => {
  const {title, buttonLabel, href, trackingEvent, buttonTarget, rel = "noopener noreferrer", children} = props;
  const handleCtaClick = () => {
    if (typeof window === "undefined" || !trackingEvent) {
      return;
    }
    try {
      window.dispatchEvent(new CustomEvent("blnk:docs-cta", {
        detail: {
          name: trackingEvent,
          href
        }
      }));
    } catch {}
    try {
      window.posthog?.capture?.(trackingEvent, {
        href
      });
    } catch {}
    const gaPayload = {
      cta_href: href
    };
    try {
      window.gtag?.("event", trackingEvent, gaPayload);
    } catch {}
    try {
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({
        event: trackingEvent,
        ...gaPayload
      });
    } catch {}
  };
  const isExternal = typeof href === "string" && (/^https?:\/\//i).test(href);
  const target = buttonTarget ?? (isExternal ? "_blank" : undefined);
  const linkRel = isExternal ? rel : undefined;
  return <section className="cta-callout not-prose relative my-8 w-full min-w-0 overflow-hidden rounded-xl border border-zinc-200 p-5 dark:border-white/10">
      <div className="cta-callout-noise" aria-hidden="true" />
      <div className="cta-callout-layout">
        {title ? <div className="cta-callout-title-row">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28" width="14" height="14" className="cta-callout-icon shrink-0 text-zinc-800 dark:text-zinc-200" aria-hidden="true">
              <g fill="none" fillRule="nonzero">
                <path d="M28 0v28H0V0h28ZM14.691833333333335 27.134333333333334l-0.012833333333333334 0.0023333333333333335 -0.08283333333333333 0.04083333333333334 -0.023333333333333334 0.004666666666666667 -0.016333333333333335 -0.004666666666666667 -0.08283333333333333 -0.04083333333333334c-0.011666666666666667 -0.004666666666666667 -0.022166666666666668 -0.0011666666666666668 -0.028000000000000004 0.005833333333333334l-0.004666666666666667 0.011666666666666667 -0.019833333333333335 0.49933333333333335 0.005833333333333334 0.023333333333333334 0.011666666666666667 0.015166666666666667 0.12133333333333333 0.08633333333333333 0.0175 0.004666666666666667 0.014000000000000002 -0.004666666666666667 0.12133333333333333 -0.08633333333333333 0.014000000000000002 -0.018666666666666668 0.004666666666666667 -0.019833333333333335 -0.019833333333333335 -0.4981666666666667c-0.0023333333333333335 -0.011666666666666667 -0.0105 -0.019833333333333335 -0.019833333333333335 -0.021Zm0.3091666666666667 -0.13183333333333336 -0.015166666666666667 0.0023333333333333335 -0.21583333333333335 0.1085 -0.011666666666666667 0.011666666666666667 -0.0035000000000000005 0.012833333333333334 0.021 0.5016666666666667 0.005833333333333334 0.014000000000000002 0.009333333333333334 0.008166666666666668 0.23450000000000004 0.1085c0.014000000000000002 0.004666666666666667 0.026833333333333334 0 0.03383333333333334 -0.009333333333333334l0.004666666666666667 -0.016333333333333335 -0.03966666666666667 -0.7163333333333334c-0.0035000000000000005 -0.014000000000000002 -0.011666666666666667 -0.023333333333333334 -0.023333333333333334 -0.025666666666666667Zm-0.8341666666666667 0.0023333333333333335a0.026833333333333334 0.026833333333334334 0 0 0 -0.0315 0.007000000000000001l-0.007000000000000001 0.016333333333333335 -0.03966666666666667 0.7163333333333334c0 0.014000000000000002 0.008166666666666668 0.023333333333333334 0.019833333333333335 0.028000000000000004l0.0175 -0.0023333333333333335 0.23450000000000004 -0.1085 0.011666666666666667 -0.009333333333333334 0.004666666666666667 -0.012833333333333334 0.019833333333333335 -0.5016666666666667 -0.0035000000000000005 -0.014000000000000002 -0.011666666666666667 -0.011666666666666667 -0.21466666666666667 -0.10733333333333334Z" strokeWidth="1.1667" />
                <path fill="currentColor" d="M14 2.916666666666667A1.75 1.75 0 0 1 15.750000000000002 4.666666666666667v6.302333333333334L21.207666666666668 7.816666666666667a1.75 1.75 0 0 1 1.75 3.031L17.5 14l5.457666666666667 3.151166666666667a1.75 1.75 0 0 1 -1.75 3.031l-5.457666666666667 -3.1500000000000004V23.333333333333336a1.75 1.75 0 0 1 -3.5 0v-6.302333333333334L6.792333333333334 20.183333333333337a1.75 1.75 0 1 1 -1.75 -3.031L10.5 14 5.042333333333334 10.848833333333333a1.75 1.75 0 0 1 1.75 -3.031l5.457666666666667 3.1500000000000004V4.666666666666667A1.75 1.75 0 0 1 14 2.916666666666667Z" strokeWidth="1.1667" />
              </g>
            </svg>
            <p className="cta-callout-title min-w-0 font-semibold text-zinc-800 dark:text-zinc-200">
              {title}
            </p>
          </div> : null}
        <div className={`cta-callout-body text-sm leading-normal text-zinc-800 dark:text-zinc-200${title ? " cta-callout-body--indented" : ""}`}>
          {children}
        </div>
        <a href={href} target={target} rel={linkRel} onClick={handleCtaClick} data-docs-cta={trackingEvent || undefined} className="cta-callout-button inline-flex items-center justify-center gap-1 rounded-full bg-white px-3 py-1.5 text-sm font-semibold transition hover:bg-zinc-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white/50 dark:bg-white dark:hover:bg-zinc-200">
          {buttonLabel}
          <span className="cta-callout-button-arrow" aria-hidden="true">
            →
          </span>
        </a>
      </div>
    </section>;
};

Transactions enable money movement between two or more balances. These can be payments, transfers, settlements, internal treasury management, etc. All transactions in Blnk are recorded with the [double entry principle](/resources/double-entry) - every transaction has a source and a corresponding destination.

Transactions happen between balances, and [balances are created](/balances/introduction) within [ledgers](/ledgers/introduction).

In this guide, you'll learn about:

1. [Transaction properties](#transaction-properties)
2. [Recording a transaction](#recording-a-transaction)
3. [Verifying transactions](#verifying-transactions)

***

## Transaction properties

1. **Immutability:** Once recorded, transactions in Blnk cannot be modified or deleted. This fundamental property ensures the integrity and reliability of your transaction history, preventing any unauthorized alterations. See also: [Transaction hashing](/transactions/hash)

2. **Idempotency:** Each transaction in Blnk produces the same result whether executed once or multiple times. This is crucial for maintaining data consistency, especially during network failures or system retries.

   <Warning>
     Blnk implements idempotency by requiring a unique `reference` for every transaction. This reference serves as a transaction identifier, preventing duplicate processing and ensuring consistent outcomes.
   </Warning>

***

## Recording a transaction

To record a transaction, call the **record-transaction** endpoint:

<CodeGroup>
  ```bash cURL wrap theme={"system"}
  curl -X POST "http://YOUR_BLNK_INSTANCE_URL/transactions" \
    -H "X-blnk-key: <api-key>" \
    -H "Content-Type: application/json" \
    -d '{
      "precise_amount": 75000,
      "reference": "ref_001adcfgf",
      "currency": "USD",
      "precision": 100,
      "source": "@FundingPool",
      "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
      "description": "Fund with starting balance amount",
      "allow_overdraft": true,
      "skip_queue": false,
      "meta_data": {}
    }'
  ```

  ```typescript TypeScript wrap theme={"system"}
  const response = await blnk.Transactions.create({
    precise_amount: 75000,
    reference: 'ref_001adcfgf',
    currency: 'USD',
    precision: 100,
    source: '@FundingPool',
    destination: 'bln_ebcd230f-6265-4d4a-a4ca-45974c47f746',
    description: 'Fund with starting balance amount',
    allow_overdraft: true,
    skip_queue: false,
    meta_data: {},
  });
  ```

  ```go Go wrap theme={"system"}
  transaction, resp, err := client.Transaction.Create(blnkgo.CreateTransactionRequest{
    ParentTransaction: blnkgo.ParentTransaction{
      PreciseAmount: 75000,
      Reference:   "ref_001adcfgf",
      Currency:    "USD",
      Precision:   100,
      Source:      "@FundingPool",
      Destination: "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
      Description: "Fund with starting balance amount",
    },
    AllowOverdraft: true,
    SkipQueue:      false,
  })
  ```

  ```bash Blnk CLI wrap theme={"system"}
  blnk transactions create
  ```
</CodeGroup>

```json Response expandable theme={"system"}
{
    "id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
    "source": "@FundingPool",
    "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
    "reference": "ref_001adcfgf",
    "amount": 750,
    "precision": 100,
    "precise_amount": 75000,
    "currency": "USD",
    "description": "Fund with starting balance amount",
    "status": "QUEUED",
    "created_at": "2024-12-21T01:36:46.997063436Z",
    "meta_data": {
      "sender_name": "John Doe",
      "sender_account": "00000000000"
    }
}
```

<Tip>
  If this is your first transaction, the participating balances will start at 0. To ensure the transaction is successful, enable overdrafts as shown above, allowing the source balance to go negative.

  Learn more about [Overdrafts](/transactions/overdrafts) and [Negative Balances](/resources/negative-balances).
</Tip>

<Tabs>
  <Tab title="Request">
    | Field            | Description                                                                                                                                                                                 | Required | Type      |
    | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------- |
    | `precise_amount` | Transaction amount in its smallest unit (recommended). Send either `precise_amount` or `amount`, not both - see [Precision](/transactions/precision#using-both-precision-options-together). | Yes      | `integer` |
    | `amount`         | Transaction amount as a float. Blnk multiplies by `precision` to store `precise_amount`.                                                                                                    | Yes      | `float`   |
    | `reference`      | Your unique reference to ensure idempotency.                                                                                                                                                | Yes      | `string`  |
    | `currency`       | Short code for your asset class.                                                                                                                                                            | Yes      | `string`  |
    | `precision`      | Precision for the currency/asset passed. See also: [Precision](/transactions/precision)                                                                                                     | No       | `int64`   |
    | `source`         | Sender's balance ID                                                                                                                                                                         | Yes      | `string`  |
    | `destination`    | Recipient's balance ID.                                                                                                                                                                     | Yes      | `string`  |
    | `description`    | Description or narration of the transaction.                                                                                                                                                | No       | `string`  |
    | `meta_data`      | Custom data associated with the transaction                                                                                                                                                 | No       | `object`  |
  </Tab>

  <Tab title="Response">
    | Field            | Description                                                                                                                  | Type      |          |
    | ---------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------- | -------- |
    | `amount`         | The transaction amount.                                                                                                      | Yes       | `float`  |
    | `reference`      | Your unique reference to ensure idempotency.                                                                                 | Yes       | `string` |
    | `currency`       | Short code for your asset class.                                                                                             | Yes       | `string` |
    | `precision`      | Precision for the currency/asset passed. See also: [Precision](/transactions/precision)                                      | No        | `int64`  |
    | `source`         | Sender's balance ID                                                                                                          | Yes       | `string` |
    | `destination`    | Recipient's balance ID.                                                                                                      | Yes       | `string` |
    | `description`    | Description or narration of the transaction.                                                                                 | No        | `string` |
    | `meta_data`      | Custom data associated with the transaction                                                                                  | No        | `object` |
    | `id`             | Unique id for the transaction. This is generated by Blnk.                                                                    | `string`  |          |
    | `precise_amount` | The transaction amount recorded after the `precision` value has been applied. See also: [Precision](/transactions/precision) | `integer` |          |
    | `status`         | Current state of your transaction record. See also: [Transaction statuses](/transactions/transaction-lifecycle#statuses)     | `string`  |          |
    | `created_at`     | Date and time of the transaction record.                                                                                     | `string`  |          |
  </Tab>
</Tabs>

<Tip>
  Passing detailed data with the `meta_data` object is encouraged; it provides you with 360-degree insights about each transaction record. Examples of data you can pass include `sender_name`, `account_number`, `bank_name`, `receiver_name`, `payment_id`, `ip_address`, `location`, `payment_method`, etc.
</Tip>

***

## Verifying transactions with queue enabled

When using the default queue system, every transaction starts as `QUEUED`. To verify your transaction status, you have two options:

1. **Webhooks**: Blnk sends [webhook notifications](/webhooks/events#transactions) when transaction states change.
2. **Direct API calls**: Query the transaction status using the reference or transaction ID. See below: <br />

   <Tabs>
     <Tab title="By reference (direct endpoint)">
       Blnk appends a `_q` suffix to your original reference after processing a `QUEUED` transaction. To verify the updated status, retrieve the transaction using your original reference plus the `_q` suffix.

       <CodeGroup>
         ```bash cURL wrap theme={"system"}
         curl -X GET "http://YOUR_BLNK_INSTANCE_URL/transactions/reference/{reference}" \
           -H "X-blnk-key: <api-key>"
         ```
       </CodeGroup>

       ```json Response theme={"system"}
       {
         "transaction_id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
         "reference": "ref_001adcfgf",
         "status": "APPLIED"
       }
       ```
     </Tab>

     <Tab title="By reference (search)">
       Use the **Search API** to look up your transaction by reference. If the transaction exists, the response will include its current status.

       <CodeGroup>
         ```bash cURL wrap theme={"system"}
         curl -X POST "http://YOUR_BLNK_INSTANCE_URL/search/transactions" \
           -H "Content-Type: application/json" \
           -d '{
             "q": "<transaction-reference>",
             "query_by": "reference"
           }'
         ```

         ```typescript TypeScript wrap theme={"system"}
         const response = await blnk.Search.search(
           { q: '<transaction-reference>', query_by: 'reference' },
           'transactions',
         );
         ```

         ```go Go wrap theme={"system"}
         results, resp, err := client.Search.SearchDocument(
           blnkgo.SearchParams{
             Q:       "<transaction-reference>",
             QueryBy: "reference",
           },
           blnkgo.Transactions,
         )
         ```
       </CodeGroup>

       ```json Response theme={"system"}
       {
         "found": 1,
         "hits": [
           {
             "document": {
               "transaction_id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
               "reference": "ref_001adcfgf",
               "status": "APPLIED"
             }
           }
         ]
       }
       ```
     </Tab>

     <Tab title="By transaction ID">
       To check the updated status, take the queued transaction ID and search with it as the `parent_transaction`. This is because Blnk treats the queued transaction as the parent for the next transaction state. See also: [Transaction lifecycle](/transactions/transaction-lifecycle)

       <CodeGroup>
         ```bash cURL wrap theme={"system"}
         curl -X POST "http://YOUR_BLNK_INSTANCE_URL/search/transactions" \
           -H "Content-Type: application/json" \
           -d '{
             "q": "<queued-transaction-id>",
             "query_by": "parent_transaction"
           }'
         ```

         ```typescript TypeScript wrap theme={"system"}
         const response = await blnk.Search.search(
           { q: '<queued-transaction-id>', query_by: 'parent_transaction' },
           'transactions',
         );
         ```

         ```go Go wrap theme={"system"}
         results, resp, err := client.Search.SearchDocument(
           blnkgo.SearchParams{
             Q:       "<queued-transaction-id>",
             QueryBy: "parent_transaction",
           },
           blnkgo.Transactions,
         )
         ```
       </CodeGroup>

       ```json Response theme={"system"}
       {
         "found": 1,
         "hits": [
           {
             "document": {
               "transaction_id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
               "parent_transaction": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
               "status": "APPLIED"
             }
           }
         ]
       }
       ```
     </Tab>
   </Tabs>

***

## Verifying transactions without queue disabled

When using `skip_queue: true`, transactions are processed immediately and you can verify them from the direct response. Learn more about [skip queue](/transactions/transaction-lifecycle#skip-transaction-queue).

<CodeGroup>
  ```bash cURL wrap theme={"system"}
  curl -X POST "http://YOUR_BLNK_INSTANCE_URL/transactions" \
    -H "X-blnk-key: <api-key>" \
    -H "Content-Type: application/json" \
    -d '{
      "precise_amount": 75000,
      "reference": "ref_001adcfgf",
      "currency": "USD",
      "precision": 100,
      "source": "@FundingPool",
      "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
      "description": "Fund with starting balance amount",
      "allow_overdraft": true,
      "skip_queue": true
    }'
  ```

  ```typescript TypeScript wrap theme={"system"}
  const response = await blnk.Transactions.create({
    precise_amount: 75000,
    reference: 'ref_001adcfgf',
    currency: 'USD',
    precision: 100,
    source: '@FundingPool',
    destination: 'bln_ebcd230f-6265-4d4a-a4ca-45974c47f746',
    description: 'Fund with starting balance amount',
    allow_overdraft: true,
    skip_queue: true,
  });
  ```

  ```go Go wrap theme={"system"}
  transaction, resp, err := client.Transaction.Create(blnkgo.CreateTransactionRequest{
    ParentTransaction: blnkgo.ParentTransaction{
      PreciseAmount: 75000,
      Reference:   "ref_001adcfgf",
      Currency:    "USD",
      Precision:   100,
      Source:      "@FundingPool",
      Destination: "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
      Description: "Fund with starting balance amount",
    },
    AllowOverdraft: true,
    SkipQueue:      true,
  })
  ```
</CodeGroup>

```json Response {11} theme={"system"}
{
  "id": "txn_6164573b-6cc8-45d4-ad2e-7b4ba6a60f7d",
  "source": "@FundingPool",
  "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
  "reference": "ref_001adcfgf",
  "amount": 750,
  "precision": 100,
  "precise_amount": 75000,
  "currency": "USD",
  "description": "Fund with starting balance amount",
  "status": "APPLIED",
  "created_at": "2024-12-21T01:36:46.997063436Z",
  "meta_data": {}
}
```

The response immediately shows the final status (`INFLIGHT`, `APPLIED`, or `REJECTED`), allowing you to confirm the transaction result without waiting for webhooks or additional API calls.

<Warning>
  When using `skip_queue: true`, you may encounter lock errors if multiple transactions are processed simultaneously on the same balance. Learn how to handle these scenarios in our [Handling Hot Balances](/guides/hot-balances) guide.
</Warning>

***

## Discarded transactions

A discarded transaction is not recorded in the ledger. Blnk discards transactions for two reasons:

1. **Duplicate reference:** Your new transaction `reference` matches an existing `reference` in your ledger. Blnk requires unique `reference` values per transaction. Options are timestamps (e.g. UNIX timestamp), random string or UUID (e.g. `ref_e55c4f33-bff7-4c30-9b9f-5d2d10a29b7a`), or a business identifier like an `order_id`.

2. **Zero amount:** Your transaction amount is 0. Zero amounts are not recorded in the Blnk ledger.

<Tip>Make sure your request body match the Blnk Ledger API specifications. For example, avoid passing `apply_overdraft` instead of `allow_overdraft`.</Tip>

***

## Managing insufficient funds

<Info>
  Available in version 0.11.0 and later. For versions 0.10.8 and older, see our [insufficient funds guide](/guides/insufficient-funds).
</Info>

Blnk performs comprehensive balance checks before processing any transaction to ensure you have sufficient funds available. The system computes an available balance by calculating `balance - inflight_debit_balance` on the source balance.

Inflight debit balance is the amount waiting to be deducted from the source balance from inflight transactions. Learn more: [Create inflight](/transactions/inflight/creating-inflight).

If the transaction amount is more than the available balance, the source has insufficient funds and:

1. The transaction is rejected and status is recorded as `REJECTED`.
2. A webhook notification to inform your system of the rejected transaction and a reason in its `meta_data`.

<Note>
  If you want a transaction to proceed even when it exceeds the available balance, you can enable overdrafts by setting `allow_overdraft: true` in your transaction request. [Learn more](/transactions/overdrafts).
</Note>

***

## Dive deeper

<CardGroup>
  <Card title="Transaction lifecycle" icon="refresh-cw" href="/transactions/transaction-lifecycle">
    States from creation through completion.
  </Card>

  <Card title="Understanding precision" icon="target" href="/transactions/precision">
    Decimal handling for accurate amounts.
  </Card>

  <Card title="Transaction statuses" icon="tag" href="/transactions/transaction-lifecycle#statuses">
    What each status means and when it applies.
  </Card>
</CardGroup>

***

## Need help?

We are very happy to help you make the most of Blnk, regardless of whether it is your first time or you are switching from another tool.

To ask questions or discuss issues, please [contact us](mailto:support@blnkfinance.com) or [join our Discord community](https://discord.gg/7WNv94zPpx).

<CtaCallout title="Connect your ledger to Blnk Cloud" href="https://cloud.blnkfinance.com/auth/sign-up?utm_source=blnk_docs&utm_medium=documentation&utm_campaign=need-help" buttonLabel="Open Blnk Cloud" trackingEvent="clicked_cloud_signup">
  Sign up and manage your ledger with our back-office dashboard. You can invite teammates to collaborate and manage your ledger operations directly from the dashboard.
</CtaCallout>
