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

# Activate Chains on a Portfolio (Stage 2)

> Stage 2 of the two-stage chain-activation flow — submits the owner's signature and creates smart accounts on the new chains.

Stage 2 of the two-stage chain-activation flow. Verifies the portfolio
owner's signature over the message returned by
`POST /v2/portfolios/{portfolioId}/chains/signature`, then creates one
smart account per requested chain inside a single transaction. On
success the portfolio can receive deposits and operate on the new chains
immediately.

The signature is verified according to the portfolio's account type:
ECDSA portfolios submit an EIP-191 `personal_sign` signature that may
cover several chains at once; ERC-1271 portfolios submit their
smart-contract wallet's signature over the stage-1 EIP-712 typed data,
verified against the owner contract on the requested chain — exactly one
chain per request.

Smart accounts use deterministic CREATE2 addresses — the **same address**
as the portfolio's existing smart accounts, now live on the new chains.
The response mirrors the `smartAccounts` shape returned by
`POST /v2/enroll` and `GET /v2/portfolios/{portfolioId}`.

* Auth: `x-api-key` header (required)
* Scope: `portfolios:write`

`chainIds` must **exactly match** the set passed to the signature stage —
the owner's signature covers that specific chain set, and any drift fails
verification with `400`.

The operation is **idempotent on the signed payload**: retrying with the
same `chainIds` + `signature` replays the original response instead of
failing on the already-active chains. A concurrent identical request
returns `409` while the first is still in flight.

Common error responses:

* `400` when the body is invalid, the signature does not verify, a chain
  is already active, the portfolio is Solana, or more than one chain is
  requested on an ERC-1271 portfolio
* `401` when `x-api-key` is missing or invalid
* `403` when the API key lacks the `portfolios:write` scope
* `404` when the portfolio does not exist or belongs to another tenant
* `409` when an identical activation request is still in flight

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.glider.fi/v2/portfolios/pf_01JWZEE2MF30KVRMRX53N88VA4/chains' \
    --header 'x-api-key: gldr_sk_your_api_key' \
    --header 'Content-Type: application/json' \
    --data '{
      "chainIds": [42161],
      "signature": "0x8b2c...signed-by-portfolio-owner...1c"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.glider.fi/v2/portfolios/pf_01JWZEE2MF30KVRMRX53N88VA4/chains",
    {
      method: "POST",
      headers: {
        "x-api-key": "gldr_sk_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        chainIds: [42161],
        signature: "0x8b2c...signed-by-portfolio-owner...1c",
      }),
    },
  );
  ```
</RequestExample>

<ResponseExample>
  ```json 201 theme={null}
  {
    "success": true,
    "data": {
      "portfolioId": "pf_01JWZEE2MF30KVRMRX53N88VA4",
      "smartAccounts": [
        {
          "accountId": "eip155:42161:0xe3a2d1f49aee887e42655b56371d4d76bbf58058"
        }
      ]
    }
  }
  ```

  ```json 400 (invalid signature) theme={null}
  {
    "success": false,
    "error": {
      "code": "API_400",
      "message": "Signature does not match the chain-activation session-key message for this portfolio's owner"
    }
  }
  ```

  ```json 404 theme={null}
  {
    "success": false,
    "error": {
      "code": "API_200",
      "message": "Portfolio with ID pf_01JWZEE2MF30KVRMRX53N88VA4 not found"
    }
  }
  ```

  ```json 409 theme={null}
  {
    "success": false,
    "error": {
      "code": "API_007",
      "message": "An identical chain-activation request is still in progress"
    }
  }
  ```
</ResponseExample>
