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

# Run with PHP SDK

> Invoke an agent from PHP with the fetch-hive/sdk Composer package

Use the official `fetch-hive/sdk` Composer package when you want to send a message to an agent from PHP. The SDK wraps the public [`POST /v1/agent/invoke`](../api-reference/invoke-agent) endpoint, handles authentication, exposes streaming responses as a generator, and accepts multimodal inputs.

## Installation

```bash theme={null}
composer require fetch-hive/sdk
```

The SDK requires PHP 8.1+ and uses Guzzle as its HTTP client.

## Authentication

Set the `FETCH_HIVE_API_KEY` environment variable to your workspace API key (the client reads it automatically):

```bash theme={null}
export FETCH_HIVE_API_KEY=fhk_...
```

```php theme={null}
<?php
require_once 'vendor/autoload.php';

use FetchHive\Sdk\FetchHive;

$client = new FetchHive();
```

Or pass the key explicitly:

```php theme={null}
$client = new FetchHive(['api_key' => 'fhk_...']);
```

See [API Keys](../workspace/api-keys) for how to create and rotate keys.

## Basic example

Send a message to an agent and read the final response:

```php theme={null}
<?php
require_once 'vendor/autoload.php';

use FetchHive\Sdk\FetchHive;

$client = new FetchHive();

$reply = $client->invokeAgent([
    'agent'   => 'AGENT_UUID',
    'message' => 'Summarize the latest AI infrastructure trends',
]);

echo $reply['response'];
```

See the [non-streaming response shape](../api-reference/invoke-agent#response).

## Method reference

| Key          | Type       | Required | Description                                                                                                           |
| ------------ | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `agent`      | `string`   | Yes      | The agent ID                                                                                                          |
| `message`    | `string`   | Yes      | The message you want to send                                                                                          |
| `thread_id`  | `string`   | No       | An arbitrary string identifying a persistent conversation thread                                                      |
| `messages`   | `array`    | No       | Caller-managed conversation history. Each item: `['role' => 'user' \| 'assistant' \| 'system', 'content' => string]`. |
| `image_urls` | `string[]` | No       | HTTPS image URLs attached to the current `message` for multimodal inputs                                              |
| `user`       | `string`   | No       | Opaque caller identifier surfaced in [User Tracking](../user-tracking/overview)                                       |
| `metadata`   | `array`    | No       | Flat caller-defined metadata for audit and log filtering. See [Invoke metadata](../user-tracking/invoke-metadata)     |

The SDK injects `streaming: false` for `invokeAgent`. To stream, use `invokeAgentStream` (below).

## Handling the response

```php theme={null}
$reply = $client->invokeAgent([
    'agent'   => 'AGENT_UUID',
    'message' => 'Hello',
]);

echo $reply['response'];        // final text
echo $reply['model'];           // model identifier
print_r($reply['usage']);       // token usage breakdown
echo $reply['request_id'];      // use this to look up the run in Logs
print_r($reply['tool_calls']);  // tool invocations made during the run
```

## Streaming

Use `invokeAgentStream` to receive Server-Sent Events as they arrive. The method returns a `Generator`:

```php theme={null}
foreach ($client->invokeAgentStream([
    'agent'     => 'AGENT_UUID',
    'message'   => 'Summarize the latest AI infrastructure trends',
    'thread_id' => 'user-456-support-session',
]) as $chunk) {
    match ($chunk['type']) {
        'response' => print($chunk['response'] ?? ''),
        'tool'     => print("\nCalling tool: " . ($chunk['tool'] ?? '')),
        'usage'    => print("\n\nUsage: " . json_encode($chunk['usage'])),
        default    => null,
    };
}
```

The stream yields the same event types documented in [Invoke Agent → Response](../api-reference/invoke-agent#response): `summary` (when auto-summarization fires), `reasoning`, `response`, `tool`, a final `usage` event, or an `error` event if the provider fails mid-stream.

## Multi-turn conversations

### Persistent threads

Pass any string as `thread_id` and Fetch Hive will create the thread on the first call and resume it on subsequent calls with the same value:

```php theme={null}
$client->invokeAgent([
    'agent'     => 'AGENT_UUID',
    'message'   => 'What are the main AI infrastructure trends right now?',
    'thread_id' => 'user-456-support-session',
]);

$client->invokeAgent([
    'agent'     => 'AGENT_UUID',
    'message'   => 'Which of those trends have the most enterprise adoption?',
    'thread_id' => 'user-456-support-session',
]);
```

### Stateless history

Manage state yourself by passing the previous turns in `messages`. Fetch Hive uses the supplied history for context but does not persist it:

```php theme={null}
$client->invokeAgent([
    'agent'    => 'AGENT_UUID',
    'message'  => 'Which of those trends have the most enterprise adoption?',
    'messages' => [
        ['role' => 'user',      'content' => 'What are the main AI infrastructure trends right now?'],
        ['role' => 'assistant', 'content' => 'Teams are focusing on evals, tool routing, and observability.'],
    ],
]);
```

## Multimodal inputs

Attach images to the current message with `image_urls`:

```php theme={null}
$result = $client->invokeAgent([
    'agent'      => 'vision-agent',
    'message'    => 'Describe this image',
    'image_urls' => ['https://example.com/photo.jpg'],
]);
echo $result['response'];
```

URLs must start with `https://`.

## Configuration

| Option     | Default                        | Description                     |
| ---------- | ------------------------------ | ------------------------------- |
| `api_key`  | `FETCH_HIVE_API_KEY` env var   | Bearer token from the dashboard |
| `base_url` | `https://api.fetchhive.com/v1` | Override the API base URL       |
| `timeout`  | `120`                          | Request timeout in seconds      |

```php theme={null}
$client = new FetchHive([
    'api_key'  => 'fhk_...',
    'base_url' => 'https://api.fetchhive.com/v1',
    'timeout'  => 120.0,
]);
```

## Errors

Non-2xx responses throw `FetchHive\Sdk\Exception\ApiException` carrying the status code and response body:

```php theme={null}
use FetchHive\Sdk\Exception\ApiException;

try {
    $reply = $client->invokeAgent([
        'agent'   => 'AGENT_UUID',
        'message' => 'Hello',
    ]);
} catch (ApiException $e) {
    error_log('Fetch Hive error: ' . $e->getMessage());
}
```

See [Errors and Rate Limits](../api-reference/errors-and-rate-limits) for status code meanings.

## Links

* [Package on Packagist](https://packagist.org/packages/fetch-hive/sdk)
* [Source on GitHub](https://github.com/Fetch-Hive/php-sdk)

## Next steps

* [Run with API](./run-with-api) - The same flow with cURL
* [Run with Python SDK](./run-with-python-sdk)
* [Run with Node.js SDK](./run-with-nodejs-sdk)
* [Run with Ruby SDK](./run-with-ruby-sdk)
* [Invoke Agent](../api-reference/invoke-agent) - Full endpoint reference
