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.