Set up your development environment

Get familiar with the Mandate AI SDKs and start authorizing agent transactions in minutes.

Overview

This guide walks you through everything you need to go from zero to authorizing your first AI agent transaction. You will register as a principal, create an agent, set spending limits via a mandate, and submit a transaction for real-time authorization.

What you'll learn

Sandbox vs. Production

Sandbox keys (mdt_test_*) work identically to production keys (mdt_live_*) but never touch real payment rails. Use sandbox keys throughout development.

Get your API key

Register as a principal to receive your API key. The key is shown only once at registration time — store it securely.

API keys use the prefix mdt_test_ for sandbox and mdt_live_ for production. All requests authenticate via the X-API-Key header.

curl -X POST https://mandateai-elwri.ondigitalocean.app/api/v1/principals/register \
  -H "Content-Type: application/json" \
  -d '{
    "type": "organization",
    "name": "Acme Corp",
    "email": "admin@acme.com",
    "country": "US",
    "org_legal_name": "Acme Corporation Inc.",
    "org_registration_number": "DE-12345678"
  }'
from mandate_ai_sdk import MandateAI

# Before you have a key, use a direct HTTP call
import httpx

response = httpx.post(
    "https://mandateai-elwri.ondigitalocean.app/api/v1/principals/register",
    json={
        "type": "organization",
        "name": "Acme Corp",
        "email": "admin@acme.com",
        "country": "US",
        "org_legal_name": "Acme Corporation Inc.",
        "org_registration_number": "DE-12345678",
    }
)

data = response.json()
api_key = data["api_key"]  # mdt_test_abc123... — save this!
// Before you have a key, use a direct fetch call
const response = await fetch(
  "https://mandateai-elwri.ondigitalocean.app/api/v1/principals/register",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      type: "organization",
      name: "Acme Corp",
      email: "admin@acme.com",
      country: "US",
      org_legal_name: "Acme Corporation Inc.",
      org_registration_number: "DE-12345678",
    }),
  }
);

const data = await response.json();
const apiKey = data.api_key; // mdt_test_abc123... — save this!

Install the SDK

Install the official SDK for your language. Both libraries provide typed models, automatic error handling, and namespaced resource access.

pip install mandate-ai-sdk
npm install @mandate-ai/sdk

Initialize the client with your API key:

from mandate_ai_sdk import MandateAI

client = MandateAI(api_key="mdt_test_abc123...")

# Verify connection
principal = client.principals.me()
print(f"Connected as: {principal.name}")
import { MandateAI } from "@mandate-ai/sdk";

const client = new MandateAI({ apiKey: "mdt_test_abc123..." });

// Verify connection
const principal = await client.principals.me();
console.log(`Connected as: ${principal.name}`);

Register your first agent

Agents represent AI systems that will transact on behalf of your organization. Each agent has a display name, optional capabilities list, and description.

agent = client.agents.create(
    display_name="Shopping Assistant v1",
    capabilities=["purchase", "price_comparison", "refund_request"],
    description="Autonomous e-commerce purchasing agent",
)

print(f"Agent ID: {agent.id}")
print(f"Status: {agent.status}")  # "active"
const agent = await client.agents.create({
  display_name: "Shopping Assistant v1",
  capabilities: ["purchase", "price_comparison", "refund_request"],
  description: "Autonomous e-commerce purchasing agent",
});

console.log(`Agent ID: ${agent.id}`);
console.log(`Status: ${agent.status}`); // "active"

Create a spending mandate

Mandates define what an agent is allowed to spend. Set maximum amounts per transaction, daily and monthly limits, merchant category restrictions, and expiry dates.

from mandate_ai_sdk.models import MandateCreate

mandate = client.mandates.create(MandateCreate(
    agent_id=agent.id,
    max_amount_per_transaction="500.00",
    currency="USD",
    valid_until="2026-12-31T23:59:59Z",
    max_daily_amount="2000.00",
    max_daily_count=20,
    allowed_mccs=["5411", "5912"],  # Grocery, drug stores
    description="Daily shopping mandate",
))

print(f"Mandate ID: {mandate.id}")
print(f"Status: {mandate.status}")  # "active"
const mandate = await client.mandates.create({
  agent_id: agent.id,
  max_amount_per_transaction: "500.00",
  currency: "USD",
  valid_until: "2026-12-31T23:59:59Z",
  max_daily_amount: "2000.00",
  max_daily_count: 20,
  allowed_mccs: ["5411", "5912"], // Grocery, drug stores
  description: "Daily shopping mandate",
});

console.log(`Mandate ID: ${mandate.id}`);
console.log(`Status: ${mandate.status}`); // "active"

Authorize a transaction

This is the core operation. Submit a transaction request and receive a real-time decision with trust scoring, risk assessment, and any gates that fired.

from mandate_ai_sdk.models import AuthorizeRequest

result = client.authorization.authorize(AuthorizeRequest(
    agent_id=agent.id,
    amount="42.99",
    currency="USD",
    merchant="Whole Foods Market #1042",
    mcc="5411",
    intent_context={
        "task": "weekly_grocery_purchase",
        "reasoning": "User requested organic produce restock",
        "items_count": 12,
    },
))

print(f"Decision: {result.decision}")         # "APPROVE"
print(f"Trust Score: {result.trust_score}")    # 0.87
print(f"Risk Score: {result.risk_score}")      # 0.12
print(f"Gates Fired: {result.gates_fired}")    # []
const result = await client.authorization.authorize({
  agent_id: agent.id,
  amount: "42.99",
  currency: "USD",
  merchant: "Whole Foods Market #1042",
  mcc: "5411",
  intent_context: {
    task: "weekly_grocery_purchase",
    reasoning: "User requested organic produce restock",
    items_count: 12,
  },
});

console.log(`Decision: ${result.decision}`);       // "APPROVE"
console.log(`Trust Score: ${result.trust_score}`);  // 0.87
console.log(`Risk Score: ${result.risk_score}`);    // 0.12
console.log(`Gates Fired: ${result.gates_fired}`);  // []
Response fields

decision: APPROVE, DECLINE, or STEP_UP. trust_score: Current CTS (0-1). risk_score: Transaction risk (0-1). gates_fired: Array of triggered safety gates. recommendations: Suggested actions if declined.

Set up webhooks

Register a webhook endpoint to receive real-time notifications about important events like gate firings, trust zone changes, and declined authorizations.

from mandate_ai_sdk.models import WebhookCreate

webhook = client.webhooks.create(WebhookCreate(
    url="https://your-app.com/webhooks/mandate-ai",
    event_types=[
        "gate.fired",
        "cts.red",
        "cts.critical",
        "authorization.decline",
        "trust.promotion",
    ],
    description="Production alerting webhook",
))

# Save the signing secret — shown only once!
print(f"Webhook ID: {webhook.id}")
print(f"Signing Secret: {webhook.signing_secret}")  # whsec_...
const webhook = await client.webhooks.create({
  url: "https://your-app.com/webhooks/mandate-ai",
  event_types: [
    "gate.fired",
    "cts.red",
    "cts.critical",
    "authorization.decline",
    "trust.promotion",
  ],
  description: "Production alerting webhook",
});

// Save the signing secret — shown only once!
console.log(`Webhook ID: ${webhook.id}`);
console.log(`Signing Secret: ${webhook.signing_secret}`); // whsec_...

Available event types:

  • gate.fired — A safety gate triggered during authorization
  • cts.red — Agent's trust score dropped to RED zone
  • cts.critical — Agent's trust score dropped to CRITICAL zone
  • session.terminate — Agent session was terminated
  • authorization.decline — A transaction was declined
  • trust.promotion — Agent was promoted to a higher trust tier
  • * — Subscribe to all event types

Next steps

Now that you can authorize transactions, explore these guides to deepen your integration: