REST API with OpenAPI: Design, Versioning and Error Format
A good API is understandable, stable and well documented. How to design REST APIs with OpenAPI cleanly, version them without breakage and save integration effort with a clear error culture.

A good REST API follows five rules: resources instead of actions in the URL, a maintained OpenAPI description as the contract, uniform status codes and error formats, versioning with a migration window instead of surprises, and automated checks against the specification. Settle these early and you save integration effort, support requests and trouble with updates.
Whether online store, CRM, mobile app or partner portal: modern software is networked, and the quality of its interfaces determines how smoothly that networking works. This article walks through the resource model, OpenAPI, conventions, error handling, versioning, security and testing – with tables that double as a checklist for your own API.
Resources instead of actions in URLs
REST thinks in resources, not function calls. Instead of endpoints like /getOrder or /createOrder, there is a resource /orders that is addressed through HTTP methods. The methods have defined properties that clients can rely on:
| Method and example | Purpose | Idempotent | Typical response |
|---|---|---|---|
| GET /orders and GET /orders/{id} | read a list or a single order | yes | 200 |
| POST /orders | create a new order | no, unless an idempotency key is used | 201 with Location header |
| PUT /orders/{id} | replace an order completely | yes | 200 or 204 |
| PATCH /orders/{id} | change individual fields | not guaranteed | 200 or 204 |
| DELETE /orders/{id} | remove an order, if permitted by the business rules | yes | 204 |
This consistency makes an API predictable: anyone who has understood one endpoint understands the others. Nested resources such as /customers/{id}/orders make sense when the relationship is unambiguous in business terms – overly deep nesting makes an API hard to read. Add uniform rules for filtering and sorting. For pagination, a cursor approach is more stable than page numbers for large or changing data sets, because no entries are skipped or delivered twice when data is added between two requests.
OpenAPI: the contract between systems
The OpenAPI specification describes a REST API in machine-readable form: endpoints, parameters, data schemas, examples and possible responses. This makes it documentation and contract at the same time. Versions 3.0 and 3.1 are currently widespread; version 3.1 uses JSON Schema for the data models. Before choosing, check which version your tools fully support.
What a maintained specification delivers
- Developers see at once which fields are expected and delivered, and find realistic examples of requests, responses and error cases.
- Clients for different programming languages and interactive documentation can be generated from the specification.
- Mock servers, for example with Prism, let front-end teams work in parallel before the back end is finished.
- Linters such as Spectral check the style guide automatically, tools such as oasdiff report breaking changes in pull requests.
- AI applications that are supposed to use your API as a tool also benefit from a precise description with clear field names and examples.
Design first or code first?
With the design-first approach, the specification is agreed before implementation. This pays off especially for partner APIs because everyone involved talks about the same foundation early on. With the code-first approach, the specification is generated from the code, which is often faster for internal APIs. In both cases the specification belongs in the repository, and a check in the pipeline ensures it does not drift from the actual behavior.
Conventions that make everyday work easier
Many problems in integration projects do not arise from complex logic but from inconsistent details. Define conventions early and record them in a short API style guide:
- Naming: one consistent spelling for fields, such as camelCase or snake_case, and resources in the plural.
- Dates and times: consistently per ISO 8601 with time zone.
- Amounts: not as floating-point numbers but as an integer in the smallest unit or as a string, each with a currency code.
- Idempotency: repeated requests must not create duplicate orders – for example through an idempotency key on POST requests.
- Pagination: one uniform method, including an indication of whether more data follows.
- Structured fields: separate fields instead of composite strings that the recipient has to split first.
Error culture: status codes and error format
An API shows its quality above all when something goes wrong. Clear status codes save support time because developers immediately see where the problem lies:
| Code | Meaning | Typical use |
|---|---|---|
| 400 | bad request | malformed JSON, missing parameters |
| 401 | not authenticated | token missing or expired |
| 403 | not authorized | valid login but no permissions |
| 404 | not found | resource does not exist or is not visible |
| 409 | conflict | concurrent editing, duplicate creation |
| 422 | unprocessable | formally correct but business validation failed |
| 429 | too many requests | rate limit reached, with Retry-After header |
| 503 | service unavailable | maintenance or overload, with Retry-After header |
A uniform error format is just as important. The standard “Problem Details for HTTP APIs” (RFC 9457) has proven itself, with the media type application/problem+json and the fields type, title, status, detail and instance. For validation errors, add a list showing which field was rejected and why. The error type should be machine-readable so clients can react specifically; stack traces and internal details do not belong in the response. Above all, avoid answering errors with status 200 and a message in the body – it makes automatic error handling harder on the client.
Versioning without breakage
APIs evolve. Most changes can be made additively without needing a new version – provided clients ignore unknown fields. You should state this rule explicitly in the documentation. The overview shows what counts as a breaking change:
| Change | Breaking change? |
|---|---|
| new optional field in the response | no |
| new endpoint or new optional parameter | no |
| removing or renaming a field | yes |
| changing the data type or format of a field | yes |
| new required field in the request | yes |
| new value in an enumeration (enum) | possible if clients do not tolerate unknown values |
| changing the meaning or status code of a behavior | yes |
| changing the authentication method | yes |
There are several ways to handle the major version. The version in the path, such as /v1/orders, is easy to see, simple to test and cache, and has become established for partner APIs. The version in a header or media type keeps URLs stable but is harder to document and test. Increase the major version only for breaking changes.
What matters is how you handle change. Breaking changes should only happen with a migration window, documented in the changelog and announced through deprecation notices. The Sunset header (RFC 8594) tells clients in machine-readable form when a version will be switched off. For partner APIs, we typically plan 90 to 180 days of parallel operation. For mobile apps, allow longer, because old app versions stay in circulation; a minimum version and a gentle update prompt help here. Log which clients use which version so you know whom to contact before you switch off.
Quality and protection: contract tests and security
Contract tests check whether an API meets the expectations of its consumers. With Pact, consumers define which requests and responses they expect, and the back end is tested against them on every deployment. In addition, responses can be validated automatically against the OpenAPI description and checked with many inputs generated from the specification using tools such as Schemathesis. This way unintended changes are caught before they hit partners.
Every production API also needs protective measures. For access by partners and servers, OAuth 2.0 has proven itself, often with client credentials for server-to-server access; API keys are only defensible with clearly limited permissions. The biggest risk is often missing authorization at object level: on every request, check not only that the caller is signed in but that they may access exactly this resource. This weakness tops the OWASP API Security Top 10 (2023 edition). Add rate limiting, input validation based on the schema and logs that make errors traceable without storing sensitive data. Our OWASP web security checklist gives an overview of typical risks.
Practical example and checklist
Interfaces in everyday business
In many projects, APIs connect existing systems – for example a real-estate CRM portal with the broker software onOffice, an online store with the ERP, or a mobile app with its back end. Suppose a retailer provides an order API to its partners. Two years later, the field price is to be split into unitPrice and currency. The clean way: the new fields appear in addition, price is marked as deprecated and announced in the changelog, and a sunset date is set far enough ahead. The logs show which partners still read price, and they are contacted individually. Only then is the old field dropped – in a new major version if it was mandatory. How such connections are planned is covered in our article Connecting ERP, CRM and online store.
Such contracts are also indispensable between the services of a distributed system. Whether splitting into services makes sense for your product at all is covered in Microservices or monolith.
Checklist for your API
- Resources and endpoints follow a uniform scheme, HTTP methods are used correctly.
- A complete OpenAPI specification with examples is in the repository and checked in the pipeline.
- Status codes and error format (RFC 9457) are defined uniformly.
- Pagination, filtering, sorting, date-time and amount formats are settled.
- Versioning strategy, breaking-change rules and migration window are documented.
- Contract tests and a breaking-change check run automatically in the pipeline.
- Authentication, object-level authorization and rate limiting are implemented.
- Access is logged without storing sensitive data; usage per version can be analyzed.
How Nano Concepts can help
If you are planning a new API or want to improve an existing one, we support you with our API and backend development – from drafting the OpenAPI description through implementation to connecting existing systems. In a free initial consultation, we clarify which interfaces you need, who will use them and how changes can be rolled out in the future without breakage.
Frequently asked questions
OpenAPI is a standard for describing REST APIs in a machine-readable way, formerly known as the Swagger specification. The description contains endpoints, parameters, data schemas, examples and possible responses. From it you can generate documentation, mock servers, clients and automated tests.
The common approach is the major version in the path, such as /v1/, or alternatively in a header. More important than the method is the process: additive changes need no new version, breaking changes only with an announcement, changelog, sunset date and sufficient parallel operation. Measure which clients still use the old version.
Contract tests automatically check whether an API meets the expectations of its consumers, for example with Pact or against the OpenAPI description. They run in the pipeline on every change. This way unintended breakage is caught before it affects partners or other systems.
Use the status codes of the HTTP specification: 400 or 422 for invalid input, 401 and 403 for missing authentication or authorization, 404, 409 for conflicts and 429 for too many requests. For the error body, the Problem Details format per RFC 9457 is recommended.
REST suits partner and public interfaces as well as classic data queries, since tooling, caching and documentation are widespread. GraphQL pays off when clients need to flexibly query very different slices of data. gRPC is often used for fast internal communication between services.
Matching services

API & Backend Development
APIs and backends that connect ERP, CRM, store and apps – automatic data exchange instead of retyping.
Learn more
Software Development
Software from requirements to operations – web, mobile and integrations from a single source.
Learn more
Web Applications
Customer portals, dashboards and SaaS platforms that run in the browser – no installation, on any device.
Learn moreTerms from this article, briefly explained
More articles

Custom Software or Off-the-Shelf? An Honest Comparison
Off-the-shelf tools are quick to roll out; custom software fits exactly. Which solution pays off over three to five years – and why a combination of both is often the best choice.
Read more
Replacing Excel: When a Custom Web App Pays Off
Version chaos, locked files, broken formulas: when Excel hits its limits, which alternatives exist and how the move to a web app with a database succeeds while operations keep running.
Read more
Prioritizing Technical Debt: Pay the Interest or Pay It Down?
Technical debt is not a synonym for bad code – it becomes dangerous when it stays invisible. Here is how to assess legacy burdens by impact and effort and reduce them in a plannable way.
Read more