Authentication
PayStream supports two authentication methods: API keys for server-to-server calls, and session tokens for portal access.
API Key Authentication
All /api/v1/* endpoints require an API key in the Authorization header.
API Key Format
API keys start with psk_ followed by a random string:
psk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
psk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxpsk_live_- Production keyspsk_test_- Test/sandbox keys
Authentication Header
Include your API key in every request:
bash
curl -X GET https://api.paystream.fi/api/v1/payments \
-H "Authorization: Bearer psk_test_xxx"API Scopes
API keys have scoped permissions. Available scopes:
| Scope | Description |
|---|---|
read:payments | View payments |
write:payments | Create and manage payments |
read:recipients | View recipients |
write:recipients | Create and manage recipients |
read:batches | View payment batches |
write:batches | Create and manage batches |
read:webhooks | View webhook subscriptions |
write:webhooks | Manage webhook subscriptions |
read:balance | View balance and funding |
write:balance | Manage balance and funding |
admin | Full administrative access |
Managing API Keys
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/api-keys | List API keys |
| POST | /api/v1/api-keys | Create API key |
| GET | /api/v1/api-keys/:id | Get key details |
| PATCH | /api/v1/api-keys/:id | Update key |
| DELETE | /api/v1/api-keys/:id | Revoke key |
| POST | /api/v1/api-keys/:id/rotate | Rotate key |
Portal Authentication (Magic Links)
Portal endpoints (/api/portal/*) use passwordless magic-link authentication.
Login Flow
- Request magic link -
POST /api/portal/auth/loginwith{ "email": "user@example.com" } - User clicks link - Valid for 15 minutes, single-use
- Verify and create session -
POST /api/portal/auth/verifywith{ "token": "..." } - Use session tokens - Access token (15 min) + refresh token (7 days)
- Refresh when needed -
POST /api/portal/auth/refresh - Logout -
POST /api/portal/auth/logout
Security Features
- Tokens are hashed (SHA-256) before storage
- Atomic redemption prevents race conditions
- IP and User-Agent logged for audit
- Failed authentication attempts are tracked
Error Responses
Invalid or missing authentication returns 401 Unauthorized:
json
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}Insufficient scopes return 403 Forbidden:
json
{
"error": {
"code": "FORBIDDEN",
"message": "Missing required scope: write:payments"
}
}Security Best Practices
- Never expose API keys in client-side code
- Use test keys in development, live keys in production
- Rotate keys regularly using the key rotation endpoint
- Use minimal scopes - only request what you need
- Monitor key usage via the audit log