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

# API Key Owner Context

> Understand how owner labels isolate API key management across teams and services.

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>Available on Blnk Core 0.14.3 and later.</Info>

Every API key belongs to an owner.

The owner is a label you choose when creating the key, such as a team name, service name, or tenant ID. Blnk stores this value as `owner_id` on the key record.

Owner context controls which keys a scoped key can manage. A scoped key can only create, list, and revoke keys that belong to its own `owner_id`. It cannot manage keys for another owner.

***

## Example scenario

Say you create two keys under different owners:

* Key `k1` has `owner_id = merchant_a`
* Key `k2` has `owner_id = merchant_b`

If `k1` is used to manage API keys, Blnk resolves the owner as `merchant_a`.

That means `k1` can manage keys for `merchant_a`, but it cannot manage keys for `merchant_b`, even if the request includes `"owner": "merchant_b"`.

<Note>
  The [master key](/advanced/secure-blnk#master-key) is different. It isn't bound to an owner, so it can manage keys for any owner. Pass `owner` in the request to target a specific one.
</Note>

***

## Delegated key management

Scoped keys can manage API keys, but only within their own owner context.

This lets a team admin create narrower service keys for a team, service, or tenant without handing out the master key. For example, a key with `api-keys:read`, `api-keys:write`, and `api-keys:delete` can create, list, and revoke keys for its own `owner_id`.

| Caller             | What it can manage                                                                                                                                                |
| :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Master key**     | Can create, list, and revoke keys for any owner. Use the `owner` field to choose which owner the request applies to.                                              |
| **Scoped API key** | Can create, list, and revoke keys only for its own `owner_id`. If the request includes a different `owner`, Blnk ignores it and uses the key's stored `owner_id`. |

Two rules apply to scoped keys:

1. **Scope inheritance.** A key can only grant scopes it already has. For example, a key with only `transactions:read` cannot create another key with `transactions:write`.

2. **No cross-owner access.** The effective owner always comes from the caller’s stored `owner_id`. A key for `merchant_a` cannot create, list, or revoke keys for `merchant_b`.

***

## Error handling

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

When a key management request breaks owner or delegation rules, Blnk returns a `400`, `403`, or `404` response.

| Code                      | Status | When it happens                                                         |
| :------------------------ | :----- | :---------------------------------------------------------------------- |
| `AUTH_CROSS_OWNER_ACCESS` | `403`  | A scoped key tries to manage keys for another owner.                    |
| `AUTH_SCOPE_ESCALATION`   | `403`  | A scoped key tries to grant scopes it does not have.                    |
| `APIKEY_NOT_FOUND`        | `404`  | The key ID does not exist in the caller’s owner context.                |
| `APIKEY_OWNER_REQUIRED`   | `400`  | The master key is used to create or list keys without an `owner` value. |

Blnk does not always return `403` for cross-owner requests.

For example, trying to revoke another owner’s key returns `404 APIKEY_NOT_FOUND` instead of `403`. This prevents the response from revealing whether that key exists under another owner.

Listing keys with `?owner=another-team` returns `403 AUTH_CROSS_OWNER_ACCESS`, because the request is explicitly trying to access another owner’s key list.

Example response:

```json 403 Forbidden wrap theme={"system"}
{
  "error": "cannot grant scopes broader than caller",
  "error_detail": {
    "code": "AUTH_SCOPE_ESCALATION",
    "message": "cannot grant scopes broader than caller"
  }
}
```

To resolve the error:

| Code                      | What to do                                                                                                                                       |
| :------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| `AUTH_CROSS_OWNER_ACCESS` | Verify the caller's `owner_id` matches the owner you're targeting. Use the [master key](/advanced/secure-blnk#master-key) for cross-owner admin. |
| `AUTH_SCOPE_ESCALATION`   | Remove scopes from the create request that the caller doesn't hold, or create the key with the master key instead.                               |
| `APIKEY_NOT_FOUND`        | Confirm the key ID exists in the caller's owner context. A `404` may mean the key belongs to another owner.                                      |
| `APIKEY_OWNER_REQUIRED`   | Include `owner` in the create body or list query when using the master key.                                                                      |

***

## Related docs

<CardGroup cols={2}>
  <Card title="Overview" icon="lock-keyhole" href="/api-keys/overview">
    Create and use scoped keys.
  </Card>

  <Card title="Scopes" icon="list-check" href="/api-keys/scopes">
    Pick the right permissions.
  </Card>

  <Card title="Manage keys" icon="list" href="/api-keys/manage-keys">
    List, revoke, and delegate keys.
  </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>
