Overview
An API is a contract. When a development team publishes an API — whether for internal services, for partner integrations, or for public consumption by external developers — they are making a commitment about how that interface will behave, what data it will accept and return, and how it will evolve. APIs that are designed without deliberate thought about these commitments tend to accumulate problems: inconsistent conventions that make the interface hard to learn, breaking changes that force consuming systems to update unexpectedly, missing versioning strategies that leave no clean path for evolution, and security gaps that create vulnerabilities at the integration boundary.
API strategy and design consultancy addresses the decisions that shape an API before and during its construction — the resource model, the authentication approach, the versioning strategy, the error handling conventions, the rate limiting design, and the documentation standards that determine whether an API is a reliable foundation or a source of ongoing friction for the systems and developers that depend on it.
This is relevant at several stages. Before building: the architecture work that defines the API surface, establishes conventions, and makes the foundational decisions that will be difficult to change later. During development: the review and guidance that keeps the API consistent with its design principles as it is built. After building: the audit that evaluates an existing API against quality standards and identifies the improvements that would make it more reliable, more consistent, and easier to work with. And at the strategic level: the API governance framework for organisations managing multiple APIs across multiple teams.
We provide API strategy and design consultancy for product companies, platforms, and organisations with significant integration surface area — where the quality of the API layer directly affects the reliability of integrations, the productivity of consuming developers, and the operational cost of maintaining the integration ecosystem.
What API Strategy and Design Covers
API resource modelling. The foundational design work that determines what the API exposes and how it is structured.
Resource identification: the process of identifying the resources that the API should expose — mapping the domain model to a REST resource hierarchy, or the operations to a GraphQL schema, or the procedure calls to a gRPC service definition. The resource model that reflects the domain's natural structure rather than the implementation's database schema or internal class hierarchy. The API that makes sense to consumers who know the domain but not the implementation.
REST resource design: URL path conventions that correctly apply REST principles — resources identified by nouns, collections at /resources, individual items at /resources/{id}, nested resources where genuine ownership relationships exist. The resource granularity that avoids both over-fetching (resources that return enormous payloads when the consumer needs three fields) and under-fetching (resources that force consumers to make many sequential requests to assemble a complete picture).
GraphQL schema design: the type system that models the domain correctly for query-based data access. The query fields that match how consumers actually need to access data. The mutation design that maps business operations to GraphQL mutations with appropriate input types and return types. The subscription design for real-time data requirements. The schema design that avoids the N+1 query problem by designing for dataloader batching from the outset.
Operation design: the HTTP methods that carry the correct semantics — GET for idempotent retrieval, POST for resource creation or non-idempotent operations, PUT for full replacement, PATCH for partial update, DELETE for removal. The operation signatures that are intuitive for consumers who understand HTTP conventions.
Request and response format design. The conventions that make the API predictable and consistent.
Field naming conventions: the consistent application of a single naming convention — camelCase for JSON APIs consumed by JavaScript clients, snake_case for APIs where Python clients dominate, kebab-case for URL parameters. The convention choice and its consistent application across every field in every endpoint. The inconsistency that forces consuming developers to remember which convention applies to which part of the API.
Data type handling: the representation of dates and times (ISO 8601 with timezone, not Unix timestamps in some places and date strings in others), monetary values (string or integer representation in smallest denomination to avoid floating-point precision issues), identifiers (consistent string or integer representation, not a mix), optional versus null versus absent fields (a consistent policy applied uniformly).
Response envelope structure: the outer structure that wraps response payloads — whether to use an envelope ({"data": {...}, "meta": {...}}) or return the resource directly, and applying the choice consistently. The pagination metadata location — always in the same place in list responses. The error response structure that is consistent across all error types.
Collection responses: the list response format — the array of items, the pagination metadata (total, page, per_page, next_cursor, has_more), the consistent structure that consuming code can depend on. Cursor-based versus offset-based pagination and the appropriate choice for each data type.
Versioning strategy. The approach to API evolution that allows the API to change without breaking existing consumers.
Versioning mechanism options: URL path versioning (/v1/, /v2/), header versioning (API-Version: 2024-01-01), query parameter versioning (?version=2). The trade-offs of each approach — URL path versioning provides the highest visibility and easiest debugging, header versioning keeps URLs clean but makes versioning less visible, query parameter versioning is explicit but can be confused with filtering parameters.
Additive change discipline: the distinction between breaking changes (removing fields, changing field semantics, changing authentication requirements, removing endpoints) and non-breaking changes (adding optional fields, adding endpoints, adding optional parameters). The development discipline that reserves new versions for genuinely breaking changes and uses additive evolution for everything else — keeping the API surface stable for existing consumers while the API grows.
Deprecation policy: the process for retiring old API versions — the deprecation notice period, the headers that signal deprecation to consuming applications (Deprecation and Sunset headers), the migration guide that helps consumers move to the new version. The deprecation timeline that is long enough for consumers to migrate but short enough to avoid maintaining old versions indefinitely.
Versioning governance: for organisations with multiple API teams, the versioning policy that ensures consistent version numbering, consistent deprecation notice periods, and consistent migration support across all APIs.
Authentication and authorisation design. The security model that controls who can access the API and what they can do.
Authentication mechanism selection: the appropriate authentication mechanism for the API's use case — API keys for simple server-to-server integrations, JWT Bearer tokens for user-context API calls, OAuth 2.0 for delegated access flows, mTLS for high-security service-to-service communication. The selection criteria that match the mechanism to the security requirements, the client types, and the operational constraints.
OAuth 2.0 flow design: for APIs that use OAuth, the flow selection — client credentials for machine-to-machine, authorisation code for user-delegated access, device code for limited-input device scenarios. The scope design that expresses permissions at the right granularity — not so coarse that clients receive more access than needed, not so fine-grained that scope management becomes operationally complex.
API key design: key format, key prefix conventions that make keys identifiable as belonging to a specific service, key permission scoping, key rotation support, key hashing for storage (so the API key database breach does not expose usable keys), and the key management endpoints that allow programmatic key lifecycle management.
Authorisation model: the permission model that controls what an authenticated caller can do — role-based access control (RBAC) for coarse-grained permissions, attribute-based access control (ABAC) for data-level permissions, resource ownership models for user-scoped data. The authorisation checks that run in the request handler and the errors that correctly distinguish authentication failures (401) from authorisation failures (403).
Error handling design. The error response format and HTTP status code usage that allows consuming applications to handle errors correctly.
HTTP status code correctness: the consistent and correct use of HTTP status codes — 400 Bad Request for malformed requests, 401 Unauthorized for missing or invalid authentication, 403 Forbidden for authenticated but unauthorised requests, 404 Not Found for non-existent resources, 409 Conflict for state conflicts, 422 Unprocessable Entity for validation failures with valid syntax, 429 Too Many Requests for rate limit violations, 500 Internal Server Error for unexpected server failures, 502/503/504 for upstream dependency failures. The status code choices that align with HTTP semantics rather than overloading 400 and 500 for all error types.
Error response structure: the machine-readable error response that consuming applications can process programmatically — a consistent error_code field with a stable identifier for each error type, a message field with a human-readable description, a details array for field-level validation errors, and optional documentation_url pointing to the error's documentation. The error structure that is identical across all API versions and all endpoints.
Error code taxonomy: the error code vocabulary that covers the API's error domain — the structured code format (RESOURCE_NOT_FOUND, VALIDATION_FAILED, RATE_LIMIT_EXCEEDED, or numeric codes) applied consistently, the error code catalogue in the documentation that allows consuming applications to implement specific error handling for each error type.
Rate limiting design. The protection mechanisms that prevent the API from being overwhelmed and ensure fair usage.
Rate limit strategy: the rate limiting approach — per-API-key limits, per-user limits, per-IP limits, or a combination. The limit dimensions — requests per second, requests per minute, requests per day. The token bucket or sliding window algorithm that implements the limits. The differentiated limits for different client tiers — higher limits for trusted partners, lower limits for anonymous or free-tier clients.
Rate limit headers: the standard headers that communicate rate limit status to clients — X-RateLimit-Limit (the limit), X-RateLimit-Remaining (requests remaining in the current window), X-RateLimit-Reset (when the window resets, as a Unix timestamp or seconds until reset). The Retry-After header on 429 responses that tells the client when to retry. The headers that allow well-behaved clients to manage their request rate proactively rather than discovering limits through 429 responses.
Burst handling: the burst capacity that allows clients to exceed the sustained rate limit briefly — the token bucket that accumulates capacity up to a burst limit. The design that handles real-world API consumption patterns where requests arrive in bursts rather than at a perfectly steady rate.
API documentation standards. The documentation that makes the API usable without requiring consumers to read source code or make trial-and-error requests.
OpenAPI specification: the OpenAPI 3.x document that formally describes the API — every endpoint, every request schema, every response schema, every authentication requirement, every error response. The specification that is machine-readable (for generating client SDKs, mock servers, and test suites) and human-readable (rendered by Swagger UI or Redoc for interactive documentation). The OpenAPI specification as the source of truth that documentation, client generation, and request validation all derive from.
Code examples: the request examples in curl, in the relevant programming languages for the API's primary consumers, and in the integration contexts where the API is typically used. The example that shows exactly how to construct a correct authenticated request — not just the endpoint, but the complete request including authentication headers, content-type headers, and a realistic request body.
Error documentation: the error catalogue that documents every possible error response — the error code, the conditions under which it occurs, the fields present in the error response, and the recommended handling. The documentation that allows consuming developers to implement correct error handling without guesswork.
Changelog and migration guides: the version history that documents what changed in each API version — the breaking changes clearly identified, the migration steps clearly described, the code examples showing how to update code from the old to the new API version.
API governance for multi-team environments. The policies and standards that ensure consistency across APIs built by multiple teams.
API standards documentation: the organisation-wide API design standards that define the naming conventions, versioning policy, authentication requirements, error response format, rate limiting conventions, and documentation standards that all APIs must follow. The standard that is specific enough to produce consistent APIs but flexible enough to accommodate the different needs of different API domains.
API review process: the design review that validates new APIs against the standards before they are built — the lightweight process that catches inconsistencies and design issues when they are easiest to fix. The review checklist that evaluates each API against each standard requirement.
API catalogue: the internal registry that documents all of the organisation's APIs — the endpoints, the authentication requirements, the owning team, the SLA, and the consuming systems. The catalogue that prevents duplication and enables API reuse.
REST, GraphQL, gRPC, and AsyncAPI
API strategy covers not just REST API design but the selection and design of the right API paradigm for each use case.
REST for resource-oriented APIs where the HTTP verbs map naturally to the operations, where caching is important, where broad client compatibility is required, or where the API is intended for public or partner consumption.
GraphQL for product APIs where clients have highly variable data requirements, where multiple client types (web, mobile, third-party) need different data shapes, and where the development team wants to avoid the proliferation of purpose-built REST endpoints for each UI screen.
gRPC for internal service-to-service APIs where performance is critical, where strong typing and code generation are valued, and where the services are under a single organisation's control so the coupling that gRPC's shared proto files introduce is acceptable.
AsyncAPI for event-driven APIs — the specification standard for message-based APIs over WebSocket, AMQP, Kafka, and other asynchronous transports. The design of event schemas, channel naming, and the publication/subscription model for async communication.
Webhooks for push notification APIs — the design of the event payload format, the signature scheme, the retry policy, and the subscription management that makes webhook-based integration reliable.
Technologies Used
- OpenAPI 3.x — REST API specification and documentation
- Swagger UI / Redoc — interactive API documentation rendering
- GraphQL — query-based API design and schema definition
- gRPC / Protocol Buffers — high-performance typed RPC API design
- AsyncAPI — event-driven API specification
- JWT / OAuth 2.0 — authentication mechanism design and implementation review
- REST / HTTP — HTTP semantics and REST API design principles
The Cost of Poor API Design
API design decisions made early are expensive to change later. An inconsistent naming convention baked into a public API's first version will be there until the API is retired — changing it breaks every existing integration. A missing versioning strategy means that the first time a breaking change is needed, there is no clean path that does not break something. A poorly structured error response means that every consuming system has developed its own ad-hoc error handling that will need to change when the format is fixed.
The investment in deliberate API design before and during construction — the resource modelling, the convention establishment, the versioning strategy, the error taxonomy, the documentation standards — is orders of magnitude cheaper than the accumulated cost of working around the consequences of design choices made without sufficient thought.
API Design as a Competitive Advantage
Well-designed APIs are faster to integrate against, require less support, produce fewer integration bugs, and create less friction for the development teams consuming them. For API-driven products and platforms, the quality of the API layer is a direct determinant of how quickly partners can integrate, how reliably those integrations operate, and how confidently the API can evolve without causing problems for existing consumers.