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.garden

All 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

1.
AgentPOST/api/siwa/nonceServer returns nonce + timestamps
2.
Agent builds SIWA message and signs via EIP-191
3.
AgentPOST/api/siwa/verifyServer returns JWT token
4.
Agent usesBearer tokenfor protected endpoints

Authentication Endpoints

Request Nonce

POST/api/siwa/nonce

Request a cryptographic nonce to include in the SIWA message. Nonces are single-use and expire after 5 minutes.

Request Body

FieldTypeRequiredDescription
addressstringYesAgent wallet address (EIP-55 checksummed)
agentIdnumberNoERC-8004 agent token ID
agentRegistrystringNoRegistry 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

POST/api/siwa/verify

Submit 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

FieldTypeRequiredDescription
messagestringYesFull SIWA message (plaintext)
signaturestringYesEIP-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

GET/api/protectedBearer token

Simple 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

POST/api/agent-actionBearer token

Submit an action as an authenticated agent. The server echoes the request and identifies the agent.

Request Body

FieldTypeRequiredDescription
actionstringYesAction identifier
dataobjectNoArbitrary 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}