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

# Execute Plan

> Execute a signed plan to trigger on-chain transactions

# Execute Plan

Executes a previously created plan. The plan must have been signed by the sub-account's signer. This triggers the actual on-chain transaction(s).

## Request

```
POST /accounts/:account_id/plan/execute
```

### Body parameters

| Parameter   | Type   | Required | Description                                                  |
| ----------- | ------ | -------- | ------------------------------------------------------------ |
| `plan_id`   | string | Yes      | The plan ID returned from a plan creation endpoint           |
| `signature` | string | Yes      | EIP-712 signature over the plan's digest (`0x`-prefixed hex) |

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://prime-api.legend.xyz/accounts/acc_2o0yiljtp378/plan/execute \
    -H "Authorization: Bearer $LEGEND_QUERY_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "plan_id": "pln_71mcui082png",
      "signature": "0x1a2b3c4d5e6f..."
    }'
  ```

  ```typescript TypeScript theme={null}
  const result = await client.plan.execute("acc_2o0yiljtp378", {
    planId: "pln_71mcui082png",
    signature: "0x1a2b3c4d5e6f...",
  });
  ```

  ```python Python theme={null}
  result = await client.plan.execute(
      "acc_2o0yiljtp378",
      plan_id="pln_71mcui082png",
      signature="0x1a2b3c4d5e6f...",
  )
  ```

  ```rust Rust theme={null}
  use legend_client::ExecuteParams;

  let result = client.plan.execute("acc_2o0yiljtp378", &ExecuteParams {
      plan_id: "pln_71mcui082png".into(),
      signature: "0x1a2b3c4d5e6f...".into(),
  }).await?;
  ```
</CodeGroup>

```json Response theme={null}
{
  "plan_id": "pln_71mcui082png",
  "quark_intent_id": "qi_abc123",
  "activity_id": "act_xyz789",
  "status": "executing"
}
```

### Response fields

| Field             | Type   | Description                                                                       |
| ----------------- | ------ | --------------------------------------------------------------------------------- |
| `plan_id`         | string | The executed plan's ID                                                            |
| `activity_id`     | string | Activity ID (`act_xxx`) — use with `GET /activities/:id` to poll execution status |
| `quark_intent_id` | string | Intent ID (`qi_xxx`)                                                              |
| `status`          | string | Always `"executing"` on success — the transaction has been submitted              |

## Signing the plan

When you create a plan (earn, withdraw, or transfer), the response includes `details.eip712_data.digest`. This is the EIP-712 hash that the account's signer must sign.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { privateKeyToAccount } from "viem/accounts";

  const signer = privateKeyToAccount(privateKey);
  const signature = await signer.sign({ hash: plan.details.eip712_data.digest });
  ```

  ```python Python theme={null}
  from eth_account import Account

  signer = Account.from_key(private_key)
  digest = plan["details"]["eip712_data"]["digest"]
  sig = signer.unsafe_sign_hash(bytes.fromhex(digest[2:]))
  signature = "0x" + sig.signature.hex()
  ```

  ```rust Rust theme={null}
  let digest = plan.digest().expect("Plan missing digest");
  // Sign with legend-signer or your own EIP-712 signer
  ```
</CodeGroup>

## Errors

| Status | Code             | Description                                            |
| ------ | ---------------- | ------------------------------------------------------ |
| 400    | `invalid_params` | Missing `plan_id` or `signature`                       |
| 404    | `plan_not_found` | Plan doesn't exist or has expired                      |
| 409    | `plan_stale`     | Plan's underlying data has changed — create a new plan |
| 500    | `internal_error` | Signature verification or execution failed             |

## Notes

* Plans expire after 2 minutes. If the plan has expired, create a new one.
* Once executed, the plan is consumed and cannot be re-executed.
* The `status: "executing"` response means the transaction has been submitted but not yet confirmed. Use [Activities](/api-reference/list-activities) or [Events](/api-reference/get-events) to track confirmation.
* The signature must come from the signer key associated with the sub-account. A signature from a different key will be rejected.
