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

# Using the SDK

> Configure authentication, timeouts, retries, and logging for the Java SDK.

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

<Info>
  Configurable client options ship in v1.3.0. See the [Changelog](/changelog/blnk-java) before upgrading.
</Info>

## Initialize the client

Your Blnk client is the single entry point to everything: ledgers, balances, transactions, webhooks, and more. Configure it once when your app starts, then use it everywhere.

```java BlnkClient.java wrap theme={"system"}
import com.blnkfinance.blnk.Blnk;
import com.blnkfinance.blnk.BlnkClientOptions;

public final class BlnkClient {
  private static final String apiKey = System.getenv().getOrDefault("BLNK_API_KEY", "");
  private static final String baseUrl = System.getenv().getOrDefault(
      "BLNK_BASE_URL",
      "http://localhost:5001"
  );

  public static final Blnk BLNK = Blnk.init(
      apiKey,
      BlnkClientOptions.builder()
          .baseUrl(baseUrl)
          .build());
}
```

That's it. One import, one call, one client. From here you can create ledgers, move money, reconcile transactions, and manage your entire financial infrastructure.

```java CreateLedgerExample.java wrap theme={"system"}
import com.blnkfinance.blnk.types.ApiResponse;
import com.blnkfinance.blnk.types.CreateLedger;
import com.fasterxml.jackson.databind.JsonNode;

import java.util.Map;

ApiResponse<JsonNode> response = BlnkClient.BLNK.ledgers().create(
    CreateLedger.create()
        .name("Customer Savings Account")
        .metaData(Map.of("project_owner", "YOUR_APP_NAME")));

System.out.println("Ledger Created: " + response.data());
```

Services are accessed through methods on the client: `ledgers()`, `ledgerBalances()`, `transactions()`, `balanceMonitor()`, `reconciliation()`, `identity()`, `metadata()`, `hooks()`, `search()`, `apiKeys()`, and `system()`.

***

## Builders and wire fields

Request bodies are built with fluent types in `com.blnkfinance.blnk.types`. Builder methods use **camelCase** (for example `metaData()`, `skipQueue()`, `preciseAmount()`). Blnk Core receives **snake\_case** JSON on the wire (for example `meta_data`, `skip_queue`, `precise_amount`).

On method pages, request field tables list the **wire field** name because it matches the HTTP API and response JSON. Map it to the Java builder in your code:

| Wire field (table) | Java builder        |
| :----------------- | :------------------ |
| `meta_data`        | `.metaData()`       |
| `skip_queue`       | `.skipQueue()`      |
| `precise_amount`   | `.preciseAmount()`  |
| `allow_overdraft`  | `.allowOverdraft()` |
| `identity_type`    | `.identityType()`   |
| `expires_at`       | `.expiresAt()`      |

When prose refers to an SDK method, it uses Java names: `createBulk`, `updateStatus`, `blnk.transactions().create`. JSON examples and metadata keys may still use snake\_case (for example a custom metadata key named `update_status`).

***

## Response bodies

Every method returns `ApiResponse<JsonNode>`. Treat `response.data()` as parsed JSON:

* **Object responses:** `response.data().get("ledger_id").asText()`
* **Array responses:** check `response.data().isArray()`, then read `response.data().get(i).get("field")`
* **Nested arrays:** `response.data().get("results").get(i).get("status").asText()`
* **No body (204):** `response.data()` is `null`; branch on `response.status()` only

Field tables on method pages use wire JSON names because they match the HTTP API. Read those fields from the `JsonNode` returned in `response.data()`.

***

## Authentication

`Blnk.init` takes two arguments: an API key and a `BlnkClientOptions` object.

The options object must include `baseUrl`, the root URL of your Blnk Core instance. The SDK sends the API key on every request in the `X-Blnk-Key` header.

How you set the API key depends on whether Core runs in secure mode:

<Tabs>
  <Tab title="Secure mode">
    When `server.secure` is enabled, pass your API key as the first argument. Set `baseUrl` to the URL where Core is reachable.

    ```java wrap theme={"system"}
    String apiKey = System.getenv().getOrDefault("BLNK_API_KEY", "");
    String baseUrl = System.getenv().getOrDefault(
        "BLNK_BASE_URL",
        "http://localhost:5001"
    );

    Blnk blnk = Blnk.init(
        apiKey,
        BlnkClientOptions.builder()
            .baseUrl(baseUrl)
            .build());
    ```
  </Tab>

  <Tab title="Auth disabled">
    When secure mode is off, pass an empty string as the first argument.

    ```java wrap theme={"system"}
    Blnk blnk = Blnk.init(
        "",
        BlnkClientOptions.builder()
            .baseUrl("http://localhost:5001")
            .build());
    ```
  </Tab>
</Tabs>

<CardGroup cols={2}>
  <Card title="Secure Blnk" icon="shield-check" href="/advanced/secure-blnk">
    Secure mode, master key, and server hardening.
  </Card>

  <Card title="Scoped API keys" icon="lock-keyhole" href="/api-keys/overview">
    Owner-scoped keys and permission limits.
  </Card>
</CardGroup>

***

## Timeouts and retries

When connections fail, Core restarts, or requests hang, the SDK handles it without blocking your app. Pass these parameters on `BlnkClientOptions.builder()`:

```java wrap theme={"system"}
Blnk blnk = Blnk.init(
    apiKey,
    BlnkClientOptions.builder()
        .baseUrl("http://localhost:5001")
        .timeout(30000)
        .retryCount(3)
        .retryDelayMs(2000)
        .build());
```

| Option         | Type  | Default | What it does for you                                                                                         |
| :------------- | :---- | :------ | :----------------------------------------------------------------------------------------------------------- |
| `timeout`      | `int` | `10000` | Milliseconds to wait before giving up on a request. Bump this for slow operations like bulk reconciliations. |
| `retryCount`   | `int` | `1`     | Total attempts including the first. `1` means one attempt, no retries. `3` means try up to 3 times.          |
| `retryDelayMs` | `int` | `2000`  | Milliseconds between retries. Uses linear backoff.                                                           |

When to tune these:

* Keep defaults if you're making fast, local calls and want to fail fast.
* Increase `timeout` if you're running large batch requests that may take a while to complete synchronously.
* Increase `retryCount` if you're reading data across an unreliable network.

<Note>
  Retries apply to `GET` requests only. Timeouts return a synthetic `408` response and are never retried.
</Note>

***

## Custom logger

By default, the SDK logs internal events through a built-in logger that writes to the console with `INFO:` and `ERROR:` prefixes.

Pass a custom `BlnkLogger` to route these messages to your own logging system instead of the console.

```java wrap theme={"system"}
import com.blnkfinance.blnk.BlnkLogger;

public final class AppLogger implements BlnkLogger {
  @Override
  public void info(String message, Object... meta) {
    appLogger.info(message);
  }

  @Override
  public void error(String message, Object... meta) {
    appLogger.error(message);
  }
}

Blnk blnk = Blnk.init(
    apiKey,
    BlnkClientOptions.builder()
        .baseUrl("http://localhost:5001")
        .logger(new AppLogger())
        .build());
```

<Note>
  Metadata passed to the logger is redacted. The SDK strips values for keys such as `api_key`, `authorization`, `token`, and `secret` before logging.
</Note>

| Level   | When the SDK calls it                                                                       |
| :------ | :------------------------------------------------------------------------------------------ |
| `info`  | Before a retry, or when a retryable `GET` failure will be retried                           |
| `error` | When a request times out, returns a non-retryable HTTP error, or fails with a network error |

```bash Example logs wrap theme={"system"}
INFO: Retrying request to transactions/txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94 { attempt: 2, maxAttempts: 3, delayMs: 2000 }

ERROR: Request timed out { endpoint: 'transactions/txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94', timeoutMs: 30000 }

ERROR: Request to transactions/txn_f482a1b3-6c2d-4e89-a17b-3d5e8f2a1c94 failed with status 404.
```

***

## Related docs

<CardGroup cols={2}>
  <Card title="Quick start" icon="rocket" href="/sdks/java/start/quick-start">
    Install the SDK and create your first transaction.
  </Card>

  <Card title="Error handling" icon="triangle-alert" href="/sdks/java/start/error-handling">
    ApiResponse checks and Core error bodies.
  </Card>

  <Card title="Changelog" icon="scroll-text" href="/changelog/blnk-java">
    Java SDK releases and version history.
  </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>
