Skip to main content
Use the public agent invoke endpoint when you want to send a message to an agent from your own app or service. In Fetch Hive, you can copy the request shape from More -> Get Code in the agents sidebar or from Code Snippet in the agent editor.

Authentication

Authorization: Bearer YOUR_API_KEY
See API Keys for how to create and manage keys.

Endpoint

POST https://api.fetchhive.com/v1/agent/invoke If you want Fetch Hive to generate the cURL example for you, open Agents, then use More -> Get Code. If you are already in the editor for a specific agent, click Code Snippet instead.

Request

Use this request shape:
FieldTypeRequiredDescription
agentstringYesThe agent ID
messagestringYesThe message you want to send to the agent
streamingbooleanNoWhether the response should stream back as events
thread_idstringNoAn arbitrary string identifying the conversation thread. Fetch Hive creates a new thread on first use and resumes it on subsequent calls with the same value.
messagesarrayNoPrevious conversation turns supplied by the caller. Used as context without persisting to the database. Each item: { "content": string, "role": "user" | "assistant" | "system", "attachments"?: array, "image_urls"?: array }.
attachmentsarrayNoHTTPS file URLs attached to the current message. Each item can be a URL string or an object with file_url. Supported document files are CSV, XLSX, PDF, DOCX, and text/Markdown by extension. Images can also be passed here.
image_urlsarrayNoBackward-compatible shorthand for HTTPS image attachments on the current message. Use this for image-only integrations, especially when the image URL has no extension.
metadataobjectNoFlat caller-defined metadata for audit and log filtering. This is not added to the agent prompt.
metadata must be flat and scalar-only: strings, numbers, booleans, or null. Nested objects and arrays return a validation error before the run starts. attachments items can be simple URL strings:
[
  "https://example.com/customer-brief.pdf",
  "https://uploads.fetchhive.com/uploads/grme67114iieusl54m3u4swipr3v"
]
They can also use this object shape when you want to provide metadata:
{
  "file_url": "https://example.com/customer-brief.pdf",
  "file_name": "customer-brief.pdf",
  "file_type": "application/pdf"
}
Only https:// URLs are accepted. Up to five attachments are allowed per message, counting both attachments and image_urls. Document attachments are exposed to the agent through the system read_file tool as an <available_files> manifest; the agent calls read_file before relying on document contents. If an attachment URL or type is invalid, Fetch Hive returns a 422 validation error instead of opening the stream. The error uses the standard error_code, error, and message fields; error and message are localized from the authenticated account language when available. Supported document attachments:
  • CSV: text/csv, .csv
  • XLSX: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, .xlsx
  • PDF: application/pdf, .pdf
  • DOCX: application/vnd.openxmlformats-officedocument.wordprocessingml.document, .docx
  • Text and Markdown by extension: .txt, .md, .markdown
For extensionless URLs, such as Fetch Hive Media Library URLs, pass the URL directly. Fetch Hive allow-lists the URL for read_file, and the file tool detects the actual type when it fetches the file. The in-app snippet shows the same body shape:
{
  "agent": "AGENT_UUID",
  "message": "Your message here",
  "streaming": true,
  "metadata": {
    "customer_id": "cus_123",
    "plan": "enterprise"
  }
}

Basic example

curl 'https://api.fetchhive.com/v1/agent/invoke' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  --data-raw '{
    "agent": "AGENT_UUID",
    "message": "Summarize the latest AI infrastructure trends",
    "metadata": {
      "customer_id": "cus_123",
      "plan": "enterprise"
    },
    "attachments": [
      "https://example.com/customer-brief.pdf"
    ],
    "streaming": true
  }' \
  --compressed
This matches the cURL snippet shown in the product. The invoke dialog currently shows cURL, while Python and TypeScript still show Coming Soon. Use metadata for audit fields you want to see or filter in logs, such as customer IDs, plan names, regions, or experiment names. It is stored with the run and displayed under User metadata in logs. See Invoke metadata for examples and log filtering details.

Response

If streaming is true, the route returns a stream of events rather than one final JSON object. If the provider fails after the stream has opened, the route sends a final error event before closing the stream.

Streaming response

The stream can include a summary event, reasoning chunks, response chunks, tool events, a final usage event, or an error event. Events arrive in this order when all successful events are present: summaryreasoningresponsetoolusage. An error event can arrive instead of usage if the provider fails mid-stream. Summary event (only emitted on threads with auto-summarization enabled):
{
  "type": "summary",
  "summary_text": "The conversation covered AI infrastructure trends. The user asked about evals and tool routing...",
  "original_token_count": 15234,
  "context_limit": 200000,
  "model": "gpt-4.1",
  "provider": "openai"
}
This event fires at the start of the stream when the accumulated thread history has crossed the auto-summarization threshold. It means the prior conversation was compressed into a summary before being sent to the model — the agent retains the context, but the raw history has been condensed. original_token_count is the token count before compression; context_limit is the model’s total context window. You can surface this to users as a “conversation summarized” indicator, or ignore it — your app’s behaviour is unaffected either way. Reasoning event:
{
  "request_id": "req_019d52846ea37682b03522fd0695cc43",
  "type": "reasoning",
  "response": "Looking at the latest model releases..."
}
Response event:
{
  "request_id": "req_019d52846ea37682b03522fd0695cc43",
  "type": "response",
  "response": "Teams are standardizing around evals, routing, and observability.",
  "done": false
}
Tool event:
{
  "request_id": "req_019d52846ea37682b03522fd0695cc43",
  "type": "tool",
  "tool_id": "tool_123",
  "tool": "google_search",
  "tool_input": {
    "query": "latest AI infrastructure trends 2026"
  },
  "observation": {
    "results": []
  }
}
Final usage event:
{
  "request_id": "req_019d52846ea37682b03522fd0695cc43",
  "type": "usage",
  "usage": {
    "duration": 4.79230260848999,
    "input_tokens": {
      "total_tokens": 24,
      "cached_tokens": 0
    },
    "output_tokens": {
      "total_tokens": 170,
      "reasoning_tokens": 64
    },
    "total_tokens": 194
  },
  "stop_reason": "completed"
}
Error event:
{
  "request_id": "req_019d52846ea37682b03522fd0695cc43",
  "type": "error",
  "id": "msg_019d52846ea37682b03522fd0695cc43",
  "error": "openai provider stream error: HTTP 400: invalid request",
  "message": "openai provider stream error: HTTP 400: invalid request",
  "provider": "openai",
  "error_type": "provider_stream_error",
  "status_code": 502
}

Non-streaming response

If streaming is false, the route returns one JSON response with the generated output, usage data, and the request ID you can use to inspect the run in Logs. Provider execution failures return 502 Bad Gateway with an error message. The exact output field can vary by provider, but the response includes the run metadata you need. For example:
{
  "request_id": "req_019d528660dd7e22b15e5b13a1931c50",
  "model": "gpt-5-nano-2025-08-07",
  "duration": 4.641960144042969,
  "response": "Teams are moving from simple wrappers to systems with evals, tool routing, and tighter cost controls.",
  "reasoning": "The request asks for a short summary of current infrastructure trends.",
  "usage": {
    "input_tokens": {
      "total_tokens": 24,
      "cached_tokens": 0
    },
    "output_tokens": {
      "total_tokens": 187,
      "reasoning_tokens": 64
    },
    "total_tokens": 211
  },
  "stop_reason": "completed"
}
If the agent uses tools, the non-streaming response can also include tool execution details.

Multi-turn conversations

The invoke endpoint supports two approaches for multi-turn conversations.

Persistent threads (Fetch Hive manages history)

Pass a thread_id — any string you choose — and Fetch Hive will automatically create the thread on the first call and resume it on every subsequent call with the same value. Message history is stored in Fetch Hive and included in the context automatically.
# First turn
curl 'https://api.fetchhive.com/v1/agent/invoke' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "agent": "AGENT_UUID",
    "message": "What are the main AI infrastructure trends right now?",
    "streaming": true,
    "thread_id": "user-456-support-session"
  }'

# Second turn — same thread_id resumes the conversation
curl 'https://api.fetchhive.com/v1/agent/invoke' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "agent": "AGENT_UUID",
    "message": "Which of those trends have the most enterprise adoption?",
    "streaming": true,
    "thread_id": "user-456-support-session"
  }'
You can use any string as a thread_id — a user ID, session ID, ticket number, or any other identifier that makes sense for your use case.

Stateless history (caller manages history)

If you prefer to manage conversation state yourself, pass the previous turns in the messages array. Fetch Hive uses the provided history for context but does not persist it.
curl 'https://api.fetchhive.com/v1/agent/invoke' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "agent": "AGENT_UUID",
    "message": "Which of those trends have the most enterprise adoption?",
    "streaming": true,
    "messages": [
      {
        "content": "What are the main AI infrastructure trends right now?",
        "role": "user",
        "attachments": [
          {
            "file_url": "https://example.com/market-data.csv",
            "file_name": "market-data.csv",
            "file_type": "text/csv"
          }
        ]
      },
      { "content": "Teams are focusing on evals, tool routing, and observability.", "role": "assistant" }
    ]
  }'
If a previous assistant turn generated a file, pass that file back on the relevant history message through messages[].attachments. Fetch Hive uses the structured attachment URLs in current and historical messages to attach the provider-facing read_file tool and authorize access for follow-up turns; URLs mentioned only in plain text are not treated as file-tool attachments. Use messages when you already maintain your own chat state and do not need Fetch Hive to store the conversation history.

Next steps