How to Subscribe
A step-by-step guide for AI agents and services that want to receive real-time events from EEP entities.
Step 1: Discover the EEP Endpoint
Resolve the entity and look for the Link header:
GET /u/acme-corp HTTP/1.1
Accept: application/json
HTTP/1.1 200 OK
Link: <https://api.example.com/eep/subscribe>; rel="subscribe"
Link: <https://api.example.com/eep/stream?source=acme-corp>; rel="monitor"Step 2: Choose a Delivery Method
| Method | Best For | Setup |
|---|---|---|
| Webhook | Server-side agents with a public URL | You provide a URL, we POST events to it |
| SSE | Lightweight subscribers, browser-based, CLI | You open a long-lived HTTP connection |
| WebSocket | Bidirectional, interactive, low-latency | Full duplex — send and receive |
Step 3: Create a Subscription (Webhook)
Create Subscription
const res = await fetch('https://api.example.com/eep/subscribe', {method: 'POST',headers: {'Authorization': 'Bearer YOUR_API_KEY','Content-Type': 'application/json',},body: JSON.stringify({source_did: 'did:web:example.com:u:acme-corp',event_types: ['com.example.entity.updated', 'com.example.trust.*'],delivery_method: 'webhook',delivery_url: 'https://your-agent.example.com/hooks/eep',}),});const subscription = await res.json();
Step 4: Handle Intent Verification
Your endpoint will receive a GET request with a challenge:
Intent Verification Handler
// Express / Honoapp.get('/hooks/eep', (req, res) => {const challenge = req.query['hub.challenge'];if (challenge) {return res.status(200).send(challenge);}res.status(400).send('Missing challenge');});
Step 5: Verify Incoming Webhooks
Webhook Verification
import { verifyEEPWebhook } from '@eep-dev/signer';app.post('/hooks/eep', (req, res) => {const valid = verifyEEPWebhook(req.rawBody, req.headers, YOUR_SECRET);if (!valid) return res.status(401).send('Invalid signature');const event = JSON.parse(req.body);console.log(`Event: ${event.type} from ${event.source}`);res.status(200).send('OK');});
Alternative: SSE Stream
Browser limitation: the standard EventSource API cannot set custom headers (including Authorization). Use a server-side subscriber, a fetch/SSE polyfill that supports headers, or a token mechanism your publisher documents (for example query parameters), never hard-coding secrets in client-side code.
SSE Client
// Node (eventsource package) or polyfill that supports headers:const es = new EventSource('https://api.example.com/eep/stream?source=acme-corp&events=entity.*,trust.*',{ headers: { 'Authorization': 'Bearer YOUR_API_KEY' } });es.onmessage = (e) => {const event = JSON.parse(e.data);console.log(event.type, event.data);};es.onerror = () => {// Will auto-reconnect with Last-Event-ID};