Agents API Reference

Agent CRUD, chat/query endpoints, SSE streaming, thread management, embedding status. Example requests and responses.

The NFYio Agents API powers RAG (Retrieval-Augmented Generation) pipelines. Create agents, manage threads, send chat messages, and stream responses. Embeddings are built from documents in your storage buckets.

Base URL: https://api.yourdomain.com (or https://agents.yourdomain.com)

Agents

Create Agent

curl -X POST https://api.yourdomain.com/v1/agents \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "docs-assistant",
    "description": "Answers questions from company documentation",
    "model": "gpt-4o-mini",
    "system_prompt": "You are a helpful assistant. Answer based on the provided context.",
    "bucket_id": "bucket_abc123",
    "embedding_paths": ["/docs/**"]
  }'

Response:

{
  "id": "agent_xyz789",
  "name": "docs-assistant",
  "description": "Answers questions from company documentation",
  "model": "gpt-4o-mini",
  "bucket_id": "bucket_abc123",
  "embedding_paths": ["/docs/**"],
  "status": "creating",
  "created_at": "2026-03-01T12:00:00Z"
}

List Agents

curl -X GET "https://api.yourdomain.com/v1/agents?limit=20&offset=0" \
  -H "Authorization: Bearer $API_KEY"

Response:

{
  "agents": [
    {
      "id": "agent_xyz789",
      "name": "docs-assistant",
      "status": "ready",
      "created_at": "2026-03-01T12:00:00Z"
    }
  ],
  "total": 1
}

Get Agent

curl -X GET https://api.yourdomain.com/v1/agents/agent_xyz789 \
  -H "Authorization: Bearer $API_KEY"

Update Agent

curl -X PATCH https://api.yourdomain.com/v1/agents/agent_xyz789 \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "system_prompt": "Updated system prompt.",
    "embedding_paths": ["/docs/**", "/faq/**"]
  }'

Delete Agent

curl -X DELETE https://api.yourdomain.com/v1/agents/agent_xyz789 \
  -H "Authorization: Bearer $API_KEY"

Response: 204 No Content

Chat & Query

Send Chat Message (Non-Streaming)

curl -X POST https://api.yourdomain.com/v1/agents/agent_xyz789/chat \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "What is our refund policy?",
    "thread_id": "thread_abc123"
  }'

Response:

{
  "id": "msg_xyz789",
  "thread_id": "thread_abc123",
  "role": "assistant",
  "content": "Our refund policy allows returns within 30 days...",
  "sources": [
    {
      "bucket": "docs-bucket",
      "key": "policies/refund.pdf",
      "score": 0.92
    }
  ],
  "created_at": "2026-03-01T12:05:00Z"
}

Send Chat Message (SSE Streaming)

Use Accept: text/event-stream and stream: true for Server-Sent Events:

curl -X POST https://api.yourdomain.com/v1/agents/agent_xyz789/chat \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "message": "Summarize the key points.",
    "thread_id": "thread_abc123",
    "stream": true
  }'

Response (SSE stream):

event: chunk
data: {"content": "Here", "done": false}

event: chunk
data: {"content": " are", "done": false}

event: chunk
data: {"content": " the", "done": false}

event: done
data: {"message_id": "msg_xyz789", "sources": [...]}

Query (Single Turn, No Thread)

For one-off questions without conversation history:

curl -X POST https://api.yourdomain.com/v1/agents/agent_xyz789/query \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "How do I reset my password?"
  }'

Response:

{
  "content": "To reset your password, go to Settings > Security...",
  "sources": [...]
}

Thread Management

Create Thread

curl -X POST https://api.yourdomain.com/v1/agents/agent_xyz789/threads \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"metadata": {"user_id": "user_123"}}'

Response:

{
  "id": "thread_abc123",
  "agent_id": "agent_xyz789",
  "metadata": {"user_id": "user_123"},
  "created_at": "2026-03-01T12:00:00Z"
}

List Threads

curl -X GET "https://api.yourdomain.com/v1/agents/agent_xyz789/threads?limit=20" \
  -H "Authorization: Bearer $API_KEY"

Get Thread (with messages)

curl -X GET https://api.yourdomain.com/v1/agents/agent_xyz789/threads/thread_abc123 \
  -H "Authorization: Bearer $API_KEY"

Response:

{
  "id": "thread_abc123",
  "agent_id": "agent_xyz789",
  "messages": [
    {"role": "user", "content": "What is our refund policy?"},
    {"role": "assistant", "content": "Our refund policy allows..."}
  ],
  "created_at": "2026-03-01T12:00:00Z"
}

Delete Thread

curl -X DELETE https://api.yourdomain.com/v1/agents/agent_xyz789/threads/thread_abc123 \
  -H "Authorization: Bearer $API_KEY"

Response: 204 No Content

Embedding Status

Get Embedding Status

Check if documents have been embedded and indexed:

curl -X GET "https://api.yourdomain.com/v1/agents/agent_xyz789/embeddings?path=/docs/" \
  -H "Authorization: Bearer $API_KEY"

Response:

{
  "path": "/docs/",
  "status": "ready",
  "document_count": 42,
  "chunk_count": 312,
  "last_updated": "2026-03-01T11:30:00Z",
  "pending": []
}

Trigger Re-embedding

Force re-indexing of documents in a path:

curl -X POST https://api.yourdomain.com/v1/agents/agent_xyz789/embeddings/trigger \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path": "/docs/"}'

Response:

{
  "job_id": "job_embed_xyz",
  "status": "running",
  "path": "/docs/"
}

JavaScript Example (Streaming)

const response = await fetch(
  `https://api.yourdomain.com/v1/agents/${agentId}/chat`,
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
      'Accept': 'text/event-stream',
    },
    body: JSON.stringify({
      message: 'What is our refund policy?',
      thread_id: threadId,
      stream: true,
    }),
  }
);

const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullContent = '';

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value, { stream: true });
  const lines = chunk.split('\n');
  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = JSON.parse(line.slice(6));
      if (data.content) fullContent += data.content;
    }
  }
}

console.log(fullContent);

Next Steps