> ## 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 Node.js SDK

> Invoke an agent from Node.js or TypeScript with the @fetch-hive/sdk package

Use the official `@fetch-hive/sdk` package when you want to send a message to an agent from Node.js or TypeScript. The SDK wraps the public [`POST /v1/agent/invoke`](../api-reference/agents/invoke) endpoint, handles authentication, exposes streaming as an `AsyncIterable`, and supports multimodal inputs.

## Installation

```bash theme={null}
npm install @fetch-hive/sdk
# or
yarn add @fetch-hive/sdk
# or
pnpm add @fetch-hive/sdk
```

The SDK targets Node.js 18+ (uses the global `fetch`) and ships with TypeScript types.

## Authentication

Set the `FETCH_HIVE_API_KEY` environment variable to your workspace API key:

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

```typescript theme={null}
import { FetchHive } from '@fetch-hive/sdk';

const client = new FetchHive();
```

Or pass the key explicitly:

```typescript theme={null}
const client = new FetchHive({ apiKey: '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:

```typescript theme={null}
import { FetchHive } from '@fetch-hive/sdk';

const client = new FetchHive();

const reply = await client.invokeAgent({
  agent: 'AGENT_UUID',
  message: 'Summarize the latest AI infrastructure trends',
});

console.log(reply.response);
```

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

## Method reference

| Field       | 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<{ role, content, attachments? }>`              | No       | Caller-managed conversation history                                                                               |
| `user`      | `string`                                              | No       | Opaque caller identifier surfaced in [User Tracking](../user-tracking/overview)                                   |
| `metadata`  | `Record<string, string \| number \| boolean \| null>` | 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

```typescript theme={null}
const reply = await client.invokeAgent({
  agent: 'AGENT_UUID',
  message: 'Hello',
});

console.log(reply.response);     // final text
console.log(reply.model);        // model identifier
console.log(reply.usage);        // token usage breakdown
console.log(reply.request_id);   // use this to look up the run in Logs
console.log(reply.tool_calls);   // tool invocations made during the run
```

## Streaming

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

```typescript theme={null}
for await (const chunk of client.invokeAgentStream({
  agent: 'AGENT_UUID',
  message: 'Summarize the latest AI infrastructure trends',
  thread_id: 'user-456-support-session',
})) {
  if (chunk.type === 'response') {
    process.stdout.write(chunk.response ?? '');
  } else if (chunk.type === 'tool') {
    console.log(`\n[Calling tool: ${chunk.tool}]`);
  } else if (chunk.type === 'usage') {
    console.log('\n\nUsage:', chunk.usage);
  }
}
```

The stream yields the same event types documented in [Invoke Agent → Response](../api-reference/agents/invoke#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:

```typescript theme={null}
await client.invokeAgent({
  agent: 'AGENT_UUID',
  message: 'What are the main AI infrastructure trends right now?',
  thread_id: 'user-456-support-session',
});

await 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:

```typescript theme={null}
await 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 `attachments`:

```typescript theme={null}
const result = await client.invokeAgent({
  agent: 'vision-agent',
  message: 'Describe this image',
  attachments: ['https://example.com/photo.jpg'],
});
console.log(result.response);
```

URLs must start with `https://`.

## Configuration

| Option    | Default                          | Description                     |
| --------- | -------------------------------- | ------------------------------- |
| `apiKey`  | `process.env.FETCH_HIVE_API_KEY` | Bearer token from the dashboard |
| `baseURL` | `https://api.fetchhive.com/v1`   | Override the API base URL       |

```typescript theme={null}
const client = new FetchHive({
  apiKey: 'fhk_...',
  baseURL: 'https://api.fetchhive.com/v1',
});
```

## Errors

Non-2xx responses throw an `Error` whose message includes the status code and response body:

```typescript theme={null}
try {
  const reply = await client.invokeAgent({
    agent: 'AGENT_UUID',
    message: 'Hello',
  });
} catch (err) {
  console.error('Fetch Hive error:', err);
}
```

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

## Links

* [Package on npm](https://www.npmjs.com/package/@fetch-hive/sdk)
* [Source on GitHub](https://github.com/Fetch-Hive/nodejs-sdk)

## Next steps

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