Rate Limits

To ensure fair usage and system stability, the Priostack API enforces rate limits on a per-API-key basis. Rate limiting is applied across all API endpoints.

Current Limits

LimitValue
Requests per minute300 per API key
Window typeFixed 60-second window
ScopePer API key (not per IP)
Long-poll requests (job activation)Counted as 1 request regardless of wait duration

Rate Limit Headers

Every API response includes the following headers so you can monitor your usage:

HeaderDescriptionExample
X-RateLimit-Limit Maximum requests allowed in the current window 300
X-RateLimit-Remaining Requests remaining in the current window 247
X-RateLimit-Window Window duration in seconds 60
X-RateLimit-Reset Unix timestamp (seconds) when the window resets 1746456780
# Inspect rate limit headers
curl -i -H "X-API-Key: your_key" \
  https://api.priostack.com/api/v1/topology

HTTP/1.1 200 OK
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 247
X-RateLimit-Window: 60
X-RateLimit-Reset: 1746456780
Content-Type: application/json
...

Handling 429 Responses

When the rate limit is exceeded, the API returns HTTP 429 with an error body. You should stop sending requests and wait until the reset time.

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1746456780
Retry-After: 23

{"error": "rate limit exceeded"}

Retry Logic in Go

func callWithRetry(req *http.Request) (*http.Response, error) {
    for attempts := 0; attempts < 5; attempts++ {
        resp, err := http.DefaultClient.Do(req)
        if err != nil {
            return nil, err
        }
        if resp.StatusCode != http.StatusTooManyRequests {
            return resp, nil
        }
        resp.Body.Close()

        // Read reset time from header
        resetStr := resp.Header.Get("X-RateLimit-Reset")
        reset, _ := strconv.ParseInt(resetStr, 10, 64)
        waitUntil := time.Unix(reset, 0)
        sleepDuration := time.Until(waitUntil) + time.Second // +1s buffer

        log.Printf("Rate limited. Waiting %s until reset.", sleepDuration)
        time.Sleep(sleepDuration)
    }
    return nil, errors.New("exceeded max retry attempts")
}

Retry Logic in Python

import time
import requests

def call_with_retry(url, headers, payload, max_attempts=5):
    for attempt in range(max_attempts):
        response = requests.post(url, headers=headers, json=payload)
        if response.status_code != 429:
            return response

        reset = int(response.headers.get("X-RateLimit-Reset", time.time() + 60))
        wait = max(0, reset - time.time()) + 1  # +1s buffer
        print(f"Rate limited. Sleeping {wait:.1f}s...")
        time.sleep(wait)

    raise Exception("Max retry attempts exceeded")

Tips for High-Volume Usage

1. Use Long-Polling for Job Workers

The GET /api/v1/jobs/activate endpoint supports long-polling with a configurable timeout (default 30 seconds). A single long-poll request that waits 30 seconds counts as only 1 request against your rate limit — far more efficient than rapid polling.

# Long-poll with 30s timeout — only 1 request per 30s
curl -X POST "https://api.priostack.com/api/v1/jobs/activate" \
  -H "X-API-Key: your_key" \
  -d '{"type": "my-worker", "maxJobsToActivate": 10, "requestTimeout": 30000}'

2. Batch Process Starts

If you need to start many process instances, use the batch endpoint to start multiple instances in a single request:

POST /api/v1/process-instances/batch
[
  {"bpmnProcessId": "order-processing", "variables": {"orderId": "1"}},
  {"bpmnProcessId": "order-processing", "variables": {"orderId": "2"}},
  {"bpmnProcessId": "order-processing", "variables": {"orderId": "3"}}
]

3. Cache Process Definitions

Avoid calling GET /api/v1/process-definitions on every request. Cache the definition key in your application after deployment. The key only changes when you redeploy.

4. Monitor Your Usage

Check the X-RateLimit-Remaining header in your application and log a warning when it drops below 20% of the limit (60 requests). This gives you time to throttle before hitting the limit.

Need higher limits? Contact sales@priostack.com or use the Contact form.