BagsBags Docs
Getting Started

Authentication & API Keys

How to authenticate with the BAGS Agent API using bag_live_ and bag_test_ API keys.

Every request to the BAGS Agent API requires a Bearer token in the Authorization header.

curl -H "Authorization: Bearer $BAGS_KEY" \
  https://www.getbags.app/api/v1/payment-links

Prefer the versioned base path /api/v1/*. Unversioned /api/* aliases still work for backward compatibility.


API key types

Key typePrefixEnvironmentReal money?
Testbag_test_sk_*SandboxNo
Livebag_live_sk_*ProductionYes

Test keys are available immediately after signup.

Live keys are available for agentic accounts without business KYB. Use them for products, agentic payment links, and transaction reads.

Agent registration for machines is human-mediated — see /auth.md.


Generate an API key

  1. Sign in at getbags.app.
  2. Open Account SettingsAPI keys (/dashboard/settings).
  3. Click Generate live key or Generate test key.
  4. Copy the key immediately — it is shown once. Store it server-side.
export BAGS_KEY="bag_live_sk_your_key_here"
# or for sandbox:
# export BAGS_KEY="bag_test_sk_your_key_here"

Live keys on agentic accounts are minted with scope = 'agentic': they can manage agentic payment links, read your own transactions, and fetch the proxy-signing secret. Endpoints from the sunset checkout product (checkout sessions, refunds, settlements) reject them with API_KEY_SCOPE_INSUFFICIENT. Machine-readable claim flow: /auth.md.


Using the key

curl -X POST https://www.getbags.app/api/v1/payment-links \
  -H "Authorization: Bearer $BAGS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Pro Plan", "amount": 29.99, "network": "base_sepolia"}'
const response = await fetch("https://www.getbags.app/api/v1/payment-links", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.BAGS_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Pro Plan",
    amount: 29.99,
    network: "base_sepolia",
  }),
});

const result = await response.json();
import os
import requests

response = requests.post(
    "https://www.getbags.app/api/v1/payment-links",
    headers={
        "Authorization": f"Bearer {os.environ['BAGS_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "name": "Pro Plan",
        "amount": 29.99,
        "network": "base_sepolia",
    },
)

result = response.json()

Key security

  • Never commit keys to version control.
  • Never expose keys in client-side code or agent prompts.
  • Rotate compromised keys in the dashboard.

Error responses

Failed auth returns 401 with a stable code:

{
  "status": "error",
  "message": "Invalid or missing API key",
  "code": "UNAUTHORIZED"
}

401 responses also carry an RFC 9728 WWW-Authenticate hint pointing at /.well-known/oauth-protected-resource.

Common causes:

  • Missing Authorization header
  • Malformed key (trailing whitespace)
  • Test key against a live-only network (or vice versa)
  • Key deleted from the dashboard

Dashboard-only routes

Some endpoints require a dashboard session (Supabase cookie), not an API key — for example agentic onboard (/api/agentic/onboard) and payout verification (/api/agentic/verification). Guides call these out explicitly.

Buyer-facing x402 links do not require buyer API keys.


What's next

On this page