Custom Software
API services: a promise about who may ask and what they get
What the contract says
Three endpoints
Read a job
- Request
- GET /v2/jobs/{id}
- Needs
- jobs:read
- Returns
- the job, with fields for the caller's scope
- Refuses
- jobs outside the caller's customer or assignment, as 404
- Limit
- 60 a minute per caller
Take a payment
- Request
- POST /v2/payments
- Needs
- payments:write
- Requires
- an idempotency key, so a retried request never charges twice
- Returns
- the payment and its status
- Refuses
- amounts that don't match the invoice, with the reason
Job completed (webhook)
- Sends
- job.completed, to subscribers
- Contains
- job ID, completion time, invoice ID; never card details
- Signed
- so the receiver can check it came from you
- Retries
- on failure, for 24 hours, then the subscriber's owner is told
How APIs break the people using them
01
Silent changes
A field renamed overnight
Every change that could break a caller goes into a new version, with the old one served until a published date.
02
Errors that leak
A stack trace in the reply
Errors explain what the caller can fix and never expose internals or other customers' data.
03
No limits
One caller slows everyone
Limits per caller, with a clear message and a time to retry.
04
Data across customers
Ask for job 1041, get someone else's
Every request is checked against the caller's customer or assignment before anything is read.
05
Undocumented behaviour
It works, nobody knows why
The contract is published, examples included, and requests are logged so a caller's question can be answered from the record.
What API services hand off
In
Out
Worth building when other software needs your records
Good fit
- A portal, an app or a partner needs to read or change your records.
- More than one system relies on the same logic.
- You want to add new tools later without rewiring the old ones.
Not the right fit
- One screen talks to one database and nothing else will. The application can do it directly.
- A partner only needs a nightly file. Send the file.
Questions about API services
REST or GraphQL?
Usually REST, because most callers expect it. GraphQL when many different screens need different shapes of the same data. The contract matters more than the style.
How do partners get access?
Each gets its own credentials and only the scopes it needs. Access can be changed or withdrawn without affecting anyone else.
What does versioning cost us?
Running two versions for a while. It's cheaper than breaking a partner's integration without warning.
Is it documented?
Yes. The contract is published with examples and kept in step with the code, because it's generated from the same definitions.