API Endpoints
SIWA Server — HTTP endpoints for the full authentication flow
Live — These endpoints are running on this website right now. You can call them directly from your terminal or agent to try the full SIWA authentication flow. No setup required.
Overview
The SIWA server implements a challenge-response authentication flow. An agent requests a nonce, signs a structured message, and submits it for verification. On success, the server returns a JWT session token for subsequent authenticated requests.
Base URL
https://siwa.builders.gardenAll endpoints accept and return application/json. CORS is enabled for all origins. You can also run a local instance with the siwa-testing package.
Authentication Flow
Authentication Endpoints
Request Nonce
/api/siwa/nonceRequest a cryptographic nonce to include in the SIWA message. Nonces are single-use and expire after 5 minutes.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| address | string | Yes | Agent wallet address (EIP-55 checksummed) |
| agentId | number | No | ERC-8004 agent token ID |
| agentRegistry | string | No | Registry ref (e.g. eip155:84532:0x8004...) |
Response 200
{
"nonce": "a1b2c3d4e5f6g7h8",
"issuedAt": "2026-02-05T12:00:00.000Z",
"expirationTime": "2026-02-05T12:05:00.000Z",
"domain": "siwa.builders.garden",
"uri": "https://siwa.builders.garden/api/siwa/verify",
"chainId": 84532
}Error 400
{ "error": "Missing address" }Verify Signature
/api/siwa/verifySubmit the signed SIWA message for verification. On success, the server validates the signature, checks nonce freshness, verifies domain binding, and returns a JWT session token (1 hour expiry).
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| message | string | Yes | Full SIWA message (plaintext) |
| signature | string | Yes | EIP-191 signature (hex, 0x-prefixed) |
Response 200
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIs...",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
"agentId": 42,
"agentRegistry": "eip155:84532:0x8004A818...",
"verified": "offline",
"expiresAt": "2026-02-05T13:00:00.000Z"
}The verified field indicates the verification mode: offline (signature only) or onchain (signature + ERC-721 ownership check via RPC).
Error 400
{ "success": false, "error": "Missing message or signature" }Error 401
{ "success": false, "error": "Signature mismatch" }Other possible errors: Invalid nonce, Message expired, Domain mismatch, Signer does not own agent NFT (onchain mode).
Protected Endpoints
These endpoints require a valid JWT token in the Authorization header. Get a token by completing the nonce + verify flow above.
Authorization: Bearer <token>Test Auth
/api/protectedBearer tokenSimple endpoint to verify your session is working. Returns the authenticated agent's identity.
Response 200
{
"message": "Hello Agent #42!",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
"agentId": 42,
"timestamp": "2026-02-05T12:01:00.000Z"
}Error 401
{ "error": "Unauthorized" }Agent Action
/api/agent-actionBearer tokenSubmit an action as an authenticated agent. The server echoes the request and identifies the agent.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| action | string | Yes | Action identifier |
| data | object | No | Arbitrary action payload |
Response 200
{
"received": {
"action": "transfer",
"data": { "to": "0xabc...", "amount": "1.0" }
},
"processedBy": "siwa-server",
"agent": {
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
"agentId": 42
},
"timestamp": "2026-02-05T12:02:00.000Z"
}Error 401
{ "error": "Unauthorized" }Try It
Run the full SIWA auth flow from your terminal. These endpoints are live — you can call them right now.
Full Flow (curl)
Step 1 — Request a nonce:
curl -s -X POST https://siwa.builders.garden/api/siwa/nonce \
-H "Content-Type: application/json" \
-d '{
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0",
"agentId": 42,
"agentRegistry": "eip155:84532:0x8004A818BFB912233c491871b3d84c89A494BD9e"
}'Step 2 — Build and sign the SIWA message using the nonce from step 1. Use the SDK or any EIP-191 signer:
import { signSIWAMessage } from '@buildersgarden/siwa';
const { message, signature } = await signSIWAMessage({
domain: 'siwa.builders.garden',
address: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
statement: 'Authenticate as a registered ERC-8004 agent.',
uri: 'https://siwa.builders.garden/api/siwa/verify',
agentId: 42,
agentRegistry: 'eip155:84532:0x8004A818BFB912233c491871b3d84c89A494BD9e',
chainId: 84532,
nonce: '<nonce-from-step-1>',
issuedAt: '<issuedAt-from-step-1>',
expirationTime: '<expirationTime-from-step-1>'
});Step 3 — Submit message + signature for verification:
curl -s -X POST https://siwa.builders.garden/api/siwa/verify \
-H "Content-Type: application/json" \
-d '{
"message": "<siwa-message-from-step-2>",
"signature": "<signature-from-step-2>"
}'Step 4 — Use the JWT token for authenticated requests:
curl -s https://siwa.builders.garden/api/protected \
-H "Authorization: Bearer <token-from-step-3>"Step 5 — Submit an agent action:
curl -s -X POST https://siwa.builders.garden/api/agent-action \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token-from-step-3>" \
-d '{
"action": "ping",
"data": { "hello": "world" }
}'SIWA Message Format
{domain} wants you to sign in with your Agent account:
{address}
{statement}
URI: {uri}
Version: 1
Agent ID: {agentId}
Agent Registry: {agentRegistry}
Chain ID: {chainId}
Nonce: {nonce}
Issued At: {issuedAt}
Expiration Time: {expirationTime}