Skip to main content

What is agent registration?

Agent registration creates a new identity in Mandate and returns two credentials: a runtimeKey for API authentication and a claimUrl for the wallet owner. The runtime key is a bearer token (prefixed mndt_test_ or mndt_live_) that your agent includes in every subsequent API call. The claim URL is a one-time link the wallet owner visits to connect the agent to their dashboard, where they configure policies, approve transactions, and view the audit log. Registration is the only unauthenticated endpoint in the Mandate API. Every other operation requires the runtime key. You run registration once per agent, store the key securely, and share the claim URL with the person who controls the wallet. No private keys are involved at any point in this process.

How do you register an agent?

Use the SDK, CLI, or raw HTTP. All three methods hit the same POST /api/agents/register endpoint and return the same response.
import { MandateClient } from '@mandate.md/sdk';

const { agentId, runtimeKey, claimUrl, evmAddress } = await MandateClient.register({
  name: 'my-trading-agent',
  evmAddress: '0xYourAgentWalletAddress' as `0x${string}`,
  chainId: 84532,
  defaultPolicy: {
    spendLimitPerTxUsd: 100,
    spendLimitPerDayUsd: 1000,
  },
});

console.log('Agent ID:', agentId);
console.log('Runtime key:', runtimeKey);  // Save securely
console.log('Claim URL:', claimUrl);      // Share with wallet owner

Registration parameters

ParameterTypeRequiredDescription
namestringYesHuman-readable agent name, displayed in the dashboard
evmAddress0x${string}YesThe agent’s wallet address on the target chain
chainIdnumberYesTarget chain ID (e.g. 84532 for Base Sepolia)
defaultPolicyobjectNoInitial spend limits in USD

Response

{
  "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "runtimeKey": "mndt_test_abc12...xyz",
  "claimUrl": "https://app.mandate.md/claim/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "evmAddress": "0xYourAgentWalletAddress",
  "chainId": 84532
}

How should you store credentials?

The runtime key is the only secret your agent needs. Treat it like a database password. SDK and curl users: save the key to a .env file with restricted permissions.
echo "MANDATE_RUNTIME_KEY=mndt_test_abc12...xyz" >> .env
chmod 600 .env
CLI users: the login command writes credentials automatically to ~/.mandate/credentials.json with 0600 permissions. All subsequent CLI commands read this file.
Never commit the runtime key to version control. Add .env and ~/.mandate/ to your .gitignore. If a key is exposed, regenerate it immediately from the dashboard or via the POST /api/agents/{agentId}/regenerate-key endpoint.

How does the wallet owner claim the agent?

The claimUrl is a one-time link. Share it with the person who owns the wallet. When they visit the URL:
  1. They sign in with GitHub (or their existing dashboard account).
  2. The agent appears in their Agents page.
  3. They can configure policies, set approval thresholds, and view the audit log.
Until the agent is claimed, it operates under the default policy you set during registration. The wallet owner can tighten or relax these limits at any time after claiming.
Claiming is not required for the agent to function. An unclaimed agent validates transactions normally using the default policy. Claiming gives the wallet owner visibility and control.

What is the default policy?

Every new agent starts with a default policy. If you do not specify defaultPolicy during registration, these values apply:
RuleDefault value
Per-transaction limit$100 USD
Daily limit$1,000 USD
Monthly limitNone
Address restrictionsNone (any recipient allowed)
Approval requiredNo
Schedule24/7
Circuit breakerOff
These defaults let you start testing immediately on Base Sepolia. Before moving to production, the wallet owner should customize the policy in the Policy Builder: add address allowlists, lower spend limits, enable approval workflows, or restrict operating hours.

What happens after registration?

With the runtime key stored, your agent is ready to validate transactions. The typical next step is calling client.validate() before every transaction to check it against the policy engine’s 14 sequential rules. If validation passes, the agent signs locally and broadcasts. If it fails, the agent receives a typed error with a specific block reason.
Test the full flow on Base Sepolia before deploying to mainnet. Get testnet ETH from the Coinbase faucet and USDC from the Circle faucet.

Next Steps

Validate Transactions

Check every transaction against the policy engine before signing.

Policy Builder

Configure spend limits, allowlists, and approval thresholds in the dashboard.

CLI Login Reference

Full flag reference for the login command.

Credential Management

Best practices for storing, rotating, and revoking runtime keys.