> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lead.bank/llms.txt
> Use this file to discover all available pages before exploring further.

# Accounts API Best Practices

> Guidance on OAuth scopes, idempotency keys, capability selection, and entity sequencing when integrating with the Lead Accounts API.

## Use the Correct Authentication Scope

Choose the right OAuth scope before making any API call:

* `POST /v0/accounts`, `PATCH /v0/accounts/{id}`, and all status-transition endpoints require **`account/read_write`**.
* `GET /v0/accounts/{id}` accepts either **`account/read`** or **`account/read_write`**.

Use the least-privileged scope appropriate to the operation. If your integration only needs to retrieve accounts, use `account/read` and avoid provisioning broader write access.

## Use Idempotency Keys on All Write Operations

Include a unique `Idempotency-Key` header on every `POST` and `PATCH` request. Use a UUID (e.g., `550e8400-e29b-41d4-a716-446655440000`).

Key behaviors to be aware of:

* If a request fails, use a new idempotency key when retrying — the original key stores the failed response for 48 hours and will replay it. Two exceptions on **409** Conflict: if the error code is `idempotency_key_conflict` and you have not reused this key for a different request, your identical request raced with itself — retry once with the same key to receive the original outcome. If the error code is conflict (resource modified concurrently), reload the resource and resubmit with a new key.
* If a request succeeds (**200**), reusing the same idempotency key returns the cached response without creating a duplicate.
* Omitting the `Idempotency-Key` header results in a 400 `idempotency_error`.

## Choose the Right Capabilities

Every account must declare at least one capability at creation. Your program may have access to a subset of all supported\_capabilities; speak to your Partner Solutions contact if you need to expand to support for additional capabilities.

Capabilities drive which fields are required and which compliance validations apply.

* **`deposit`** — use for depository accounts (checking, savings). Does not require `application_id` or credit-specific fields.
* **`credit_with_underwriting`** — use for credit products tied to an approved application. Requires `application_id` and the full `details.credit` object.
* **`credit_without_underwriting`** — use for credit products that do not require underwriting (e.g., overdraft). Does not require `application_id` or credit-specific fields.

An account may have multiple capabilities. For example, a checking account with overdraft would use `["deposit", "credit_without_underwriting"]`.

Capabilities cannot be removed once added. If an account was created with incorrect capabilities, close it and create a new one.

## Create Entities First

The Accounts API validates entity IDs on account creation. Before calling `POST /v0/accounts`, create the relevant entities using the Entity API and collect the `entity_`-prefixed IDs from those responses.

Use the server-generated `id` (e.g., `entity_3frCuaBe93vyJZxK3yOhlVuriBY`) in the `entities.account_holders`, `entities.authorized_signers`, and `entities.authorized_users` arrays. Entity creation must be sequenced ahead of account creation — the Accounts API does not create entities on your behalf.

## Create Applications Before Credit Accounts

For accounts with the `credit_with_underwriting` capability, the `application_id` field is required. The referenced application must be in `approved` status.

Sequence your integration as:

1. Create entities via the Entity API.
2. Create the application via the Applications API, referencing the entity IDs.
3. Create the account via the Accounts API, referencing the `application_id` from step 2.

On account creation, Lead validates that the account holder type and at least one account holder match between the application and the account. Mismatches return a `422` error.

## Understand Consumer vs. Commercial Accounts

The `account_holder_type` field (`consumer` or `commercial`) is derived from the entity types in `entities.account_holders` — you do not set it directly:

* **Individual** entities produce `consumer`.
* **Business** or **sole proprietor** entities produce `commercial`.

Do not mix individual entities with business or sole proprietor entities within `account_holders`. A single account may not contain both individual and business/sole proprietor account holders. Business and sole proprietor entities may be combined with each other within the same account — both produce an `account_holder_type` of `commercial`.

Commercial accounts (those with business or sole proprietor account holders) require at least one entry in `entities.authorized_signers`. Each authorized signer entity must have the `authorized_signer` role assigned. Consumer accounts do not require authorized signers.

## Use Status-Transition Endpoints for Lifecycle Changes

The Accounts API manages status through dedicated endpoints, not through `PATCH`:

* **`POST /v0/accounts/{id}/deactivate`** — transitions `active` to `inactive`. Requires a `status_reason` (`dormant`, `frozen`, or `other`).
* **`POST /v0/accounts/{id}/activate`** — transitions `inactive` back to `active`. No request body required.
* **`POST /v0/accounts/{id}/close`** — transitions `active` or `inactive` to `closed`. Requires a `status_reason` (`entity_closed`, `client_closed`, `paid_off`, `charged_off`, or `canceled`). This is terminal and cannot be undone.
* The Status transition endpoints additionally support self-serve error correction, allowing a transition from `closed` to `active`. These should only be used to correct a mistakenly reported Account - if an account can be reopened through the normal course of business, an `inactive` status, not a `closed` status should be used.

Attempting to set `status` through `PATCH` has no effect.

If an account needs to be closed and the status reason is `client_closed`, an adverse action notice (`details.adverse_action_notice`) is required on the account before or at the time of closure.

## Use PATCH for Data Updates Only

`PATCH /v0/accounts/{id}` updates mutable data fields on an account. It does not support:

* **Status changes** — use the dedicated status-transition endpoints.
* **Entity relationship changes** — use the entity relationships endpoints.

When patching:

* Only include fields you want to update. Omitted fields remain unchanged.
* `documents`, if provided, **replaces the entire existing list**. To add a document, include all existing documents plus the new one.
* `capabilities`, if provided, can only add new capabilities. Existing capabilities are preserved and cannot be removed. The full updated list of `capabilities` should be provided when updating via `PATCH` - not just the new one(s). If you receive an error that your program does not support a capability, please reach out to Lead's Partner Solutions team to ensure approval for the capability being used.
* Closed accounts cannot be updated. `PATCH` on a closed account returns a `422`.

## Handle Credit Report and Adverse Action Notice Fields as All-or-Nothing

Two objects on the account follow an all-or-nothing pattern:

* **`details.credit.report`** — if included, all three fields (`score`, `pulled_at`, `source`) must be present. Providing a partial set returns a `422`.
* **`details.adverse_action_notice`** — if included, all three fields (`delivered_at`, `reason`, `delivery_method`) must be present. Providing a partial set returns a `422`.

## Retrieve Entity Relationships Separately

The `GET /v0/accounts/{id}` response includes the derived `account_holder_type` but does not return the underlying entity ID lists. To see which entities are linked to an account and in which role (`account_holder`, `authorized_signer`, or `authorized_user`), use the entity relationships endpoint when it becomes available.
