Custom API Integrations: How to Connect Your Business Systems with APIs
Author
ZTABS Team
Date Published
Every growing business eventually hits the same wall: their systems don't talk to each other. Sales data lives in the CRM. Orders are in the e-commerce platform. Customer support tickets are in a separate help desk. Finance reconciles everything in spreadsheets.
This isn't just inefficient — it's expensive. Manual data entry introduces errors. Teams waste hours switching between tools. Decisions are made on incomplete data because getting a unified view requires pulling reports from five different systems.
Custom API integrations solve this by connecting your business systems programmatically. Data flows automatically between systems, processes trigger across platforms, and your team works with a single source of truth instead of fragmented silos.
This guide covers how to approach business system integration — from choosing the right pattern to handling the messy realities of API rate limits, error recovery, and keeping everything secure.
Why Businesses Need Integrations
The average mid-size business uses 100+ SaaS applications. Even a small startup typically runs on 10–20 tools. Without integration, each tool is an island.
| Pain Point | Impact | Integration Solution | |-----------|--------|---------------------| | Manual data entry between systems | Human errors, wasted time | Automatic data sync | | Inconsistent data across platforms | Wrong decisions, customer confusion | Single source of truth | | Delayed information flow | Slow response times, missed opportunities | Real-time event propagation | | No unified reporting | Can't see the full picture | Aggregated dashboards | | Manual process triggers | Tasks fall through the cracks | Automated workflows | | Customer experience gaps | "Sorry, I need to check another system" | Unified customer view |
ROI of Integration
Integration projects typically pay for themselves quickly:
| Metric | Typical Improvement | |--------|-------------------| | Time spent on manual data entry | 60–90% reduction | | Data errors from manual processes | 80–95% reduction | | Time to generate cross-system reports | 90% reduction | | Customer response time | 30–50% improvement | | Order processing speed | 40–70% improvement |
Integration Architecture Patterns
Point-to-Point
The simplest pattern: System A connects directly to System B.
System A ──────▸ System B
Pros: Simple to implement, low overhead for 1–2 integrations. Cons: Doesn't scale. With N systems, you need N×(N-1)/2 connections. Changing one system requires updating every connection.
Best for: A single integration between two systems (e.g., CRM → email marketing).
Hub-and-Spoke
A central integration layer (the hub) connects to all systems (the spokes). Systems communicate through the hub rather than directly with each other.
CRM ──────┐
▼
ERP ────────▸ HUB ◂──────── E-commerce
▲
Help Desk ───┘
Pros: Centralized logic, easier to maintain, adding a new system only requires one new connection. Cons: Hub becomes a single point of failure, can become a bottleneck.
Best for: 3–10 systems that need to share data. This is the most common pattern for growing businesses.
Event-Driven
Systems publish events to a message broker. Other systems subscribe to events they care about.
CRM publishes ──▸ "customer.created" ──▸ Email System subscribes
──▸ Analytics subscribes
──▸ Billing subscribes
Pros: Loose coupling, systems don't need to know about each other, scales well, resilient to individual system failures. Cons: More complex to set up and debug, eventual consistency.
Best for: High-volume integrations, real-time requirements, microservices architectures.
API Gateway
A single entry point that routes, transforms, and manages all API traffic.
External/Internal ──▸ API Gateway ──▸ Service A
Consumers ──▸ Service B
──▸ Service C
Pros: Centralized auth, rate limiting, monitoring, and versioning. Cons: Additional infrastructure to manage.
Best for: When you're exposing APIs to external consumers or managing many internal services.
Choosing the Right Pattern
| Scenario | Recommended Pattern | |---------|-------------------| | 2 systems, simple sync | Point-to-point | | 3–10 systems, moderate complexity | Hub-and-spoke | | High volume, real-time requirements | Event-driven | | External API consumers | API gateway | | Large enterprise, many teams | Event-driven + API gateway |
Integration by System Type
CRM Integration (Salesforce, HubSpot, Pipedrive)
| Integration | Data Flow | Common Triggers | |-------------|----------|-----------------| | Website → CRM | Form submissions create leads | Form submit, page visit | | CRM → Email marketing | Sync contacts and segments | Contact created/updated, deal stage change | | CRM → Support | Customer context for support agents | Ticket created, customer lookup | | E-commerce → CRM | Purchase history updates contact records | Order placed, order fulfilled | | CRM → Analytics | Pipeline and revenue data for dashboards | Daily sync or real-time |
Example: Syncing new orders from Shopify to HubSpot
import { Client } from "@hubspot/api-client";
const hubspot = new Client({ accessToken: process.env.HUBSPOT_TOKEN });
async function syncOrderToHubSpot(order: ShopifyOrder) {
const contact = await hubspot.crm.contacts.searchApi.doSearch({
filterGroups: [{
filters: [{
propertyName: "email",
operator: "EQ",
value: order.customer.email,
}],
}],
});
const contactId = contact.results[0]?.id;
if (!contactId) return;
await hubspot.crm.deals.basicApi.create({
properties: {
dealname: `Order ${order.order_number}`,
amount: order.total_price,
pipeline: "default",
dealstage: "closedwon",
closedate: order.created_at,
},
associations: [{
to: { id: contactId },
types: [{ associationCategory: "HUBSPOT_DEFINED", associationTypeId: 3 }],
}],
});
}
ERP Integration (NetSuite, SAP, QuickBooks)
ERP integrations are typically the most complex due to the depth of data models and the critical nature of financial data.
| Integration | Purpose | Complexity | |-------------|---------|-----------| | E-commerce → ERP | Sync orders, inventory, customers | High | | ERP → E-commerce | Push inventory levels, pricing | Medium | | CRM → ERP | Convert won deals to invoices | Medium | | ERP → Reporting | Financial data for dashboards | Medium | | ERP → Shipping | Order fulfillment triggers | Medium |
Payment Integration (Stripe, PayPal, Square)
| Integration | Data Flow | Use Case | |-------------|----------|----------| | Stripe → Accounting | Sync transactions and payouts | Automated bookkeeping | | Stripe → CRM | Payment events update customer records | Revenue tracking per customer | | Stripe → Email | Payment confirmations, failed payment alerts | Customer communication | | Stripe → Analytics | Revenue metrics, MRR, churn | Business intelligence | | Stripe → ERP | Invoice and payment reconciliation | Financial reporting |
Shipping and Logistics (ShipStation, EasyPost, FedEx)
| Integration | Purpose | |-------------|---------| | E-commerce → Shipping | Auto-create shipping labels | | Shipping → E-commerce | Tracking updates for customers | | Shipping → ERP | Shipping costs for accounting | | Shipping → Notifications | Delivery alerts to customers |
Marketing Automation (Mailchimp, Klaviyo, ActiveCampaign)
| Integration | Purpose | |-------------|---------| | CRM → Email | Segment-based campaigns | | E-commerce → Email | Abandoned cart, post-purchase flows | | Website → Email | Lead capture, newsletter signup | | Email → Analytics | Campaign performance in unified dashboard |
HR and Payroll (Gusto, BambooHR, Rippling)
| Integration | Purpose | |-------------|---------| | HR → IT | Auto-provision accounts for new hires | | HR → Payroll | Employee data sync | | HR → Project management | Team structure updates | | HR → Access control | Role-based permissions from HR system |
REST vs GraphQL vs Webhooks
Comparison
| Aspect | REST | GraphQL | Webhooks | |--------|------|---------|----------| | Direction | Pull (client requests) | Pull (client requests) | Push (server sends) | | Data shape | Fixed by endpoint | Client specifies exactly what it needs | Fixed by event type | | Best for | CRUD operations, standard APIs | Complex queries, reducing over-fetching | Real-time event notifications | | Caching | Easy (HTTP caching) | Complex (query-level) | Not applicable | | Learning curve | Low | Medium | Low | | Availability | Nearly every SaaS API | Growing but less common | Most modern SaaS platforms |
When to Use Each
| Scenario | Recommendation | |---------|---------------| | Reading/writing data on demand | REST API | | Need specific nested data from complex models | GraphQL | | React to events in real-time | Webhooks | | Bulk data sync (initial load) | REST API with pagination | | Keep data in sync continuously | Webhooks + REST for reconciliation |
Webhook Implementation
import express from "express";
import crypto from "crypto";
const app = express();
app.post("/webhooks/stripe", express.raw({ type: "application/json" }), (req, res) => {
const signature = req.headers["stripe-signature"] as string;
try {
const event = stripe.webhooks.constructEvent(
req.body,
signature,
process.env.STRIPE_WEBHOOK_SECRET!
);
switch (event.type) {
case "payment_intent.succeeded":
handlePaymentSuccess(event.data.object);
break;
case "customer.subscription.deleted":
handleSubscriptionCanceled(event.data.object);
break;
case "invoice.payment_failed":
handlePaymentFailed(event.data.object);
break;
}
res.json({ received: true });
} catch (err) {
res.status(400).send(`Webhook Error: ${err.message}`);
}
});
Error Handling and Retry Logic
Integrations fail. APIs go down, rate limits get hit, data formats change, tokens expire. Robust error handling is what separates production integrations from demo-quality code.
Error Categories
| Error Type | Example | Strategy | |-----------|---------|----------| | Transient | Network timeout, 503 Service Unavailable | Retry with exponential backoff | | Rate limiting | 429 Too Many Requests | Respect Retry-After header, queue requests | | Authentication | 401 Unauthorized, token expired | Refresh token, re-authenticate | | Validation | 400 Bad Request, data format mismatch | Log, alert, fix data transformation | | Permanent | 404 Not Found, resource deleted | Log, skip, alert for investigation |
Retry Pattern with Exponential Backoff
async function withRetry<T>(
fn: () => Promise<T>,
options: {
maxRetries?: number;
baseDelayMs?: number;
maxDelayMs?: number;
} = {}
): Promise<T> {
const { maxRetries = 3, baseDelayMs = 1000, maxDelayMs = 30000 } = options;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxRetries) throw error;
const isRetryable =
error.status === 429 ||
error.status === 503 ||
error.code === "ECONNRESET" ||
error.code === "ETIMEDOUT";
if (!isRetryable) throw error;
const retryAfter = error.headers?.["retry-after"];
const delay = retryAfter
? parseInt(retryAfter) * 1000
: Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
throw new Error("Unreachable");
}
const result = await withRetry(() =>
hubspot.crm.contacts.basicApi.create({ properties: contactData })
);
Dead Letter Queue
When retries are exhausted, failed messages need to go somewhere for investigation and replay.
async function processWithDLQ(event: IntegrationEvent) {
try {
await withRetry(() => processEvent(event));
} catch (error) {
await deadLetterQueue.send({
event,
error: {
message: error.message,
status: error.status,
timestamp: new Date().toISOString(),
retryCount: event.retryCount || 0,
},
});
await alertOpsTeam({
message: `Integration event failed after retries`,
eventType: event.type,
error: error.message,
});
}
}
Security
API integrations handle sensitive business data. Security is not optional.
Authentication Methods
| Method | Security Level | Use Case | |--------|---------------|----------| | API key | Basic | Internal services, simple integrations | | OAuth 2.0 | High | Third-party SaaS integrations | | JWT | High | Service-to-service, user-context auth | | mTLS | Very high | Enterprise, financial systems | | HMAC signatures | High | Webhook verification |
Security Best Practices
| Practice | Why It Matters | |----------|---------------| | Store credentials in environment variables or secret manager | Never hardcode API keys | | Use OAuth with short-lived tokens | Minimize blast radius of token compromise | | Validate webhook signatures | Prevent spoofed events | | Encrypt data in transit (TLS) | Prevent eavesdropping | | Encrypt sensitive data at rest | Protect stored credentials and PII | | Implement rate limiting on your endpoints | Prevent abuse | | Audit log all API calls | Debugging and compliance | | Principle of least privilege | Request minimum scopes needed | | Rotate credentials regularly | Limit exposure window |
OAuth 2.0 Token Management
class TokenManager {
private tokens: Map<string, StoredToken> = new Map();
async getValidToken(integration: string): Promise<string> {
const stored = this.tokens.get(integration);
if (stored && !this.isExpiringSoon(stored)) {
return stored.accessToken;
}
if (stored?.refreshToken) {
const refreshed = await this.refreshToken(integration, stored.refreshToken);
this.tokens.set(integration, refreshed);
return refreshed.accessToken;
}
throw new Error(`No valid token for ${integration}. Re-authorization required.`);
}
private isExpiringSoon(token: StoredToken): boolean {
const bufferMs = 5 * 60 * 1000;
return Date.now() + bufferMs >= token.expiresAt;
}
private async refreshToken(
integration: string,
refreshToken: string
): Promise<StoredToken> {
const config = getIntegrationConfig(integration);
const response = await fetch(config.tokenUrl, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token: refreshToken,
client_id: config.clientId,
client_secret: config.clientSecret,
}),
});
const data = await response.json();
return {
accessToken: data.access_token,
refreshToken: data.refresh_token || refreshToken,
expiresAt: Date.now() + data.expires_in * 1000,
};
}
}
Monitoring
You can't fix what you can't see. Integration monitoring is essential for reliability.
Key Metrics to Track
| Metric | Description | Alert Threshold | |--------|-------------|----------------| | Sync success rate | % of sync operations that succeed | under 95% | | Sync latency | Time from event to sync completion | >5 minutes for real-time, >1 hour for batch | | Error rate by type | Breakdown of error categories | Any permanent errors | | API quota usage | % of rate limit consumed | >80% | | Data freshness | Time since last successful sync | Depends on requirements | | Queue depth | Unprocessed events in queue | Growing over time | | Token expiration | Time until credentials expire | under 24 hours |
Health Check Endpoint
app.get("/health/integrations", async (req, res) => {
const checks = await Promise.allSettled([
checkCRMConnection(),
checkPaymentConnection(),
checkEmailConnection(),
checkERPConnection(),
]);
const results = {
crm: checks[0].status === "fulfilled" ? checks[0].value : { healthy: false },
payments: checks[1].status === "fulfilled" ? checks[1].value : { healthy: false },
email: checks[2].status === "fulfilled" ? checks[2].value : { healthy: false },
erp: checks[3].status === "fulfilled" ? checks[3].value : { healthy: false },
};
const allHealthy = Object.values(results).every((r) => r.healthy);
res.status(allHealthy ? 200 : 503).json({
status: allHealthy ? "healthy" : "degraded",
integrations: results,
timestamp: new Date().toISOString(),
});
});
iPaaS vs Custom: When to Use Each
iPaaS Platforms (Integration Platform as a Service)
iPaaS tools like Zapier, Make (Integromat), and n8n let you build integrations without code using visual workflow builders.
| Platform | Best For | Pricing | Limitations | |----------|---------|---------|-------------| | Zapier | Simple, pre-built integrations | $20–$600/month | Limited customization, per-task pricing | | Make | More complex logic, affordable | $9–$300/month | Steeper learning curve than Zapier | | n8n | Self-hosted, technical teams | Free (self-hosted) or $20+/month | Requires technical knowledge to host | | Workato | Enterprise, complex workflows | Custom pricing | Expensive for small teams | | Tray.io | Enterprise, API-heavy | Custom pricing | Complex setup |
When to Use iPaaS
| Scenario | Recommendation | |---------|---------------| | Simple data sync between 2 SaaS tools | iPaaS (Zapier/Make) | | Non-technical team needs to manage integrations | iPaaS | | Standard use case with pre-built connectors | iPaaS | | Prototype or temporary integration | iPaaS | | Budget-constrained, under 1,000 events/month | iPaaS |
When to Build Custom
| Scenario | Recommendation | |---------|---------------| | High volume (>10,000 events/day) | Custom (iPaaS per-event pricing becomes expensive) | | Complex data transformations | Custom | | Need full control over error handling and retries | Custom | | Security/compliance requirements (data can't pass through third-party) | Custom | | Integration is core to your product | Custom | | Need real-time processing (under 1 second) | Custom | | Custom or legacy APIs without pre-built connectors | Custom |
Hybrid Approach
The smartest approach for many businesses is hybrid: use iPaaS for simple, non-critical integrations and build custom for high-volume, complex, or critical data flows.
| Integration | Approach | Reason | |-------------|---------|--------| | New lead → Slack notification | iPaaS | Low volume, non-critical, pre-built | | CRM → email marketing sync | iPaaS | Standard use case, pre-built connectors | | Order processing → ERP | Custom | Critical path, complex logic, high volume | | Payment reconciliation | Custom | Financial accuracy, audit requirements | | Customer data warehouse sync | Custom | High volume, complex transformations |
Getting Started
Phase 1: Audit and Prioritize
- List all your business systems and what data they hold
- Map the data flows that currently happen manually
- Prioritize by impact (time saved × frequency × error rate)
- Identify which integrations are iPaaS-appropriate vs. custom
Phase 2: Build Foundation
- Choose your integration architecture pattern
- Set up credential management (secret store)
- Build error handling and retry infrastructure
- Implement monitoring and alerting
Phase 3: Integrate Incrementally
- Start with the highest-impact, lowest-complexity integration
- Validate data accuracy before expanding
- Add integrations one at a time
- Document each integration's data flow, error handling, and monitoring
Phase 4: Optimize and Expand
- Monitor performance and optimize bottlenecks
- Add real-time capabilities where needed
- Build a unified dashboard for integration health
- Consider an integration platform if managing 10+ integrations
Building reliable integrations requires understanding both the business processes and the technical details of each API. Our custom integration and API development teams have connected hundreds of business systems — from straightforward CRM syncs to complex multi-system automation workflows.
Need help connecting your business systems? Get in touch and we'll audit your current setup, recommend the right approach, and build integrations that actually work.
Need Help Building Your Project?
From web apps and mobile apps to AI solutions and SaaS platforms — we ship production software for 300+ clients.
Related Articles
Marketplace Development Guide: How to Build a Two-Sided Platform in 2026
A complete guide to building a two-sided marketplace. Covers marketplace types, architecture, critical features, payment integration, trust and safety, growth strategies, and cost breakdown.
10 min readHow Much Does Custom Software Development Cost in 2026? Complete Pricing Guide
Custom software development costs range from $25,000 to $500,000+. This guide breaks down pricing by project type, team model, and features so you can…
10 min readHow to Choose a Software Development Company: The Ultimate 2026 Guide
Choosing the wrong development partner can cost you months and hundreds of thousands of dollars. This guide gives you a proven framework for evaluating…