DGuardAPI Docs

Security & Compliance

DGuard is designed to comply with the highest security standards required by financial institutions.

Certifications & Compliance

ISO 27001

Certified

Information Security Management System

SOC 2 Type II

Certified

Security, availability and confidentiality controls

PCI-DSS Level 1

Compliant

Card data security standard

GDPR

Compliant

European data protection regulation

PSD2

Compliant

Payment 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

TierRequests/MinuteRequests/DayBurst Limit
Sandbox601,00010 requests/second
Production1,000100,000100 requests/second
Enterprise10,000Unlimited1,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:

HeaderDescriptionExample
X-RateLimit-Limit-MinuteYour minute limit1000
X-RateLimit-Remaining-MinuteRequests remaining in current minute window847
X-RateLimit-Limit-DayYour daily limit100000
X-RateLimit-Remaining-DayRequests remaining until daily reset95234
X-RateLimit-ResetUnix timestamp when minute limit resets1705234567
Retry-AfterSeconds to wait (only on 429 responses)42

Rate Limited Response (429)

json
{
  "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:

typescript
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

✓ TLS 1.3Required
✓ TLS 1.2Supported
✗ TLS 1.1, 1.0Disabled

Advanced Authentication

OAuth 2.0 + JWT

Standard authentication method

Standard

mTLS

Mutual authentication with certificates

Enterprise

IP Whitelisting

Source IP restriction

Enterprise