# Integrating Squid Intents

Integrating Squid Intents follows the same flow as a standard Squid integration. If you already have Squid integrated, the only steps are to have Squid Intents enabled on your integrator ID, poll for status with a `quoteId`, and handle the transaction request type.

Squid Intents must be enabled on your integrator ID. Reach out to the Squid team to get started.

### Route Request <a href="#route-request" id="route-request"></a>

Squid Intents uses the `/v2/route` endpoint. When Squid Intents is enabled and a route is available, it will be automatically selected.

**There are no expiry constraints** — You do not need to submit the transaction within a time window.

#### EVM Route Request Example <a href="#evm-route-request-example" id="evm-route-request-example"></a>

<a class="button secondary">Copy</a>

```
const params = {
  fromAddress: signer.address,
  fromChain: "42161",          // Arbitrum
  fromToken: usdcAddress,
  fromAmount: amount,
  toChain: "1",                // Ethereum
  toToken: nativeToken,
  toAddress: signer.address,
  quoteOnly: false,
};

// Get the route
const routeResult = await axios.post(
  "https://v2.api.squidrouter.com/v2/route",
  params,
  {
    headers: {
      "x-integrator-id": integratorId,
      "Content-Type": "application/json",
    },
  }
);

const route = routeResult.data.route;
const quoteId = route.quoteId; // Save this — required for status tracking
console.log("Quote ID:", quoteId);
```

### Transaction Request Types <a href="#transaction-request-types" id="transaction-request-types"></a>

The route response's `transactionRequest` object will include a `transaction_request_type` field that determines how to execute the transaction. There are three types:

TypeDescription

`ON_CHAIN_EXECUTION`

Standard on-chain transaction (EVM). Execute like any Squid transaction.

`DEPOSIT_ADDRESS_CALLDATA`

Deposit to the provided address with the specified calldata. Used for certain non-EVM chains.

`DEPOSIT_ADDRESS_WITH_SIGNATURE`

Submit a signed deposit to the provided address. Used for certain non-EVM chains.

### Executing the Route <a href="#executing-the-route" id="executing-the-route"></a>

#### `ON_CHAIN_EXECUTION` (EVM Transactions) <a href="#on_chain_execution-evm-transactions" id="on_chain_execution-evm-transactions"></a>

For EVM-to-EVM Squid Intents routes where `transaction_request_type` is `ON_CHAIN_EXECUTION`, execution is the same as any Squid transaction:

<a class="button secondary">Copy</a>

```
const tx = await signer.sendTransaction({
  to: route.transactionRequest.target,
  data: route.transactionRequest.data,
  value: route.transactionRequest.value,
  gasLimit: route.transactionRequest.gasLimit,
  gasPrice: route.transactionRequest.gasPrice,
});

const receipt = await tx.wait();
console.log("Transaction hash:", receipt.transactionHash);
```

#### `DEPOSIT_ADDRESS_CALLDATA` & `DEPOSIT_ADDRESS_WITH_SIGNATURE` <a href="#deposit_address_calldata-and-deposit_address_with_signature" id="deposit_address_calldata-and-deposit_address_with_signature"></a>

For certain chains, Squid Intents uses a **deposit address flow** instead of standard on-chain execution. The `transaction_request_type` field will be one of:

* `"DEPOSIT_ADDRESS_CALLDATA"` — submit a deposit to the provided address with the specified calldata
* `"DEPOSIT_ADDRESS_WITH_SIGNATURE"` — submit a signed deposit to the provided address

<a class="button secondary">Copy</a>

```
const route = routeResult.data.route;
const transactionRequest = route.transactionRequest;

// Check the type to determine the execution flow
console.log("Transaction type:", transactionRequest.transaction_request_type);
// "ON_CHAIN_EXECUTION", "DEPOSIT_ADDRESS_CALLDATA", or "DEPOSIT_ADDRESS_WITH_SIGNATURE"

// Follow the deposit instructions in the transactionRequest
// The specific fields will vary by chain and type
```

### Status Tracking <a href="#status-tracking" id="status-tracking"></a>

**Status polling is required for Squid Intents.** After executing a Squid Intent transaction, you **must** call the status API with the `quoteId` parameter. A Squid Intent transaction will fail unless status is called with `quoteId`.

#### Getting the Quote ID <a href="#getting-the-quote-id" id="getting-the-quote-id"></a>

The `quoteId` is returned at the top level of the route response:

<a class="button secondary">Copy</a>

```
{
    "route": {
        "quoteId": "6f388be5205ee044cd7fd5047a4ce72e"
    }
}
```

#### Polling for Status <a href="#polling-for-status" id="polling-for-status"></a>

<a class="button secondary">Copy</a>

```
// Function to get the status of a Coral V2 transaction
const getStatus = async (params) => {
  try {
    const result = await axios.get("https://v2.api.squidrouter.com/v2/status", {
      params: {
        transactionId: params.transactionId,
        fromChainId: params.fromChainId,
        toChainId: params.toChainId,
        quoteId: params.quoteId, // Required for Coral V2
      },
      headers: {
        "x-integrator-id": integratorId,
      },
    });
    return result.data;
  } catch (error) {
    if (error.response) {
      console.error("API error:", error.response.data);
    }
    throw error;
  }
};

// Poll for transaction completion
const updateTransactionStatus = async (txHash, quoteId) => {
  const getStatusParams = {
    transactionId: txHash,
    fromChainId: fromChainId,
    toChainId: toChainId,
    quoteId: quoteId, // Required for Coral V2
  };

  let status;
  const completedStatuses = ["success", "partial_success", "needs_gas", "not_found", "refund"];
  const maxRetries = 10;
  let retryCount = 0;

  do {
    try {
      status = await getStatus(getStatusParams);
      console.log(`Route status: ${status.squidTransactionStatus}`);
    } catch (error) {
      if (error.response && error.response.status === 404) {
        retryCount++;
        if (retryCount >= maxRetries) {
          console.error("Max retries reached. Transaction not found.");
          break;
        }
        console.log("Transaction not found. Retrying...");
        await new Promise((resolve) => setTimeout(resolve, 5000));
        continue;
      } else {
        throw error;
      }
    }

    if (!completedStatuses.includes(status.squidTransactionStatus)) {
      await new Promise((resolve) => setTimeout(resolve, 5000));
    }
  } while (!completedStatuses.includes(status.squidTransactionStatus));
};
```

### Refund Behavior <a href="#refund-behavior" id="refund-behavior"></a>

When a Squid Intent transaction fails, funds are automatically refunded on the source chain. Refunds typically complete within **\~15 minutes**.

* Funds are transferred from the `msg.sender` on the source chain
* Refunds are sent to the `order.fromAddress`, which corresponds to the `fromAddress` in the route request
* This ensures refunds go to the actual user even if the transaction was initiated through a smart contract

### Squid Intents Limitations <a href="#coral-v2-limitations" id="coral-v2-limitations"></a>

* Bitcoin and Solana support is coming soon


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.squidrouter.com/api-and-sdk-integration/coral-intent-swaps/integrating-squid-intents.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
