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

# Bridge Transaction Status

> Track the status of crosschain bridge transactions across Stargate, CCIP, Relay, and CCTP

export const date_0 = "2026-04-07"

After submitting a crosschain transaction via the [Route](/pages/build/get-started/route) or [Bundle](/pages/build/get-started/bundling-actions) API, the bridge delivery is asynchronous. Enso provides protocol-specific status endpoints to track delivery progress on the destination chain.

## Quick Reference

| Bridge Protocol | Status Endpoint                     | Status Field |
| --------------- | ----------------------------------- | ------------ |
| CCIP            | `GET /api/v1/ccip/bridge/check`     | `status`     |
| CCTP            | `GET /api/v1/cctp/bridge/check`     | `status`     |
| Relay           | `GET /api/v1/relay/bridge/check`    | `status`     |
| Stargate        | `GET /api/v1/stargate/bridge/check` | `status`     |

All endpoints accept two query parameters:

* `chainId` — source chain ID (number)
* `txHash` — source transaction hash (string, `0x` + 64 hex characters)

<Warning>
  **Rate limit**: All bridge status endpoints are limited to **1 request per 10
  seconds** per API key (or per IP if unauthenticated). Exceeding this returns
  HTTP 429. Enforce a minimum 10-second interval between polls.
</Warning>

## Status Lifecycle

Bridge transactions progress through a unified status lifecycle:

```mermaid theme={null}
stateDiagram-v2
    [*] --> pending
    pending --> inflight : Bridge picks up message
    inflight --> delivered : Destination tx confirmed
    inflight --> failed : Execution error
    pending --> failed : Bridge rejection
    pending --> unknown : Cannot determine
```

* **`pending`** — Source transaction confirmed, bridge protocol hasn't picked it up yet
* **`inflight`** — Bridge protocol is processing the cross-chain message
* **`delivered`** — Tokens and callbacks successfully delivered on the destination chain
* **`failed`** — Bridge or callback execution failed (check `error` and `ensoDestinationEvent` for details)
* **`unknown`** — Status could not be determined

## Identifying the Bridge Protocol

<Tabs>
  <Tab title="Route API">
    When using the Route API, the response tells you which bridge was automatically selected:

    1. Check the `route` array for the hop where `action === "bridge"` — its `protocol` field contains the bridge protocol
    2. The `bridgingEstimates` array provides the protocol name and estimated delivery time

    ```typescript theme={null}
    const route = await ensoClient.getRouteData({
      fromAddress: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      chainId: 1,
      destinationChainId: 8453,
      tokenIn: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"],
      tokenOut: ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],
      amountIn: ["1000000000"],
      slippage: "300",
      routingStrategy: "delegate",
    });

    // Extract bridge protocol from the route hops
    const bridgeHop = route.route.find((hop) => hop.action === "bridge");
    const bridgeProtocol = bridgeHop?.protocol; // "stargate" | "ccip" | "relay" | "cctp"

    // Get estimated delivery time (useful for initial polling delay)
    const estimatedSeconds = route.bridgingEstimates?.[0]?.estimatedSeconds;
    ```
  </Tab>

  <Tab title="Bundle API">
    When using the Bundle API, you already know the bridge protocol — it's the `protocol` field you specified in your bridge action:

    ```typescript theme={null}
    const bundle = await client.getBundleData(
      { chainId: 1, fromAddress: "0x...", routingStrategy: "router" },
      [
        {
          protocol: "stargate", // <-- This is your bridge protocol
          action: "bridge",
          args: {
            primaryAddress: "0x...",
            destinationChainId: 42161,
            tokenIn: "0x...",
            amountIn: "1000000000",
            receiver: "0x...",
          },
        },
      ],
    );
    ```
  </Tab>
</Tabs>

## Status Check Endpoints

<AccordionGroup>
  <Accordion title="CCIP (Chainlink)">
    `GET /api/v1/ccip/bridge/check` — Check Chainlink CCIP bridge transaction status.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const API_KEY = process.env.ENSO_API_KEY;
      const chainId = 56; // Source chain (e.g., BNB Chain)
      const txHash = "0x80f1faf..."; // Source transaction hash

      const response = await fetch(
      `https://api.enso.finance/api/v1/ccip/bridge/check?chainId=${chainId}&txHash=${txHash}`,
      {
      headers: { Authorization: `Bearer ${API_KEY}` },
      }
      );
      const data = await response.json();

      console.log(data.status); // "pending" | "inflight" | "delivered" | "failed" | "unknown"
      console.log(data.sourceChainEstimatedTimeForFinalitySeconds); // Seconds until finality
      console.log(data.destinationTxHash); // Destination tx hash when delivered

      ```

      ```bash cURL theme={null}
      curl "https://api.enso.finance/api/v1/ccip/bridge/check?chainId=56&txHash=0x80f1faf..." \
        -H "Authorization: Bearer $ENSO_API_KEY"
      ```
    </CodeGroup>

    **Response fields:**

    | Field                                        | Type             | Description                                                                          |
    | -------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------ |
    | `status`                                     | `string`         | `pending` / `inflight` / `delivered` / `failed` / `unknown`                          |
    | `sourceChainId`                              | `number`         | Source chain ID                                                                      |
    | `sourceTxHash`                               | `string`         | Source transaction hash                                                              |
    | `sourceChainIdFinality`                      | `number`         | Required finality time in seconds for the source chain                               |
    | `sourceChainEstimatedTimeForFinalitySeconds` | `number?`        | Estimated seconds remaining until finality                                           |
    | `destinationChainId`                         | `number?`        | Destination chain ID                                                                 |
    | `destinationTxHash`                          | `string?`        | Destination tx hash (when delivered)                                                 |
    | `ccipSendParamsDecoded`                      | `object?`        | Decoded CCIP params: destination chain, token amounts with metadata, fees, gas limit |
    | `ensoSourceEvent`                            | `object \| null` | Enso execution event on source chain                                                 |
    | `ensoDestinationEvent`                       | `object \| null` | Enso callback execution event on destination                                         |
    | `error`                                      | `string?`        | Error message if something went wrong                                                |

    <Warning>
      **Finality delay**: CCIP waits for source chain finalization before delivering
      to the destination. This can range from sub-second (Avalanche) to 15-20
      minutes (Ethereum, Optimism). Use `sourceChainEstimatedTimeForFinalitySeconds`
      to determine your initial polling delay. See [Chainlink's Finality By
      Blockchain](https://docs.chain.link/ccip/ccip-execution-latency#finality-by-blockchain)
      for current times per chain.
    </Warning>
  </Accordion>

  <Accordion title="CCTP (Circle)">
    `GET /api/v1/cctp/bridge/check` — Check Circle CCTP v2 bridge transaction status.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const API_KEY = process.env.ENSO_API_KEY;
      const chainId = 8453; // Source chain (e.g., Base)
      const txHash = "0x4ac72089..."; // Source transaction hash

      const response = await fetch(
      `https://api.enso.finance/api/v1/cctp/bridge/check?chainId=${chainId}&txHash=${txHash}`,
      {
      headers: { Authorization: `Bearer ${API_KEY}` },
      }
      );
      const data = await response.json();

      console.log(data.status); // "pending" | "inflight" | "delivered" | "failed" | "unknown"
      console.log(data.cctpTransferType); // "fast" | "standard" (executed mode)
      console.log(data.destinationTxHash); // Destination tx hash when delivered

      ```

      ```bash cURL theme={null}
      curl "https://api.enso.finance/api/v1/cctp/bridge/check?chainId=8453&txHash=0x4ac72089..." \
        -H "Authorization: Bearer $ENSO_API_KEY"
      ```
    </CodeGroup>

    **Response fields:**

    | Field                           | Type                    | Description                                                                                               |
    | ------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------- |
    | `status`                        | `string`                | `pending` / `inflight` / `delivered` / `failed` / `unknown`                                               |
    | `sourceChainId`                 | `number`                | Source chain ID                                                                                           |
    | `sourceTxHash`                  | `string`                | Source transaction hash                                                                                   |
    | `destinationChainId`            | `number?`               | Destination chain ID (resolved from CCTP domain)                                                          |
    | `destinationTxHash`             | `string?`               | Destination tx hash (when minted)                                                                         |
    | `cctpTransferType`              | `"fast" \| "standard"?` | Reflects `finalityThresholdExecuted` (may differ from requested type)                                     |
    | `depositForBurn`                | `object?`               | Raw `depositForBurn` params — present only when the source call had no hookData                           |
    | `depositForBurnDecoded`         | `object?`               | Decoded `depositForBurn`: token metadata, chain IDs, `maxFee` vs `feeExecuted`, finality info             |
    | `depositForBurnWithHook`        | `object?`               | Raw `depositForBurnWithHook` params — present only when hookData is non-empty                             |
    | `depositForBurnWithHookDecoded` | `object?`               | Decoded form including `hookData.forwardingService` (true when bytes match Circle's `cctp-forward` magic) |
    | `ensoSourceEvent`               | `object \| null`        | Enso execution event on source chain                                                                      |
    | `error`                         | `string?`               | Error message if the check failed                                                                         |

    <Note>
      **Fast vs Standard detection**: After the burn is attested, `cctpTransferType`
      is set from `finalityThresholdExecuted` (≤ 1000 = `fast`, ≥ 2000 =
      `standard`). This is the **actual** path Circle took — it can differ from your
      requested `cctpTransferType` if Fast allowance was exhausted or the source
      chain didn't support Fast.
    </Note>

    <Tip>
      **Manual claim**: If a transfer gets stuck, call [`GET
              /api/v1/cctp/bridge/claim`](/pages/use-cases/bridges/cctp-bridge#manual-claim-recovery-flow)
      to get a ready-to-submit `receiveMessage` transaction for the destination
      chain. Both endpoints are rate-limited to 1 request per 10 seconds.
    </Tip>

    <Note>
      **Upstream source**: this endpoint is backed by Circle's Iris [`GET
              /v2/messages/{sourceDomainId}
              `](https://developers.circle.com/api-reference/cctp/all/get-messages-v2) —
      Enso wraps it with on-chain enrichment (token metadata, chain IDs decoded from
      CCTP domains, executed-fee vs requested-fee). See Circle's [supported
      blockchains
      matrix](https://developers.circle.com/cctp/concepts/supported-chains-and-domains#supported-blockchains)
      for which chains support Fast Transfer.
    </Note>
  </Accordion>

  <Accordion title="Relay">
    `GET /api/v1/relay/bridge/check` — Check Relay bridge transaction status.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const API_KEY = process.env.ENSO_API_KEY;
      const chainId = 1; // Source chain
      const txHash = "0x94e5ea9..."; // Source transaction hash

      const response = await fetch(
      `https://api.enso.finance/api/v1/relay/bridge/check?chainId=${chainId}&txHash=${txHash}`,
      {
      headers: { Authorization: `Bearer ${API_KEY}` },
      }
      );
      const data = await response.json();

      console.log(data.status); // "pending" | "inflight" | "delivered" | "failed" | "unknown"
      console.log(data.destinationTxHash); // Destination tx hash when delivered

      ```

      ```bash cURL theme={null}
      curl "https://api.enso.finance/api/v1/relay/bridge/check?chainId=1&txHash=0x94e5ea9..." \
        -H "Authorization: Bearer $ENSO_API_KEY"
      ```
    </CodeGroup>

    **Response fields:**

    | Field                  | Type             | Description                                                                       |
    | ---------------------- | ---------------- | --------------------------------------------------------------------------------- |
    | `status`               | `string`         | `pending` / `inflight` / `delivered` / `failed` / `unknown`                       |
    | `sourceChainId`        | `number`         | Source chain ID                                                                   |
    | `sourceTxHash`         | `string`         | Source transaction hash                                                           |
    | `destinationChainId`   | `number?`        | Destination chain ID                                                              |
    | `destinationTxHash`    | `string?`        | Destination tx hash (when delivered)                                              |
    | `relayRequest`         | `object?`        | Relay details: raw status, user, recipient, in/out txs, fee breakdown, timestamps |
    | `ensoSourceEvent`      | `object \| null` | Enso execution event on source chain                                              |
    | `ensoDestinationEvent` | `object \| null` | Enso callback execution event on destination                                      |
    | `error`                | `string?`        | Error message if something went wrong                                             |

    <Tip>
      **Fee breakdown**: `relayRequest.fees` provides a detailed breakdown in wei
      (`gas`, `fixed`, `price`), and `relayRequest.feesUsd` gives USD equivalents
      for each component.
    </Tip>
  </Accordion>

  <Accordion title="Stargate">
    `GET /api/v1/stargate/bridge/check` — Check Stargate (LayerZero) bridge transaction status.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const API_KEY = process.env.ENSO_API_KEY;
      const chainId = 1; // Source chain
      const txHash = "0x80f1faf..."; // Source transaction hash

      const response = await fetch(
      `https://api.enso.finance/api/v1/stargate/bridge/check?chainId=${chainId}&txHash=${txHash}`,
      {
      headers: { Authorization: `Bearer ${API_KEY}` },
      }
      );
      const data = await response.json();

      console.log(data.status); // "pending" | "inflight" | "delivered" | "failed" | "unknown"
      console.log(data.destinationTxHash); // Destination tx hash when delivered

      ```

      ```bash cURL theme={null}
      curl "https://api.enso.finance/api/v1/stargate/bridge/check?chainId=1&txHash=0x80f1faf..." \
        -H "Authorization: Bearer $ENSO_API_KEY"
      ```
    </CodeGroup>

    **Response fields:**

    | Field                  | Type             | Description                                                 |
    | ---------------------- | ---------------- | ----------------------------------------------------------- |
    | `status`               | `string`         | `pending` / `inflight` / `delivered` / `failed` / `unknown` |
    | `sourceChainId`        | `number`         | Source chain ID                                             |
    | `sourceTxHash`         | `string`         | Source transaction hash                                     |
    | `destinationChainId`   | `number?`        | Destination chain ID (when known)                           |
    | `destinationTxHash`    | `string?`        | Destination tx hash (when delivered)                        |
    | `isMultiBridge`        | `boolean?`       | `true` for multi-hop bridge transactions                    |
    | `hops`                 | `array?`         | Individual hop details for multi-bridge transactions        |
    | `layerZeroMessage`     | `object?`        | LayerZero message pathway and timing details                |
    | `ensoSourceEvent`      | `object \| null` | Enso execution event on source chain                        |
    | `ensoDestinationEvent` | `object \| null` | Enso callback execution event on destination                |
    | `ensoMetadata`         | `object?`        | Request metadata (tokenIn, tokenOut, amountIn)              |
    | `error`                | `string?`        | Error message if something went wrong                       |

    <Note>
      **Multi-hop support**: Stargate supports multi-hop transactions (up to 5
      sequential bridges). When `isMultiBridge` is `true`, the `hops` array contains
      per-hop status tracking with individual `sourceChainId`, `destinationChainId`,
      `status`, and `layerZeroMessage` fields.
    </Note>
  </Accordion>
</AccordionGroup>

## Callback Execution Events

Stargate, CCIP, and Relay include both `ensoSourceEvent` and `ensoDestinationEvent` in their responses — these track whether Enso's callback logic executed successfully on each chain.

CCTP returns only `ensoSourceEvent` (no Enso callback runs on the destination because CCTP doesn't support post-bridge actions — the mint is a pure Circle `receiveMessage`).

| Field                          | Value   | Meaning                                                         |
| ------------------------------ | ------- | --------------------------------------------------------------- |
| `ensoSourceEvent`              | `null`  | Source event not yet found                                      |
| `ensoSourceEvent.success`      | `true`  | Source chain execution succeeded                                |
| `ensoSourceEvent.success`      | `false` | Source chain execution failed — check `error` field             |
| `ensoDestinationEvent`         | `null`  | Destination event not yet found (bridge still in transit)       |
| `ensoDestinationEvent.success` | `true`  | Destination callback executed successfully                      |
| `ensoDestinationEvent.success` | `false` | Destination callback failed — check `error` and `refundDetails` |

When a callback fails, `refundDetails` provides information about where funds were sent:

```json theme={null}
{
  "refundDetails": {
    "token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "amount": "1000000000",
    "recipient": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    "isNative": false
  }
}
```

## Resources

* [Crosschain Routing Guide](/pages/build/get-started/crosschain-routing) — How to build crosschain transactions
* [Crosschain Bridges](/pages/use-cases/bridges/index) — Bridge protocol use cases and examples
* [Bridge Action Reference](/pages/build/reference/actions#bridge) — Technical details on bridge parameters

<div className="text-right text-xs gray-200 font-semibold w-full" style={{marginTop: '0'}}>
  <p style={{
        color: "#b2b2b2"  
    }}>Updated {date_0}</p>
</div>
