Production Readiness

A checklist and best-practice guide for launching your Dual integration in production.

Pre-Launch Checklist

Before switching from sandbox to production, work through each item below.

1. Environment Setup

  • Maintain separate sandbox and production base URLs:

    Sandbox: https://sandbox.api-testnet.dual.network

  • Production: https://api-testnet.dual.network

    Generate distinct API keys per environment, never reuse sandbox keys in production Use environment variables to switch between configurations (e.g., .env.development vs .env.production) Verify client initialization points to the correct base URL before deploying

2. Authentication

Dual supports two authentication methods, choose based on your integration pattern:

  • API Key Rotation: Rotate keys on a regular schedule (e.g., quarterly). Use the dashboard's grace period feature to allow old keys for 5 minutes during transition.
  • Key Storage: Never commit keys to source control, use secrets managers (AWS Secrets Manager, HashiCorp Vault, Vercel Secrets, etc.)
  • Token Refresh: For JWT flows, refresh tokens before expiry. Implement automatic retry on 401 Unauthorized responses.
  • Signature Verification: Verify EIP-712 signatures on all mutation requests to cryptographically prove intent

3. Rate Limits

Production rate limits are documented in the Rate Limits reference. Default limits:

Handling Rate Limits:

  • Monitor the X-RateLimit-Remaining and X-RateLimit-Reset response headers
  • Implement exponential backoff with jitter for 429 responses:
Code
// Exponential backoff example
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000) + Math.random() * 1000;
setTimeout(() => retry(), delay);
  • For high-throughput scenarios, use the Batch Actions endpoint to submit up to 500 actions per request
  • Contact support to request higher limits for your use case

4. Webhook Reliability

  • HMAC Verification: Validate the x-dual-signature header using the timestamp + body pattern:
Code
// Node.js example
const crypto = require('crypto');
const timestamp = req.headers['x-dual-timestamp'];
const message = \`\${timestamp}.\${JSON.stringify(body)}\`;
const expected = crypto.createHmac('sha256', SECRET).update(message).digest('hex');
if (expected !== req.headers['x-dual-signature']) throw new Error('Invalid signature');
  • Idempotency: Implement idempotency keys in your webhook handler, the platform may retry delivery for transient failures. Store a deduplication table keyed by event_id + timestamp.
  • Retry Handling: Respond with 200 OK within 5 seconds. For long-running work, queue the event asynchronously (e.g., to a message bus or background job queue).
  • Retry Strategy: The platform retries failed deliveries up to 5 times with exponential backoff. After deactivation, webhooks can be reactivated via the API.
  • Dead-Letter Queue: Set up a monitoring dashboard to track failed webhook deliveries and alert on patterns

5. Error Handling

Structured Error Responses: All Dual API errors follow a consistent format:

Code
{
"error": {
"code": 400,
"message": "Template not found",
"details": [
{ "field": "template_id", "reason": "No template with this ID exists" }
]
},
"x_request_id": "req_abc123def456"
}

Common Error Codes & Handling:

  • 401 Unauthorized, Expired or invalid credentials. Refresh JWT token or rotate API key.
  • 403 Forbidden, Insufficient permissions. Verify scopes on your API key or JWT claims.
  • 429 Too Many Requests, Rate limited. Implement exponential backoff (see Rate Limits section).
  • 5xx Server Errors, Transient failures. Capture the X-Request-Id header and retry with exponential backoff. Include request ID in support tickets.
  • SDK Error Hierarchy: The TypeScript and Python SDKs provide typed errors (DualAuthError, DualNotFoundError, DualRateLimitError). Use instanceof checks to handle specific error types.
Code
// TypeScript, production-grade client config
import { DualClient, DualRateLimitError, DualAuthError } from "dual-sdk";
const client = new DualClient({
token: process.env.DUAL_API_KEY,
authMode: "api_key",
retry: { maxAttempts: 3 },
timeout: 15_000,
});
# Python
from dual_sdk import DualClient, DualRateLimitError, DualAuthError
client = DualClient(
token=os.environ["DUAL_API_KEY"],
auth_mode="api_key",
retry={"max_attempts": 3},
timeout=15.0,
)

6. Monitoring

  • Health Endpoint: Poll GET /health to verify platform availability and health status
  • Webhook Delivery Monitoring: Subscribe to webhook.failed events via the Event Bus or check the webhooks dashboard for delivery failures
  • Balance Alerts: Set up notifications when your organization's DUAL token balance falls below a threshold
  • Event Bus Monitoring: Subscribe to Event Bus streams for real-time operational visibility of actions and state changes
  • Sequencer Batch Confirmation: Track Sequencer batch confirmations via the Sequencer API to monitor on-chain settlement progress
  • Changelog Subscription: Monitor the Updates & Changelog for breaking changes and deprecations affecting your integration

7. Batch Operations

  • Batch Size Limit: Submit up to 500 actions per batch request via POST /ebus/actions/batch
  • Use Cases: Batch operations are ideal for high-throughput scenarios (bulk imports, daily settlements, etc.)
  • Ordering Guarantee: Actions within a batch are executed sequentially in the order submitted
  • Partial Failures: If one action fails, subsequent actions in the batch still execute. Check the response for per-action status codes.
  • Rate Limit Impact: Batch requests count against the Event Bus rate limit (2,000 actions/sec per org). See the Rate Limits page for details.

8. On-Chain Settlement

  • Optimistic Mode (Default): Objects are immediately available for transfer/use while settlement is processed. A 4-hour challenge window allows disputes before finality.
  • ZK Proof Mode (Instant Finality): Use zero-knowledge proofs for instant cryptographic finality when you cannot tolerate the challenge window. Configure per template.
  • Settlement Receipts: Access on-chain transaction hashes and proofs via the Settlement API for independent verification
  • Gas Optimization: Batch multiple operations into a single Sequencer checkpoint every 15 minutes to minimize on-chain costs

9. Data Backup & Recovery

  • Event Sourcing: Dual's event-sourced architecture means actions are the source of truth, the system can be rebuilt from the Event Bus at any time
  • Data Export: Regularly export object state and action history via the Indexer API for backup and compliance reporting
  • Action History: Use the Event Bus API to stream all actions into your own data warehouse or archival system
  • Disaster Recovery: Document your backup and restore procedures. Test recovery in the sandbox environment.

10. Compliance & Audit

  • Audit Trail: Dual's event-sourced architecture provides a complete, immutable audit trail via the Event Bus
  • Action History Queries: Use the Indexer API to export object histories, including all state transitions and mutations
  • EIP-712 Signatures: All mutation requests can be verified with EIP-712 typed data signatures, providing cryptographic proof of intent
  • On-Chain Verification: Settlement receipts on Ethereum provide independent cryptographic verification of state commitments
  • Data Retention: Determine your data retention policy for audit trails and configure automated deletion if required by your compliance framework

Go-Live Steps

  1. Complete all checklist items above
  2. Run your full test suite against the sandbox environment one final time
  3. Swap environment variables to production values and verify in a staging environment
  4. Create a small batch of test objects in production to verify end-to-end flow, including webhooks and monitoring
  5. Monitor webhook deliveries, error rates, and Sequencer batches closely for the first 24 hours
  6. Have a rollback plan in case of unexpected issues (e.g., pause API calls, disable webhooks, switch to read-only mode)

Further Reading