> ## 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, logging, and request shapes for the Go 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.2.0. See the [Changelog](/changelog/blnk-go) before upgrading.
</Info>

## Initialize the client

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

```go client.go theme={"system"}
package blnk

import (
	"net/url"
	"os"
	"time"

	blnkgo "github.com/blnkfinance/blnk-go"
)

func NewBlnkClient() *blnkgo.Client {
	baseURL, _ := url.Parse(os.Getenv("BLNK_BASE_URL"))
	if baseURL == nil || baseURL.String() == "" {
		baseURL, _ = url.Parse("http://localhost:5001/")
	}

	apiKey := os.Getenv("BLNK_API_KEY")
	return blnkgo.NewClient(
		baseURL,
		&apiKey,
		blnkgo.WithTimeout(10*time.Second),
		blnkgo.WithRetry(2),
	)
}
```

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.

```go create-ledger.go theme={"system"}
client := NewBlnkClient()

ledger, resp, err := client.Ledger.Create(blnkgo.CreateLedgerRequest{
	Name: "Customer Savings Account",
	MetaData: map[string]interface{}{
		"project_owner": "YOUR_APP_NAME",
	},
})
if err != nil {
	return err
}

fmt.Printf("Ledger created (HTTP %d): %s\n", resp.StatusCode, ledger.LedgerID)
```

Per-method SDK pages in the sidebar list each call on `client.Ledger`, `client.LedgerBalance`, and other services.

***

## Authentication

`NewClient` takes a base URL and an optional API key pointer. The SDK sends the key on every request in the `X-Blnk-Key` header when you pass a non-nil pointer.

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 a pointer to your API key as the second argument.

    ```go theme={"system"}
    apiKey := os.Getenv("BLNK_API_KEY")
    client := blnkgo.NewClient(baseURL, &apiKey)
    ```
  </Tab>

  <Tab title="Auth disabled">
    When secure mode is off, pass `nil` as the API key.

    ```go theme={"system"}
    client := blnkgo.NewClient(baseURL, nil)
    ```
  </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 functional options to `NewClient` to tune behavior:

```go theme={"system"}
client := blnkgo.NewClient(
	baseURL,
	&apiKey,
	blnkgo.WithTimeout(30*time.Second),
	blnkgo.WithRetry(3),
	blnkgo.WithRetryDelay(2*time.Second),
)
```

| Option           | Type            | Default | What it does for you                                                                                     |
| :--------------- | :-------------- | :------ | :------------------------------------------------------------------------------------------------------- |
| `WithTimeout`    | `time.Duration` | `10s`   | How long to wait before giving up on a request. Bump this for slow operations like bulk reconciliations. |
| `WithRetry`      | `int`           | `1`     | Total attempts including the first try. `1` means no retries. `3` means up to three attempts.            |
| `WithRetryDelay` | `time.Duration` | `2s`    | Base delay between retries. Uses linear backoff.                                                         |

When to tune these:

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

<Note>
  Retries apply to idempotent `GET` requests and retryable network failures. `POST`, `PUT`, and `DELETE` are not retried on HTTP errors.
</Note>

***

## Custom logger

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

Pass a type that implements `blnkgo.Logger` to route these messages to your own logging system instead of stdout.

```go theme={"system"}
type appLogger struct{}

func (l appLogger) Info(msg string)  { log.Println("info:", msg) }
func (l appLogger) Error(msg string) { log.Println("error:", msg) }

client := blnkgo.NewClient(
	baseURL,
	&apiKey,
	blnkgo.WithLogger(appLogger{}),
)
```

| Level   | When the SDK calls it                                                                 |
| :------ | :------------------------------------------------------------------------------------ |
| `Info`  | Before a retry, or when a retryable network failure will be retried                   |
| `Error` | When a request returns a retryable HTTP status on a `GET`, or exhausts retry attempts |

***

## Building transaction requests

Call `client.Transaction.Create` and pass a `blnkgo.CreateTransactionRequest` struct. It has two parts:

1. **`ParentTransaction`** holds the core transaction fields: amount, currency, source, destination, reference, and metadata.
2. **Top-level fields** control how the request is processed, such as `AllowOverdraft`, `Inflight`, and `ScheduledFor`.

<Note>
  `ParentTransaction` is an embedded struct in the Go SDK, not a field in the API request body. The API expects flat JSON with fields like `amount` and `source` at the root.

  Do not confuse this struct with the API response field `parent_transaction`, which is a transaction ID linking related records such as inflight commits or split distributions.
</Note>

```go theme={"system"}
blnkgo.CreateTransactionRequest{
	ParentTransaction: blnkgo.ParentTransaction{
		PreciseAmount: 100000,
		Precision: 100,
		Currency: "USD",
		Source: "bln_28f25ef6-2e0d-4fa6",
		Destination: "bln_86ba7976-499d-4282",
		Reference: "payment_001",
	},
	AllowOverdraft: true,
}
```

Transactions are the exception. Every other resource uses a single request struct with no nesting. Pass `CreateLedgerRequest` to `client.Ledger.Create`, `CreateLedgerBalanceRequest` to `client.LedgerBalance.Create`, and so on.

***

## JSON field names

Go struct fields use PascalCase, like `MetaData` and `LedgerID`. These map to the API's snake\_case JSON fields (`meta_data`, `ledger_id`).

You should always use the Go field names in your code.

***

## Date and time fields

Fields such as `DOB`, `EffectiveDate`, `ScheduledFor`, `InflightCommitDate`, and historical balance timestamps use `time.Time` (or `*time.Time`). Parse ISO 8601 strings with `time.Parse(time.RFC3339, "...")`, for example `"2024-04-22T15:28:03Z"` or `"2024-12-21T01:36:46+01:00"`, then pass the resulting value. Use a pointer when the field is optional so zero values omit from JSON.

***

## Related docs

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

  <Card title="Error handling" icon="triangle-alert" href="/sdks/go/start/error-handling">
    Three-value returns and Core error bodies.
  </Card>

  <Card title="Changelog" icon="scroll-text" href="/changelog/blnk-go">
    Go SDK releases and version history.
  </Card>

  <Card title="Go SDK examples" icon="github" href="https://github.com/blnkfinance/blnk-go/tree/main/examples">
    Escrow, savings, cards, and reconciliation.
  </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>
