Skip to main content

/docs/http-mode

HTTP mode — implement IICP without binary framing

HTTP mode is the mandatory transport for Phase 1–3 conformance. If your node speaks plain HTTP/JSON it can satisfy the Phase 1–3 transport requirements — no binary framing library required. Binary framing (native mode) is a Phase 4 performance upgrade, not a prerequisite for joining the mesh.

Good news — you don't have to do anything. IICP works over plain HTTP/JSON out of the box; the SDKs and every curl example already use it. This page is the spec detail for implementers who want to write their own client. Full reference below.

You are already in HTTP mode

The IICP adapter, directory, and REACH conformance probes all speak HTTP mode. Every curl example in the docs is HTTP mode. This page explains the spec contract behind those commands.

5-command quickstart

These five curl calls walk through the full HTTP mode lifecycle. Replace MY_ENDPOINT with your node's public URL.

1

Register your node

curl -s -X POST https://iicp.network/api/v1/register \
  -H "Content-Type: application/json" \
  -H "X-IICP-Version: 1.9" \
  -d '{
    "endpoint": "https://MY_ENDPOINT",
    "region": "eu-central",
    "capabilities": [{
      "intent": "urn:iicp:intent:llm:chat:v1",
      "models": ["llama-3-8b"],
      "max_tokens": 4096
    }],
    "limits": { "max_concurrent": 4, "tokens_per_min": 10000 }
  }'

Save the returned node_id and node_token — both are required for subsequent calls. The directory verifies your endpoint is reachable before accepting the registration.

2

Send heartbeats every 30 seconds

# Run this on a 30-second cron or in a loop
curl -s -X POST https://iicp.network/api/v1/heartbeat \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <node_token>" \
  -H "X-IICP-Version: 1.9" \
  -d '{
    "node_id": "<node_id>",
    "load": 0.4,
    "queue_depth": 2,
    "error_rate_1m": 0.0
  }'

Nodes not seen for 90 seconds are marked unavailable and disappear from discovery results. A 30-second heartbeat interval gives three missed-heartbeat tolerance before being dropped.

3

Expose a health endpoint

# Your node must respond to GET /iicp/health with 200 OK
# Minimal implementation (Python):
from http.server import BaseHTTPRequestHandler, HTTPServer
import json

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/iicp/health':
            body = json.dumps({"status":"ok","load":0.4}).encode()
            self.send_response(200)
            self.send_header('Content-Type','application/json')
            self.send_header('X-IICP-Version','1.9')
            self.end_headers()
            self.wfile.write(body)

HTTPServer(('0.0.0.0', 9484), Handler).serve_forever()

The directory probes GET /iicp/health during registration and periodically after. Return HTTP 200 — any body is accepted. The X-IICP-Version: 1.9 header advertises your conformance level.

4

Receive and serve tasks

# The IICP proxy routes tasks to your node as:
POST /v1/task
Authorization: Bearer <node_token>
Content-Type: application/json

{
  "task_id": "t-abc123",
  "intent": "urn:iicp:intent:llm:chat:v1",
  "payload": {
    "messages": [{"role": "user", "content": "Hello!"}],
    "max_tokens": 512
  }
}

# Your node responds:
HTTP 200 OK
Content-Type: application/json

{
  "task_id": "t-abc123",
  "output": { "choices": [{"message": {"role":"assistant","content":"Hi!"}}] },
  "usage": { "prompt_tokens": 10, "completion_tokens": 5 }
}

Authenticate the incoming node_token on every request. Return 401 if the token is missing or invalid. The adapter handles this automatically; if you are implementing a custom node, verify using constant-time comparison (bcrypt or HMAC).

5

Discover and verify your node is visible

# Check that your node appears in discovery results
curl -s 'https://iicp.network/api/v1/discover?view=public&intent=urn:iicp:intent:llm:chat:v1' \
  | python3 -m json.tool

Discovery confirmed

Appearing in discovery confirms current registration, heartbeat and eligibility state. It does not by itself prove every Phase 1–3 conformance requirement; run the applicable conformance profiles and retain their results.

HTTP ↔ native message mapping

Each native binary frame type (defined in the binary framing specification) has an HTTP counterpart for the base operations. Transport-specific behavior and negotiated profiles, including task-result streaming, require their own contracts.

Native typeMeaningMethodEndpoint / responseBody
INIT (0x01)Register nodePOST/api/v1/registerJSON or application/iicp+cbor
ACK (0x02)Register responsePOST200 response to INITJSON — contains node_id, node_token
DISCOVER (0x03)Discover nodesGET/api/v1/discover?view=public&intent=<urn>Query param: intent URN
CALL (0x05)Submit taskPOST/v1/taskJSON or application/iicp+cbor
RESPONSE (0x06)Task resultPOST200 response to CALLJSON — task output
FEEDBACK (0x08)Heartbeat / livenessPOST/api/v1/heartbeatJSON — node_id + load metrics
PING (0x09)Health checkGET/iicp/healthNo body
PONG (0x0A)Health responseGET200 response to PINGJSON — load stats
OBSERVE (0x0D)Event subscriptionGET/v1/stream (SSE)text/event-stream
TELEMETRY (0x0E)Telemetry reportPOST/v1/telemetryJSON

CLOSE (0x07) is implicit: any 4xx/5xx response or connection close. CONTROL (0x0B) and ADVERTISE (0x0C) map to /v1/control and /api/v1/node/{node_id} respectively — not required for Phase 1–3.

Required headers

HeaderRequired onExample valuePurpose
X-IICP-VersionAll outbound requests1.9Declares conformance level — required by REACH
Authorizationheartbeat, task endpointsBearer <node_token>Node authentication — validate on every inbound request
Content-TypePOST requests with bodyapplication/jsonJSON (Phase 1–3) or application/iicp+cbor (optional)
X-IICP-FramingOptionalnative/1Signal to peer that native binary framing is available

FAQ

Do I need to implement binary framing?

No. Binary framing is a Phase 4 feature. For Phase 1–3 conformance — which covers everything from registration to task routing to heartbeats — HTTP/JSON is the MUST-implement transport. You can join the mesh, pass all REACH conformance probes, and serve real tasks entirely over HTTP.

What is the difference between HTTP mode and native mode?

The draft native mode uses a 12-byte binary frame header over TCP with CBOR-encoded payloads and integer-keyed maps defined by the binary framing specification. It adds explicit connection state, explicit CLOSE frames, fragmentation support, and lower per-message overhead. HTTP mode maps the same semantic operations to standard HTTP verbs and JSON bodies over an existing HTTP/1.1 or HTTP/2 connection. The QUIC mapping remains draft work and is not a currently supported implementation claim.

How do I know if my node is Phase 1–3 conformant?

Run the REACH conformance probe suite against your endpoint. Its active probe set covers areas such as registration format, discovery response shape, heartbeat acceptance, health endpoint availability, and telemetry authentication. Passing is project-operated evidence for the requirements covered by that run; it is not independent implementation evidence. The probe-to-requirement mapping is defined in the conformance suite.

Can I use CBOR bodies in HTTP mode?

Yes. HTTP mode optionally supports CBOR body encoding via content negotiation: send Accept: application/iicp+cbor and set Content-Type: application/iicp+cbor on your request. HTTP mode CBOR uses string-keyed maps (human-readable field names). Native framing uses integer-keyed maps. The two are semantically equivalent but structurally distinct — do not mix key styles.

What port should my node listen on?

Port 9484 is the canonical IICP port. It is in the registered range (1024–49151) per RFC 6335 and is not assigned to any other IANA-registered protocol. For Phase 1–3 you can expose port 9484 directly or terminate TLS on a standard port (443/80) and proxy to port 9484 internally. The directory performs its liveness check against whatever URL you register — the port in your endpoint field is what gets probed.

How do I implement custom intents?

Use the x.<vendor> URN prefix: urn:iicp:intent:x.acme:invoice-classify:v1. No registry approval is required. The directory accepts any x.* URN at registration time. Consumers discover your custom intent via the standard discovery endpoint — the intent string is an exact-match filter. See the intent semantics specification for the full ABNF grammar and upgrade path.

Does streaming work in HTTP mode?

Yes — via Server-Sent Events (SSE). The native OBSERVE frame (0x0D) maps to GET /v1/stream with Content-Type: text/event-stream. SSE is the Phase 1–3 streaming transport; native OBSERVE frames are Phase 4 only. The IICP adapter supports SSE streaming out of the box.

Phase 1–3 HTTP mode checklist

  • ✓POST /api/v1/register — valid JSON payload, X-IICP-Version: 1.9 header
  • ✓GET /iicp/health — returns HTTP 200 at all times
  • ✓POST /api/v1/heartbeat — sent every ≤ 30 seconds with node_id and load
  • ✓POST /v1/task — accepts task requests, verifies node_token, returns structured response
  • ✓All outbound requests include Authorization: Bearer <node_token>
  • ✓Endpoints follow the HTTP-to-native message mapping table
  • ✓REACH conformance checks pass: iicp-reach --once (see the live stats page for current coverage)