An API is a promise you cannot quietly break
Internal code can be refactored on a Tuesday. An API that partners have integrated against cannot. That difference — the fact that every mistake becomes permanent the moment someone depends on it — is why API design deserves more care than it usually gets.
You might be here because
Situations we are brought in for
- Partners keep asking for the same thing because the documentation does not answer it.
- You need to change a response shape and have no idea who would break.
- Every integration is bespoke, and each new one takes as long as the last.
- A customer wants webhooks and you have no delivery, retry or replay story.
What you get
Concrete deliverables, not a retainer with a hope attached
API design and contract
Resources, errors, pagination, idempotency and auth designed as one coherent thing, published as an OpenAPI or GraphQL schema that is generated from the implementation rather than maintained beside it.
Versioning and deprecation policy
How you will ship breaking changes before you need to: version strategy, sunset headers, deprecation timelines and the telemetry that tells you who is still on the old path.
Webhooks and event delivery
Signed payloads, at-least-once delivery, exponential backoff, a dead-letter path and a replay endpoint — so integrators do not lose events when their own service has a bad hour.
Documentation and SDKs
Reference generated from the schema, plus the worked examples that actually get people to first successful call. Client libraries where the integration volume justifies them.
How it works
Four phases, each with an exit you control
- 01
Consumers first
We start from the integrations people want to build, not from your database tables. An API that mirrors an internal schema exports your internal problems to everyone who uses it.
- 02
Contract
The schema is agreed and reviewed before implementation, with a mock server so consumers can start building against it immediately.
- 03
Implement
Handlers, authorization, rate limiting and observability per endpoint, with contract tests that fail CI on any unintended change to the published shape.
- 04
Operate
Per-consumer usage and error visibility, sandbox credentials, and a support path that does not route through an engineer for every question.
Tools we reach for
Chosen per problem, not per fashion
This is what we use most for api development. If your team is already productive in something else, we work in that instead — familiarity in your team beats preference in ours.
- TypeScript
- Node.js
- Go
- OpenAPI
- GraphQL
- PostgreSQL
- Redis
- Kafka
Where this usually starts
Discovery Sprint
Discovery Sprint
Deciding what to build, before committing a budget to building it
A short, fixed-scope investigation that turns an ambiguous problem into a plan you could hand to any competent team — including one that is not us.
- Typical duration
- 1–2 weeks
- Commitment
- Fixed scope, fixed fee
Includes
- Stakeholder and user interviews
- Technical constraint and risk analysis
- Architecture options with trade-offs stated
- Scoped delivery plan with sequencing
- Written recommendation, including "do not build this" where that is the answer
You keep
- Findings document
- Annotated architecture diagram
- Prioritised delivery backlog
- Effort and risk assessment
Fee agreed after scoping. No commitment to that conversation.
Common questions
REST or GraphQL?
REST for most public and partner APIs: it is cacheable, it is what integrators expect, and it fails in ways they can debug. GraphQL earns its complexity when consumers have genuinely varied data requirements you cannot anticipate — typically a first-party client with many screens. Choosing GraphQL for a public API commits you to solving query cost and rate limiting yourself.
Can you add an API to an existing system?
Yes, and it is a common shape of work. The interesting part is rarely the endpoints; it is establishing a boundary that lets the system underneath keep changing. Done well, an API layer is also the first seam in a modernization effort.
How do you handle rate limiting and abuse?
Per-consumer quotas enforced at the edge, with limits published in headers so integrators can back off correctly rather than retrying into a wall. Beyond that: idempotency keys on writes, request size ceilings, and query cost limits anywhere a consumer can ask for arbitrary amounts of data.
Related reading
The connection pool exhaustion that was not a connection pool problem
A production incident where every symptom pointed at the database, and the actual cause was an HTTP client with no timeout three services away.
Other services
Product engineering
Ship the product your roadmap keeps promising — designed, built and maintained.
Platform & infrastructure
Make deploys boring, incidents rare, and cloud spend explainable.
Legacy modernisation
Untangle the system nobody fully understands — without stopping the business.
AI & applied ML
Put language models into production without betting the product on a demo.
Custom software
For the process no product on the market actually fits — built once, properly.
SaaS development
Multi-tenancy, billing and onboarding — the unglamorous parts that decide whether it scales.
Web applications
Serious applications in the browser — dashboards, editors, real-time tools that stay fast with real data.
Mobile apps
Apps that work on a bad connection, clear store review, and can be shipped weekly.
Next step
Think this is your problem?
Send us the shape of it. We will tell you whether it is a fit, what we would do first, and roughly what that takes.