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

# Product updates

> Release notes and announcements for the Bastion platform: API changes, new endpoints, webhook updates, deprecations, and migration guidance.

<Update label="June 1, 2026">
  ## 🚀 API change notice: Introducing new identity and account status

  **TL;DR:**

  **Bastion is replacing fragmented compliance fields with a unified `status` model for Identities and Accounts, effective immediately, with legacy fields deprecated on July 31, 2026.**

  * **New fields**: `identity.status`, `identity.sub_status`, and `account.status` are now the single source of truth for lifecycle state.
  * **New webhook**: `identity_status_update` fires on every status transition (onboarding progress, suspensions, reinstatements, terminations) — replacing the old `compliance_check_status_update` and `account_freeze_status_update`.
  * **Deprecating July 31, 2026**: `kyc_status`, `kyb_status`, `account.frozen`, `account.account_status`, and the two legacy webhooks above.
  * **Migration**: Start consuming the new fields and webhook today. Remove legacy field reads before August 5th, 2026.

  If you're unsure whether a change affects you, we're happy to walk through your integration with you.

  ## ⚠️ 1. Deprecation notice

  The below fields and webhooks are now marked as deprecated and will be fully sunset on August 5th, 2026.

  Webhooks:

  * `compliance_check_status_update`
  * `account_freeze_status_update`

  API fields:

  * Identity:
    * `kyc_status`
    * `kyb_status`
  * Account:
    * `frozen`
    * `account_status`

  ***

  ## 🌟 2. What's new

  Bastion's new Identity and account status fields expose two capabilities:

  * **Identity and Account statuses** are now governed by the new `identity.status` and `account.status` fields with clear values indicating the current state of the identity and account.
    * **Additional onboarding-step visibility via `sub_status`.** Previously you had no field that told you which onboarding step was outstanding for an identity — you had to infer it from the absence or shape of `kyc_status`/`kyb_status`. Now `sub_status` reports it directly: `IDV_REQUESTED`, `IDV_IN_PROGRESS`, `IDV_EXPIRED`, `RFI_REQUIRED`, etc. This is purely additive — there is nothing to migrate from, just a new field to start consuming.
  * **Lifecycle events fire on every transition.** The legacy `compliance_check_status_update` webhook fired once at onboarding completion; suspensions and reinstatements were silent at the customer boundary. The new `identity_status_update` event fires on every state and sub-status change, including onboarding progress, compliance suspensions, manual reinstatements, and terminations.

  ### Relevant API guides and endpoints:

  * [Identities and accounts](/guides/concepts/identities-and-accounts)
  * [Onboard an individual customer](/guides/quickstarts/onboard-an-individual-customer)
  * [Onboard a business customer](/guides/quickstarts/onboard-a-business-customer)
  * [Compliance notifications (v2)](/v2/api-reference/webhooks/notifications/compliance-notifications-v2)

  ## 3. Newly introduced fields

  ### `identity.status`

  | Value                | Meaning                                                                                            |
  | -------------------- | -------------------------------------------------------------------------------------------------- |
  | `PENDING_ONBOARDING` | Identity created; onboarding workflow in progress. See `sub_status` for the precise step.          |
  | `ACTIVE`             | KYC/KYB approved, identity is able to transact                                                     |
  | `SUSPENDED`          | Previously active; temporarily suspended by Bastion Compliance                                     |
  | `REJECTED`           | KYC/KYB denied during onboarding. Identity is not able to transact or proceed with account opening |
  | `TERMINATED`         | Identity and all associated accounts are permanently closed.                                       |

  ### `identity.sub_status`

  | Value                           | Meaning                                                                                                                     |
  | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
  | `CREATED`                       | Identity exists; no compliance work has started yet.                                                                        |
  | `COMPLIANCE_CHECKS_IN_PROGRESS` | KYC/KYB checks running.                                                                                                     |
  | `IDV_REQUIRED`                  | Identity-document verification needs to be initiated. IDV will only be required for KYC / individual identities.            |
  | `IDV_REQUESTED`                 | IDV link sent to the user; awaiting completion. IDV will only be required for KYC / individual identities.                  |
  | `IDV_IN_PROGRESS`               | User has started but not finished IDV. IDV will only be required for KYC / individual identities.                           |
  | `IDV_EXPIRED`                   | IDV session expired before completion; needs to be re-requested. IDV will only be required for KYC / individual identities. |
  | `RFI_REQUIRED`                  | Request-for-information initiated by Bastion (additional documents/data).                                                   |

  ### `account.status`

  | Value    | Meaning                                                                    |
  | -------- | -------------------------------------------------------------------------- |
  | `ACTIVE` | Account is cleared to transact and usable.                                 |
  | `FROZEN` | Account is blocked (derived from a SUSPENDED parent identity).             |
  | `CLOSED` | Account is permanently closed (derived from a TERMINATED parent identity). |

  ## 4. Newly introduced webhooks

  There will be a single type of event trigger for compliance notifications

  * **`identity_status_update` Events:** These are sent whenever an identity (and its associated accounts) undergo a change in status. These can happen for various reasons:
    * During onboarding, compliance checks are initiated for an identity upon receipt of a [Submit Compliance Data](/v2/api-reference/compliance/submit-compliance-data) request. The event will return updates to the status, or if an RFI is required.
    * Throughout the customer lifecycle post-onboarding, a change in identity status can occur. E.g., an identity could move from `ACTIVE` to `SUSPENDED`.

  ### Identity status update events

  An example `identity_status_update` event payload of an identity that has completed onboarding is as follows:

  ```json Example Event Payload theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "id": "01HZXISMEVT_KYB_ACTIVE001",
    "type": "identity_status_update",
    "data": {
      "identity": {
        "id": "01HZXBUSINESSIDENTITY0001",
        "label": "corp_acme_001",
        "identity_type": "BUSINESS",
        "status": "ACTIVE",
        "sub_status": ""
      },
      "affected_account_ids": [],
      "status_reason": null,
      "previous_status": "PENDING_ONBOARDING",
      "previous_sub_status": "COMPLIANCE_CHECKS_IN_PROGRESS"
    }
  }
  ```

  An example `identity_status_update` event payload of an approved identity that has been suspended is as follows

  ```json Example Event Payload theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "id": "01HZXISMEVT_KYB_ACTIVE001",
    "type": "identity_status_update",
    "data": {
      "identity": {
        "id": "01HZXBUSINESSIDENTITY0001",
        "label": "corp_acme_001",
        "identity_type": "BUSINESS",
        "status": "SUSPENDED",
        "sub_status": ""
      },
      "affected_account_ids": [],
      "status_reason": null,
      "previous_status": "ACTIVE",
      "previous_sub_status": ""
    }
  }
  ```

  <br />

  ## 5. Field-by-field mapping from legacy fields to new fields

  ### On `Identity` ([`GET /v2/identities/{id}`](/v2/api-reference/identities/get-identity))

  | ❌ Legacy field                                                                                  | ✅ Read this instead                              |
  | ----------------------------------------------------------------------------------------------- | ------------------------------------------------ |
  | `kyc_status.kyc_passed`                                                                         | `status == "ACTIVE"`                             |
  | `kyb_status.kyb_passed`                                                                         | `status == "ACTIVE"`                             |
  | `kyc_status.kyc_failure_reason` / `kyb_status.kyb_failure_reason`                               | `status` (`REJECTED`, `SUSPENDED`, `TERMINATED`) |
  | `kyc_status.jurisdiction_check_passed` / `kyb_status.jurisdiction_check_passed`                 | `status == "ACTIVE"`                             |
  | `kyc_status.jurisdiction_check_failure_reason` / `kyb_status.jurisdiction_check_failure_reason` | `status`                                         |

  ### On `Account` ([`GET /v2/accounts/{id}`](/v2/api-reference/accounts/get-account))

  | ❌ Legacy field                                        | ✅ Read this instead  |
  | ----------------------------------------------------- | -------------------- |
  | `frozen` (bool)                                       | `status == "FROZEN"` |
  | `account_status` *(already marked `deprecated=true`)* | `status`             |

  ### Fields that are **not** going away (don't migrate these)

  | Field                                      | Why it stays                                                                       |
  | ------------------------------------------ | ---------------------------------------------------------------------------------- |
  | `Identity.fiat_operations_enabled`         | Independent fiat-rails entitlement. An identity can be `ACTIVE` but fiat-disabled. |
  | `Identity.type` (formerly `identity_type`) | This is an unrelated rename; `type` is already the correct field to read.          |
  | `Account.type` (formerly `account_type`)   | Same — unrelated rename.                                                           |

  ## 6. API examples

  ### [`GET /v2/identities/{id}`](/v2/api-reference/identities/get-identity) — Individual (KYC) example

  #### ❌ Old shape

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "identity": {
      "id": "id_01HX3K…",
      "type": "INDIVIDUAL",
      "label": "user-42",
      "account_ids": ["acct_01HX4Q…"],
      "fiat_operations_enabled": true,
      "kyc_status": {
        "kyc_passed": true,
        "kyc_failure_reason": null,
        "jurisdiction_check_passed": true,
        "jurisdiction_check_failure_reason": null,
        "allowed_to_transact_fungibles": true
      }
    }
  }
  ```

  #### ✅ New shape

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "identity": {
      "id": "id_01HX3K…",
      "type": "INDIVIDUAL",
      "label": "user-42",
      "account_ids": ["acct_01HX4Q…"],
      "fiat_operations_enabled": true,
      "status": "ACTIVE",
      "sub_status": null
    }
  }
  ```

  <br />

  #### ✅ New shape — mid-onboarding, IDV outstanding

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "identity": {
      "id": "id_01HX3K…",
      "type": "INDIVIDUAL",
      "label": "user-42",
      "account_ids": [],
      "fiat_operations_enabled": false,
      "status": "PENDING_ONBOARDING",
      "sub_status": "IDV_REQUESTED"
    }
  }
  ```

  <br />

  #### ✅ New shape — suspended after compliance review

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "identity": {
      "id": "id_01HX3K…",
      "type": "INDIVIDUAL",
      "label": "user-42",
      "account_ids": ["acct_01HX4Q…"],
      "fiat_operations_enabled": false,
      "status": "SUSPENDED",
      "sub_status": null
    }
  }
  ```

  <br />

  > During the deprecation window, the legacy `kyc_status` / `kyb_status` blocks will continue to appear in responses; their `*_failure_reason` fields will now be **derived from the new identity state** (e.g., `"identity is currently suspended"`) so they stay in sync. Treat them as read-only shadows — do not branch on them.

  ### [`GET /v2/accounts/{id}`](/v2/api-reference/accounts/get-account)

  #### ❌ Old shape

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "account": {
      "id": "acct_01HX4Q…",
      "identity_id": "id_01HX3K…",
      "type": "SEGREGATED",
      "frozen": false,
      "account_status": "ACTIVE"
    }
  }
  ```

  <br />

  #### ✅ New shape

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "account": {
      "id": "acct_01HX4Q…",
      "identity_id": "id_01HX3K…",
      "type": "SEGREGATED",
      "identity_status": "ACTIVE",
      "identity_sub_status": null,
      "status": "ACTIVE"
    }
  }
  ```

  > `Account.status` is the source of truth. `Account.identity_status` / `Account.identity_sub_status` are convenience mirrors of the parent Identity — handy if you don't want a second round-trip.

  ## 7. Migration guidance

  1. **Today** — Add handlers for `identity_status_update`. You can keep your existing `compliance_check_status_update` / `account_freeze_status_update` handlers in place during this deprecation period.
  2. **In your API reads** — Switch your "is this identity allowed to transact?" check to:
     ```javascript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
     identity.status == "ACTIVE"
     ```
     Switch your "is this account usable?" check to:
     ```javascript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
     account.status == "ACTIVE"
     ```
       <br />
  3. **For onboarding UIs** — Use `identity.sub_status` to drive your user-facing onboarding step indicator instead of inferring it from `kyc_status` presence/absence.
  4. **For failure messaging** — The canonical source will be `identity.status`. The legacy `*_failure_reason` will still be supported during the deprecation window.
  5. **Before deprecation on August 5th, 2026** — Remove all reads of `kyc_status`, `kyb_status`, `frozen`, and `account_status`. Stop subscribing to `compliance_check_status_update` and `account_freeze_status_update`.

  <br />

  Questions? Reach out to your Bastion integration contact for assistance.
</Update>

<Update label="April 1, 2026">
  ## 🚀 Release summary - KYC schema updates

  ## **✨ What's new**

  **KYC schema updates:**

  * New required fields have been added to `/v2/identities/{identity_id}/compliance`
  * The `account_purpose` enum values have also been updated
  * **Action required:**
    * Collect additional required information from end users during onboarding
    * Update any code that uses `/v2/identities/{identity_id}/compliance` to always include the required fields and enum values

  | **New Field**          | **Type**                                 | **Required**                                          |
  | ---------------------- | ---------------------------------------- | ----------------------------------------------------- |
  | `occupation`           | enum                                     | Yes                                                   |
  | `source_of_funds`      | enum                                     | Yes                                                   |
  | `nationality`          | string (ISO 3166-1 alpha-2 country code) | Yes                                                   |
  | `country_of_birth`     | string (ISO 3166-1 alpha-2 country code) | Yes                                                   |
  | `additional_id_number` | string                                   | Conditionally required based on identity jurisdiction |

  View [Submit Compliance Data API →](/v2/api-reference/compliance/submit-compliance-data)
</Update>

<Update label="March 26, 2026">
  ## 🚀 Release summary – Account type rename, gas sponsorship, and deposit improvements

  > **TL;DR:** We've renamed two account type values: `LEDGER` is now `OMNIBUS` and `ONCHAIN` is now `SEGREGATED`. You'll need to update your integration before June 24, 2026. On the new features side: gas fees on EVM transfers are now sponsored by Bastion, deposits have a redesigned webhook with Solana support, and we've added a Deposit History API. We also shipped a couple of reliability fixes to crypto transfers.

  If you're unsure whether a change affects you, we're happy to walk through your integration with you.

  ***

  ### **⚠️ Deprecation notice**

  **Account type values renamed: `LEDGER` → `OMNIBUS`, `ONCHAIN` → `SEGREGATED`**

  **What changed**

  The `account_type` enum values used when creating and reading accounts via the **Accounts API** (`/v2/accounts`) have been renamed to better reflect their meaning:

  * `LEDGER` is now `OMNIBUS`: for pooled, ledger-based custody accounts
  * `ONCHAIN` is now `SEGREGATED`: for individually isolated, on-chain wallet accounts

  **Transition period**

  Both the old and new values are currently accepted and returned. The legacy values (`LEDGER`, `ONCHAIN`) will be removed on **June 24, 2026**.

  **Action required**

  Update any code that sends or parses `account_type` to use the new values. If you use generated clients, regenerate from the latest schema.

  ***

  ### **✨ What's new**

  * **EVM gas sponsorship:** Your users can now send on Ethereum, Polygon, Base, and Optimism without ever holding ETH or native gas tokens. Bastion sponsors gas fees automatically across all supported EVM chains, and for most integrations, it costs you nothing. Every API customer gets \$100 in gas credits, and you're only billed if you exceed that.

    **Already using the Crypto Transfers API on EVM chains? You're basically done.** If you're calling `/v2/crypto/transfers`, gas sponsorship is enabled automatically, no new integration work needed. Just set your `destination_chain` to any supported EVM chain (`ETHEREUM_MAINNET`, `POLYGON_MAINNET`, `BASE_MAINNET`, `OPTIMISM_MAINNET`) and we handle the rest.

  * **New `deposit_v2` webhook event:** We've redesigned the wallet deposit notification webhook with a cleaner payload structure, and it now supports Solana in addition to EVM chains. Key changes:
    * **Solana support:** Deposit webhooks now fire for SOL and SPL token deposits on Solana wallets. If you already handle deposit webhooks, you'll automatically start receiving them for Solana.
    * New `source_type` field: `ON_CHAIN` for external chain deposits, `ACCOUNT` for internal P2P transfers received by the destination account
    * New `dedup_key` field for idempotent event handling
    * Consistent `snake_case` field naming throughout
      [View Webhooks reference →](/v2/api-reference/webhooks/notifications/deposit-notifications)

  Example `deposit_v2` payload:

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
  "id": "3AX4GQAUWy8OgAvmkmK1QPPK6GA",
  "type": "deposit_v2",
  "data": {
  "id": "3AX4GQAUWy8OgAvmkmK1QPPK6GA",
  "dedup_key": "4vJ9jDQkpMHcpbNSG8YRXfj7WEdNRpQ2bXkh6M3TzKVrE9Pf5C1gNwHzYuL8aJqRdmF7BhN2sKpXvWcTy6D3oAn::0",
  "account_id": "3BX5HRAVXz9PgBwnlL2zKR4tYdB",
  "account_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
  "source_type": "ON_CHAIN",
  "source_address": "8DwKActJ8swmNXGLyfdaoe6vmD2TxX19bhyE3txsmwfj",
  "currency_symbol": "USDC",
  "amount": "123.44",
  "destination_chain": "SOLANA_MAINNET",
  "transaction_hash": "4vJ9jDQkpMHcpbNSG8YRXfj7WEdNRpQ2bXkh6M3TzKVrE9Pf5C1gNwHzYuL8aJqRdmF7BhN2sKpXvWcTy6D3oAn",
  "status": "CONFIRMED",
  "confirmed_at": "2026-03-05T15:45:14Z",
  "created_at": "2026-03-05T15:45:14Z"
  }
  }
  ```

  * **Deposit history API:** Two new endpoints are available for querying deposit history:
    * [`GET /v2/crypto/deposits`](/v2/api-reference/cryptocurrency-deposits/list-cryptocurrency-deposits): paginated list of deposits, filterable by chain, currency, and time range.
    * [`GET /v2/crypto/deposits/{deposit_id}`](/v2/api-reference/cryptocurrency-deposits/get-cryptocurrency-deposit): fetch a single deposit by ID.
      Deposits are persisted as they flow through the system going forward.

  ***

  ### **⚡ Improvements**

  * **EVM gas estimation:** Fixed gas estimation logic that was causing premature transaction cancellations on EVM chains.

  * **Confirmation timeout extended from 1 min to 5 min:** Applies to the **Crypto Transfers API** (`/v2/crypto/transfers`). Provides a wider window for transactions to confirm before auto-cancellation.

  * **Gov ID upload removed from KYC flow:** KYC submissions via the Submit Compliance Data API no longer require gov ID images, reducing the integration surface for identity verification.
    * `gov_id_image_front` and `gov_id_image_back` have been removed from the KYC submission payload.
    * KYB is not affected.

  * **Crypto Transfers (v2): Structured destination format:** The Crypto Transfers API (`/v2/crypto/transfers`) now accepts a structured `address_destination` object (`{ "address", "chain" }`) as an alternative to the existing `destination_address` + `destination_chain` fields. Both formats remain supported; new integrations should prefer `address_destination`.

    ## 📘 Learn more

    Find deeper documentation and technical details on each endpoint:

    * [Accounts API](/v2/api-reference/accounts/overview)
    * [Submit Compliance Data](/v2/api-reference/compliance/submit-compliance-data)
    * [Deposit Notifications](/v2/api-reference/webhooks/notifications/deposit-notifications)
    * [Submit Cryptocurrency Transfers](/v2/api-reference/cryptocurrency-transfers/submit-cryptocurrency-transfer)
</Update>

<Update label="February 19, 2026">
  ## 🚀 Release summary - Solana gas sponsorship

  Your users can now send on Solana without ever touching SOL. Bastion sponsors gas fees automatically, and for most integrations, it costs you nothing. Every API customer gets \$100 in gas credits, and you're only billed if you exceed that. This is the first chain in our gas sponsorship rollout.

  **Already using the Crypto Transfers API with Solana? You're basically done.** If you're calling `/v2/crypto/transfers`, just set `destination_chain: SOLANA_MAINNET` — no new integration work needed.

  For deeper technical details, check out [Submit Cryptocurrency Transfers](/v2/api-reference/cryptocurrency-transfers/submit-cryptocurrency-transfer).

  <br />
</Update>

<Update label="February 3, 2026">
  ## 🚀 Release summary - API enhancements and reliability improvements

  > **TL;DR:** KYC/KYB ID requirement change, Faster identity-based queries, and more reliable webhook delivery.

  ***

  ### ⚠️ Breaking change

  #### Back of ID requirement for KYC and KYB (effective immediately)

  **Summary**

  [Submit Compliance Data API](/v2/api-reference/compliance/submit-compliance-data) now conditionally requires the **back of the ID depending on the document type**.

  **What changed**

  * **KYC (individuals) and KYB (Beneficial Owners)** will now require back of the ID depending on the document type

  | Document type                     | Front required | Back required |
  | --------------------------------- | -------------- | ------------- |
  | DOCUMENT\_TYPE\_PASSPORT          | Yes            | No            |
  | DOCUMENT\_TYPE\_DRIVER\_LICENSE   | Yes            | Yes           |
  | DOCUMENT\_TYPE\_NATIONAL\_ID      | Yes            | Yes           |
  | DOCUMENT\_TYPE\_RESIDENCE\_PERMIT | Yes            | Yes           |

  **Impact**

  * Requests that omit required fields now **fail validation**.

  **Action required**

  * Update payloads and mappings to always include the required fields.
  * When Submitting Compliance Data with ID type = DOCUMENT\_TYPE\_DRIVER\_LICENSE, DOCUMENT\_TYPE\_NATIONAL\_ID or DOCUMENT\_TYPE\_RESIDENCE\_PERMIT document type, include gov\_id\_image\_back (same format as gov\_id\_image\_front).

  ***

  ### ✨ What's new

  **Identity-based transfer queries** — The [List Cryptocurrency Transfers API](/v2/api-reference/cryptocurrency-transfers/list-cryptocurrency-transfers) now supports querying by `identity_Id`, returning all transfers across an identity's accounts in a single call—no more iterating through each account separately.

  **Identity filtering on ListAccounts** — The [List Accounts](/v2/api-reference/accounts/list-accounts) endpoint now accepts an optional `identity_Id` parameter to retrieve only accounts belonging to a specific identity.

  ***

  ### ⚡ Improvements

  * **Webhook notification retries** — Failed webhook deliveries are now automatically retried with persistent tracking, improving reliability for event-driven integrations.

  * **Consistent error responses** — [`GET /v2/transaction-limits/policies/{id}`](/v2/api-reference/transaction-limits/get-transaction-limit-policy) now returns `404` when a policy isn't found (previously `500`). Conversion lookups follow the same pattern. Unsupported HTTP methods now properly return `405`.

  ***

  ### 🧰 Fixes

  * Corrected gRPC message size limits for document downloads, preventing failures when processing larger identity verification images.

  <br />
</Update>

<Update label="January 6, 2026">
  ## 🚀 Release summary – API and platform contract updates

  **TL;DR:** This release includes several **breaking changes** that may require updates to your integration:

  * KYC/KYB schema enforcement (effective immediately)
  * JSON fields standardized to `snake_case` (transition period until **March 6, 2026**)
  * Banking payment instruction payload flattened
  * Stablecoin endpoint **renamed** from `/stablecoins/transfers` to `/conversions` (old path no longer supported)

  Plus: higher API key limits, clearer HTTP semantics, richer CryptoTransfer lifecycle, and performance improvements.

  If you’re unsure whether a change affects you, we’re happy to walk through your integration with you.

  ## ⚠️ Breaking changes

  ### 1. KYC/KYB schema enforcement (effective immediately)

  **What changed**

  * KYC/KYB submissions must now include a **front image of government ID** and **region code** on all addresses.
  * Legacy `kycLevel` and `kybLevel` fields have been removed from the schema.

  **Impact**

  * Requests that omit required fields or send removed fields now **fail validation**.

  **Action required**

  * Update payloads and mappings to always include the required fields.
  * Stop referencing `kycLevel` and `kybLevel` anywhere in your integration.

  ### 2. JSON field standardization to `snake_case`

  **What changed**

  * All JSON field names are now standardized to **`snake_case`** (for example, `identity_type`, `request_id`, `account_type`) to align with Protocol Buffers.

  **Transition period**

  * **Now – March 6, 2026:** Both `camelCase` and `snake_case` field names are accepted.
  * **After March 6, 2026:** Only `snake_case` field names are accepted.

  **Impact**

  * Requests using `camelCase` field names (for example, `identityType`, `requestId`, `kycStatus`) **after March 6, 2026** will fail validation.
  * Responses now return field names in `snake_case`.

  **Action required**

  * Update all request and response handling to use `snake_case`.
  * Common examples:
    * `identityType` → `identity_type`
    * `requestId` → `request_id`
    * `accountType` → `account_type`
    * `kycStatus` → `kyc_status`
    * `fiatOperationsEnabled` → `fiat_operations_enabled`
  * If you use generated clients, regenerate from the latest schema.

  ### 3. Banking payment instruction payload flattening

  **What changed**

  * Banking payment instruction JSON has been **flattened**; fields previously nested under `payment_instructions` are now top-level.

  **Before (nested):**

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "id": "36zeVf290384Gw97eS7w5Aa2huL",
    "instructions": {
       "country": "US",
       "fiatCurrencySymbol": "USD",
       "name": "Johny Doe",
       "paymentMethod": "WIRE",
  		 "bank_account_details": { ... }
    }
  }
  ```

  **After (flattened):**

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "id": "36zeVf290384Gw97eS7w5Aa2huL",
    "country": "US",
    "fiat_currency_symbol": "USD",
    "name": "Johny Doe",
    "payment_method": "WIRE",
    "bank_account_details": { ... }
  }
  ```

  **Impact**

  * Code that builds or parses the old nested `payment_instructions` object will break.

  **Action required**

  * Update request builders and response parsers to use the flattened structure.
  * Regenerate clients from the latest schema if you use codegen.

  ### 4. On-/off-ramp endpoint rename (`/stablecoins/transfers` → `/conversions`)

  **What changed**

  * The on-/off-ramp endpoint path has been **renamed** to `/conversions` to align with the unified Conversion lifecycle.

  **Impact**

  * Requests to `/stablecoins/transfers` now **fail**. `/conversions` is the required path going forward.

  **Action required**

  * Update all integrations to call `/conversions`.
  * If relevant, rename any internal references from "stablecoin transfers" to "conversions".
  * We can help confirm that all traffic is on `/conversions`.

  ***

  ## ✨ What’s new

  ### 1. Increased API key limits

  * API key limit increased to **50 keys per workspace**, making it easier to use per-service / per-environment keys, rotate keys more frequently, and separate vendor access. No changes are required for existing keys.

  ### 2. Enhanced CryptoTransfer lifecycle

  **What changed**

  * Crypto transfers now expose a richer lifecycle with more detailed statuses and events.

  **Statuses**

  * `ACCEPTED` – Validated, awaiting submission.
  * `SUBMITTED` – Submitted on-chain, waiting for confirmations.
  * `CONFIRMED` – Confirmed on-chain (terminal success).
  * `FAILED` – Failed (terminal; see `failure_details`).
  * `DROPPED` – Dropped (terminal).

  **Events**

  * `submitted` event when a transfer is first accepted and submitted.
  * Additional reconciliation events during confirmation.
  * Clearer `failed` events with `failure_details`.

  **Impact**

  * Any code that maps statuses or consumes webhooks may see new values and events.

  **Action required**

  * Ensure status mappings and webhook handlers cover all enum values and new events.

  ***

  ## ⚡ Improvements

  * **HTTP semantics:** Create operations now return **`201 Created`** instead of `200 OK`. If you assert on exact status codes, update checks to accept `201`.
  * **Read performance:** Read queries now route to read replicas for better performance. For strict write-then-read flows, consider a small retry or delay to handle occasional replication lag.

  ***

  ## 📘 Learn more

  Find deeper documentation and technical details on each endpoint:

  * [Submit Compliance Data](/v2/api-reference/compliance/submit-compliance-data)
  * [Create Payment Instructions](/v2/api-reference/payment-instructions/create-payment-instructions)
  * [Submit Stablecoin Conversion](/v2/api-reference/conversions/submit-conversion)
  * [Submit Cryptocurrency Transfers](/v2/api-reference/cryptocurrency-transfers/submit-cryptocurrency-transfer)

  <br />
</Update>

<Update label="December 8, 2025">
  ## 🚀 Release summary - v2 cryptocurrency transfers

  **TL;DR:** Introducing an upgraded asynchronous cryptocurrency transfer API with parallel transaction support, built-in idempotency, and enhanced status tracking across supported blockchain networks.

  ## ✨ What's new

  The V2 Cryptocurrency Transfers API delivers a non-blocking, asynchronous architecture that enables faster integrations and supports concurrent transaction submissions - a significant improvement over our previous sequential processing model.

  ### Asynchronous transfer submission

  The new submit endpoint returns immediately after accepting your request, allowing your application to continue processing without waiting for blockchain confirmation. Transfers proceed through multiple stages - asset pricing checks, compliance verification, and blockchain confirmation - while you poll for status updates at your convenience via the GET endpoint. This separation makes GET the authoritative place to retrieve transfer status. And soon, we’ll be introducing webhook-based status notifications so you can receive updates automatically without polling.

  **Submit Request:**

  ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  curl --location --request POST 'https://api.bastion.io/v2/crypto/transfers' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <your-api-key>' \
  --data '{
    "requestId": "903c9e51-51af-4597-9174-0a93ca80dbac",
    "accountId": "36NxLzj97KjakwizwUt2erT3c1S",
    "destinationChain": "BASE_SEPOLIA",
    "currencySymbol": "ETH",
    "amount": "0.001",
    "destinationAddress": "0x6F4268e34965Fb49ED87b2DA5a82cbb06044b6C4"
  }'
  ```

  **Submit Response (202 Accepted):**

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "id": "36NypbAj5Ok4BCepBbMhZDEmf3C",
    "requestId": "903c9e51-51af-4597-9174-0a93ca80dbac"
  }
  ```

  **Get Transfer Response:**

  ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
  {
    "id": "36NypbAj5Ok4BCepBbMhZDEmf3C",
    "requestId": "903c9e51-51af-4597-9174-0a93ca80dbac",
    "accountId": "36NxLzj97KjakwizwUt2erT3c1S",
    "accountAddress": "0xf655d368bc4D6f0004BD1550Bc45ce8260A1aA3c",
    "currencySymbol": "ETH",
    "amount": "0.001",
    "destinationAddress": "0x6F4268e34965Fb49ED87b2DA5a82cbb06044b6C4",
    "destinationChain": "BASE_SEPOLIA",
    "status": "CONFIRMED",
    "createdAt": "2025-12-04T15:18:28Z",
    "updatedAt": "2025-12-04T15:18:30Z",
    "transactionHash": "0xa23f89e5893a5ac73592e9cc81a9ff3bbb5c60d59dd09e37f2d03c4c824beb5e",
    "completedAt": "2025-12-04T15:18:30Z",
    "failureDetails": null,
    "events": []
  }
  ```

  ### Parallel transaction support

  For EVM-based chains, you can now submit multiple cryptocurrency transfers concurrently without worrying about transaction ordering. We handle EVM nonce serialization internally, ensuring all parallel submissions are processed correctly and confirmed on-chain in the proper sequence.

  Non-EVM chains already support parallel transaction submission by design, so this improvement primarily benefits EVM transfers.

  ### Built-in idempotency

  Every request requires a unique `requestId` (UUID) that serves as an idempotency key. If you submit the same `requestId` multiple times (whether due to network retries or concurrent submission bugs), we return the existing `transferId`, guaranteeing that only one transfer is ever created. Otherwise, if the transfer was already processed, repeated submissions return a `409 Conflict - DUPLICATE_TRANSACTION` error.

  ## 📘 Learn more

  Find deeper documentation and technical details on each endpoint:

  * [Submit Cryptocurrency Transfer →](/v2/api-reference/cryptocurrency-transfers/submit-cryptocurrency-transfer)
  * [Get Cryptocurrency Transfer →](/v2/api-reference/cryptocurrency-transfers/get-cryptocurrency-transfer)
  * [List Cryptocurrency Transfers →](/v2/api-reference/cryptocurrency-transfers/list-cryptocurrency-transfers)
  * [Supported Assets →](/v2/api-reference/assets/list-supported-assets)

  <br />
</Update>

<Update label="October 8, 2025">
  ## 🚀 Release summary - Tx limits and request signing

  **TL;DR:** Introducing secure request signing, compliance‑gated account creation, and new transaction limits to keep your platform interactions safe and reliable.

  ***

  ### ✨ What’s new

  Request signing, improved onboarding compliance, and new transaction limits deliver more secure and controlled API usage without disrupting existing integrations.

  * **Request signing** — You can now submit a public key to Bastion and use it to sign API requests. When an API key is paired with a public key, every call must include a signature to authenticate successfully. This feature is available in both Sandbox and Production environments.
  * **Account creation changes** — New accounts can only be created after completing successful compliance checks. This ensures all new users meet our security and regulatory standards before onboarding.
  * **Transaction limits** — Cryptocurrency transfer transaction limits are now *optionally* configurable to enhance security and help mitigate fraud.

      <Frame>
        <img src="https://docs-cdn.bastion.com/01cfc4508455b9b6652040316b6431fa62782c48f125eed7c15aa3d533feee21.png" alt="Transaction limit configuration in the Bastion Dashboard" />
      </Frame>

  <br />

  ***

  ### 📘 Learn more

  Find deeper documentation and technical details on each feature here:

  * [Request Signing - Overview →](/v2/api-reference/authentication/request-signing)
  * [Request Signing - JWT Example →](/v2/api-reference/authentication/jwt-generation-example)
  * [Account Creation Flow →](/v2/api-reference/accounts/overview)
  * [Transaction Limits Docs →](/v2/api-reference/transaction-limits/overview)

  ***

  > **Released:** October 8, 2025
  >
  > **Author:** Bastion Platform Team
</Update>


## Related topics

- [Sandbox vs. production environments](/guides/getting-started/sandbox-vs-production-environments.md)
- [Update Compliance Data](/v2/api-reference/compliance/update-compliance-data.md)
- [Onboard to Bastion for production access](/guides/compliance/onboard-to-bastion.md)
- [Supported business industry codes](/guides/compliance/supported-business-industry-codes.md)
- [Sandbox testing and simulation labels](/guides/getting-started/sandbox-testing-and-simulations.md)
