Skip to content

API Documentation

REST API for building unsigned Ethereum transactions. Same PlaybookEngine as the CLI, hosted as a managed service.

Base URL: https://wallet-intent.dev-nethermind.xyz
All endpoints require Bearer token auth except GET /health and POST /auth/register.

Quick start

1
Register for an API key
curl -s -X POST https://wallet-intent.dev-nethermind.xyz/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'
Response
{
  "api_key": "aw_a1b2c3...",
  "email": "[email protected]",
  "plan": "free"
}
2
Build a transaction (deterministic, no LLM)
curl -s -X POST https://wallet-intent.dev-nethermind.xyz/v1/build \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "aave_supply",
    "arguments": {"asset": "USDC", "amount": "500"},
    "from_address": "0xYourWallet"
  }'
Response
{
  "success": true,
  "payload": {
    "action": "aave_supply",
    "target_contract": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
    "function_name": "supply",
    "arguments": { "asset": "0xA0b8...", "amount": "500000000" }
  },
  "raw_tx": {
    "chain_id": 1,
    "to": "0x8787...",
    "value": "0",
    "data": "0x617ba037..."
  },
  "approvals": [{ "token": "0xA0b8...", "spender": "0x8787..." }]
}
3
Or use the agent chat session

Create a session, then send messages. The agent handles intent parsing and transaction building.

# Create session
curl -s -X POST https://wallet-intent.dev-nethermind.xyz/v1/sessions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from_address": "0xYourWallet", "model": "claude-sonnet-4-6"}'
Response
{
  "session_id": "a1b2c3d4-...",
  "model": "claude-sonnet-4-6",
  "from_address": "0x...",
  "chain_id": 1,
  "supported_actions": ["aave_borrow", "aave_supply", "..."]
}
# Send intent
curl -s -X POST https://wallet-intent.dev-nethermind.xyz/v1/sessions/SESSION_ID/message \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Supply 100 USDC to Aave"}'
Response
{
  "reply": "I've built the transaction to supply 100 USDC to Aave V3.",
  "logs": [...],
  "transactions": [
    { "type": "approval", "raw_tx": {"to": "0xA0b8...", "value": "0", "data": "0x..."} },
    { "type": "action", "action": "aave_supply", "raw_tx": {"to": "0x8787...", "value": "0", "data": "0x..."} }
  ]
}

Authentication

POST /auth/register

Register for a new API key. No authentication required.

Request:

{ "email": "[email protected]", "name": "Your Name" }

Response:

200 OK
{
  "api_key": "aw_a1b2c3d4e5f6...",
  "email": "[email protected]",
  "plan": "free"
}
Save your key immediately. It cannot be retrieved again. Keys are prefixed with aw_.
GET /auth/me

Get account info, plan, and daily usage.

200 OK
{
  "email": "[email protected]",
  "plan": "free",
  "created_at": "2026-03-10T12:00:00",
  "requests_today": 12,
  "daily_limit": 50
}
POST /auth/rotate

Rotate API key. Deactivates current key, returns a new one.

DELETE /auth/key

Permanently deactivate your API key.

Layer 1: Deterministic engine

These endpoints expose the PlaybookEngine directly. No LLM involved. Deterministic input/output.

GET /v1/actions

List all supported actions grouped by protocol.

200 OK
{
  "actions": {
    "aave_supply": { "protocol": "aave_v3", "description": "..." },
    "lido_stake": { "protocol": "lido", "description": "..." }
  },
  "by_protocol": {
    "aave_v3": ["aave_supply", "aave_withdraw", "..."],
    "lido": ["lido_stake", "lido_request_withdrawal", "..."]
  },
  "count": 44
}
GET /v1/actions/{action_name}

Get parameter schema, valid tokens, and example for a specific action.

200 OK
{
  "action": "uniswap_swap",
  "protocol": "uniswap_v3",
  "description": "Swap tokens via Uniswap V3 single-hop",
  "parameters": {
    "required": {
      "asset_in": { "type": "token_symbol", "hint": "Token to sell" },
      "asset_out": { "type": "token_symbol", "hint": "Token to buy" },
      "amount": { "type": "human_amount", "hint": "Amount to swap" }
    },
    "optional": {
      "slippage": { "type": "percentage", "hint": "Max slippage (default 0.5%)" }
    }
  },
  "valid_tokens": null,
  "example": {
    "action": "uniswap_swap",
    "arguments": { "asset_in": "USDC", "asset_out": "WETH", "amount": "1000" }
  }
}
POST /v1/build

Build an unsigned Ethereum transaction. Deterministic: same input always produces the same output.

Request:

{
  "action": "aave_supply",
  "arguments": { "asset": "USDC", "amount": "500" },
  "from_address": "0x...",
  "chain_id": 1
}

Response:

200 OK
{
  "success": true,
  "payload": {
    "action": "aave_supply",
    "target_contract": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
    "function_name": "supply",
    "arguments": { "asset": "0xA0b8...", "amount": "500000000" }
  },
  "raw_tx": {
    "chain_id": 1,
    "to": "0x8787...",
    "value": "0",
    "data": "0x617ba037..."
  },
  "approvals": [{ "token": "0xA0b8...", "spender": "0x8787..." }]
}

Layer 2: Agent sessions

Sessions maintain conversation state. The LLM agent discovers actions, checks parameters, and builds transactions via tool calling. Multi-turn: if info is missing, the agent asks clarifying questions.

POST /v1/sessions

Create a conversation session.

FieldTypeDefaultDescription
modelstringclaude-sonnet-4-6LLM model for the agent
from_addressstring-Sender wallet address
chain_idint1Chain ID (1 = mainnet only)

Response:

200 OK
{
  "session_id": "a1b2c3d4-...",
  "model": "claude-sonnet-4-6",
  "from_address": "0x...",
  "chain_id": 1,
  "supported_actions": ["aave_borrow", "aave_supply", "..."]
}
POST /v1/sessions/{session_id}/message

Send a message. Returns the agent reply, built transactions (if any), and detailed logs.

Request:

{ "message": "Supply 100 USDC to Aave" }

Response (transaction built):

200 OK
{
  "reply": "I've built the transaction to supply 100 USDC to Aave V3.",
  "logs": [
    { "kind": "tool_call", "message": "Calling action_info", "data": {...} },
    { "kind": "tool_call", "message": "Calling build_transaction", "data": {...} },
    { "kind": "tool_result", "message": "build_transaction returned", "data": {...} }
  ],
  "transactions": [
    { "type": "approval", "action": null, "raw_tx": {"to": "0xA0b8...", "value": "0", "data": "0x..."} },
    { "type": "action", "action": "aave_supply", "raw_tx": {"to": "0x8787...", "value": "0", "data": "0x..."} }
  ]
}

Response (clarifying question):

200 OK
{
  "reply": "Which token would you like to swap, and how much?",
  "logs": [],
  "transactions": []
}
Multi-turn: If transactions is empty and the reply asks a question, send the user's answer as another message to the same session.
DELETE /v1/sessions/{session_id}

Delete session and free server resources.

Health

GET /health

Check API status. No auth required.

200 OK
{ "status": "ok", "actions_count": 44 }

Rate limits

PlanRequests / Day
Free50
Pro1,000
Enterprise10,000

Limits are per API key, counted daily (UTC). Exceeding returns 429.

Error codes

CodeMeaning
401Invalid or missing API key
403API key deactivated
404Session or action not found
409Email already registered
422Invalid action, arguments, or from_address
429Rate limit exceeded
500Server error

Safety