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-linksPrefer the versioned base path /api/v1/*. Unversioned /api/* aliases still work for backward compatibility.
API key types
| Key type | Prefix | Environment | Real money? |
|---|---|---|---|
| Test | bag_test_sk_* | Sandbox | No |
| Live | bag_live_sk_* | Production | Yes |
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
- Sign in at getbags.app.
- Open Account Settings → API keys (/dashboard/settings).
- Click Generate live key or Generate test key.
- 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
Authorizationheader - 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.