From pip install to your first human-approved agent action in five minutes.
No iPhone required — start with any TOTP authenticator, upgrade to Face ID later.
Google Authenticator, Authy, 1Password, Apple Passwords — anything that generates 6-digit TOTP codes. No iPhone required. Upgrade to Face ID later for higher assurance.
Create an account via magic link and generate an API key. It starts with aa_. Copy it — this connects your agent to your approver device.
The SDK and MCP server need Python. The REST API works with any language — curl, Node.js, Go, anything that makes HTTP requests.
Create an account, register your device, enroll TOTP, and generate an API key. You can do this entirely from the command line or use the interactive quickstart script.
pip install synauthThe quickstart script walks you through account creation, TOTP enrollment (scan a QR code), and API key generation.
# Clone the examples or download quickstart_totp.py from GitHub
python quickstart_totp.py
Or do it step by step with curl:
# 1. Create account (returns token in dev mode, emails it in production)
curl -s -X POST https://synauth.fly.dev/api/v1/auth/magic-link \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'
# 2. Verify & register device
curl -s -X POST https://synauth.fly.dev/api/v1/auth/verify \
-H "Content-Type: application/json" \
-d '{"token": "TOKEN_FROM_STEP_1", "device_name": "My Laptop"}'
# Save the device_id from the response
# 3. Set up TOTP — scan the provisioning_uri as a QR code
curl -s -X POST https://synauth.fly.dev/api/v1/totp/setup \
-H "X-Device-Id: YOUR_DEVICE_ID"
# 4. Verify TOTP with a code from your authenticator
curl -s -X POST https://synauth.fly.dev/api/v1/totp/verify-setup \
-H "X-Device-Id: YOUR_DEVICE_ID" \
-H "Content-Type: application/json" \
-d '{"code": "123456"}'
# 5. Create an API key for your agent
curl -s -X POST https://synauth.fly.dev/api/v1/keys \
-H "X-Device-Id: YOUR_DEVICE_ID" \
-H "Content-Type: application/json" \
-d '{"agent_id": "my-agent", "name": "My First Agent"}'
# Save the key — starts with aa_, shown only once
dev_...) — your approver identityaa_...) for your agent to useNow choose how to integrate your agent. ↓
All three paths do the same thing: send an action request to SynAuth, get biometric approval on your iPhone, and return the result to your agent. Pick the one that fits your setup.
Best for custom Python agents. Full-featured client with typed errors, convenience methods, and spending limit checks.
pip install synauthBest for Claude, Cursor, and any MCP-compatible agent. Drop-in biometric approval with zero code.
pip install synauth-mcpBest for any language or framework. Direct HTTP calls — works everywhere.
https://synauth.fly.dev/api/v1pip install synauthCreate a client with your API key and request approval for an action. This sends a push notification to your iPhone.
from synauth import SynAuthClient
client = SynAuthClient(api_key="aa_your_key_here")
# Request approval for an action
result = client.request_action(
action_type="communication",
title="Send quarterly report",
description="Email to [email protected] with Q4 results",
risk_level="low",
)
print(f"Request created: {result['id']}")
print(f"Status: {result['status']}") # "pending" or "approved" (if auto-approved by rules)
Your iPhone buzzes. You see the action details, verify with Face ID, and the agent gets the result.
# Block until the user approves, denies, or the request expires
status = client.wait_for_result(result["id"])
if status["status"] == "approved":
print("Approved! Proceeding with action.")
# Your agent does its thing
elif status["status"] == "denied":
print(f"Denied: {status.get('deny_reason', 'No reason given')}")
elif status["status"] == "expired":
print("Request expired (default: 5 minutes)")
The SDK provides typed exceptions so your agent can handle each failure mode.
from synauth import (
SynAuthClient,
ActionDeniedError,
ActionExpiredError,
RateLimitError,
SynAuthAPIError,
)
try:
result = client.request_action(
action_type="purchase",
title="Buy API credits",
amount=49.99,
)
status = client.wait_for_result(result["id"])
except ActionDeniedError as e:
print(f"User denied: {e.reason}")
except ActionExpiredError:
print("Request expired before user responded")
except RateLimitError:
print("Rate limited — back off and retry")
except SynAuthAPIError as e:
print(f"API error {e.status_code}: {e.detail}")
pip install synauth-mcpFor Claude Desktop, add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"synauth": {
"command": "synauth-mcp",
"env": {
"SYNAUTH_API_KEY": "aa_your_key_here"
}
}
}
}
For Claude Code, add the same config to .mcp.json in your project root.
Restart Claude. The agent now has SynAuth tools available.
That’s it. No code to write. Ask your agent to perform an action that needs approval. It discovers SynAuth’s tools automatically via MCP.
Send the quarterly report to [email protected]
I’ll request approval through SynAuth first.
request_approval(action_type: "communication", title: "Send quarterly report to [email protected]")
Push notification → Face ID verification → Approved
Approved. Sending the report now.
POST to the actions endpoint with your API key in the header. Works from any language.
curl -X POST https://synauth.fly.dev/api/v1/actions \
-H "X-API-Key: aa_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"action_type": "purchase",
"title": "Buy DigitalOcean credits",
"description": "3x droplets for staging environment",
"amount": 49.99,
"risk_level": "medium"
}'
Response:
{
"id": "act_7f3a2b1c8d9e0f4a",
"status": "pending",
"action_type": "purchase",
"title": "Buy DigitalOcean credits",
"amount": 49.99,
"created_at": "2026-02-18T14:30:00Z",
"expires_at": "2026-02-18T14:35:00Z"
}
After the user verifies with Face ID, the status updates to approved or denied.
curl https://synauth.fly.dev/api/v1/actions/act_7f3a2b1c8d9e0f4a \
-H "X-API-Key: aa_your_key_here"
Response after approval:
{
"id": "act_7f3a2b1c8d9e0f4a",
"status": "approved",
"resolved_by": "face_id",
"resolved_at": "2026-02-18T14:30:12Z"
}
Skip polling. Include a callback_url and SynAuth will POST the result to your server when the user responds.
curl -X POST https://synauth.fly.dev/api/v1/actions \
-H "X-API-Key: aa_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"action_type": "purchase",
"title": "Buy API credits",
"amount": 49.99,
"callback_url": "https://your-server.com/webhook/synauth"
}'
API base URL: https://synauth.fly.dev/api/v1 ·
Full API docs on GitHub
Two approval methods. Same security. Choose based on what you have.
Works with any authenticator app. No iOS app needed. When your agent requests an action, check pending requests and approve with a 6-digit TOTP code.
# Check pending actions
curl -s https://synauth.fly.dev/api/v1/pending \
-H "X-Device-Id: dev_yours"
# Approve with TOTP code
curl -s -X POST https://synauth.fly.dev/api/v1/actions/ACTION_ID/approve \
-H "X-Device-Id: dev_yours" \
-H "Content-Type: application/json" \
-d '{"totp_code": "123456"}'
NIST AAL2. Proves device possession.
Upgrade to the SynAuth iOS app for push-notification approval with biometric verification. Your iPhone buzzes, you glance, Face ID confirms it’s you. Under two seconds.
Push notification with action details
Review — risk level, amount, context
Approve with Face ID — agent proceeds
NIST AAL3. Proves physical identity.
Once your first request is working, explore these features to build a production-ready integration.
Store your API keys (OpenAI, GitHub, Stripe) in SynAuth. After biometric approval, SynAuth injects the credential and executes the API call. Your agent never sees the key.
# Discover services in the vault
services = client.list_vault_services()
# Execute through the vault
result = client.execute_api_call(
service_name="openai",
method="POST",
url="https://api.openai.com/v1/chat/completions",
body='{"model": "gpt-4", "messages": [...]}'
)
Not every action needs Face ID. Configure rules in the iOS app to auto-approve low-risk actions, auto-deny from untrusted agents, or require biometric for purchases over a threshold.
# Your agent doesn't need to know about rules.
# request_action returns "approved" instantly
# if a rule matches, or "pending" if it
# needs Face ID.
result = client.request_action(
action_type="scheduling",
title="Book team lunch",
risk_level="low", # Auto-approved by rule
)
Set per-agent daily, weekly, or monthly spending caps. Hard constraints that override auto-approve rules — even trusted agents hit the ceiling.
# Check spending before purchasing
summary = client.get_spending_summary()
for s in summary["summaries"]:
remaining = s["limit"] - s["spent"]
print(f"{s['period']}: ${remaining:.2f} left")
Seven built-in action types with default risk levels. Use the right type for clear audit trails and intelligent rules.
communication low
purchase medium
scheduling low
legal critical
data_access high
social medium
system high
Free tier: 25 actions/month. Unlimited: $0.99/month.
pip install synauth