Skip to main content

Rate Limits

The Intelliprint API enforces rate limits to ensure reliable service for all customers:
EnvironmentRequests/Second
Test Mode10 req/s
Production50 req/s
Exceeding rate limits returns 429 Too Many Requests. Implement exponential backoff to handle this gracefully.

Production Best Practices

1. Always Test First

Use test mode during development to avoid charges and physical mail:
const printJob = await ip.prints.create({
  testmode: true,  // ✅ No charges, no physical sending
  content: '<h1>Test</h1>',
  recipients: [{address: {/* ... */}}],
  confirmed: true
});

2. Implement Retry Logic with Exponential Backoff

Handle temporary failures and rate limits gracefully:
async function createPrintWithRetry(params, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await ip.prints.create(params);
    } catch (error) {
      // Don't retry client errors (4xx except 429)
      if (error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429) {
        throw error;
      }
      
      // Last attempt - throw error
      if (attempt === maxRetries - 1) {
        throw error;
      }
      
      // Exponential backoff: 1s, 2s, 4s
      const delay = Math.pow(2, attempt) * 1000;
      console.log(`Retrying after ${delay}ms...`);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

// Usage
const printJob = await createPrintWithRetry({
  testmode: true,
  content: '<h1>Hello</h1>',
  recipients: [{address: {/* ... */}}]
});

3. Batch Operations for Bulk Sending

Don’t loop through recipients one-by-one. Use mailing lists for bulk operations.
❌ Slow - Makes 1,000 API calls:
// DON'T DO THIS
for (const recipient of recipients) {
  await ip.prints.create({
    content: html,
    recipients: [recipient],
    confirmed: true
  });
}
✅ Fast - Makes 1 API call:
// DO THIS INSTEAD
await ip.prints.create({
  template: 'tmpl_abc123',  // Dashboard template with variables
  mailing_list: 'mal_abc123',  // All recipients
  confirmed: true
});
Learn more about bulk mailing →

4. Use Appropriate Envelope Sizes

Choose the right envelope for your content to avoid extra costs:
EnvelopeCapacityUse For
C5 (default)Up to 30 sidesMost letters (1-15 sheets)
C4Up to 100 sidesMulti-page documents
C4+Up to 500 sidesLarge packets
A4 BoxUp to 3,600 sidesVery large mailings
const printJob = await ip.prints.create({
  content: longDocument,  // 40 pages
  recipients: [{address: {/* ... */}}],
  
  // ✅ Use C4 for 40 pages
  envelope: {
    size: 'c4'
  }
});
Learn more about envelopes →

5. Enable Double-Sided Printing

Save ~50% on paper costs by printing on both sides:
const printJob = await ip.prints.create({
  content: fourPageLetter,
  recipients: [{address: {/* ... */}}],
  
  printing: {
    double_sided: 'yes'  // ✅ Saves money!
  }
});

// 4 pages = 2 sheets instead of 4 sheets
Learn more about costs →

6. Monitor Your API Usage

Track your usage in the dashboard:

View Usage Dashboard

Monitor API calls, print volumes, and spending

Production Deployment Checklist

Before going live, ensure you’ve completed these steps:
1

Generate Production API Keys

Create separate keys for production in the API Settings.
Never use the same API key for test and production environments.
2

Remove Test Mode

Ensure testmode: false (or omit it entirely) in production code:
const printJob = await ip.prints.create({
  // testmode: true,  ❌ Remove this line!
  content: html,
  recipients: [{address: {/* ... */}}]
});
3

Implement Error Handling

Handle all possible error types gracefully:
try {
  await ip.prints.create(params);
} catch (error) {
  switch (error.type) {
    case 'authentication_error':
      // Invalid API key
      break;
    case 'invalid_request_error':
      // Invalid parameters
      break;
    case 'payment_error':
      // Insufficient balance
      break;
    case 'rate_limited':
      // Too many requests
      break;
    default:
      // Server error - retry
  }
}
Learn more about errors →
4

Store API Keys Securely

Use environment variables, never hardcode keys:
// ✅ Good
const ip = Intelliprint(process.env.INTELLIPRINT_API_KEY);

// ❌ Bad
const ip = Intelliprint('ik_live_abc123...'); // Don't do this!
5

Set Up Monitoring

Monitor these metrics:
  • API response times
  • Error rates by error type
  • Print job success/failure rates
  • Cost per print job
6

Test Edge Cases

Test these scenarios in test mode:
  • Invalid addresses
  • Missing required fields
  • Large file uploads
  • Network timeouts
  • Rate limit handling
7

Document Your Integration

Document for your team:
  • How to generate API keys
  • Where keys are stored
  • Error handling procedures
  • Support escalation process

Performance Optimisation Tips

Parallel Processing

Process multiple print jobs concurrently (within rate limits):
// Process 10 print jobs in parallel
const printJobs = await Promise.all(
  letters.map(letter => 
    ip.prints.create({
      content: letter.html,
      recipients: [letter.recipient],
      confirmed: true
    })
  )
);
Stay within rate limits: max 10 req/s in test mode, 50 req/s in production.

File Upload Optimisation

For PDF uploads, optimise file sizes:
// ✅ Compress PDFs before upload
// Use tools like Ghostscript or online compressors

// ✅ Use appropriate DPI: 300 DPI for images
// ✅ Remove unnecessary pages
// ✅ Embed fonts to avoid rendering issues

Connection Pooling

Reuse HTTP connections for better performance:
// Most SDKs handle this automatically
// Node.js example with keep-alive:
const https = require('https');

const agent = new https.Agent({
  keepAlive: true,
  maxSockets: 50
});

const ip = Intelliprint('your-api-key', {
  httpAgent: agent
});

Common Anti-Patterns to Avoid

❌ Don’t: Loop Through Recipients

// Slow and hits rate limits
for (const recipient of recipients) {
  await ip.prints.create({
    content: html,
    recipients: [recipient]
  });
}

✅ Do: Use Mailing Lists

// Fast and efficient
await ip.prints.create({
  template: 'tmpl_abc123',
  mailing_list: 'mal_abc123'
});

❌ Don’t: Ignore Errors

// Silent failures
await ip.prints.create(params).catch(() => {});

✅ Do: Handle Errors Properly

// Log and alert on failures
try {
  await ip.prints.create(params);
} catch (error) {
  logger.error('Print job failed', { error, params });
  alerting.notify('Print job failure', error);
  throw error;
}

❌ Don’t: Hardcode API Keys

// Security risk
const ip = Intelliprint('ik_live_abc123...');

✅ Do: Use Environment Variables

// Secure
const ip = Intelliprint(process.env.INTELLIPRINT_API_KEY);

Need Help?