API Integration: How to Plan Integrations That Survive Production
The first version of an API integration usually works. A veterinary hospital group connects its practice software to a reference lab’s ordering API, a test order goes through, the result comes back into the patient record, and the demo looks finished. The trouble arrives in month three, when the lab rotates a credential nobody tracked, a busy Monday hits the lab’s request limit, and a retry sends the same blood panel order twice for the same dog.
API integration is the work of connecting two software systems through their application programming interfaces so they can exchange data and trigger actions without a person copying anything across. The part that decides whether an integration survives production is everything around the happy path: who owns the credentials, how the code behaves under rate limits, whether a retry can create a duplicate, what happens when the other side changes its API, and who notices when it stops working. Each of those is a decision an engineering leader can make before the build, and each is far cheaper to make early.
What Is API Integration?
An API integration is code that lets one system read from or write to another system through the interface that system publishes. Your software calls the provider’s endpoints, the provider may call yours back through webhooks, and both sides agree, at least implicitly, on what a request means and what a response promises.
The word “integration” hides how much of the work sits outside the API calls themselves. In the veterinary example, the calls to submit an order and fetch a result are a small share of the code. The larger share maps the hospital’s patient and test codes to the lab’s codes, stores which orders are pending, handles results that arrive for orders the hospital has since cancelled, and records enough detail that a support engineer can answer “where is this result?” without reading logs line by line.
What Should You Decide Before Anyone Writes Code?
Before the build, decide which system owns each piece of data, which direction each flow runs, how fresh the data needs to be and what the business should see when the connection fails. A one-page integration brief that answers those four questions prevents most of the arguments that otherwise surface during testing.
Ownership comes first. If the practice software and the lab both store the patient’s species and weight, one of them has to win when they disagree, and the integration should never write the losing value back over the winning one. Direction follows from ownership: orders flow out, results flow in, and reference data such as the lab’s test catalog flows in on its own schedule.
Freshness is a business question with an engineering cost. A result the veterinarian is waiting on during an appointment needs to appear within minutes, which points toward webhooks or frequent polling. The lab’s catalog of available tests changes rarely and can sync overnight. Treating every flow as real time spends request budget and engineering effort where nobody benefits.
The failure experience is the decision teams most often skip. When the lab’s API is unreachable, should the order screen block the technician, queue the order and show it as pending, or fall back to a printed requisition? There is no universal answer, but there should be a deliberate one, written down and agreed with the people who run the clinic.
How Should You Handle Authentication and Credentials?
Handle API credentials as production infrastructure with a named owner, the narrowest permissions the integration needs and a plan for rotation. Many integration outages that look mysterious turn out to be an expired token, a revoked key or an account that belonged to someone who left.
Many providers use OAuth 2.0, where the integration holds an access token and often a refresh token, while others issue a static API key. The IETF’s current security guidance for OAuth says access token privileges should be restricted to the minimum required for the particular application or use case (Source: IETF, RFC 9700 OAuth 2.0 Security Best Current Practice). In practice, that means the lab integration gets permission to create orders and read results for the hospital’s own account, and nothing that lets it modify billing or user settings on the lab’s side.
Three practical decisions follow. Register the integration under a service account owned by the company, never under an engineer’s personal login. Store secrets in a managed secrets store with access logged, never in a configuration file in the repository. Put rotation dates on a calendar the operations team actually reads, and test that the integration picks up a new credential without a redeploy. If outside engineers will work on the integration, they fall under the same policy: Gun.io sets out how it approaches security and privacy on its side, and your own access rules still decide what anyone can reach.
How Do Rate Limits Shape the Design?
Rate limits set a budget for how many requests your integration can make in a window, and the design has to fit inside that budget on the busiest day, not the average one. When an integration exceeds the limit, HTTP APIs commonly respond with status 429, and the standard that defines it says the response may include a Retry-After header indicating how long to wait before making a new request (Source: IETF, RFC 6585 Additional HTTP Status Codes).
Honoring Retry-After, rather than retrying immediately in a loop, is the minimum. The more useful work is knowing where the budget goes. In the veterinary group, the scheduled job that polls for pending results, the nightly catalog sync and the live order submissions may all draw from the same allowance. If a backfill of old results runs on a Monday morning, it can starve the live orders that technicians are waiting on.
A few design choices keep the integration inside its budget. Prefer webhooks over polling when the provider offers them, so you ask only when something changed. Batch reads where the API supports it. Give live, user-facing requests priority over background jobs, either with separate queues or by pausing background work when the remaining budget drops. And ask the provider, before launch, whether limits apply per API key, per account or per endpoint, because the answer changes how you split the work.
How Do You Make Retries Safe?
Make retries safe by giving every write a stable identifier from your side, so that sending the same request twice cannot create two records. Networks fail between the moment a provider processes a request and the moment you receive its response, and from your side a lost response looks exactly like a request that never arrived.
The duplicate blood panel is the result of retrying a create call without that protection. The hospital’s system sent the order, the connection dropped before the confirmation came back, the retry logic sent it again, and the lab now holds two orders for one sample. Someone at the lab may catch it, or the client may be billed twice and the second order may sit open for weeks.
The fix depends on what the provider supports, so read its documentation for this specifically. Some APIs accept a client-supplied idempotency key or a client reference field and reject or merge a second request carrying the same value. Where that exists, generate the key once when the order is created in your system and reuse it on every retry. Where it does not, look up whether an order with your reference already exists before creating a new one, and accept that this check narrows the window rather than closing it. Either way, add a reconciliation job that compares what your system believes it sent against what the provider reports, and flags the differences for a person.
The same thinking applies in reverse. Webhooks from the provider can arrive twice or out of order, so the code that receives a result should recognize a result it has already stored and should not let an older status overwrite a newer one.
What Happens When the Other Side Changes Its API?
Plan for change by isolating the provider’s API behind your own adapter, tracking its version and deprecation notices, and testing against its sandbox on a schedule. Every external API you depend on will change during the life of your product, and the change will arrive on the provider’s timeline rather than yours.
An adapter is a thin layer in your codebase that translates between your domain model and the provider’s. The rest of the practice software deals with “lab order” and “lab result” in its own terms. Only the adapter knows that the lab calls a species field animal_type and returns weights in kilograms. When the lab ships a new version that renames a field or adds a required one, the change lands in one place.
Pin the API version your integration uses, where the provider allows it, so upgrades happen on purpose. Subscribe a shared team inbox, not a single engineer’s address, to the provider’s developer notices. Run a small set of contract tests against the provider’s sandbox regularly, because sandboxes drift from production too, and a failing test a month before a deprecation deadline is far better than a failing order on the day of it.
How Do You Know an Integration Is Working?
You know an integration is working when you monitor business outcomes, such as orders sent and results received, alongside technical signals such as error rates and latency. A dashboard that shows zero errors can sit beside an integration that has silently stopped receiving webhooks.
For the veterinary group, the most useful alert is simple: results received in the last hour compared with what the clinic schedule would predict. If the hospitals ran dozens of panels in the morning and no results have arrived by early afternoon, something is wrong even if every API call returns a success code. Pair that with technical monitoring: the share of requests failing by status code, the remaining rate-limit budget, the age of the oldest pending order and the size of any queue of messages that failed processing.
Every alert needs an owner and a runbook. The runbook says what the alert means, how to check the provider’s status, how to replay failed messages safely and who to contact at the provider. Without it, the person on call at 7 a.m. is reverse engineering the integration while technicians wait.
| Decision | What to have in place before launch |
|---|---|
| Data ownership | A written list of which system owns each shared field |
| Credentials | A company-owned service account, least-privilege scopes, a rotation date |
| Rate limits | Known limits per key or account, priority for live requests over background jobs |
| Retry safety | A stable reference on every write, a reconciliation job |
| Change | An adapter layer, a pinned version, scheduled sandbox tests |
| Monitoring | Business-outcome alerts, a runbook, a named on-call owner |
Who Should Own an API Integration?
One engineer or team should own each integration end to end, from the user-facing behavior through the adapter to the provider relationship. Integrations break at boundaries, and split ownership leaves every boundary with nobody standing on it.
At Gun.io, we usually find one strong full-stack engineer handles an integration like the lab connection better than a frontend and a backend developer splitting it, because the person who writes the order screen’s pending state also understands why an order is pending. A second engineer adds redundancy when the integration is central to the business. A specialist earns a place when the integration has distinct depth, such as a regulated data exchange format or a provider with an unusually complex event model, and the trade-offs behind splitting backend and frontend developer roles apply here as they do anywhere else in the product.
Ownership also outlasts the build. Someone has to answer the provider’s deprecation notice two years from now, and that person needs the integration brief, the runbook and the reasoning behind non-obvious choices. If you are inheriting integrations through an acquisition or a new codebase, a technical due diligence review is a reasonable place to surface which ones lack an owner.
How Gun.io Approaches API Integration Work
Systems integration is a regular part of Gun.io’s work, usually next to backend and data engineering and the internal tools that automate business workflows. Before anyone is assigned, we want to know what the connection has to do for the business, which provider sits on the other side and where a failure would hurt, because those answers decide what kind of engineer the work needs and how much ownership they should carry.
A team with a lead and an integration plan typically brings in an engineer through staff augmentation, and that engineer joins the team’s sprints and reviews under its direction. A team that needs the integration brief written, the provider’s quirks worked out and the build owned end to end is better served by scoped project delivery. Gun.io handles sourcing, technical vetting, contracting, compliance and payments in both cases, with no minimum commitment, and the solutions overview lists the engineering areas involved.
Frequently Asked Questions
Should We Build an API Integration In-House or Use a Prebuilt Connector?
Use a prebuilt connector when the flow is standard and the connector’s behavior on failure is acceptable to you. Build custom code when the integration carries business rules, needs specific retry or reconciliation behavior, or is central enough that you need to control how it changes. Many teams use both, with connectors for simple syncs and custom code for the flows that matter most.
How Long Does an API Integration Take to Build?
The duration depends on the quality of the provider’s documentation and sandbox, the number of data flows, how much mapping the two data models need, and how quickly your team and the provider answer questions. A well-documented API with one flow is a very different project from a partner API with a thin sandbox and slow support, so estimate after reading the documentation rather than before.
What Is the Difference Between an API and an Integration?
An API is the interface one system exposes, while an integration is the code and agreements that use that interface to connect two systems for a business purpose. The same lab API might support several different integrations, each with its own data mapping, schedule and failure handling.
Do We Need Webhooks or Is Polling Enough?
Polling is enough when the data changes slowly or when a delay of minutes does no harm. Webhooks are worth the extra work when users wait on the result or when polling would consume a large share of your rate limit. If you adopt webhooks, verify their signatures, store them before processing, and keep a periodic poll as a safety net for events that never arrive.
How Should We Test an API Integration Before Launch?
Test against the provider’s sandbox with realistic data, then deliberately test the failure paths: expired credentials, a 429 response, a timeout after the provider accepted a request, a duplicate webhook and a malformed payload. Run a short pilot with one location or one customer before switching everyone over, and compare its records against the provider’s side by hand.
How Should an API Integration Handle Time Zones and Timestamps?
Store and exchange timestamps in UTC with an explicit offset, in a standard format such as the one defined in RFC 3339, and convert to local time only for display. A lab that reports result times in its own local time without an offset can produce a result that appears to arrive before its order, especially around a daylight saving change.
Plan the Failure Paths Before the Happy Path
An integration that survives production is one whose failures were designed on purpose: the expired credential, the throttled Monday, the lost response and the renamed field. If you have an integration coming up and want to think it through with engineers who have built and maintained them, tell us which systems you need to connect, who owns each one today and what the business needs to see when the connection fails.