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

# Executing Tools

> Run tools synchronously, asynchronously, or in batches.

Once an agent is bound to a toolkit, it can call tools. Hexel resolves the credentials, calls the provider, and returns the result — your code just says "send this email" and the platform handles auth, retries, and response formatting. This is where the work actually happens.

Once an agent is bound to a toolkit, it can execute that toolkit's tools. The Tool Gateway supports synchronous and asynchronous execution, batching, preflight validation, and idempotency keys for safe retries.

## Execution modes

| Mode        | Behavior                                                                     | Use for                               |
| ----------- | ---------------------------------------------------------------------------- | ------------------------------------- |
| `sync`      | Runs and returns the result inline.                                          | Fast, interactive calls.              |
| `async`     | Returns immediately with a call ID; result delivered via webhook or polling. | Long-running or deferred work.        |
| `batch`     | Runs multiple executions in one request.                                     | Many calls at once.                   |
| `preflight` | Validates inputs without executing.                                          | Checking readiness before committing. |

## Execute a tool

<Tabs>
  <Tab title="Python">
    ```python theme={"dark"}
    # Synchronous (default)
    result = client.tools.execute(
        tool_slug="GMAIL_SEND_EMAIL",
        input={"to": "user@example.com", "subject": "Hello", "body": "Hi there"},
    )

    # Asynchronous
    call = client.tools.execute(
        tool_slug="GITHUB_CREATE_ISSUE",
        input={"repo": "your-org/repo", "title": "Bug report"},
        mode="async",
        webhook_url="https://your-app.example.com/hooks/tool-done",
    )
    # Poll later
    result = client.tools.get_call(call["id"])
    ```
  </Tab>

  <Tab title="curl">
    ```bash theme={"dark"}
    curl -X POST https://api.hexelstudio.com/tools/v1/executions \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: YOUR_IDEMPOTENCY_KEY" \
      -d '{
        "tool_slug": "GMAIL_SEND_EMAIL",
        "input": {"to": "user@example.com", "subject": "Hello", "body": "Hi there"}
      }'
    ```
  </Tab>
</Tabs>

## Preflight validation

Check inputs and credentials before executing:

```python theme={"dark"}
client.tools.preflight(
    tool_slug="GMAIL_SEND_EMAIL",
    input={"to": "user@example.com", "subject": "Hi", "body": "..."},
)
```

## Batch execution

Run several tool calls in one request:

```python theme={"dark"}
results = client.tools.batch([
    {"tool_slug": "SLACK_POST_MESSAGE", "input": {"channel": "#alerts", "text": "Deploy started"}},
    {"tool_slug": "SLACK_POST_MESSAGE", "input": {"channel": "#alerts", "text": "Deploy finished"}},
])
```

## Idempotency

Supply an `idempotency_key` so repeated requests do not execute the tool twice. Use a stable key per logical operation:

```python theme={"dark"}
result = client.tools.execute(
    tool_slug="GMAIL_SEND_EMAIL",
    input={"to": "user@example.com", "subject": "Report", "body": "..."},
    idempotency_key="send-report-2025-06-06",
)
```

## How credential resolution works

<img src="https://mintcdn.com/hexelstudio-2127951d/utVkRjxsT1DGYlO5/assets/diagrams/tool-execution.png?fit=max&auto=format&n=utVkRjxsT1DGYlO5&q=85&s=a1c22c6833ee4c70b96e96bbb74da1ca" alt="Tool execution flow" width="1536" height="1024" data-path="assets/diagrams/tool-execution.png" />

## Errors

| HTTP  | `code`            | When                                                                      |
| ----- | ----------------- | ------------------------------------------------------------------------- |
| `400` | `INVALID_REQUEST` | Missing `tool_slug`, invalid `input`, or a malformed batch.               |
| `404` | —                 | The tool or connected account doesn't exist.                              |
| `409` | —                 | Idempotency conflict — the same key was reused with different parameters. |
| `429` | —                 | Rate limit exceeded (see below).                                          |

## Rate limits

Execution is rate-limited at three levels — per organization, per toolkit, and per connected account — plus any provider-side limit on the tool itself. Exceeding any level returns `429`. Values depend on your plan and the provider; check the [Console](https://console.hexelstudio.com).

<Note>
  Each tool backend has a circuit breaker. If a provider fails repeatedly, calls fail fast for a short period and then recover automatically. Treat a burst of provider `5xx`s as transient and retry with backoff.
</Note>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Tool call fails with an authorization error">
    The connected account's grant has expired or lacks the required scopes, or the agent isn't bound to the toolkit. Reconnect the account and confirm the [binding](/docs/tool-gateway/bindings).
  </Accordion>

  <Accordion title="Execution times out">
    Use asynchronous execution for long-running tools and poll the call result, rather than blocking on a synchronous call.
  </Accordion>

  <Accordion title="A retried call ran twice">
    Pass an `idempotency_key` so repeated requests return the original result instead of executing again.
  </Accordion>
</AccordionGroup>

## Common mistakes

* **Running long jobs synchronously.** Use `async` mode and poll or listen via webhook.
* **Retrying without idempotency.** A naive retry can duplicate side effects.
* **Skipping preflight for destructive calls.** Preflight catches bad inputs before they take effect.

## Best practices

* Preflight calls with side effects before executing.
* Use idempotency keys for any retryable operation.
* Batch related calls to reduce round trips.

## Related pages

<CardGroup cols={2}>
  <Card title="Bindings" icon="link-horizontal" href="/docs/tool-gateway/bindings">
    Required before execution.
  </Card>

  <Card title="Triggers & Webhooks" icon="bolt" href="/docs/tool-gateway/triggers-and-webhooks">
    Execute tools on external events.
  </Card>

  <Card title="Tool Catalog" icon="grip" href="/docs/tool-gateway/catalog">
    Find tool slugs and input schemas.
  </Card>

  <Card title="Connected Accounts" icon="link" href="/docs/tool-gateway/connected-accounts">
    Credentials used during execution.
  </Card>
</CardGroup>
