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

# Agent quickstart

> Open a session, give the agent a task, and poll for the finished result.

This guide runs a complete agent turn: create a session, send a task, wait for the answer, and continue the conversation. Use either official SDK below or follow the cURL walkthrough for the raw request lifecycle.

## Prerequisites

* An API key ID and secret with Agent API access ([contact support](mailto:support@higgsfield.ai) to enable it)
* A credit balance — agent turns and the generations they run are billed to your account

<Warning>
  API credentials grant access to your account and credits. Use them only in server-side code and never commit them to source control.
</Warning>

## Use the SDK

Install Python SDK 0.2.0 or later:

```bash theme={"dark"}
pip install "higgsfield-client>=0.2.0"
```

The `agents` namespace covers the whole flow. `run()` sends the task and polls with backoff until the turn ends, so one call returns the finished answer:

```python Python theme={"dark"}
from higgsfield_client import SyncClient

client = SyncClient(api_key="key-id:key-secret")

# Sessions are durable: keep the id, the agent remembers previous turns.
session = client.agents.sessions.create()

result = client.agents.sessions.run(
    session.session_id,
    "Generate one image of a quiet alpine lake at sunrise, editorial "
    "photography, 4:3. Reply with the image URL.",
    # Answer a clarifying question inline; without the handler run() returns
    # TurnResult(status="awaiting_input") with the question in .text.
    on_question=lambda question: "Photorealistic style.",
)
print(result.status)      # completed | failed | awaiting_input
print(result.text)        # the agent's answer
print(result.asset_urls)  # URLs of generated assets

# Follow-ups reuse the same session (memory persists).
follow_up = client.agents.sessions.run(
    session.session_id, "Now make a 16:9 version of the same scene at dusk."
)

# Give the agent an input file: upload, then reference the URL in the task.
with open("photo.jpeg", "rb") as f:
    url = client.agents.media.upload(f.read(), extension="jpeg", type="image")
client.agents.sessions.run(session.session_id, f"Animate this image: {url}")
```

`SyncClient()` also reads credentials from `HF_KEY` or the pair `HF_API_KEY` and `HF_API_SECRET`. `AsyncClient` exposes the same agent methods; await each call. `on_question` is a synchronous callback returning an answer string for both clients.

Python `run()` polls with backoff from 2 to 10 seconds and waits up to 30 minutes by default. Override the wait limit with `run(..., timeout=seconds)`. If the limit is reached, it raises `AgentTimeoutError`; the server-side turn keeps running. Read its messages or explicitly call `sessions.interrupt()` to request that it stop.

### TypeScript

Install JS SDK 0.2.4 or later and use the recommended `@higgsfield/client/v2` entry point:

```bash theme={"dark"}
npm install "@higgsfield/client@^0.2.4"
```

```typescript TypeScript theme={"dark"}
import { readFile } from 'node:fs/promises';
import { createHiggsfieldClient } from '@higgsfield/client/v2';

const client = createHiggsfieldClient({
  credentials: 'key-id:key-secret',
});
const session = await client.agents.sessions.create();
const result = await client.agents.sessions.run(
  session.session_id,
  'Generate one image of a quiet alpine lake at sunrise. Reply with the image URL.',
  {
    onQuestion: () => 'Photorealistic style.',
    timeout: 30 * 60 * 1000,
  }
);
console.log(result.status, result.text, result.assetUrls);

const bytes = await readFile('photo.jpeg');
const url = await client.agents.media.upload(bytes, 'jpeg', 'image');
await client.agents.sessions.run(session.session_id, `Animate this image: ${url}`);
```

The configured singleton also exposes `higgsfield.agents` after `config({ credentials: 'key-id:key-secret' })`. Import both from `@higgsfield/client/v2`. Explicit clients created with configuration keep their credentials separate.

TypeScript `run()` takes `timeout` in **milliseconds** (default: 30 minutes). Its `onQuestion` handler can return a string or a promise of one. A timeout stops the local wait while the server-side turn continues, just as in Python.

Errors are typed: a busy session raises `SessionBusyError` (a turn is already running — one turn per session at a time), missing access raises `AgentAccessDeniedError`, and an exhausted balance raises `InsufficientCreditsError` in Python or `NotEnoughCreditsError` in TypeScript. Lower-level methods (`sessions.send`, `sessions.messages`, `sessions.interrupt`) are available when you want to drive the poll loop yourself.

## Use cURL

The same flow over raw REST — useful to understand what the SDK does. You'll need `curl` and `jq`.

### 1. Configure credentials

```bash theme={"dark"}
export HF_API_KEY_ID="your-api-key-id"
export HF_API_KEY_SECRET="your-api-key-secret"
```

### 2. Create a session

```bash theme={"dark"}
SESSION=$(curl --silent --show-error --fail-with-body \
  --request POST \
  --url https://api.higgsfield.ai/v1/agent/sessions \
  --header "Authorization: Key ${HF_API_KEY_ID}:${HF_API_KEY_SECRET}" \
  --header "Content-Type: application/json" \
  --data '{}')

echo "$SESSION" | jq
export SESSION_ID=$(echo "$SESSION" | jq --raw-output '.session_id')
```

```json theme={"dark"}
{
  "session_id": "50eeb94c-c396-439d-b504-aee2147b7ec0",
  "status": "idle"
}
```

Sessions are durable: keep the `session_id` and reuse it — the agent remembers previous turns.

### 3. Send a task

```bash theme={"dark"}
MESSAGE=$(curl --silent --show-error --fail-with-body \
  --request POST \
  --url "https://api.higgsfield.ai/v1/agent/sessions/${SESSION_ID}/messages" \
  --header "Authorization: Key ${HF_API_KEY_ID}:${HF_API_KEY_SECRET}" \
  --header "Content-Type: application/json" \
  --data '{
    "content": "Generate one image of a quiet alpine lake at sunrise, editorial photography, 4:3. Reply with the image URL."
  }')

echo "$MESSAGE" | jq
```

```json theme={"dark"}
{
  "message_id": "4bf91fcb-abb3-44f4-815c-a74dda7817d3",
  "status": "processing"
}
```

The request is accepted with `202` and the turn runs asynchronously. If the session is already running a turn you get `409 session_busy`.

### 4. Poll for the result

```bash theme={"dark"}
curl --silent --show-error --fail-with-body \
  --url "https://api.higgsfield.ai/v1/agent/sessions/${SESSION_ID}/messages" \
  --header "Authorization: Key ${HF_API_KEY_ID}:${HF_API_KEY_SECRET}" | jq
```

Poll every few seconds (start at two, back off to ten) until the assistant message for your turn has `"status": "completed"`. A simple turn finishes in under a minute; a turn with several generations can take considerably longer.

```json theme={"dark"}
{
  "status": "idle",
  "messages": [
    {
      "message_id": "4bf91fcb-abb3-44f4-815c-a74dda7817d3",
      "role": "user",
      "status": "completed",
      "message": { "type": "text", "text": "Generate one image of..." },
      "created_at": "2026-09-01T14:37:53.000Z"
    },
    {
      "message_id": "a0600bbf-b0c8-4c13-b0ff-83df14a2aa2d",
      "role": "assistant",
      "status": "completed",
      "message": {
        "id": "a0600bbf-b0c8-4c13-b0ff-83df14a2aa2d",
        "role": "assistant",
        "parts": [
          { "type": "text", "text": "Here is your image: https://cdn.higgsfield.ai/..." }
        ]
      },
      "created_at": "2026-09-01T14:38:41.000Z"
    }
  ]
}
```

The assistant's `message` is a structured object; the answer text lives in its `parts` array. To extract it:

```bash theme={"dark"}
curl --silent --show-error --fail-with-body \
  --url "https://api.higgsfield.ai/v1/agent/sessions/${SESSION_ID}/messages" \
  --header "Authorization: Key ${HF_API_KEY_ID}:${HF_API_KEY_SECRET}" \
  | jq --raw-output '
      [.messages[] | select(.role == "assistant" and .status == "completed")]
      | last
      | [.message.parts[] | select(.type == "text") | .text]
      | join("\n")'
```

### 5. Continue the conversation

The session keeps memory. Send a follow-up the same way:

```bash theme={"dark"}
curl --silent --show-error --fail-with-body \
  --request POST \
  --url "https://api.higgsfield.ai/v1/agent/sessions/${SESSION_ID}/messages" \
  --header "Authorization: Key ${HF_API_KEY_ID}:${HF_API_KEY_SECRET}" \
  --header "Content-Type: application/json" \
  --data '{"content": "Now make a 16:9 version of the same scene at dusk."}'
```

## If the agent asks a question

When a task is ambiguous, the agent may ask for a decision instead of guessing. The session status becomes `awaiting_input` and the turn parks. Answer with a regular message — your reply resumes the same turn:

```bash theme={"dark"}
curl --silent --show-error --fail-with-body \
  --request POST \
  --url "https://api.higgsfield.ai/v1/agent/sessions/${SESSION_ID}/messages" \
  --header "Authorization: Key ${HF_API_KEY_ID}:${HF_API_KEY_SECRET}" \
  --header "Content-Type: application/json" \
  --data '{"content": "Use the photorealistic style."}'
```

## Next steps

* [API reference](/docs/agent/reference) — all endpoints, media uploads, interrupts, errors, and billing.
* [Agent overview](/docs/agent/overview) — what the agent can and cannot do.


## Related topics

- [Client libraries](/docs/how-to/sdk.md)
- [Agent overview](/docs/agent/overview.md)
- [Agent API reference](/docs/agent/reference.md)
- [Quickstart](/docs/quickstart.md)
- [Support](/docs/help/support.md)
