AgentLeash API Documentation

Blockchain-authenticated dynamic authorization for AI agents

Getting Started

What is AgentLeash?

AgentLeash is a blockchain-based authorization system that provides fine-grained, time-limited permissions for AI agents. By minting permission tokens on-chain, you can:

  • Define granular permissions - Control exactly what an agent can access
  • Set time constraints - Permissions automatically expire
  • Verify authenticity - Cryptographic proof of authorization
  • Revoke instantly - Burn tokens to immediately remove access

How It Works

3-Step Process:
  1. Define permissions → Specify what the agent can do
  2. Mint token → Create blockchain-backed authorization
  3. Enforce → Verify token before granting access

Quick Start Guide

1. Get Your API Key

Sign up at tokenform.com and retrieve your API key from the dashboard.

2. Make Your First Mint Call

curl
curl -X POST https://api.tokenform.com/api/mint \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key-here" \
  -d '{
    "agent_id": "my-first-agent",
    "permissions": ["read", "write"],
    "resource": "documents/*",
    "expires_in_hours": 24,
    "chain": "algorand"
  }'
JavaScript
const response = await fetch('https://api.tokenform.com/api/mint', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'your-api-key-here'
  },
  body: JSON.stringify({
    agent_id: 'my-first-agent',
    permissions: ['read', 'write'],
    resource: 'documents/*',
    expires_in_hours: 24,
    chain: 'algorand'
  })
});

const result = await response.json();
console.log('Minted token:', result.asset_id);

3. Verify the Token

Use the returned asset_id to verify permissions before granting access:

Verification Example
// In your application
async function checkPermissions(assetId, action, resource) {
  // Fetch token metadata from Algorand
  const tokenData = await getAlgorandAsset(assetId);
  
  // Parse permissions from token metadata
  const permissions = parseTokenPermissions(tokenData);
  
  // Check if action is allowed
  return permissions.includes(action) && 
         matchesResource(permissions.resource, resource) &&
         !isExpired(permissions.expires_at);
}

Authentication

API Key Authentication

Most API endpoints require authentication via API key in the request header:

x-api-key: your-api-key-here
Security: Never expose API keys in client-side code or public repositories. Use environment variables or secure key management systems.

Dashboard Authentication

The TokenForm dashboard uses OTP email authentication:

  1. Enter your email address
  2. Receive one-time password via email
  3. Enter OTP to access dashboard
  4. Session token valid for 24 hours

Session Tokens

Dashboard sessions use JWT tokens stored in secure cookies. These are automatically managed by the browser and expire after 24 hours of inactivity.

API Reference

POST /api/mint

Mint a new permission token for an AI agent on the specified blockchain.

Headers

Header Value Required
Content-Type application/json Yes
x-api-key Your API key Yes

Request Body

Parameter Type Required Description
agent_id string Yes Unique identifier for the agent
permissions array Yes Array of permission strings
resource string No Resource pattern (supports wildcards)
constraints object No Additional constraints object
expires_in_hours number No Token expiration time (default: 24)
chain string Yes "algorand" or "base"

Example Request

curl
curl -X POST https://api.tokenform.com/api/mint \
  -H "Content-Type: application/json" \
  -H "x-api-key: tf-mint-2026-secure" \
  -d '{
    "agent_id": "customer-support-bot",
    "permissions": ["read", "write", "send"],
    "resource": "support-tickets/*",
    "constraints": {
      "max_actions": 100,
      "allowed_hours": "09:00-17:00",
      "ip_whitelist": ["192.168.1.0/24"]
    },
    "expires_in_hours": 8,
    "chain": "algorand"
  }'
JavaScript
const response = await fetch('https://api.tokenform.com/api/mint', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'tf-mint-2026-secure'
  },
  body: JSON.stringify({
    agent_id: 'customer-support-bot',
    permissions: ['read', 'write', 'send'],
    resource: 'support-tickets/*',
    constraints: {
      max_actions: 100,
      allowed_hours: '09:00-17:00',
      ip_whitelist: ['192.168.1.0/24']
    },
    expires_in_hours: 8,
    chain: 'algorand'
  })
});

const result = await response.json();

Example Response

JSON Response (200 OK)
{
  "success": true,
  "asset_id": "1234567890",
  "transaction_id": "YXZ123...",
  "agent_id": "customer-support-bot",
  "permissions": ["read", "write", "send"],
  "resource": "support-tickets/*",
  "expires_at": "2026-04-12T07:52:00Z",
  "chain": "algorand",
  "created_at": "2026-04-11T23:52:00Z",
  "metadata": {
    "token_version": "1.0",
    "issuer": "TokenForm"
  }
}

POST /api/revoke

Revoke (burn) an active permission token, immediately removing all associated permissions.

Request Body

Parameter Type Required Description
asset_id string Yes (Algorand) Token asset ID on Algorand
token_id string Yes (Base) Token ID on Base
agent_id string Yes Agent identifier for verification
reason string No Reason for revocation
chain string Yes "algorand" or "base"

Example Request

curl
curl -X POST https://api.tokenform.com/api/revoke \
  -H "Content-Type: application/json" \
  -H "x-api-key: tf-mint-2026-secure" \
  -d '{
    "asset_id": "1234567890",
    "agent_id": "customer-support-bot",
    "reason": "Agent task completed",
    "chain": "algorand"
  }'

POST /api/verify-signature

Verify a cryptographic signature against an agent's blockchain address.

Request Body

Parameter Type Required Description
message string Yes Original message that was signed
signature string Yes Cryptographic signature (hex)
address string Yes Blockchain address to verify against
chain string Yes "algorand" or "base"

Example Request

curl
curl -X POST https://api.tokenform.com/api/verify-signature \
  -H "Content-Type: application/json" \
  -d '{
    "message": "I am agent customer-support-bot requesting access",
    "signature": "0x1234567890abcdef...",
    "address": "ALGO123ABC...",
    "chain": "algorand"
  }'

GET /api/health

Check the health and status of the AgentLeash API service.

Example Response

JSON Response
{
  "status": "healthy",
  "timestamp": "2026-04-11T23:52:00Z",
  "version": "1.0.0",
  "services": {
    "database": "connected",
    "algorand_node": "synced",
    "base_node": "synced",
    "redis": "connected"
  },
  "uptime_seconds": 86400
}

Dashboard Proxy Endpoints

The following endpoints are available through the Cloudflare Worker proxy for dashboard integration:

POST /api/tokens/mint

Same functionality as /api/mint but routed through the dashboard proxy.

POST /api/tokens/revoke

Same functionality as /api/revoke but routed through the dashboard proxy.

Permissions Reference

Available Permission Types

Permission Description Use Cases
read Read access to resources Viewing documents, checking status, reading configurations
write Create and modify resources Creating files, updating records, modifying settings
execute Execute operations or scripts Running commands, triggering workflows, processing tasks
delete Remove or destroy resources Deleting files, removing records, cleanup operations
send Send messages or notifications Email sending, API calls, webhook triggers
admin Administrative access System configuration, user management, full control

Permission Structure in Tokens

Permissions are embedded in the token metadata as a JSON object:

Token Metadata Structure
{
  "agent_id": "customer-support-bot",
  "permissions": ["read", "write", "send"],
  "resource": "support-tickets/*",
  "constraints": {
    "max_actions": 100,
    "allowed_hours": "09:00-17:00"
  },
  "expires_at": "2026-04-12T07:52:00Z",
  "issued_at": "2026-04-11T23:52:00Z",
  "issuer": "TokenForm",
  "version": "1.0"
}

Permission Combinations

Common permission combinations for different agent types:

Common Permission Sets
// Read-only agent
{
  "permissions": ["read"],
  "resource": "documents/*"
}

// Content creator agent
{
  "permissions": ["read", "write"],
  "resource": "content/*"
}

// Automation agent
{
  "permissions": ["read", "write", "execute"],
  "resource": "workflows/*"
}

// Communication agent
{
  "permissions": ["read", "send"],
  "resource": "notifications/*"
}

// Administrative agent
{
  "permissions": ["admin"],
  "resource": "*"
}

Constraint Objects

Constraints provide additional fine-grained control:

Time-Based Constraints

{
  "allowed_hours": "09:00-17:00",
  "allowed_days": ["monday", "tuesday", "wednesday", "thursday", "friday"],
  "timezone": "UTC"
}

Resource-Scoped Constraints

{
  "ip_whitelist": ["192.168.1.0/24", "10.0.0.0/8"],
  "max_actions": 1000,
  "rate_limit": "100/hour",
  "allowed_methods": ["GET", "POST"]
}

Action-Limited Constraints

{
  "max_file_size": "10MB",
  "max_recipients": 50,
  "approval_required": ["delete", "admin"],
  "audit_trail": true
}

Chain Support

Algorand Testnet

AgentLeash tokens on Algorand are implemented as Algorand Standard Assets (ASAs) with metadata stored in the asset configuration.

Key Features:

  • Asset ID: Unique identifier for each permission token
  • Metadata: Permissions and constraints stored in asset URL field
  • Revocation: Assets can be destroyed to revoke permissions
  • Verification: Read asset info directly from Algorand node

Example Asset Structure:

Algorand Asset Info
{
  "asset-id": 1234567890,
  "params": {
    "creator": "TOKENFORM_ISSUER_ADDRESS",
    "decimals": 0,
    "default-frozen": false,
    "name": "AgentLeash-customer-support-bot",
    "name-b64": "QWdlbnRMZWFzaC1jdXN0b21lci1zdXBwb3J0LWJvdA==",
    "total": 1,
    "unit-name": "ALEASH",
    "url": "https://api.tokenform.com/metadata/1234567890",
    "url-b64": "aHR0cHM6Ly9hcGkudG9rZW5mb3JtLmNvbS9tZXRhZGF0YS8xMjM0NTY3ODkw"
  }
}

Base Mainnet

On Base, AgentLeash tokens are implemented as ERC-721 NFTs with metadata stored on IPFS or our API.

Key Features:

  • Token ID: Unique identifier for each permission token
  • Smart Contract: ERC-721 contract with custom burning functionality
  • Metadata URI: Points to JSON metadata with permissions
  • Gas Efficiency: Optimized for minimal transaction costs

Smart Contract Address:

Base Mainnet: 0x742d35Cc6bF3b4570b3F0Fc10C6C9C8D6C8E9c4F

Dual Verification

For security, both the blockchain state and our API endpoint must agree on token validity:

Security Model: Tokens are only considered valid if they exist on-chain AND pass verification through our API. This prevents replay attacks and ensures real-time revocation.
Verification Process
async function verifyToken(assetId, chain) {
  // 1. Check blockchain state
  const onChainExists = await checkBlockchain(assetId, chain);
  
  // 2. Verify with TokenForm API
  const apiValid = await verifyWithAPI(assetId);
  
  // 3. Both must be true
  return onChainExists && apiValid;
}

Chain-Specific Parameters

Parameter Algorand Base
Token Identifier asset_id token_id
Network Testnet Mainnet
Block Time ~4.5 seconds ~2 seconds
Transaction Costs ~0.001 ALGO Variable gas fees

Rate Limits

Default Limits by Plan

Plan Requests/Minute Requests/Hour Requests/Day
Beta (Free) 10 100 1,000
Starter 60 1,000 10,000
Pro 300 5,000 50,000
Enterprise 1,000 25,000 Custom

Rate Limit Headers

All API responses include rate limit information in headers:

Response Headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1734567890
X-RateLimit-Window: 60
Header Description
X-RateLimit-Limit Maximum requests allowed in current window
X-RateLimit-Remaining Requests remaining in current window
X-RateLimit-Reset Unix timestamp when window resets
X-RateLimit-Window Window duration in seconds

429 Rate Limit Handling

When rate limits are exceeded, the API returns a 429 status code:

429 Response
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1734567890

{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Try again in 60 seconds.",
  "retry_after": 60,
  "limit": 60
}

Best Practices

  • Implement exponential backoff when receiving 429 responses
  • Monitor rate limit headers to avoid hitting limits
  • Cache responses when appropriate to reduce API calls
  • Batch operations where possible to use fewer requests
Rate Limit Handling Example
async function makeAPICall(url, options) {
  const response = await fetch(url, options);
  
  if (response.status === 429) {
    const retryAfter = response.headers.get('Retry-After');
    console.log(`Rate limited. Retrying in ${retryAfter} seconds.`);
    
    await new Promise(resolve => 
      setTimeout(resolve, parseInt(retryAfter) * 1000)
    );
    
    return makeAPICall(url, options); // Retry
  }
  
  return response;
}

Error Codes

HTTP Status Codes

Status Code Error Type Description Common Causes
400 Bad Request Invalid request format or parameters Missing required fields, invalid JSON, wrong parameter types
401 Unauthorized Missing or invalid authentication Missing x-api-key header, invalid API key
403 Forbidden Insufficient permissions API key lacks required permissions, account suspended
404 Not Found Resource does not exist Invalid endpoint, token not found, agent not found
429 Rate Limited Too many requests Exceeded rate limits for your plan
500 Internal Error Server-side error Database issues, blockchain connectivity problems

Error Response Format

All error responses follow a consistent JSON format:

Error Response Structure
{
  "error": "error_code",
  "message": "Human-readable error description",
  "details": {
    "field": "Additional context",
    "code": "SPECIFIC_ERROR_CODE"
  },
  "timestamp": "2026-04-11T23:52:00Z",
  "request_id": "req_1234567890abcdef"
}

Specific Error Codes

Authentication Errors (401)

{
  "error": "unauthorized",
  "message": "Invalid API key",
  "details": {
    "code": "INVALID_API_KEY"
  }
}

{
  "error": "unauthorized", 
  "message": "API key required",
  "details": {
    "code": "MISSING_API_KEY"
  }
}

Validation Errors (400)

{
  "error": "validation_failed",
  "message": "Required field missing: agent_id",
  "details": {
    "field": "agent_id",
    "code": "REQUIRED_FIELD_MISSING"
  }
}

{
  "error": "validation_failed",
  "message": "Invalid chain specified",
  "details": {
    "field": "chain",
    "allowed_values": ["algorand", "base"],
    "code": "INVALID_CHAIN"
  }
}

Resource Errors (404)

{
  "error": "not_found",
  "message": "Token not found",
  "details": {
    "asset_id": "1234567890",
    "code": "TOKEN_NOT_FOUND"
  }
}

{
  "error": "not_found",
  "message": "Agent not found",
  "details": {
    "agent_id": "non-existent-agent",
    "code": "AGENT_NOT_FOUND"
  }
}

Blockchain Errors (500)

{
  "error": "blockchain_error",
  "message": "Failed to connect to Algorand network",
  "details": {
    "chain": "algorand",
    "code": "BLOCKCHAIN_CONNECTIVITY_ERROR"
  }
}

{
  "error": "transaction_failed",
  "message": "Token minting failed on blockchain",
  "details": {
    "transaction_id": "failed_tx_123",
    "code": "MINT_TRANSACTION_FAILED"
  }
}

Try It

Test the AgentLeash API directly from your browser. This playground generates curl commands you can copy and execute.

API Endpoint Tester

Generated curl Command
# Select an endpoint and fill in the form to generate a curl command
Note: This is a command generator only. Replace placeholder values with real data before executing commands.

Webhooks

Coming Soon: Webhook support is planned for a future release. This will allow you to receive real-time notifications when tokens are minted, revoked, or expire.

Planned Webhook Events

  • token.minted - A new permission token has been created
  • token.revoked - A token has been manually revoked
  • token.expired - A token has reached its expiration time
  • token.used - A token has been used for verification
  • agent.created - A new agent has been registered

Expected Webhook Payload Format

Webhook Payload (Planned)
{
  "event": "token.minted",
  "timestamp": "2026-04-11T23:52:00Z",
  "data": {
    "asset_id": "1234567890",
    "agent_id": "customer-support-bot",
    "permissions": ["read", "write"],
    "expires_at": "2026-04-12T23:52:00Z"
  },
  "webhook_id": "wh_1234567890"
}

Stay tuned for updates on webhook availability. Subscribe to our changelog for notifications.

SDKs & Libraries

Coming Soon: Official SDKs are in development to make AgentLeash integration even easier.

Planned SDK Support

🐍 Python SDK

Full-featured Python library with async support

  • Type hints included
  • Poetry/pip compatible
  • Comprehensive examples
pip install agentleash

🟨 JavaScript/Node SDK

Native TypeScript support for Node.js and browsers

  • ES6+ modules
  • TypeScript definitions
  • React hooks included
npm install @tokenform/agentleash

🐹 Go SDK

High-performance Go client library

  • Context support
  • Structured logging
  • Minimal dependencies
go get github.com/tokenform/agentleash-go

Community Libraries

We encourage community-developed libraries and will feature them here. If you've built an AgentLeash integration, let us know!

Current Integration

Until official SDKs are available, you can integrate directly using HTTP requests as shown in the API Reference section.

Changelog

v1.0.0 — Initial API Release

Released: April 11, 2026

  • Core API endpoints: mint, revoke, verify-signature, health
  • Blockchain support: Algorand Testnet and Base Mainnet
  • Permission system: 6 permission types with constraint support
  • Rate limiting: Tiered limits based on subscription plan
  • Dashboard integration: Web UI for token management
  • Security features: Dual verification (blockchain + API)
What's Next: We're actively working on webhook support, official SDKs, and additional blockchain integrations. Follow our blog for updates.

Upcoming Releases

  • v1.1.0: Webhook support for real-time notifications
  • v1.2.0: Python SDK release
  • v1.3.0: JavaScript/TypeScript SDK release
  • v2.0.0: Additional blockchain support (Ethereum, Polygon)

Subscribe to our newsletter or follow @tokenform on Twitter for release announcements.