M MetadataONE / docs
Docs / Getting Started / Authentication

Authentication

All MetadataONE MCP requests are authenticated with a bearer token scoped to a single account. Keys are minted from the app, stored server-side only, and can be rotated or revoked at any time.

Mint an API key

  1. Sign in at app.metadataone.com
  2. Open Settings → API Keys
  3. Click Create Key, name it after the agent that will use it (claude-code-gil, hermes-prod, paperclip-sandbox)
  4. Set scopes (see below) and copy the token, it's shown exactly once

Keys are shown once. If you lose a key, rotate it rather than contacting support. Treat tokens like passwords, never commit to git, never log them, never paste into chat.

Scopes

Keys can be scoped to limit blast radius. If a key only needs analytics, don't grant launch permissions.

ScopeGrantsDestructive
read:allAll get_*, search_*, list_*, *_stats, *_insights toolsNo
write:audiencesCreate, update, archive audiences & target groupsNo (reversible)
write:creativesGenerate/upload creatives, build adsNo
write:campaignsCreate & edit campaigns in Draft, excluding launchNo
launch:campaignslaunch_campaign, manage_campaign, real spend beginsYes
write:integrationsConnect/disconnect channels & CRMsYes
admin:*Account impersonation, billing, user mgmtYes

Using the key

As an environment variable

The MCP client reads the key from METADATA_API_KEY by default:

Shell
export METADATA_API_KEY="md1_live_7f3a…"
npx @anthropic/mcp-client add metadataone

In Claude Code

Add to your ~/.config/claude-code/mcp.json:

JSON
{
  "mcpServers": {
    "metadataone": {
      "command": "npx",
      "args": ["-y", "@metadataone/mcp-server"],
      "env": {
        "METADATA_API_KEY": "md1_live_7f3a…"
      }
    }
  }
}

Direct HTTP (non-MCP)

If you're not using the MCP protocol, every tool is also exposed at https://mcp.metadataone.com/v1/<tool_name>:

cURL
curl -X POST https://mcp.metadataone.com/v1/get_account_details \
  -H "Authorization: Bearer $METADATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Multi-account access

If your user has access to multiple MetadataONE accounts (agencies, holding companies), call list_user_accounts first and include X-Account-ID on subsequent requests:

Python
accounts = mcp.list_user_accounts()
for a in accounts:
    stats = mcp.account_level_stats(
        account_id=a["id"],        # passed on every call
        date_range="last_30_days",
    )
    print(a["name"], stats["total_spend"])

Key rotation

Best practice is to rotate keys quarterly, and immediately on any of:

Rotation is atomic, the old key stays valid for 15 minutes after a new one is issued, so you can deploy the new key without downtime. Older keys are hard-revoked after the grace window.

Auth errors

HTTPCodeMeaning
401missing_keyNo Authorization header
401invalid_keyKey is revoked, rotated out, or malformed
403scope_deniedKey is valid but lacks the scope for this tool
403account_mismatchX-Account-ID not accessible to this user
402insufficient_creditsCredit balance is zero, top up or upgrade tier

Next: with a key in hand, connect MetadataONE to your MCP client, or jump straight to shipping your first campaign.