Overview
The PayAI facilitator authenticates merchants using short-lived JWTs signed with Ed25519 (the EdDSA algorithm). If you use the@payai/facilitator TypeScript package, this is handled automatically. This guide explains the underlying protocol so you can implement authentication in any language without depending on PayAI packages.
Authentication is optional for ordinary exact payments and Solana batch settlement on the public shared lane. Use an API key for paid usage, account attribution, or an assigned enterprise lane. If you send a credential, it must be valid; PayAI does not silently downgrade invalid credentials to anonymous access. Autonomous agents can buy credits and receive a key over x402 without portal signup; PayAI creates a wallet-owned agent account programmatically. The merchant dashboard is the optional human-managed route.
API key structure
Your API key has two parts, returned by the portal-free agent vending flow or available from the merchant dashboard:
The secret may be prefixed with
payai_sk_ as shown in the dashboard. Strip this prefix before use — the remaining string is a standard base64-encoded PKCS#8 DER key.
Protocol steps
1. Normalize the API key secret
If the secret starts withpayai_sk_, remove that prefix. The result is a base64-encoded Ed25519 private key in PKCS#8/DER format.
2. Build the JWT header
3. Build the JWT payload
4. Encode and sign
- Base64url-encode the header JSON ->
headerB64 - Base64url-encode the payload JSON ->
payloadB64 - Form the signing input:
headerB64 + "." + payloadB64 - Sign the UTF-8 bytes of the signing input with your Ed25519 private key
- Base64url-encode the 64-byte signature ->
signatureB64 - The JWT is:
headerB64.payloadB64.signatureB64
+ replaced by -, / replaced by _, and no = padding.
5. Send the request
Include the JWT as a Bearer token on all facilitator requests:POST /verify and POST /settle when using authenticated service. GET /supported is public. Without a token it returns the public shared-lane fee payer; a valid enterprise token can select the account’s assigned fee payer.
Token caching
JWTs are valid for the fullexp - iat window (default: 120 seconds). To avoid signing on every request, cache the token and refresh it ~30 seconds before expiry.
Code examples
The following examples implement the full authentication flow with no PayAI-specific dependencies.- TypeScript
- Python
- Go
- Rust
Uses the Web Crypto API — works in Node.js 18+, Deno, Bun, and browsers with zero dependencies.
Facilitator endpoints
All endpoints are athttps://facilitator.payai.network. Note that /verify validates the request body before the token, so a malformed request returns 400 rather than 401 even when the token is missing or bad.
Request body (/verify and /settle)
Troubleshooting
Need help?
Join our Community
Have questions or want to connect with other developers? Join our Discord server.

