API Design Guidelines
This document defines mandatory API design conventions for all internal services. Every endpoint must conform to these rules unless an exemption is approved. Intended for backend engineers building or maintaining HTTP APIs.
Data Integrity & Types
- Use Integers as currency to eliminate floating-point rounding errors. Always pair the value with a Currency Code (ISO 4217).
- Treat null, empty, and default values carefully. In Fintech,
0is a valid balance, not “missing data.” - If you accept a partial payload (PATCH), ensure your validation logic explicitly rejects unknown fields.
Performance & Efficiency
- Don’t Base64 encode large files. Use
multipart/form-datafor uploads and binary streaming with correctContent-Typeheaders for downloads. - Apply dual-layer limiting. Use Infrastructure-level limiting (e.g., Nginx, API Gateway) to stop DDoS, and Application-level limiting (e.g., Redis Token Bucket) for business rules per user/tenant.
- Use pagination (cursor-based preferred over offset-based for large datasets), filtering, and sorting on all collection endpoints.
- All internal APIs must accept and use standard Tracing Headers (e.g., W3C
traceparentor B3 headers) to ensure we can debug a request across microservices. - For batch/bulk operations, clarify whether it’s an Atomic Transaction or allows ‘Partial Success’. If partial success is allowed, the response structure must explicitly map individual IDs to their success/error status.
- For long running operations do not block the HTTP request. Return
202 Acceptedwith aLocationheader pointing to a status polling endpoint, or use Webhooks.”
Reliability & Safety
- Use idempotency for state-changing operations (POST/PATCH). Cache the response result (200/422) with a TTL; if a client retries with the same key, return the cached response immediately without re-processing.
- Set endpoint timeouts, Implement Circuit Breakers to fail fast when downstream dependencies are unhealthy.
- Redact PII/PCI from logs and traces. In Fintech, logging a raw request body that contains a credit card number or a refresh token can have severe consequences; always apply log sanitization.
HTTP Semantics & Status Codes
- Collections: A search that finds nothing (e.g.,
GET /transactions?date=today) is a success. Return200 OKwith an empty list[]. - Resources: A request for a specific entity that is missing (e.g.,
GET /transactions/tx-123) must return404 Not Found. - Consistent Errors: Standardize error responses (e.g., RFC 7807 Problem Details) across internal APIs so clients can parse
code,message, anddetailsuniformly.
Security
- Authenticate (who are you?) before Authorizing (what can you do?). Enforce Role-Based (RBAC) or Attribute-Based (ABAC) access control at the endpoint level.
- Enforce TLS 1.2+ and use strict CORS policies.
Lifecycle & Versioning
- Never break a live API. When introducing v2, deploy it alongside v1. Mark v1 as deprecated (via headers), monitor traffic until it hits zero, and then remove.
- Use explicit versioning in the URL (
/v1/) or Header (Accept-Version), each with their own tradeoffs. - Document the actual behavior, including edge cases and error responses. Use schema-first design (OpenAPI/Swagger) to ensure implementation matches documentation.
Request Coalescing
Use request coalescing to deduplicate concurrent identical requests to the same upstream. When a request arrives for key X, check if an upstream call for X is already in-flight. If yes, subscribe the caller to the existing result instead of opening a new connection. Go’s golang.org/x/sync/singleflight implements this pattern.
References
- Stripe API Reference — Idempotent Requests
- Stripe API Reference — Pagination (cursor-based)
- Google Cloud API Design Guide
- Microsoft REST API Guidelines
- RFC 7807 — Problem Details for HTTP APIs
- W3C Trace Context — traceparent
- Go singleflight package
- Zapier Engineering — Request Coalescing
- AWS — Timeouts, retries, and backoff
- Stripe — Designing APIs for humans
- GitHub API v3 — Conditional requests (caching)