JustPaid Workflows
Getting Started

Authentication

Learn how to authenticate with the Workflows API

Authentication

The Workflows API uses API keys for authentication. All API requests must include your API key in the x-api-key header.

API Key Format

API keys follow this format:

wfk_[32 character random string]

Example: wfk_abc123def456ghi789jkl012mno345pq

Using Your API Key

Include your API key in the x-api-key header with every request:

curl http://localhost:3000/api/v1/workflows \
  -H "x-api-key: wfk_your_api_key_here"
const API_KEY = process.env.WORKFLOWS_API_KEY;

const response = await fetch('http://localhost:3000/api/v1/workflows', {
  headers: {
    'x-api-key': API_KEY
  }
});
const API_KEY = process.env.WORKFLOWS_API_KEY as string;

const response = await fetch('http://localhost:3000/api/v1/workflows', {
  headers: {
    'x-api-key': API_KEY
  }
});
import os
import requests

API_KEY = os.environ.get('WORKFLOWS_API_KEY')

response = requests.get(
    'http://localhost:3000/api/v1/workflows',
    headers={'x-api-key': API_KEY}
)

API Key Scopes

API keys can be configured with different permission scopes:

ScopeDescriptionEndpoints
workflows:readRead workflow definitionsGET /workflows, GET /workflows/:id
workflows:writeCreate and modify workflowsPOST /workflows, PUT /workflows/:id
workflows:executeRun workflowsPOST /workflows/:id/run
runs:readRead workflow run historyGET /runs, GET /runs/:id
connections:readView connectionsGET /connections
connections:writeManage connectionsPOST /connections, DELETE /connections/:id

Security Best Practices

Never expose your API key in client-side code, public repositories, or logs.

Do's

  • Store API keys in environment variables
  • Use different keys for development and production
  • Rotate keys periodically (every 90 days recommended)
  • Use the minimum required scopes
  • Revoke compromised keys immediately

Don'ts

  • Don't commit API keys to version control
  • Don't share keys via email or chat
  • Don't use production keys in development
  • Don't log API keys in application logs

Environment Variables

We recommend storing your API key in an environment variable:

# .env (add to .gitignore!)
WORKFLOWS_API_KEY=wfk_your_api_key_here

Then access it in your code:

const apiKey = process.env.WORKFLOWS_API_KEY;
import os
api_key = os.environ.get('WORKFLOWS_API_KEY')
export WORKFLOWS_API_KEY=wfk_your_api_key_here
curl -H "x-api-key: $WORKFLOWS_API_KEY" ...

Rate Limits

API requests are rate limited per API key using a sliding window algorithm:

CategoryLimitEndpoints
Read1000/minGET requests
Write100/minPOST, PUT, DELETE requests
Execute500/minWorkflow run, cancel, retry
Webhooks10000/minWebhook ingestion (by IP)

Rate Limit Headers

Every authenticated response includes rate limit headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1702531200
HeaderDescription
X-RateLimit-LimitMaximum requests allowed in window
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when window resets

Handling Rate Limits

When you exceed the rate limit, you'll receive a 429 Too Many Requests response:

{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Limit: 100 requests per minute."
  }
}

Best practices for handling rate limits:

  1. Check rate limit headers proactively
  2. Implement exponential backoff on 429 errors
  3. Queue non-urgent requests
  4. Cache responses where appropriate
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const resetTime = response.headers.get('X-RateLimit-Reset');
      const waitMs = resetTime
        ? (parseInt(resetTime) * 1000) - Date.now()
        : Math.pow(2, i) * 1000;

      await new Promise(resolve => setTimeout(resolve, waitMs));
      continue;
    }

    return response;
  }
  throw new Error('Max retries exceeded');
}

Error Responses

401 Unauthorized

Missing or invalid API key:

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

403 Forbidden

API key lacks required permissions:

{
  "success": false,
  "error": {
    "code": "FORBIDDEN",
    "message": "Insufficient permissions for this operation"
  }
}

Managing API Keys

List API Keys

curl http://localhost:3000/api/v1/auth/api-keys \
  -H "x-api-key: YOUR_API_KEY"

Create API Key

curl -X POST http://localhost:3000/api/v1/auth/api-keys \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production API Key",
    "scopes": ["workflows:read", "workflows:write", "workflows:execute"]
  }'

Revoke API Key

curl -X DELETE http://localhost:3000/api/v1/auth/api-keys/{KEY_ID} \
  -H "x-api-key: YOUR_API_KEY"

Next Steps

On this page