Skip to content

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_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • psk_live_ - Production keys
  • psk_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:

ScopeDescription
read:paymentsView payments
write:paymentsCreate and manage payments
read:recipientsView recipients
write:recipientsCreate and manage recipients
read:batchesView payment batches
write:batchesCreate and manage batches
read:webhooksView webhook subscriptions
write:webhooksManage webhook subscriptions
read:balanceView balance and funding
write:balanceManage balance and funding
adminFull administrative access

Managing API Keys

MethodEndpointDescription
GET/api/v1/api-keysList API keys
POST/api/v1/api-keysCreate API key
GET/api/v1/api-keys/:idGet key details
PATCH/api/v1/api-keys/:idUpdate key
DELETE/api/v1/api-keys/:idRevoke key
POST/api/v1/api-keys/:id/rotateRotate key

Portal endpoints (/api/portal/*) use passwordless magic-link authentication.

Login Flow

  1. Request magic link - POST /api/portal/auth/login with { "email": "user@example.com" }
  2. User clicks link - Valid for 15 minutes, single-use
  3. Verify and create session - POST /api/portal/auth/verify with { "token": "..." }
  4. Use session tokens - Access token (15 min) + refresh token (7 days)
  5. Refresh when needed - POST /api/portal/auth/refresh
  6. 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

  1. Never expose API keys in client-side code
  2. Use test keys in development, live keys in production
  3. Rotate keys regularly using the key rotation endpoint
  4. Use minimal scopes - only request what you need
  5. Monitor key usage via the audit log

Released under the MIT License.