APIs & Integrations
APIs & Integrations
Every piece of software you build will talk to other software. Payment providers, authentication systems, AI models, CRMs, email platforms, social media APIs — the value of your product increasingly comes from how intelligently it orchestrates these external services, not from what it builds from scratch.
REST: The Lingua Franca
REST is not a protocol — it is a set of conventions that emerged as the most practical way to design HTTP APIs. The conventions:
- Resources as nouns, not verbs:
/users/123not/getUser?id=123 - HTTP verbs carry intent: GET (read), POST (create), PUT/PATCH (update), DELETE (remove)
- Stateless requests: the server holds no session state between requests; the client sends auth credentials (typically a Bearer token in the Authorization header) with every call
- Standard status codes: 200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 404 Not Found, 429 Too Many Requests, 500 Internal Server Error
When consuming a third-party REST API, the first things to check: authentication method, base URL, rate limits, and pagination strategy. Most production APIs paginate results — they return 25–100 items plus a cursor or page number, not the full dataset in one call.
Webhooks: Event-Driven Integration
Polling is asking "is it done yet?" every N seconds. Webhooks are the system telling you when it is done. The difference in efficiency is massive at scale.
Stripe uses webhooks to notify you when a payment succeeds. GitHub uses them to trigger your CI pipeline when code is pushed. Twilio uses them to tell you when an SMS is delivered.
Setting up a webhook endpoint:
- You expose a public HTTPS URL on your server (
/webhooks/stripe) - You register that URL with the external service
- When an event fires, the service sends a POST request to your URL with event data as JSON
- Your server processes the event and returns HTTP 200 within ~5 seconds (or the service will retry)
Critical: always verify webhook signatures. Stripe, for example, includes a header Stripe-Signature containing an HMAC-SHA256 signature of the payload. If you do not verify it, any attacker who knows your webhook URL can send fake events.
OAuth 2.0 Flows
OAuth is about delegation: a user grants your app permission to act on their behalf, without giving you their password.
The Authorization Code flow (used for web apps):
- User clicks "Connect with Stripe" on your app
- Your app redirects to Stripe's OAuth server with your
client_idand requestedscopes - User logs in to Stripe and approves the permissions
- Stripe redirects back to your app with a
codeparameter - Your server exchanges that code (plus your
client_secret) for anaccess_token - You use the access token in API calls on the user's behalf
The access token is short-lived (often 1 hour). A refresh_token (long-lived) allows you to get new access tokens without re-prompting the user.
Error Handling and Retries
Network calls fail. Database connections drop. Third-party APIs go down for maintenance. Robust integrations handle failure gracefully.
The retry pattern for transient failures:
- Catch HTTP 500, 503, or network timeout errors
- Wait before retrying (exponential backoff: 1s, 2s, 4s, 8s)
- Set a maximum retry count (3–5 attempts)
- Log every retry with the error and attempt number
For critical operations (payments, data writes), use idempotency keys: include a unique ID with every request so that if you retry a timed-out request, the server recognizes the duplicate and returns the original result rather than processing twice.
API Design Principles
When you are building an API others will consume:
- Version from day one (
/v1/...) — you will need to make breaking changes - Return consistent error shapes:
{ error: { code: "NOT_FOUND", message: "..." } } - Document with OpenAPI/Swagger so developers can generate client code automatically
- Use pagination for any collection endpoint that could return more than 50 items
- Never expose internal database IDs in public APIs — use UUIDs