HTTP/SSE Binding
RESTful access to ASP sessions with server-sent events for real-time updates
The HTTP/SSE binding provides REST API access to ASP sessions. Clients send messages via POST requests and receive real-time updates through a server-sent events stream. All requests route through npayload internally for delivery guarantees.
This binding is designed for browser clients, REST integrations, and lightweight agents that do not require a persistent bidirectional connection.
Endpoints
Discovery
GET /v1/asp/discover?capability={capability}&min_trust={score}| Parameter | Type | Required | Description |
|---|---|---|---|
capability | string | Yes | The capability to search for (e.g., negotiate.compute) |
min_trust | integer | No | Minimum trust score (0-100). Default: 0 |
Session Management
POST /v1/asp/sessions # Create session (sends PROPOSE invitation)
GET /v1/asp/sessions/{sessionId} # Get session status and metadata
DELETE /v1/asp/sessions/{sessionId} # Close session (sends CLOSE)Messages
POST /v1/asp/sessions/{sessionId}/messages # Send a message
GET /v1/asp/sessions/{sessionId}/messages # List messages (paginated)
GET /v1/asp/sessions/{sessionId}/messages/{messageId} # Get a single message| Query Parameter | Type | Description |
|---|---|---|
cursor | string | Pagination cursor from previous response |
limit | integer | Number of messages per page (default: 50, max: 200) |
since_sequence | integer | Return messages with sequence number greater than this value |
Agent Cards
GET /v1/asp/agents/{agentId}/card # Get an agent's published cardAuthentication
All requests MUST include DPoP (Demonstrating Proof-of-Possession) authentication headers:
POST /v1/asp/sessions/ase_abc123/messages HTTP/1.1
Host: api.npayload.com
Authorization: DPoP <access_token>
DPoP: <dpop_proof_jwt>
Content-Type: application/asp+json
Asp-Session-Id: ase_abc123| Header | Required | Description |
|---|---|---|
Authorization | Yes | DPoP-bound access token |
DPoP | Yes | Proof-of-possession JWT binding the token to this request |
Content-Type | Yes | MUST be application/asp+json |
Asp-Session-Id | Yes | The session identifier |
The DPoP proof binds the access token to the specific HTTP method and URL. This prevents token replay attacks even if the token is intercepted. See Authentication for details on obtaining tokens and generating proofs.
Sending Messages
Send an ASP message by POSTing to the messages endpoint:
POST /v1/asp/sessions/ase_abc123/messages HTTP/1.1
Authorization: DPoP eyJhbGciOiJSUzI1NiJ9...
DPoP: eyJhbGciOiJFUzI1NiJ9...
Content-Type: application/asp+json{
"version": "asp/0.1",
"performative": "PROPOSE",
"content": {
"body": {
"proposalId": "prop_001",
"type": "terms",
"subject": "GPU compute procurement",
"terms": {
"gpuType": "A100",
"quantity": 2,
"pricePerHour": 3.50
}
}
}
}The server assigns messageId, sequenceNumber, timestamp, and computes the integrity fields. The response includes the complete message with all server-assigned fields:
HTTP/1.1 201 Created
Content-Type: application/asp+json{
"version": "asp/0.1",
"messageId": "019526a1-8f2a-7000-8000-000000000005",
"sessionId": "ase_abc123",
"sequenceNumber": 3,
"timestamp": "2026-03-07T14:30:00.000Z",
"sender": {
"agentId": "agent://acme.com/procurement/alpha",
"orgId": "org_acme",
"trustScore": 68,
"dpopProof": "eyJ..."
},
"performative": "PROPOSE",
"content": {
"body": {
"proposalId": "prop_001",
"type": "terms",
"subject": "GPU compute procurement",
"terms": {
"gpuType": "A100",
"quantity": 2,
"pricePerHour": 3.50
}
}
},
"integrity": {
"hash": "sha256:a1b2c3d4e5f6...",
"previousHash": "sha256:9f8e7d6c5b4a...",
"signature": "ed25519:x1y2z3..."
}
}Server-Sent Events
For real-time message delivery, open an SSE stream:
GET /v1/asp/sessions/ase_abc123/stream HTTP/1.1
Accept: text/event-stream
Authorization: DPoP <access_token>
DPoP: <dpop_proof_jwt>Event Types
| Event | Data Format | Description |
|---|---|---|
message | ASP envelope JSON | A complete ASP message (performative + content + integrity) |
session_state | { "state": "CONVERSING", "previous": "INTRODUCED" } | Session state transition |
trust_update | { "agentId": "...", "score": 72, "previous": 68 } | Trust score change for a participant |
heartbeat | { "timestamp": "...", "state": "CONVERSING" } | Connection keepalive (every 30s) |
error | { "code": "...", "message": "..." } | Error notification |
SSE Stream Format
event: message
data: {"version":"asp/0.1","messageId":"019526a1-8f2a-7000-8000-000000000005","performative":"PROPOSE","content":{"body":{"proposalId":"prop_001","type":"terms","subject":"GPU compute"}},"integrity":{"hash":"sha256:a1b2...","previousHash":"sha256:9f8e..."}}
event: session_state
data: {"state":"CONVERSING","previous":"INTRODUCED","timestamp":"2026-03-07T14:30:00.000Z"}
event: trust_update
data: {"agentId":"agent://acme.com/procurement/alpha","score":72,"previous":68}
event: heartbeat
data: {"timestamp":"2026-03-07T14:30:30.000Z","state":"CONVERSING"}Client Example
const source = new EventSource(
`https://api.npayload.com/v1/asp/sessions/${sessionId}/stream?since_sequence=0`,
{ headers: { Authorization: `DPoP ${token}` } }
)
source.addEventListener("message", (event) => {
const envelope = JSON.parse(event.data)
// Process the ASP message
handlePerformative(envelope.performative, envelope.content.body)
})
source.addEventListener("session_state", (event) => {
const { state, previous } = JSON.parse(event.data)
console.log(`Session transitioned: ${previous} -> ${state}`)
})
source.addEventListener("trust_update", (event) => {
const { agentId, score } = JSON.parse(event.data)
console.log(`Trust updated: ${agentId} -> ${score}`)
})
source.addEventListener("error", () => {
// Reconnect with last known sequence number
reconnectWithBackoff()
})Reconnection
When the SSE connection drops, reconnect with the since_sequence query parameter to resume from the last processed message:
Track the last sequence number
Store the sequenceNumber of the last successfully processed message.
Reconnect with backoff
Use exponential backoff (1s, 2s, 4s, 8s, max 30s) before reconnecting.
Resume the stream
Pass since_sequence to receive all messages after the given sequence number:
GET /v1/asp/sessions/{sessionId}/stream?since_sequence=42The server replays any messages with a sequence number greater than 42 before delivering new messages.
Your client MUST track the last seen sequence number. If you reconnect without since_sequence, you will receive all messages from the beginning of the session.
Limitations
| Limitation | Description |
|---|---|
| Unidirectional streaming | SSE delivers messages from server to client only. Sending requires a separate POST request. |
| JSON only | The HTTP/SSE binding does not support MessagePack. All messages use application/asp+json. |
| Higher latency | HTTP request/response overhead adds latency compared to the npayload or WebSocket bindings. |
| No built-in DLQ | If your client is offline, messages are not retried through SSE. Use the npayload binding for reliable delivery. |
| Reconnection tracking | Your client must track the last seen sequence number and pass it on reconnect. |
For production agent-to-agent communication, use the npayload binding. HTTP/SSE is designed for gateway access, browser clients, and development.
Other Bindings
Was this page helpful?