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

> ## Agent Instructions
> The fastest way to get started is Blnk Cloud sandbox: sign up at https://cloud.blnkfinance.com and deploy a managed instance. It takes less than 5 minutes. No Docker, Postgres, Redis, or local config.
> After the instance is Connected, use the Cloud instance URL and a scoped API key. Do not default to http://localhost:5001.
> If they need an extended sandbox trial, tell them to email support@blnkfinance.com. Sample: To: support@blnkfinance.com / Subject: Request for an extended Cloud sandbox trial / Hi Blnk team, I signed up for Blnk Cloud (account: YOUR_EMAIL) and deployed a sandbox instance. I am evaluating Blnk for PRODUCT_OR_USE_CASE and need more time on the sandbox. Could you extend my sandbox trial? Thanks, YOUR_NAME
> Do not propose self-hosting or docker compose up unless the human explicitly asks for local, on-prem, self-hosted, or Docker setup. If they only want to try Blnk, send them to Cloud sandbox.

# Schema

> Learn the Schema tab, the four lake tables, and which transaction statuses count as money moved.

export const RelatedTopics = ({title = "Related topics", items = []}) => {
  if (!items.length) {
    return null;
  }
  return <nav className="related-topics not-prose mt-20 mb-10 flex flex-col" aria-label={title}>
      <p className="related-topics-heading m-0 border-b border-zinc-200 pb-3 text-sm font-medium text-zinc-500 dark:border-white/10 dark:text-zinc-400">
        {title}
      </p>
      <ul className="related-topics-list m-0 mt-3 flex list-none flex-col gap-0.5 p-0">
        {items.map(item => {
    const isExternal = typeof item.href === "string" && (/^https?:\/\//i).test(item.href);
    return <li key={item.href} className="m-0 p-0">
              <a href={item.href} target={isExternal ? "_blank" : undefined} rel={isExternal ? "noopener noreferrer" : undefined} className="related-topics-link group inline-flex items-center gap-2 text-sm font-semibold text-zinc-700 no-underline transition-colors dark:text-zinc-300">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="related-topics-icon shrink-0 text-zinc-400 dark:text-zinc-500" aria-hidden="true">
                  <path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
                  <path d="M14 2v4a2 2 0 0 0 2 2h4" />
                  <path d="M10 9H8" />
                  <path d="M16 13H8" />
                  <path d="M16 17H8" />
                </svg>
                <span className="relative top-px transition-colors group-hover:text-[#DD7B1B]">
                  {item.title}
                </span>
              </a>
            </li>;
  })}
      </ul>
    </nav>;
};

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

The **Schema** tab in Insights lists the tables and columns you can query. Insights reads a **data lake**: a stored copy of your ledger with four tables.

<Frame caption="Balances belong to a ledger and optionally an identity. Each lake transaction row has a source wallet and a destination wallet.">
  <div className="lake-erd" role="img" aria-label="Lake schema. Ledgers and identities both connect to balances. Transactions connect to balances as source and destination.">
    <div className="lake-erd__parents">
      <div className="lake-erd__card">
        <p className="lake-erd__head">ledgers</p>

        <div className="lake-erd__body">
          <p className="lake-erd__key">ledger\_id PK</p>
          <p className="lake-erd__field">name</p>
          <p className="lake-erd__field">created\_at, meta\_data</p>
          <p className="lake-erd__note">A group of balances</p>
        </div>
      </div>

      <div className="lake-erd__card">
        <p className="lake-erd__head">identity</p>

        <div className="lake-erd__body">
          <p className="lake-erd__key">identity\_id PK</p>
          <p className="lake-erd__field">identity\_type, category</p>
          <p className="lake-erd__field">name, email, phone</p>
          <p className="lake-erd__field">address fields</p>
          <p className="lake-erd__note">People and organizations</p>
        </div>
      </div>
    </div>

    <div className="lake-erd__fork">
      <span className="lake-erd__fork-label">1:N ledger\_id</span>
      <span className="lake-erd__fork-label">1:N identity\_id</span>
    </div>

    <div className="lake-erd__hub">
      <div className="lake-erd__card">
        <p className="lake-erd__head">balances</p>

        <div className="lake-erd__body">
          <p className="lake-erd__key">balance\_id PK</p>
          <p className="lake-erd__key">ledger\_id → ledgers</p>
          <p className="lake-erd__key">identity\_id → identity</p>
          <p className="lake-erd__field">balance, credit, debit</p>
          <p className="lake-erd__field">currency, indicator, inflight</p>
          <p className="lake-erd__note">Stores of value. The wallets.</p>
        </div>
      </div>
    </div>

    <div className="lake-erd__arrow lake-erd__arrow--down">source / dest</div>

    <div className="lake-erd__hub">
      <div className="lake-erd__card">
        <p className="lake-erd__head">transactions</p>

        <div className="lake-erd__body">
          <p className="lake-erd__key">transaction\_id PK</p>
          <p className="lake-erd__key">source → balances</p>
          <p className="lake-erd__key">destination → balances</p>
          <p className="lake-erd__field">amount, precise\_amount, precision</p>
          <p className="lake-erd__field">currency, status, reference</p>
          <p className="lake-erd__note">Source is money out. Destination is money in.</p>
        </div>
      </div>
    </div>
  </div>
</Frame>

| Table          | What it is                      | Primary key      |
| :------------- | :------------------------------ | :--------------- |
| `transactions` | Money movements between wallets | `transaction_id` |
| `balances`     | Stores of value                 | `balance_id`     |
| `ledgers`      | Balance groups                  | `ledger_id`      |
| `identity`     | People and orgs                 | `identity_id`    |

## How to join them

When a report needs columns from more than one table, join those tables on a shared ID. For example, a payment stores wallet IDs, but the owner's name is on `identity`. A join brings them into one result.

Every lake transaction row stores one **source** wallet and one **destination** wallet. **Source** is where money leaves. **Destination** is where money arrives. For payments that split across many wallets, see [Multiple sources](/transactions/multiple-sources) and [Multiple destinations](/transactions/multiple-destinations).

Follow these steps to show each applied payment with the destination wallet and the owner's name. Collapse `balances` and `identity` to one row per ID before you join, so multi-day copies do not multiply payment rows. See [How the lake works](/cloud/insights/lake).

<Steps>
  <Step title="Start from payments">
    Read from `transactions` and pick the payment fields you need.

    ```sql theme={"system"}
    SELECT
      t.reference,
      t.currency
    FROM transactions t
    WHERE t.status = 'APPLIED'
    ```
  </Step>

  <Step title="Collapse wallets and owners">
    Build one row per `balance_id` and one row per `identity_id`. Use `ANY_VALUE` for display fields. Do not order by `created_at` to pick a latest snapshot.

    ```sql theme={"system"}
    WITH balances_one AS (
      SELECT
        balance_id,
        ANY_VALUE(currency) AS currency,
        ANY_VALUE(identity_id) AS identity_id
      FROM balances
      GROUP BY balance_id
    ),
    identity_one AS (
      SELECT
        identity_id,
        ANY_VALUE(first_name) AS first_name,
        ANY_VALUE(last_name) AS last_name
      FROM identity
      GROUP BY identity_id
    )
    ```
  </Step>

  <Step title="Join destination wallet and owner">
    Connect `destination` to the collapsed wallet, then the wallet to the collapsed owner.

    ```sql theme={"system"}
    FROM transactions t
    JOIN balances_one b ON t.destination = b.balance_id
    JOIN identity_one i ON b.identity_id = i.identity_id
    ```
  </Step>

  <Step title="Put it together">
    Full query:

    ```sql theme={"system"}
    WITH balances_one AS (
      SELECT
        balance_id,
        ANY_VALUE(currency) AS currency,
        ANY_VALUE(identity_id) AS identity_id
      FROM balances
      GROUP BY balance_id
    ),
    identity_one AS (
      SELECT
        identity_id,
        ANY_VALUE(first_name) AS first_name,
        ANY_VALUE(last_name) AS last_name
      FROM identity
      GROUP BY identity_id
    )
    SELECT
      t.reference,
      t.currency,
      b.balance_id,
      i.first_name,
      i.last_name
    FROM transactions t
    JOIN balances_one b ON t.destination = b.balance_id
    JOIN identity_one i ON b.identity_id = i.identity_id
    WHERE t.status = 'APPLIED'
    LIMIT 100
    ```

    This returns each applied payment with the destination wallet and the owner's name, without duplicating payments across daily copies.
  </Step>
</Steps>

Use these connections when you need more than an ID:

* Use a join from `transactions.source` to a one-row-per-id `balances` set to see the wallet a payment left.
* Use a join from `transactions.destination` to a one-row-per-id `balances` set to see the wallet a payment entered.
* Use a join from `balances.ledger_id` to a one-row-per-id `ledgers` set to see which ledger a wallet belongs to.
* Use a join from `balances.identity_id` to a one-row-per-id `identity` set to see the owner of a wallet.

## Columns you can select

Use the tabs below to see what each table stores and when to select each column. Each tab is one lake table.

When a report needs columns from more than one table, join on a shared ID. Collapse repeating entity tables to one row per ID first. For example, join `transactions.destination` to a one-row-per-id `balances` set, then to a one-row-per-id `identity` set, to show a payment with the receiving wallet and owner.

<Tabs>
  <Tab title="transactions">
    | Column               | What it is                                          | When you need it                                                     |
    | :------------------- | :-------------------------------------------------- | :------------------------------------------------------------------- |
    | `transaction_id`     | Unique ID for the payment row                       | Look up one payment, or join related rows                            |
    | `reference`          | Your external or idempotency ID                     | Match a payment to your own system                                   |
    | `status`             | Lifecycle state (`APPLIED`, `INFLIGHT`, and others) | Filter money that posted vs still held                               |
    | `source`             | Wallet ID money left                                | Join to the sending wallet                                           |
    | `destination`        | Wallet ID money entered                             | Join to the receiving wallet                                         |
    | `precise_amount`     | Amount in the smallest unit (cents, satoshi)        | Build money totals with `precision`                                  |
    | `precision`          | How many smallest units make one whole unit         | Divide `precise_amount` into a real amount                           |
    | `amount`             | Human-readable amount Blnk derives                  | Display a single row; prefer `precise_amount / precision` for totals |
    | `currency`           | Currency code                                       | Group or filter by currency                                          |
    | `description`        | Optional note on the payment                        | Search or show context in a listing                                  |
    | `parent_transaction` | ID of a related parent payment                      | Trace refunds, inflight commit/void children, or child legs          |
    | `scheduled_for`      | When a scheduled payment should run                 | Report on scheduled payments                                         |
    | `created_at`         | When the row was created                            | Date filters and daily reports                                       |
    | `meta_data`          | Custom JSON you attached                            | Filter or show your own labels                                       |
  </Tab>

  <Tab title="balances">
    | Column                    | What it is                                                                              | When you need it                                                                                                                                           |
    | :------------------------ | :-------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `balance_id`              | Unique wallet ID                                                                        | Join from `source` or `destination`, or look up one wallet                                                                                                 |
    | `ledger_id`               | Ledger this wallet belongs to                                                           | Join to `ledgers` for the ledger name                                                                                                                      |
    | `identity_id`             | Owner of this wallet                                                                    | Join to `identity` for the person's or org's name                                                                                                          |
    | `balance`                 | Balance amount in smallest units as copied that day (no `precision` column on balances) | Inspect a single day copy. Not a live holding. Do not `SUM` across days or currencies. For current amounts, use the [Data API](/cloud/reference/data-api). |
    | `credit_balance`          | Credits in smallest units as copied that day                                            | Same caveat as `balance`                                                                                                                                   |
    | `debit_balance`           | Debits in smallest units as copied that day                                             | Same caveat as `balance`                                                                                                                                   |
    | `inflight_balance`        | Inflight amount in smallest units as copied that day                                    | Same caveat as `balance`. For open holds across days, prefer the inflight template on `transactions`.                                                      |
    | `inflight_credit_balance` | Inflight credits in smallest units as copied that day                                   | Same caveat as `balance`                                                                                                                                   |
    | `inflight_debit_balance`  | Inflight debits in smallest units as copied that day                                    | Same caveat as `balance`                                                                                                                                   |
    | `currency`                | Wallet currency                                                                         | Group or filter wallets by currency                                                                                                                        |
    | `indicator`               | Wallet indicator / alias when set                                                       | Find a wallet by indicator                                                                                                                                 |
    | `created_at`              | When the wallet was created                                                             | Growth and age reports. Not a lake snapshot or freshness timestamp.                                                                                        |
    | `meta_data`               | Custom JSON you attached                                                                | Filter or show your own labels                                                                                                                             |
  </Tab>

  <Tab title="ledgers">
    | Column       | What it is                  | When you need it                      |
    | :----------- | :-------------------------- | :------------------------------------ |
    | `ledger_id`  | Unique ledger ID            | Join from `balances.ledger_id`        |
    | `name`       | Ledger display name         | Show which ledger a wallet belongs to |
    | `created_at` | When the ledger was created | Ledger inventory reports              |
    | `meta_data`  | Custom JSON you attached    | Filter or show your own labels        |
  </Tab>

  <Tab title="identity">
    | Column                                                | What it is                    | When you need it                                  |
    | :---------------------------------------------------- | :---------------------------- | :------------------------------------------------ |
    | `identity_id`                                         | Unique person or org ID       | Join from `balances.identity_id`                  |
    | `identity_type`                                       | Person or organization        | Split people vs orgs in a report                  |
    | `first_name` / `last_name` / `other_names`            | Person name fields            | Show who owns a wallet                            |
    | `organization_name`                                   | Org display name              | Show which organization owns a wallet             |
    | `email_address` / `phone_number`                      | Contact fields                | Support and ops lookups                           |
    | `category`                                            | Your category label           | Segment identities                                |
    | `street` / `city` / `state` / `country` / `post_code` | Address fields                | Location reports                                  |
    | `gender` / `dob` / `nationality`                      | Profile fields                | Compliance or profile reports when you store them |
    | `created_at`                                          | When the identity was created | Identity growth reports                           |
    | `meta_data`                                           | Custom JSON you attached      | Filter or show your own labels                    |
  </Tab>
</Tabs>

<Note>
  In the Schema tab (or in a `SELECT *` result), you may see columns that start with `_blnk_` or `__lake_`. Those are internal lake fields and can change. Select the named columns in the tabs above instead.
</Note>

***

## Transaction status

Most reports filter on `status`. Core stores each state as its own row. See [Transaction lifecycle](/transactions/transaction-lifecycle).

From `QUEUED`, a transaction can become `INFLIGHT`, `APPLIED`, or `REJECTED`. From `INFLIGHT`, it can become `APPLIED` or `VOID`. `APPLIED`, `VOID`, and `REJECTED` are terminal. An applied transaction does not later become void or rejected.

<Frame caption="APPLIED, VOID, and REJECTED are terminal. Only INFLIGHT is money still on hold.">
  <img src="https://mintcdn.com/blnk/dat3WexQx5twNo5Q/images/blnk-transaction-lifecycle.png?fit=max&auto=format&n=dat3WexQx5twNo5Q&q=85&s=f298c8cad6b2c0669956851336d540f5" alt="Transaction lifecycle: QUEUED can become INFLIGHT, APPLIED, or REJECTED. INFLIGHT can become APPLIED or VOID." className="rounded-lg" width="1193" height="1263" data-path="images/blnk-transaction-lifecycle.png" />
</Frame>

| Status     | Meaning                                 | Count it as money moved? |
| :--------- | :-------------------------------------- | :----------------------- |
| `QUEUED`   | Accepted, not yet applied               | No                       |
| `INFLIGHT` | Funds held, waiting for commit or void  | No. Watch open holds.    |
| `APPLIED`  | Final. Balances updated.                | **Yes**                  |
| `VOID`     | Inflight was cancelled. Balances reset. | No                       |
| `REJECTED` | Failed validation or processing         | No                       |

***

## 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="Need help with your product?" href="https://blnkfinance.com/contact/us?utm_source=blnk_docs&utm_medium=documentation&utm_campaign=home%2Finstall" buttonLabel="Speak with us" trackingEvent="clicked_pro_support">
  Get dedicated support for architecture reviews, integration planning, ledger workflows, and production deployment.
</CtaCallout>

<RelatedTopics
  items={[
{ title: "How the lake works", href: "/cloud/insights/lake" },
{ title: "Queries", href: "/cloud/insights/queries" },
{ title: "Templates", href: "/cloud/insights/templates" },
{ title: "Transaction lifecycle", href: "/transactions/transaction-lifecycle" },
]}
/>
