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

MethodBest ForSetup
WebhookServer-side agents with a public URLYou provide a URL, we POST events to it
SSELightweight subscribers, browser-based, CLIYou open a long-lived HTTP connection
WebSocketBidirectional, interactive, low-latencyFull 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 / Hono
app.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
};