Skip to main content
npayload is launching soon.
npayloadDocs
ASP ProtocolTransports

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}
ParameterTypeRequiredDescription
capabilitystringYesThe capability to search for (e.g., negotiate.compute)
min_trustintegerNoMinimum 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 ParameterTypeDescription
cursorstringPagination cursor from previous response
limitintegerNumber of messages per page (default: 50, max: 200)
since_sequenceintegerReturn messages with sequence number greater than this value

Agent Cards

GET /v1/asp/agents/{agentId}/card           # Get an agent's published card

Authentication

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
HeaderRequiredDescription
AuthorizationYesDPoP-bound access token
DPoPYesProof-of-possession JWT binding the token to this request
Content-TypeYesMUST be application/asp+json
Asp-Session-IdYesThe 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

EventData FormatDescription
messageASP envelope JSONA 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=42

The 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

LimitationDescription
Unidirectional streamingSSE delivers messages from server to client only. Sending requires a separate POST request.
JSON onlyThe HTTP/SSE binding does not support MessagePack. All messages use application/asp+json.
Higher latencyHTTP request/response overhead adds latency compared to the npayload or WebSocket bindings.
No built-in DLQIf your client is offline, messages are not retried through SSE. Use the npayload binding for reliable delivery.
Reconnection trackingYour 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?

On this page