> ## 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.

# Transaction Precision

> Ensure correctness when recording amounts with floating points in your Blnk Ledger

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>;
};

Blnk ensures accuracy by storing transaction amounts and balances as integers, even though real-world values are typically expressed as decimals, such as USD 25.34, BTC 0.248917, or ETH 0.18920753698279.

Precision is a feature that converts these decimals into integers by converting amounts into their smallest asset-specific units:

* Dollar to cent (USD 25.34 becomes 2534 cents)
* Bitcoin to satoshi (BTC 0.248917 becomes 24891700 satoshis)
* Ethereum to wei (ETH 0.189207535698279 becomes 189207535698279000 wei)

When recording transactions, pass the smallest unit in `precise_amount` and include `precision` so Blnk can derive the human-readable `amount` in responses.

Alternatively, you can pass a float in `amount` and let Blnk convert it to an integer using `precision`.

***

## Determining your precision value

Follow these steps to calculate the best precision value for an asset class:

<Steps>
  <Step title="Identify the smallest possible unit of the asset.">
    For example, the smallest unit for USD is \$0.01 (1 cent), and for BTC, it's 0.00000001 (1 satoshi).
  </Step>

  <Step title="Convert this smallest unit into an integer.">
    To do this, multiply the smallest unit by a factor that results in a whole number. For instance:

    * For USD, multiply 0.01 by 100 to get 1 (since 100 cents makes a dollar).
    * For BTC, multiply 0.00000001 by 100,000,000 to get 1 (since 100 million satoshis makes 1 BTC).
  </Step>

  <Step title="Use the multiplication factor as your precision value.">
    The number you used to convert the smallest unit to an integer becomes the precision value. In the examples above:

    * USD precision value: 100
    * BTC precision value: 100,000,000

    <Card title="Fiat currencies and their precision values" icon="dollar-sign" href="https://github.com/blnkfinance/blnk-assets">
      151 fiat currencies and precision values.
    </Card>
  </Step>
</Steps>

***

## Applying precision

You can apply precision to amounts in your ledger in one of two ways.

1. Use **`precise_amount`** (recommended) to pass the smallest unit directly, or
2. Pass a float in **`amount`** and let Blnk convert it using `precision`.

<Tabs>
  <Tab title="Using precise amount">
    <Info>Available in version 0.10.1 or later</Info>

    Pass the amount in its smallest unit in `precise_amount`, and include the corresponding `precision` value.

    Blnk stores `precise_amount` as the ledger integer and returns the human-readable `amount` in responses (`amount = precise_amount / precision`).

    * Convert the amount to its smallest unit. [Learn how](#determining-your-precision-value)
    * Enter this value directly into the `precise_amount` field of your request.
    * Include the corresponding `precision` value.

    <CodeGroup>
      ```bash cURL wrap {5,6} 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": 75023,
          "precision": 100,
          "reference": "ref_abc123",
          "currency": "USD",
          "source": "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
          "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
          "description": "Wallet funding"
        }'
      ```

      ```typescript TypeScript wrap {2,3} theme={"system"}
      const response = await blnk.Transactions.create({
        precise_amount: 75023,
        precision: 100,
        reference: 'ref_abc123',
        currency: 'USD',
        source: 'bln_28edb3e5-c168-4127-a1c4-16274e7a28d3',
        destination: 'bln_ebcd230f-6265-4d4a-a4ca-45974c47f746',
        description: 'Wallet funding',
      });
      ```

      ```go Go wrap {3,4} theme={"system"}
      transaction, resp, err := client.Transaction.Create(blnkgo.CreateTransactionRequest{
        ParentTransaction: blnkgo.ParentTransaction{
          PreciseAmount: big.NewInt(75023),
          Precision:     100,
          Reference:     "ref_abc123",
          Currency:      "USD",
          Source:        "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
          Destination:   "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
          Description:   "Wallet funding",
        },
      })
      ```
    </CodeGroup>

    | Field            | Type    | Description                                                                   |
    | :--------------- | :------ | :---------------------------------------------------------------------------- |
    | `precise_amount` | Integer | The transaction value in its smallest unit (e.g. 75023 cents for USD 750.23). |
    | `precision`      | Number  | The precision value (e.g. 100 converts USD to cents)                          |

    ```json Response {6,8} theme={"system"}
    {
      "transaction_id": "txn_6164573b-6cc8-45a4-ad2e-7b4ba6a60f7d",
      "source": "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
      "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
      "reference": "ref_001adcfgf",
      "amount": 750.23,
      "precision": 100,
      "precise_amount": 75023,
      "currency": "USD",
      "description": "For fees",
      "status": "QUEUED",
      "created_at": "2024-02-20 05:28:03 UTC"
    }
    ```

    When using `precise_amount` with multiple sources or destinations, use `precise_distribution` instead of `distribution` for fixed amounts in your `sources` or `destinations` array.

    Percentages (`"10%"`) and the remainder (`"left"`) still use `distribution`.

    ```json Example with precise_distribution wrap theme={"system"}
    {
      ...
      "destinations": [
        {
          "identifier": "bln_f2073f6b-905a-4e3e-b5a2-8d1b3dc2fb7f",
          "precise_distribution": "2300000"
        },
        {
          "identifier": "bln_64c50fb5-32d5-4f78-9f4a-e8b01aaf025d",
          "distribution": "left"
        }
      ]
    }
    ```

    See [Multiple sources](/transactions/multiple-sources) and [Multiple destinations](/transactions/multiple-destinations) for more details.
  </Tab>

  <Tab title="Using amount">
    Pass the amount as a floating-point value in `amount` and specify its `precision` value. Blnk multiplies `amount` by `precision` to store `precise_amount`.

    <Warning>
      The `amount` field only supports up to 15 digits. Exceeding this will throw [a rounding error](/transactions/precision#more-than-15-digits-in-the-amount-field) or truncation; switch to `precise_amount` for accuracy with larger values.
    </Warning>

    <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 '{
          "amount": 750.23,
          "precision": 100,
          "reference": "ref_abc123",
          "currency": "USD",
          "source": "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
          "destination": "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
          "description": "Wallet funding"
        }'
      ```

      ```typescript TypeScript wrap theme={"system"}
      const response = await blnk.Transactions.create({
        amount: 750.23,
        precision: 100,
        reference: 'ref_abc123',
        currency: 'USD',
        source: 'bln_28edb3e5-c168-4127-a1c4-16274e7a28d3',
        destination: 'bln_ebcd230f-6265-4d4a-a4ca-45974c47f746',
        description: 'Wallet funding',
      });
      ```

      ```go Go wrap theme={"system"}
      transaction, resp, err := client.Transaction.Create(blnkgo.CreateTransactionRequest{
        ParentTransaction: blnkgo.ParentTransaction{
          Amount:      750.23,
          Precision:   100,
          Reference:   "ref_abc123",
          Currency:    "USD",
          Source:      "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
          Destination: "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
          Description: "Wallet funding",
        },
      })
      ```
    </CodeGroup>

    | Field       | Type   | Description                                          |
    | :---------- | :----- | :--------------------------------------------------- |
    | `amount`    | Float  | The transaction value as is.                         |
    | `precision` | Number | The precision value (e.g. 100 converts USD to cents) |

    The resulting `precise_amount` is stored and used to compute your ledger balances.
  </Tab>
</Tabs>

***

## Important considerations

1. `amount` and `precise_amount` cannot be passed simultaneously when recording a transaction. Prefer `precise_amount` for consistency across your integration.

2. Ensure that your precision value converts the target amount to the lowest unit possible for its asset class. For example, while 100 works for most fiat currencies, it is not advisable to use it for cryptocurrencies like Bitcoin or Ethereum.

3. Be consistent with how precision is applied in your application. Transactions with the same `currency` should always have the same precision applied to their amounts.

4. Balance fields are integers in minor units. Core does not return `precision` on balances. To display an amount, divide by the precision you use for that currency (`100000 / 100` = \$1,000.00).

5. Regularly review and audit your ledger to ensure that precision is applied consistently and correctly.

***

## Error handling

<Info>
  Structured errors are available from Blnk Core 0.15.0 and later.
</Info>

[Create transaction](/reference/create-transaction) returns `400 TXN_VALIDATION_ERROR` when the amount fields in your request fail validation.

<Tabs>
  <Tab title="Missing amount fields">
    Neither `amount` nor `precise_amount` is set:

    ```json 400 Bad Request wrap theme={"system"}
    {
      "error_detail": {
        "code": "TXN_VALIDATION_ERROR",
        "message": "amount: either amount or precise_amount is required."
      },
      "errors": "amount: either amount or precise_amount is required."
    }
    ```
  </Tab>

  <Tab title="Both fields exist">
    Both `amount` and `precise_amount` are sent in the same request:

    ```json 400 Bad Request wrap theme={"system"}
    {
      "error_detail": {
        "code": "TXN_VALIDATION_ERROR",
        "message": "amount: either amount or precise_amount should be provided, not both."
      },
      "errors": "amount: either amount or precise_amount should be provided, not both."
    }
    ```
  </Tab>

  <Tab title="15-digit limit">
    `amount` has more than 15 significant digits:

    ```json 400 Bad Request wrap theme={"system"}
    {
      "error_detail": {
        "code": "TXN_VALIDATION_ERROR",
        "message": "amount: amount has more than 15 significant digits which may cause rounding errors; use precise_amount instead"
      },
      "errors": "amount: amount has more than 15 significant digits which may cause rounding errors; use precise_amount instead"
    }
    ```
  </Tab>
</Tabs>

***

## 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>
