Overview
Payo uses two types of credentials:
| Credential | Used By | Purpose |
|---|
| Provider API Key | MCP Providers | Authenticate charge requests |
| Agent Token | AI Agents | Identify who’s being charged |
Both are secret keys that should never be shared publicly.
Provider API Keys
What They Are
Provider keys authenticate your MCP server to the Payo platform. When your server charges an agent, the provider key proves it’s really you.
sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
sk_ - Secret key prefix
live_ - Production environment
- 64 hex characters - Unique identifier
Scope
Provider keys have provider:charge scope, which allows:
- Charging agents via
/api/v1/charge
- No other actions (can’t manage agents, can’t access admin features)
Usage
Pass as environment variable to your MCP server:
PAYO_API_KEY=sk_live_xxx node server.js
Used in SDK configuration:
withPayments(server, {
apiKey: process.env.PAYO_API_KEY!,
pricing: { ... }
});
Security
Your provider key is a secret. Exposure allows anyone to charge agents on your behalf.
Best practices:
- Store in environment variables, never in code
- Use secrets management (Vercel, Railway, AWS Secrets Manager)
- Rotate periodically
- Different keys for development vs production
Agent Tokens
What They Are
Agent tokens identify which agent is making a tool call. When an agent calls a paid tool, their token is used to charge their account.
Same as provider keys:
sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...
Scope
Agent tokens have agent:connect scope, which allows:
- Being charged for tool calls
- No other actions (can’t charge others, can’t access platform features)
Usage
stdio transport (Claude Desktop, Cursor):
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["server.js"],
"env": {
"AGENT_TOKEN": "sk_live_agent_xxx"
}
}
}
}
HTTP transport (custom agents):
const response = await fetch(url, {
headers: {
'Authorization': 'Bearer sk_live_agent_xxx'
}
});
Security
Agent tokens control spending. Exposure allows anyone to spend your credits.
Best practices:
- Store securely (not in version control)
- Use different tokens for different agents/environments
- Monitor for unexpected charges
- Rotate if compromised
Key Storage
Keys are stored securely:
Raw Key: sk_live_abc123xyz789...
↓
SHA256 Hash: 5d41402abc4b2a76b9719d911017c592...
↓
Stored in DB: key_hash = "5d41402abc..."
key_prefix = "sk_live_"
key_last4 = "9..."
The raw key is:
- Shown once at creation
- Never stored
- Cannot be retrieved
Only the hash is stored for validation.
Key Validation
When a key is used:
1. Receive: sk_live_abc123xyz789...
2. Compute: SHA256("sk_live_abc123xyz789...") = "5d41402..."
3. Query: SELECT * FROM api_keys
WHERE key_hash = "5d41402..."
AND deleted_at IS NULL
4. Check: scopes @> '{required_scope}'
5. Return: { workspace_id, key_name } or error
This allows validation without ever storing the raw key.
Scopes
Each key type has a specific scope:
| Key Type | Scope | Permissions |
|---|
| Provider | provider:charge | Call /api/v1/charge |
| Agent | agent:connect | Be charged for tool calls |
Keys cannot perform actions outside their scope:
- An agent token cannot charge other agents
- A provider key cannot be charged
Key Lifecycle
Creation
- User clicks “Create Key” in dashboard
- System generates 64 random hex bytes
- Key is hashed and stored
- Raw key is displayed once
Usage
- Key is passed to API or MCP server
- System hashes and looks up
- Validates scope and status
- Authorizes the action
Rotation
- Create a new key
- Update your configuration
- Delete the old key
Deletion
- User clicks “Delete” in dashboard
- Key is soft-deleted (
deleted_at set)
- Key immediately stops working
- Key cannot be recovered
Multiple Keys
You can create multiple keys for different purposes:
Agents:
- Separate keys per agent instance
- Separate keys per environment
- Easy to revoke one without affecting others
Providers:
- Separate keys per MCP server
- Separate keys per environment
- Independent rotation schedules
Common Issues
”Invalid provider key”
- Key was deleted
- Key doesn’t exist
- Key is from wrong account
- Key was typed incorrectly
Fix: Create a new key in dashboard.
”Invalid agent token”
- Token was deleted
- Token doesn’t exist
- Token was typed incorrectly
Fix: Agent must create new token.
”Token missing”
AGENT_TOKEN env var not set
Authorization header not sent
- Configuration syntax error
Fix: Check agent configuration.