REST-AP Protocol
REST Agent Protocol for agent discovery and communication over HTTP
REST-AP Protocol#
REST-AP (REST Agent Protocol) is the communication standard that ID Agents uses for agent discovery and messaging. It defines a minimal set of HTTP endpoints that let agents find each other, exchange messages, and poll for results.
REST-AP is intentionally simple. It works with standard HTTP, requires no WebSockets or streaming, and interoperates with any agent framework.
Core Endpoints#
REST-AP requires only four endpoints:
| Endpoint | Method | Purpose | Triggers LLM? |
|---|---|---|---|
/.well-known/restap.json | GET | Discovery catalog | No |
/talk | POST | Send a message or task | Yes |
/news | GET | Poll for updates and completed tasks | No |
/news | POST | Receive replies or notifications | No (default) |
Discovery: GET /.well-known/restap.json#
Every REST-AP agent exposes a catalog at /.well-known/restap.json that describes what it can do and how to interact with it.
{
"restap_version": "1.0",
"agent": {
"name": "My Agent",
"description": "I can create web pages and analyze data",
"contact": "support@example.com",
"documentation": "/restap.md"
},
"endpoints": {
"talk": "/talk",
"news": "/news",
"news_post": "/news"
},
"packages": {
"skills": "/skills/",
"sdk": "npm install id-agents"
}
}
Hosts can optionally serve a human-readable /restap.md file with detailed documentation.
Talk: POST /talk#
Send a message that the agent will process. This triggers LLM inference and returns immediately with a query_id for tracking.
curl -X POST http://localhost:4101/talk \
-H "Content-Type: application/json" \
-d '{"message": "Create a landing page"}'
Response:
{
"query_id": "query_123",
"status": "processing",
"message": "Task is being processed. Poll /news for completion."
}
News: GET /news#
Poll for completed tasks and updates. This endpoint is free -- no LLM inference required. Call it as often as needed.
curl http://localhost:4101/news?since=0
Response:
{
"items": [
{
"type": "query.completed",
"timestamp": 1703012345000,
"data": {
"query_id": "query_123",
"result": {
"result": "Here is the landing page code...",
"sessionId": "session_456",
"model": "claude-haiku-4-5-20251001"
}
}
}
],
"timestamp": 1703012350000
}
The actual response text is in items[].data.result.result.
News (POST): POST /news#
Receive replies and notifications from other agents without triggering LLM processing. This prevents infinite loops in agent-to-agent communication.
curl -X POST http://localhost:4101/news \
-H "Content-Type: application/json" \
-d '{
"type": "reply",
"from": "agent-b",
"in_reply_to": "query_123",
"message": "Here is my response..."
}'
Optionally, set "trigger": true to request LLM processing. When triggered, the agent processes the message but is instructed not to reply back to the sender, preventing ping-pong loops.
Manager Endpoints#
In addition to the core REST-AP endpoints, the ID Agents manager exposes:
| Endpoint | Method | Purpose |
|---|---|---|
/agents | GET | List all agents |
/message | POST | Agent-to-agent messaging (fire-and-forget or wait) |
/remote | POST | Execute CLI commands programmatically |
List Agents#
curl http://localhost:4100/agents
Remote Command#
curl -X POST http://localhost:4100/remote \
-H "Content-Type: application/json" \
-d '{"command":"/status"}'
Communication Patterns#
Asynchronous (Recommended)#
The standard pattern for longer tasks:
1. Client → POST /talk → Agent (returns immediately with query_id)
2. Client ← GET /news ← Agent (poll until query.completed appears)
Direct Reply#
Agents can send replies directly to the sender's /news endpoint instead of requiring polling:
1. Agent A → POST /talk → Agent B (processes the request)
2. Agent A ← POST /news ← Agent B (sends reply directly)
Agent-to-Agent Example#
# Step 1: Send a message to Agent B
RESPONSE=$(curl -s -X POST http://localhost:4102/talk \
-H "Content-Type: application/json" \
-d '{"message": "What are best practices for buttons?"}')
QUERY_ID=$(echo $RESPONSE | jq -r '.query_id')
# Step 2: Poll for the response
sleep 3
NEWS=$(curl -s "http://localhost:4102/news?since=0")
# Step 3: Extract the answer
ANSWER=$(echo $NEWS | jq -r \
".items[] | select(.data.query_id==\"$QUERY_ID\") | .data.result.result")
echo "Agent B says: $ANSWER"
Polling Best Practices#
- Start with 2--5 second intervals for typical tasks
- Use the
sinceparameter to only get new items:/news?since=1703012345000 - Implement exponential backoff for long-running tasks
- Check for both
query.completedandquery.failedevent types - Set reasonable timeouts (30--120 seconds depending on the task)
Design Principles#
- No timeouts --
POST /talkreturns immediately; work continues in the background - Cost-effective -- Polling
/newsis free (no LLM calls) - Scalable -- One client can wait for many parallel tasks
- Simple -- Plain HTTP GET/POST, no WebSockets or streaming
- Resilient -- If a poll fails, just try again
- Framework-agnostic -- Works with any LLM, language, or agent framework