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

# Integrations

> Reusable HTTP tool integrations that agents can call mid-conversation.

Integrations are reusable tool definitions — an endpoint URL + method +
headers + a JSON schema for arguments — that you can attach to one or
more agents. During a call the agent uses the tool's schema to decide
when to call out; ThunderPhone makes the outbound HTTP request on the
agent's behalf using the integration's saved configuration.

See also [Function Tools](/tools/overview) for the shape of the JSON
schema an integration's `spec` must follow.

## Endpoints

| Method   | Path                                         | Description                                  |
| -------- | -------------------------------------------- | -------------------------------------------- |
| `GET`    | `/v1/integrations`                           | List integrations                            |
| `POST`   | `/v1/integrations`                           | Create an integration                        |
| `GET`    | `/v1/integrations/{integration_id}`          | Retrieve an integration                      |
| `PATCH`  | `/v1/integrations/{integration_id}`          | Update an integration                        |
| `DELETE` | `/v1/integrations/{integration_id}`          | Delete an integration                        |
| `POST`   | `/v1/integrations/{integration_id}/transfer` | Copy / move to another org                   |
| `GET`    | `/v1/integrations/{integration_id}/versions` | List prior configuration revisions           |
| `POST`   | `/v1/integrations/test-request`              | Probe an integration endpoint from a sandbox |

## Integration object

```json theme={null}
{
  "id": "f9b5a1a4-...",
  "display_name": "Weather API",
  "spec": {
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Return the current weather for a zip code.",
      "parameters": { /* JSON Schema */ }
    }
  },
  "endpoint_url": "https://api.example.com/weather",
  "endpoint_method": "GET",
  "headers": [
    { "key": "X-Api-Key", "value": "abc..." }
  ],
  "wizard_input": "Use https://api.example.com/weather with X-Api-Key header.",
  "validation_status": "validated",
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z"
}
```

| Field                      | Type      | Description                                                                                   |
| -------------------------- | --------- | --------------------------------------------------------------------------------------------- |
| `id`                       | UUID      | Integration id                                                                                |
| `display_name`             | string    | 1–255 chars                                                                                   |
| `spec`                     | object    | OpenAI-style function tool schema (see [Function Tools](/tools/overview))                     |
| `endpoint_url`             | string    | Outbound HTTP URL the tool calls. Empty string when the integration is still being configured |
| `endpoint_method`          | string    | `GET`, `POST`, `PUT`, `PATCH`, or `DELETE`. Defaults to `POST`                                |
| `headers`                  | array     | List of `{key, value}` pairs sent with every tool invocation                                  |
| `wizard_input`             | string    | Free-form text from the "describe this integration" wizard; kept for audit only               |
| `validation_status`        | string    | `untested`, `validated`, `error` — updated by [test-request](#test-integration-request)       |
| `created_at`, `updated_at` | timestamp | ISO 8601 UTC                                                                                  |

***

## List integrations

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.thunderphone.com/v1/integrations \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY"
  ```
</CodeGroup>

Returns an array of [Integration objects](#integration-object).

***

## Create an integration

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.thunderphone.com/v1/integrations \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "display_name": "Weather API",
      "spec": {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Return the current weather for a zip code.",
          "parameters": {
            "type": "object",
            "properties": {
              "zip": { "type": "string" }
            },
            "required": ["zip"]
          }
        }
      },
      "endpoint_url":    "https://api.example.com/weather",
      "endpoint_method": "GET",
      "headers": [
        { "key": "X-Api-Key", "value": "abc..." }
      ]
    }'
  ```
</CodeGroup>

### Request fields

| Field             | Type   | Required | Description                                                 |
| ----------------- | ------ | -------- | ----------------------------------------------------------- |
| `display_name`    | string | yes      | 1–255 chars                                                 |
| `spec`            | object | yes      | Function-tool JSON schema. `spec.type` must be `"function"` |
| `endpoint_url`    | string | no       | HTTPS URL; defaults to empty string if omitted              |
| `endpoint_method` | string | no       | `GET`, `POST` (default), `PUT`, `PATCH`, `DELETE`           |
| `headers`         | array  | no       | `[{key, value}]` pairs                                      |
| `wizard_input`    | string | no       | Free-form notes                                             |

Returns `201 Created` with the new [Integration object](#integration-object) in
`validation_status="untested"`.

***

## Retrieve / update / delete

`GET`, `PATCH`, and `DELETE` behave conventionally. `PATCH` accepts any
subset of the create fields. Deleting an integration removes it from
every agent it was linked to.

***

## Transfer an integration

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.thunderphone.com/v1/integrations/f9b5a1a4-.../transfer \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"target_org_id": 77, "mode": "copy"}'
  ```
</CodeGroup>

| Field           | Type    | Required | Description                      |
| --------------- | ------- | -------- | -------------------------------- |
| `target_org_id` | integer | yes      |                                  |
| `mode`          | string  | yes      | `copy` or `move`                 |
| `name`          | string  | no       | Override the copy's display name |

Returns `201 Created` for `copy` / `200 OK` for `move`:

```json theme={null}
{ "mode": "copy", "target_org_id": 77, "integration": { /* ... */ } }
```

***

## Version history

<CodeGroup>
  ```bash cURL theme={null}
  curl 'https://api.thunderphone.com/v1/integrations/f9b5a1a4-.../versions?limit=20' \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY"
  ```
</CodeGroup>

Response is analogous to [Agent versions](/api-reference/agents#version-history):
`{count, results[]}` with each result containing `id`, `revision`,
`created_by`, `snapshot`, and `changed_fields`.

***

## Test integration request

Execute a one-off HTTP request against the integration endpoint
(from ThunderPhone's servers) to validate connectivity before linking
the integration to an agent. The sandbox enforces SSRF guards — no
requests to localhost or private IP ranges.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.thunderphone.com/v1/integrations/test-request \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://api.example.com/weather?zip=94110",
      "method": "GET",
      "headers": { "X-Api-Key": "abc..." }
    }'
  ```
</CodeGroup>

| Field             | Type             | Required | Description                                                     |
| ----------------- | ---------------- | -------- | --------------------------------------------------------------- |
| `url`             | string           | yes      | HTTPS; `http://` is only allowed for localhost during local dev |
| `method`          | string           | yes      | `GET`, `POST`, `PUT`, `PATCH`, `DELETE`                         |
| `headers`         | object           | no       | Header-name → value map                                         |
| `body`            | string \| object | no       | For `POST`/`PUT`/`PATCH`; JSON body or raw string               |
| `timeout_seconds` | integer          | no       | 1–20 (default 10)                                               |

```json Response theme={null}
{
  "ok": true,
  "status": 200,
  "elapsed_ms": 187,
  "response_headers": { "content-type": "application/json" },
  "response_preview": "{\"temperature_f\": 64, ...}"
}
```

Response bodies are truncated at 6 kB. SSRF-blocked requests return
`400` with `code="url_not_allowed"`.

***

## Related

<CardGroup cols={2}>
  <Card title="Agents" icon="robot" href="/api-reference/agents">
    Attach integrations to agents via `integration_ids`.
  </Card>

  <Card title="Function Tools" icon="screwdriver-wrench" href="/tools/overview">
    The JSON schema shape for `spec`.
  </Card>
</CardGroup>
