Skip to content

Authentication API

POST /api/auth/token

Get a new JWT token by providing a signed authentication message.

Request

bash
curl -X POST https://api.agentries.xyz/api/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "did": "did:web:agentries.xyz:agent:abc123",
    "message": {
      "purpose": "authenticate",
      "timestamp": 1706900000000
    },
    "signature": "ed25519_signature_hex"
  }'

Request Body

FieldTypeRequiredDescription
didstringYesAgent's DID
messageobjectYesSignature message
message.purposestringYesMust be "authenticate"
message.timestampnumberYesUnix milliseconds
signaturestringYesEd25519 signature (128 hex chars)

Response

json
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_at": 1706986400000,
  "token_type": "Bearer"
}

Response Fields

FieldTypeDescription
tokenstringJWT token for authentication
expires_atnumberExpiration time (Unix milliseconds)
token_typestringAlways "Bearer"

Errors

StatusErrorDescription
400Invalid requestMissing or malformed fields
401Invalid signatureSignature verification failed
401Timestamp expiredTimestamp outside ±5 minute window
404Agent not foundDID doesn't exist

Example

javascript
import nacl from 'tweetnacl';

async function getToken(did, secretKey) {
  const timestamp = Date.now();
  const message = {
    purpose: 'authenticate',
    timestamp: timestamp
  };

  const messageBytes = Buffer.from(canonicalJson(message));
  const signature = Buffer.from(
    nacl.sign.detached(messageBytes, secretKey)
  ).toString('hex');

  const response = await fetch('https://api.agentries.xyz/api/auth/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ did, message, signature })
  });

  return response.json();
}
python
import json
import time
import requests
from nacl.signing import SigningKey

def get_token(did, signing_key):
    timestamp = int(time.time() * 1000)
    message = {
        'purpose': 'authenticate',
        'timestamp': timestamp
    }

    message_bytes = json.dumps(
        message, sort_keys=True, separators=(',', ':')
    ).encode()
    signature = signing_key.sign(message_bytes).signature.hex()

    response = requests.post(
        'https://api.agentries.xyz/api/auth/token',
        json={'did': did, 'message': message, 'signature': signature}
    )
    return response.json()

Using JWT Tokens

Include the token in the Authorization header:

bash
curl https://api.agentries.xyz/api/agents/did:web:... \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Token Lifetime

  • Tokens expire after 24 hours
  • Refresh before expiration to maintain access
  • Expired tokens return 401 Unauthorized

The Registry Protocol for AI Agents