Security & Compliance
DGuard is designed to comply with the highest security standards required by financial institutions.
Certifications & Compliance
ISO 27001
CertifiedInformation Security Management System
SOC 2 Type II
CertifiedSecurity, availability and confidentiality controls
PCI-DSS Level 1
CompliantCard data security standard
GDPR
CompliantEuropean data protection regulation
PSD2
CompliantPayment services directive
Rate Limiting
DGuard enforces rate limits to ensure fair usage and protect API stability. Rate limits are applied per Client ID (Application). All requests authenticated with the same credentials share the same rate limit pool.
Rate Limit Tiers
| Tier | Requests/Minute | Requests/Day | Burst Limit |
|---|---|---|---|
| Sandbox | 60 | 1,000 | 10 requests/second |
| Production | 1,000 | 100,000 | 100 requests/second |
| Enterprise | 10,000 | Unlimited | 1,000 requests/second |
How Rate Limits Interact
Three-Layer Rate Limiting
Rate limits are enforced in three layers. A request must pass all three to succeed:
1. Burst Limit
Maximum requests per second. Prevents sudden traffic spikes from overwhelming the API.
2. Minute Limit
Rolling 60-second window. Resets continuously, not at fixed intervals.
3. Daily Limit
24-hour window resetting at 00:00 UTC. Once exhausted, wait until reset.
Example Scenario
With Production tier (1,000/min, 100,000/day): If you send 1,000 requests in one minute, you'll hit the minute limit but still have 99,000 daily requests remaining. You must wait until the minute window resets (rolling window, not fixed minute boundaries) before sending more requests. The daily limit only blocks you after 100,000 total requests in 24 hours.
Rate Limit Response Headers
Every API response includes headers to help you track your rate limit status:
| Header | Description | Example |
|---|---|---|
| X-RateLimit-Limit-Minute | Your minute limit | 1000 |
| X-RateLimit-Remaining-Minute | Requests remaining in current minute window | 847 |
| X-RateLimit-Limit-Day | Your daily limit | 100000 |
| X-RateLimit-Remaining-Day | Requests remaining until daily reset | 95234 |
| X-RateLimit-Reset | Unix timestamp when minute limit resets | 1705234567 |
| Retry-After | Seconds to wait (only on 429 responses) | 42 |
Rate Limited Response (429)
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please retry after the specified time.",
"details": {
"limit_type": "minute",
"limit": 1000,
"current_usage": 1000,
"retry_after_seconds": 42,
"daily_remaining": 95234
},
"request_id": "req_abc123xyz"
}
}Recommended Retry Strategy
Implement exponential backoff with jitter to handle rate limits gracefully. Here's a recommended implementation:
interface RetryConfig {
maxRetries: number;
baseDelayMs: number;
maxDelayMs: number;
}
async function fetchWithRetry(
url: string,
options: RequestInit,
config: RetryConfig = { maxRetries: 5, baseDelayMs: 1000, maxDelayMs: 60000 }
): Promise<Response> {
let lastError: Error | null = null;
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
try {
const response = await fetch(url, options);
// Success - return response
if (response.ok) {
return response;
}
// Rate limited - use Retry-After header if available
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter
? parseInt(retryAfter, 10) * 1000
: calculateBackoff(attempt, config);
console.log(`Rate limited. Waiting ${waitTime}ms before retry ${attempt + 1}`);
await sleep(waitTime);
continue;
}
// Server error - retry with backoff
if (response.status >= 500) {
const waitTime = calculateBackoff(attempt, config);
console.log(`Server error ${response.status}. Waiting ${waitTime}ms before retry`);
await sleep(waitTime);
continue;
}
// Client error (4xx except 429) - don't retry
return response;
} catch (error) {
lastError = error as Error;
const waitTime = calculateBackoff(attempt, config);
console.log(`Network error. Waiting ${waitTime}ms before retry`);
await sleep(waitTime);
}
}
throw lastError || new Error('Max retries exceeded');
}
function calculateBackoff(attempt: number, config: RetryConfig): number {
// Exponential backoff: 1s, 2s, 4s, 8s, 16s... capped at maxDelayMs
const exponentialDelay = config.baseDelayMs * Math.pow(2, attempt);
const cappedDelay = Math.min(exponentialDelay, config.maxDelayMs);
// Add jitter (0-25% random variation) to prevent thundering herd
const jitter = cappedDelay * 0.25 * Math.random();
return Math.floor(cappedDelay + jitter);
}
function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Usage example
const response = await fetchWithRetry(
'https://api.dguard.ai/v1/fraud/score/realtime',
{
method: 'POST',
headers: {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
},
body: JSON.stringify(transactionData)
}
);Rate Limit Best Practices
Monitor rate limit headers
Track X-RateLimit-Remaining headers proactively and slow down before hitting limits.
Use batch endpoints when possible
Instead of 100 individual requests, use batch endpoints to analyze multiple items in one call.
Implement request queuing
Queue requests and process them at a steady rate rather than in bursts.
Cache responses
Cache API responses when appropriate to reduce unnecessary duplicate requests.
Contact us for higher limits
If you consistently need higher limits, contact sales about Enterprise tier options.
API Security
Encryption in Transit
Advanced Authentication
OAuth 2.0 + JWT
Standard authentication method
StandardmTLS
Mutual authentication with certificates
EnterpriseIP Whitelisting
Source IP restriction
Enterprise