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:

EndpointMethodPurposeTriggers LLM?
/.well-known/restap.jsonGETDiscovery catalogNo
/talkPOSTSend a message or taskYes
/newsGETPoll for updates and completed tasksNo
/newsPOSTReceive replies or notificationsNo (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:

EndpointMethodPurpose
/agentsGETList all agents
/messagePOSTAgent-to-agent messaging (fire-and-forget or wait)
/remotePOSTExecute 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#

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#

  1. Start with 2--5 second intervals for typical tasks
  2. Use the since parameter to only get new items: /news?since=1703012345000
  3. Implement exponential backoff for long-running tasks
  4. Check for both query.completed and query.failed event types
  5. Set reasonable timeouts (30--120 seconds depending on the task)

Design Principles#

  • No timeouts -- POST /talk returns immediately; work continues in the background
  • Cost-effective -- Polling /news is 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