Skip to content

Infrastructure & Integrations

API integration: a contract between two systems

Connecting two systems takes an afternoon. Knowing whether an update actually happened, handling the times the other side says no, and never creating the same invoice twice is the real work. Every integration we build starts as a contract: who owns each record, what each side may do, and what happens when something fails.
Close-out workflowAccounting APIPOST /invoices · key job-J-418429 Too many requests · retry after 20 swait 20 sPOST /invoices · same key201 Created · INV-2207POST /invoices · same key · after a timeout200 Already exists · INV-22073 requests · 1 invoice

Connected isn't the same as integrated

Most integrations work on the day they're switched on. Trouble starts later: the accounting API is busy and says “try again”, a request times out and nobody knows if it went through, a field is renamed. A connection that just fires requests turns each of these into a missing invoice or a duplicate one.

An integration is a contract. It says which system is the authority for each piece of data, which actions the connection is allowed to take, and how each kind of answer is handled. With that written down, a failed update is a visible exception with a recovery path, not a mystery.

Who owns what

The close-out integration between the field service app and accounting. Every shared item has one owner; the other system reads it.
Job, parts used and hoursField appField appAccounting
Customer billing detailsAccountingField appAccounting
Price list and tax codesAccountingField appAccounting
Invoice number and statusAccountingField appAccounting
Job photosField appstays in the field app

Nothing is edited in both places. When the field app needs a customer's billing address, it reads it from accounting; when accounting needs parts used, it takes them from the job. Two owners for one field is how integrations end up arguing with each other.

Five answers an API can give

Each kind of response gets its own handling, decided in advance.
  1. 01

    Success

    2xx

    Record the outcome and the ID the other system returned, such as the invoice number.

    Watch for: treating “accepted for processing” as “done”.

  2. 02

    Rejected

    400, 422

    The request was wrong: a missing field, an unknown tax code. Retrying won't help; set the case aside and tell its owner what to fix.

    Watch for: retry loops on bad data.

  3. 03

    Not allowed

    401, 403

    Credentials expired or permissions changed. Stop, and alert whoever manages the connection.

    Watch for: keys that expire on a schedule nobody tracked.

  4. 04

    Slow down

    429

    The other system is rate-limiting. Wait as long as it asks, then send the same request with the same key.

    Watch for: bursts that could be spread out.

  5. 05

    Unavailable

    5xx, timeouts

    The other side failed or didn't answer. Retry with growing gaps if the request is keyed; otherwise queue it and check before trying again.

    Watch for: timeouts that actually succeeded.

Retries that don't double

A timeout doesn't tell you whether the request worked. So every request that creates or changes something carries a key tied to the business record: the job, not the attempt. If the request arrives twice, the other system, or our own record of outcomes, recognises the key and returns the original result.

Read a customerYesRetry freely
Create an invoiceWith a keyKey = the job ID; a repeat returns the same invoice
Send an emailNot by itselfCheck the send record before trying again
Take a paymentNoNever automatically; the case goes to a person

What an integration hands off

In

Access
scoped to the job it does
Contract
ownership, fields, allowed actions
Request
the event to synchronise
Integration
validate · send · record

Out

Updates
confirmed, with returned IDs
Outcome record
what was tried, what happened
Exceptions
queued, with an owner

Worth building when systems must agree

Good fit

  • Systems need to exchange data repeatedly, with clear ownership.
  • A missed or duplicated update would cost something.
  • The systems offer usable APIs, webhooks or exports.

Not the right fit

  • The API doesn't offer the operation, permissions or reliability the workflow needs; settle that boundary first.
  • A one-time data move; that's a migration.

Questions about API integration

Can't we use a connector from the app marketplace?

Often, for simple one-way copies. When ownership, retries or duplicates matter, a marketplace connector rarely lets you control them. We use existing connectors where they fit and build the contract around them.

What if the system we use doesn't have an API?

Then we look at exports, webhooks or database access, and at whether the system can do what the workflow needs at all. Sometimes the honest answer is that it can't, and that changes the design.

How do you stop duplicates?

Every request that creates something carries a key tied to the business record, and every outcome is saved. A repeat finds the existing result instead of making a new one.

Who owns the integration after it's built?

You do. The contract, credentials and error handling are documented, alerts go to a named owner, and the integration is monitored like any other workflow.