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
retryAfterduration 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-Keyheader - 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 Conflicterror 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: trueheader to indicate this is a replay
Same key, different request:
- Returns
409 Conflictwith 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
- Always use Idempotency-Key for critical operations — account creation, card issuance, fund transfers
- Generate unique keys per logical operation — use UUID v4 or a unique transaction ID
- Reuse the same key when retrying — this ensures idempotent behavior
- Do not reuse keys for different operations — each operation should have its own key
- 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.