An integration is a distributed system — two services, a fallible network, and two teams that don't talk to each other. This page is the discipline we apply so that when one side wobbles, your side doesn't fall over.
With ±25% jitter, so a thundering herd doesn't retry in lockstep. After 5 failures, open the circuit for 60s — stop hammering a service that's already having a bad day.
Every integration ships with a small recorded set of real responses (with secrets stripped). CI runs Zod schemas against those recordings. When Stripe/HubSpot/whoever adds an optional field or renames one, the test fails on the next dep bump — not at 2am on Black Friday.
// contracts/hubspot-contact.ts
export const HubspotContact = z.object({
id: z.string(),
properties: z.object({
email: z.string().email(),
firstname: z.string().optional(),
lastname: z.string().optional(),
lifecyclestage: z.enum([
"subscriber", "lead", "mql", "sql",
"opportunity", "customer", "evangelist",
]),
}),
createdAt: z.string().datetime(),
});
// tests/hubspot-contract.test.ts
for (const f of fixtures) {
expect(() => HubspotContact.parse(f)).not.toThrow();
}One id through every hop. `grep req_abc` and you have the full story.
Not `console.log`. Parseable, filterable, shippable.
Every unhandled error routed with breadcrumbs + user.
Real requests from real regions. Not just `/health`.
P50, P95, P99 per external dependency.
Alert when a dep is degraded, not just down.
Because 'the other API changed' — a field became optional, a rate limit tightened, a webhook payload shape shifted. Contract tests catch these on deploy; monitoring catches them at runtime; graceful degradation stops them from taking down your product.
Tell us your goals — we'll recommend the right technology honestly, even if it isn't this one.