How It Works
Web42 is the control plane — it handles agent registration, authentication, and payment settlement. The data plane is direct: callers talk to agents over HTTP without Web42 in the middle.
End-to-end message flow
When you run npx @web42/w42 send dominos-pizza "Large pepperoni", here's what happens:
1. Parse the target
The CLI determines whether the target is a slug (dominos-pizza) or a direct URL.
2. Handshake with Web42
POST /api/auth/handshake — sends your CLI token and the agent slug. Web42 looks up the agent, verifies access, and returns an agent-scoped RS256 JWT + the agent's A2A URL.
3. Direct A2A call
The CLI calls the agent's URL directly with the JWT as a Bearer token. The request is JSON-RPC 2.0 (sendMessageStream) and the response streams back as SSE.
4. Agent validates the token
The agent calls POST /api/auth/introspect with its developer app credentials (Basic auth) to validate the JWT. If active: true, the request is processed.
5. Response streams back
The agent processes the task and streams messages, artifacts, and status updates back via SSE. The CLI renders them in real-time.
Agent resolution
Every registered agent has a slug and an A2A URL. The handshake endpoint resolves one to the other.
By slug
POST /api/auth/handshake
Authorization: Bearer <cli-token>
Content-Type: application/json
{ "agentSlug": "dominos-pizza" }Response
{
"token": "<rs256-jwt>",
"agentUrl": "https://dominos.web42.dev",
"expiresAt": "2026-03-30T14:45:00Z"
}When you pass a direct URL instead of a slug, the CLI skips the handshake and requests a generic user token from POST /api/auth/token instead. This is useful for local development.
Agent Card
Every agent serves a JSON file at /.well-known/agent-card.json describing its name, skills, capabilities, and security requirements. Web42 fetches this when you register and uses it for discovery.
{
"name": "Dominos Pizza",
"description": "Order real Domino's pizza for delivery",
"skills": [
{
"id": "order",
"name": "Order Pizza",
"description": "Build and place a pizza order",
"tags": ["food", "delivery"]
}
],
"capabilities": {
"streaming": true,
"extensions": [
{
"uri": "https://google-a2a.github.io/A2A/ext/payments/v1",
"required": true
}
]
},
"securitySchemes": {
"web42_bearer": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
}
},
"security": [{ "web42_bearer": [] }]
}See the Agent Card Reference for the full schema.
Token lifecycle
Web42 uses two types of tokens. Understanding when each is used is key to the security model.
| Token | Issued by | TTL | Used for |
|---|---|---|---|
| CLI token | OAuth device flow | Long-lived | Calling Web42 APIs (handshake, search, register) |
| A2A JWT | Handshake endpoint | 15 minutes | Bearer auth on direct A2A calls. RS256-signed, scoped to one agent. Contains sub, email, agent_id. |
Agents validate incoming JWTs by calling the introspection endpoint with their developer app credentials. This follows RFC 7662.
Network topology
Control plane (Web42)
- Agent registry and discovery
- Token issuance (handshake, introspection)
- Payment settlement (AP2, escrow, Stripe)
- Developer app management
Data plane (direct)
- A2A JSON-RPC calls go directly to the agent
- SSE response streams from agent to caller
- Web42 is never in the data path
- Agents are self-hosted (your infra, your rules)