🔌 API Guide - Design, security and infrastructure
Six sections on Application Interfaces (API) according to international practice: REST principles (Roy Fielding, 2000), HTTP methods and status codes (RFC 9110), security (OWASP API Top 10, OAuth 2.0, JWT), API gateways, reverse proxy and load balancer differences, design practices (RFC 9457, OpenAPI 3.1) and standards references. Examples are fictional, intended for teaching.
What API is
REST architecture style - Roy Fielding (2000)
API (Application Programming Interface) is an agreement between two programs on how they exchange data. Web API is usually based on the HTTP protocol and REST architecture style: resources are addressed by URL, activities are expressed by HTTP methods, but data are most often transmitted in JSON format.
Customer Server
The client (what the user sees) is separated from the server (data and logic), so both can be developed and scaled independently.
Free
Each request shall contain all the context necessary for its execution. The server does not maintain the position of the client session, which simplifies horizontal scaling.
Capacity
Each response makes it clear whether it can be cached (Cache-Control, ETag) - this reduces server load and response time.
Uniform interface
Common principles of interaction: identification of resources, representation thereof (e.g. JSON), self-practical reports and hyperlinks (HATEOAS).
Sounded system
There may be intermediate layers (reverse proxy, gateway, cache) between the client and the server without the customer knowing about them.
Code on request
Optional principle: the server can send an executable code (e.g. JavaScript), temporarily expanding the client's functionality.
One API Request step by step
What happens between the client, server and database - and where to have security checks.
API Request
- 1Customer → APIGET /rekini/42Authorization: Bearer ..
The customer requires bill No 42 and adds an access token.
- 2APIchecks the token: signature, publisher, term → user = Anna
Authentication: The server determines who asks. Invalid token → 401.
- 3APIdoes the bill 42 belong to Anna?
Authorization: It is the absence of this test that is the most common API risk (BOLA) - you can see foreign bills when you change the number.
- 4API → DatabaseSELECT ... WHERE id = 42 AND owner = Anna
A request with parameters and owner's condition - not with user text pasted SQL.
- 5Database → API1 line
The database returns the entry or nothing.
- 6API → Client200 OK + JSON
If the invoice is not for Anna, the answer is 404, not 403 - to find out that there is such an invoice.
Try it with curl
The examples use a placeholder address. Test only your own API.
First request
-
Shows the status, headers and body.
curl -i https://api.example.com/v1/items -
Gets JSON and formats it for reading.
curl -s https://api.example.com/v1/items/42 -H 'Accept: application/json' | jq . -
Checks pagination.
curl -s 'https://api.example.com/v1/items?limit=10&page=2' | jq '.items | length'
REST
Resource-oriented architectural style above HTTP. Simple and quashable. Dominates public web API.
GraphQL
One endpoint. The client requires the necessary fields. Reduces excessive and insufficient data loading.
gRPC
Binary, high performance RPC frame (Protocol Buffers, HTTP/2). Suitable for internal microservice communication.
WebSocket / SOAP
WebSocket - a permanent two-way real-time channel. SOAP - older XML protocol with a strictly defined contract (WSDL).
RFC 9110 - HTTP Semantics
Methods (safe/idempotent) and status codes
| Method | Safe | Idempotent | Chechoyam | Typical application |
|---|---|---|---|---|
| GET | ✔ | ✔ | ✔ | Read resource without side effects |
| HEAD | ✔ | ✔ | ✔ | Returns only headers without body |
| POST | ✗ | ✗ | rare | Creates a resource or launches an activity |
| JU | ✗ | ✔ | ✗ | Fully replaces the resource |
| PAATCH | ✗ | ✗ | ✗ | Partially update resource |
| DELETE | ✗ | ✔ | ✗ | Deleting Resource |
| OPTIONS | ✔ | ✔ | ✗ | Methods supported. CORS preview |
Methods and status codes with curl
One line per method, and `-w` prints only the status code.
Methods
-
HEAD: headers only.
curl -I https://api.example.com/v1/items/42 -
POST: creates a resource, 201 expected.
curl -i -X POST https://api.example.com/v1/items -H 'Content-Type: application/json' -d '{"name":"tests"}' -
PATCH: partial change.
curl -i -X PATCH https://api.example.com/v1/items/42 -H 'Content-Type: application/merge-patch+json' -d '{"name":"jauns"}' -
DELETE: 404 expected on repeat, the state does not change.
curl -i -X DELETE https://api.example.com/v1/items/42 -
Shows the allowed methods in the Allow header.
curl -i -X OPTIONS https://api.example.com/v1/items
Status code in a script
-
Only the code and the response time.
curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' https://api.example.com/v1/items
Safe
Do not change server status. Just read the data. GET, HEAD, OPTIONS.
Idempotent
If the same request is repeated, the result shall be the same as at the same call. This allows you to safely repeat the demand for network failure.
POST not idempotent
The repeated POST may create duplicates. Solution - Idempotency-Key header (see section Design Practices).
OWASP API Security Top 10:2023, OAuth 2.0, JWT
Authentication, authorisation and most common API risks
API security is based on a clear separation between authentication (identity confirmation) and authorization (defining access rights). On the web, the standard solution is OAuth 2.0 with access tokens (usually JWT), which are checked in each request.
OAuth 2.0 with PKCE step by step
Four sides: user, app, authorization server and API. The app never sees the password.
OAuth 2.0 with PKCE
- 1Applicationcreates accidentalcode verifierand its mixing valuecode challenge
The app prepares a unique secret. It may show the mixing value, the secret itself - no.
- 2Application → Authorization serverforwarding + code challenge
The app sends the user through the browser to the authorization server.
- 3User → Authorization serverapplication and consent
User login directly to the authorization server - application does not see his password.
- 4Authorization server → Applicationone-off code
The server will return a temporary code through the browser. This step can be intercepted - that's why we need a PKCE.
- 5Application → Authorization servercodecode verifier
The app exchanges the code by adding the original secret. The server checks that its mixing value coincides with the code challenge.
- 6Authorization server → Applicationaccess token (JWT, short term)refresh token
The code is not enough for the receiver - without the code verifier token he does not get.
- 7Application → APIGET / Resource + Bearer token
The app calls API. API checks token signature, addressee (aud) and deadline (exp) and then responds.
Security tests
Only your own API or with written permission. In a test environment, with two test accounts.
Authentication
-
401 expected without a token.
curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/v1/me -
401 also expected with an invalid token.
curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/v1/me -H 'Authorization: Bearer nederigs' -
Shows the JWT claims: `exp`, `aud`, `iss`. They are not encrypted.
cut -d. -f2 <<< "$TOKEN" | base64 -d 2>/dev/null | jq .
Authorization (BOLA)
-
User B requests an object of A: 403 or 404 expected, not 200.
curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/v1/orders/<lietotāja-A-id> -H "Authorization: Bearer $TOKEN_B" -
A regular user on an admin function: 403 expected.
curl -s -o /dev/null -w '%{http_code}\n' -X DELETE https://api.example.com/v1/admin/users/1 -H "Authorization: Bearer $TOKEN_B"
Input and volume
-
An extra field must not change privileges.
curl -i -X POST https://api.example.com/v1/items -H 'Content-Type: application/json' -d '{"name":"t","is_admin":true}' -
Checks the limit: 429 expected above the threshold.
for i in $(seq 1 50); do curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/v1/items; done | sort | uniq -c
Transport and browser
-
A foreign origin must not be allowed.
curl -sI -H 'Origin: https://svesa-vietne.example' https://api.example.com/v1/items | grep -i access-control -
TLS versions, ciphers and certificate.
testssl.sh api.example.com -
mTLS: the connection must fail without a client certificate.
curl --cert klients.pem --key klients.key https://api.example.com/v1/items
API keys
Simple service identification. Not to be placed on the customer side or code repository. Regularly change (rotation).
OAuth 2.0 / OIDC
Delegated authorization with tokens. The OIDC adds a layer of identity. RFC 9700 (2025): PKCE for all customers, indirect (implicit) and password flow is not used.
JWT
Cryptographically signed token in three parts: header.payload.signature. Always check the signature with a pre-defined algorithm (alg: non-rejected), issuer (issue), addressee (aud) and expiry date (exp) - RFC 8725.
mTLS
Two-sided TLS - both client and server present certificates. Strong mutual authentication between services.
BOLA
Lack of object level authorization - the user accesss an object of another subject by manipulating an identifier (e.g. /recini/123). The most common API risk.
Incomplete authentication
Weak or incorrectly checked tokens, unverified signature, unlimited number of login attempts.
BOPLA
Lack of authorisation of object properties level - excessive disclosure of data in response or unauthorised mass assignment.
Unlimited consumption of resources
Lack of volume and speed limits - this allows service failure (DoS) and infrastructure costs to increase.
BFLA
Lack of functionality level authorization - the usual user accesses administrative functions.
Sensitive business flows
Unlimited access to sensitive business flows - automated abuse (e.g. mass ticket shopping).
SSRF
Server side requests for counterfeiting - the server executes the request of an attacker controlled URL, reaching internal resources.
Deficiencies in security configuration
Missing safety heads, too open CORS, too detailed error messages.
Insufficient management of inventories
Forgotten or outdated versions and test media remain publicly available and unsafe.
Insecure consumption
Blind trust in third party API data - without verification and restriction.
Infrastructure in front of API
API gateway vs reverse proxy vs load balancer
All three are located between the customer and backend, so they tend to be confused. In fact, all are reverse proxy types, each specializing in their work. In practice, their boundaries overlap and often operate simultaneously.
| Aspect | Reverse proxy | Load balance | API Gate |
|---|---|---|---|
| Main objective | Transfer requests to backend, hide its topology | Split traffic by multiple server instances | Manages API - single entry point for microservices |
| OSI layer | L7 (may also L4) | L4 (transport) or L7 | L7 (use) |
| Route by | Host / road | IP/port (L4) or content (L7) | API path, versions, consumer |
| TLS termination | Yes | Yes (L7) | Yes |
| Authentication / Authorisation | Basic (possible WAF) | No | Yes - OAuth / JWT / API keys (main role) |
| Rate-limit / Quotas | Limited | No | Yes (main role) |
| Health checks | Rare | Yes (main role) | Common (through balancer) |
| Transformation / aggregation | No | No | Yes - REST↔gRPC, combining several services |
| Typical tools | Nginx, Apache, HAPRoxy, Envoy | HAPRoxy, Nginx, AWS NLB/ALB, F5 | Kong, Apigee, AWS API Gateway, Azure APIM, Tyk |
What sits in front of the API
Headers show which layer answers and whether it reveals too much.
Headers and route
-
`Server` and `X-Powered-By` should not reveal a version.
curl -sI https://api.example.com/v1/items -
A request to one specific server behind the balancer.
curl -sv --resolve api.example.com:443:<IP> https://api.example.com/health -
A forged header must not bypass the IP limit.
curl -s -H 'X-Forwarded-For: 203.0.113.9' -o /dev/null -w '%{http_code}\n' https://api.example.com/v1/items
Reverse proxy
Basic Concept - a server in front of a client that transfers requests to backend. Provides cover-up of TLS terms, caches, compressions and topology. The other two are its specialization.
Load balance
Reverse proxy that specializes in traffic distribution (round-robin, lower-connections) and accessibility - with health checks and sticky sessions.
API Gate
Reverse proxy, which specializes in API management: authentication, rate-limit, versioning, transformation, aggregation and observation. It usually also includes load balancing.
In practice
Typical order: client → DNS/CDN → load balance → API gateway → microservices. Borders overlap and one tool often performs several roles.
Good practice, RFC 9457, OpenAPI 3.1
Versioning, limits, errors and description of the contract
Versioning
URL (v1/...), header or media type. The compatibility of existing versions must not be broken - a new version must be added.
Pagination
Large lists are divided into pages by offset/limit or cursor method. The maximum leaf size should always be limited.
Rate limiting
Speed limitation of requests by reply 429 Too Many Requests and Retry-After header. Protects against overload and abuse.
Idempotency-Key
Idempotency-Key header for POST calls prevents duplicates if the request is repeated after a network failure.
Uniform error format
RFC 9457 Problem Details - machine-readable JSON error structure (type, title, status, detail).
OpenAPI 3.1
Machine-readable API agreement - generates documentation, customer code and validation. A common source of truth for the interface.
Error response - RFC 9457 Problem Details
HTTP/1.1 429 Too Many Requests Content-Type: application/problem+json Retry-After: 30 { "type": "https://api.piemers.lv/kludas/rate-limit", "title": "Pārāk daudz pieprasījumu", "status": 429, "detail": "Limits 100 pieprasījumi minūtē ir pārsniegts.", "instance": "/v1/lietotaji" }
Contract and error checks
An OpenAPI description lets you test the API against its own contract.
Contract
-
Checks the OpenAPI description.
spectral lint openapi.yaml -
Schemathesis generates tests from the contract.
st run openapi.yaml --url https://<testa-vide> -
ZAP security scan based on the OpenAPI description.
docker run -t ghcr.io/zaproxy/zaproxy:stable zap-api-scan.py -t https://<testa-vide>/openapi.json -f openapi
Errors and retries
-
`application/problem+json` expected for errors.
curl -si https://api.example.com/v1/nav-tada | grep -i content-type -
Shows how many requests remain.
curl -si https://api.example.com/v1/items | grep -iE 'ratelimit|retry-after' -
Repeating with the same key must not create a second record.
curl -i -X POST https://api.example.com/v1/payments -H 'Idempotency-Key: 1f3a' -d @maksajums.json
References
International standards and specifications
Relationship to the NIS2
Safe development and testing of APIs shall comply with the requirements of Article 21 (2) (e) of the NIS2 (EU 2022/2555) on security in procurement, development and maintenance.
DGPR
Only necessary (data minimisation) should be disclosed in the reply - excessive disclosure of data (OWASP API3) is also a breach of personal data protection.
Reservation
The material is an educational overview, not a full text of standards. Specific implementation should always be considered as an official source.
Abbreviations
Abbreviations used in the Roadmap: the original name and what it means.
- API
- Application Programming Interface - agreeing how programmes exchange data.
- REST
- Representational State Transfer - API style where resources are addressed by URLs and actions are expressed by HTTP methods.
- HTTP
- Hypertext Transfer Protocol - the web request and response protocol.
- JSON
- JavaScript Object Notation - text format for data exchange.
- HATEOAS
- Hypermedia as the Engine of Application State - the answer contains links to future possible actions.
- GraphQL
- Query language in which the client himself indicates which fields you need.
- gRPC / RPC
- Remote Procedure Call - remote calling; gRPC - Google's fast binary option.
- SOAP / WSDL
- Simple Object Access Protocol / Web Services Description Language - older XML API protocol and description of its contract.
- OAuth 2.0
- Standard how an application receives permission to access data on behalf of a user without knowing his password.
- OIDC
- OpenID Connect - an OAuth 2.0 supplement that also tells who the user is.
- PKCE
- Proof Key for Code Exchange - protection against intercepting the authorization code.
- JWT
- JSON Web Token - signed a token with user and rights data.
- mTLS
- mutual TLS - the connection in which both the client and the server present the certificate.
- BOLA
- Broken Object Level Authorization - user accessing a foreign object by replacing an identifier (OWASP API1).
- BOPLA
- Broken Object Property Level Authorization - the answer reveals or allows changes in fields that are not due to the user (API3).
- BFLA
- Broken Function Level Authorization - normal user calls administrator function (API5).
- SSRF
- Server-Side Request Forgery - the attacker makes the server call his address, including the internal network (API7).
- CORS
- Cross-Origin Resource Sharing - the rules from which the browser may call APIs.
- DoS
- Denial of Service - service failure - system overload until it no longer responds.
- WAF
- Web Application Firewall - a firewall that filters attacks on web applications.
- CDN
- Content Delivery Network - a network of servers supplying content from the nearest user location.
- LB / ALB / NLB
- Load Balancer / Application / Network Load Balancer - load balance; ALB works with HTTP, NLB with TCP.
- TLS
- Transport Layer Security - encrypted network connection.
- ETag
- Entity Tag - the symbol of the response version - allows the cache and does not send unchanged content.
- OpenAPI / OAS
- OpenAPI Specification - machine-readable API description from which documentation and clients are generated.
- RFC
- Request for Comments - internet standard document series (e.g. RFC 9110 - HTTP).
- OWASP
- Open Worldwide Application Security Project - a non-profit-making community that publishes app safety guidelines and Top 10.
- SPA
- Single-Page Application - a web application running on a single page and collecting data from APIs.