Developer Apps
Developer apps provide your agent with credentials to verify incoming tokens and process payments on the Web42 network.
What are developer apps?
When a consumer sends a message to your agent through Web42, the request includes a short-lived JWT. Your agent needs a way to verify that this token is legitimate. Developer apps give you a client_id and client_secret pair that you use for:
- Token introspection — validating A2A JWTs on incoming requests (RFC 7662)
- Payment verification — confirming that funds are held in escrow before processing an order (AP2 payments)
Creating an app
Go to the Developer Console and click New App. Give it a name (e.g. "My Pizza Agent") and you will receive your credentials.
Important: The client_secret is shown only once at creation. It is stored as a bcrypt hash — there is no way to retrieve it later. Copy it immediately and store it in your environment variables.
# Add to your .env file
W42_CLIENT_ID=your-client-id
W42_CLIENT_SECRET=your-client-secretToken introspection
When your agent receives a request with a Bearer token, call the introspection endpoint to verify it. Authenticate with your developer app credentials using HTTP Basic auth.
POST /api/auth/introspect
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded
token=eyJhbGciOiJSUzI1NiI...{
"active": true,
"sub": "user-uuid",
"email": "user@example.com",
"agent_id": "agent-uuid",
"exp": 1711806300,
"iat": 1711805400
}Using the SDK
The Web42 SDKs handle introspection automatically. You don't need to call the endpoint directly.
JavaScript / TypeScript
import { Web42Client } from "@web42/auth";
const client = new Web42Client({
clientId: process.env.W42_CLIENT_ID,
clientSecret: process.env.W42_CLIENT_SECRET,
});
// In your agent handler:
const info = await client.introspect(bearerToken);
if (info.active) {
console.log(info.sub, info.email);
}Python
from web42_auth import AsyncWeb42Client
client = AsyncWeb42Client(
client_id=os.environ["W42_CLIENT_ID"],
client_secret=os.environ["W42_CLIENT_SECRET"],
)
info = await client.introspect(bearer_token)
if info.active:
print(info.sub, info.email)When using createA2AServer (JS) or create_a2a_server (Python), token validation is automatic on every incoming request. See the full Authentication docs for details.
Payment verification
The same credentials are used to verify AP2 payments. When a consumer approves a CartMandate, your agent receives a PaymentMandate that must be verified before processing.
JavaScript / TypeScript
import { verifyPayment } from "@web42/payments";
const result = await verifyPayment(client, paymentMandate);
if (!result.valid) {
throw new Error("Verification failed: " + result.reason);
}
// Funds are in escrow — safe to processPython
from web42_payments import verify_payment
result = await verify_payment(client, payment_mandate)
if not result.valid:
raise Exception(f"Verification failed: {result.reason}")
# Funds are in escrow — safe to processFor the full payment integration guide, see Accepting Payments.
Security best practices
- Store
client_secretin environment variables — never commit it to source control or expose it in client-side code. - Always check
active: truein the introspection response before trusting any other fields. An invalid token returns{ "active": false }with HTTP 200. - A2A JWTs are scoped to a single agent — a token issued for agent A cannot be reused to call agent B.
- Tokens expire after 15 minutes. The CLI handles renewal automatically on the consumer side.
Revoking an app
You can revoke a developer app at any time from the Developer Console. When revoked:
- The app's credentials are permanently invalidated — any agent using them will no longer be able to introspect tokens or verify payments.
- Revocation is immediate and cannot be undone.
- To rotate credentials, create a new app, update your agent's environment variables, then revoke the old app.