Skip to main content

API Reliability & Best Practices

This guide explains rate limiting, how to handle timeouts safely, and optional protections to prevent duplicate requests.

Rate Limiting​

The Partner API enforces a global rate limit per account. All requests from your partner account share the same rate limit pool.

Default limit​

  • 800 requests per minute per partner account

If you need a higher rate limit, please contact Paynovus support — limits can be adjusted based on your integration needs.

Rate limit response​

When the limit is exceeded, you receive a 429 Too Many Requests response:

{
"success": false,
"error": "Too many requests. Please slow down and retry later.",
"retryAfter": 60
}

Handling rate limit errors​

  • Reduce the frequency of requests to stay under the limit
  • Use batch endpoints when available (e.g., list operations with pagination)
  • Space out concurrent API calls if making parallel requests
  • Wait for the retryAfter duration before retrying

Request Timeouts & Safe Retries​

Network timeouts or temporary service disruptions can cause requests to fail without being processed. To safely retry failed requests without accidentally duplicating operations, use the optional Idempotency-Key header.

Idempotency​

The Idempotency-Key header tells the API to remember your request and ensure the same operation is never executed twice, even if you retry with the same key.

How it works​

  • Non-GET requests (POST, PUT, PATCH, DELETE) can include an Idempotency-Key header
  • If the same key is sent within 60 seconds, the API returns the original response instead of reprocessing
  • If the same key is sent with different request data, you get a 409 Conflict error to prevent accidental mismatches
  • Idempotency records expire after 60 seconds, so old keys can be reused

Setting the Idempotency-Key​

The key can be any unique identifier. UUID v4 is recommended:

curl -X POST https://api.card-management-staging.paynovus.com/api/partner/individual/accounts \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{
"firstName": "John",
"lastName": "Doe",
...
}'

Node.js example​

import { v4 as uuidv4 } from 'uuid';

const idempotencyKey = uuidv4();

const response = await fetch('https://api.card-management-staging.paynovus.com/api/partner/individual/accounts', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Idempotency-Key': idempotencyKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
firstName: 'John',
lastName: 'Doe'
// ... other fields
})
});

Idempotency responses​

Same key, same request:

  • Returns the original response with the original HTTP status code
  • Includes X-Idempotency-Replay: true header to indicate this is a replay

Same key, different request:

  • Returns 409 Conflict with an error message
  • Prevents accidental data corruption from request mutations

Request still processing:

  • Returns 202 Accepted (in-progress)
  • Suggests retrying after a few seconds

Best practices​

  1. Always use Idempotency-Key for critical operations — account creation, card issuance, fund transfers
  2. Generate unique keys per logical operation — use UUID v4 or a unique transaction ID
  3. Reuse the same key when retrying — this ensures idempotent behavior
  4. Do not reuse keys for different operations — each operation should have its own key
  5. Monitor rate limits — adjust request frequency if approaching the limit

Testing​

To test idempotency, send the same request with the same key twice:

# First request
curl -X POST https://api.card-management-staging.paynovus.com/api/partner/individual/accounts \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: test-key-001" \
-H "Content-Type: application/json" \
-d '{"firstName": "John", "lastName": "Doe"}'

# Second request with same key — should return the same result
curl -X POST https://api.card-management-staging.paynovus.com/api/partner/individual/accounts \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: test-key-001" \
-H "Content-Type: application/json" \
-d '{"firstName": "John", "lastName": "Doe"}'

Both calls should return the same response with the same HTTP status code.