API Examples, Schemas, and Useful Error Documentation

Write API examples, schemas, and error docs that help developers send valid requests, handle failures, and understand exactly what a response means.

published: reading time: 10 min read author: GeekWorkBench
Quick Summary

Useful API docs connect field rules to examples clients can actually send. This guide shows how request and response samples, a machine-readable schema, and stable error codes work together, including nullability, validation failures, and retry guidance. It also covers CI checks that catch drift, safe telemetry, access controls, and ownership. Readers can use these practices to make an API easier to integrate and safer to operate.

API Examples, Schemas, and Useful Error Documentation

Introduction

A schema tells a client what a payload can contain. An example shows what a realistic payload looks like. Error documentation explains what to do when a request fails. When these are vague, developers guess, and guesses become support tickets or brittle client code.

Good API docs make edge cases visible. A field may be optional but non-null when present; a timestamp may require UTC; a failure may return a stable code while the message changes. The goal is to explain behavior a consumer can rely on, not every internal detail.

For every field, state its type, whether it is required, its range or format, and its meaning. Clarify omitted versus null, empty versus absent, and whether unknown properties are rejected or ignored. Make constraints match runtime validation rather than aspirations.

Give clients examples they can adapt

Here is a small contract for creating an invoice. The request, response, and validation error use matching field names so a client can see how the pieces fit. The values are synthetic; the service should enforce the same constraints at runtime.

Request:

{
  "customerId": "cus_demo_42",
  "currency": "USD",
  "lines": [{ "sku": "desk-lamp", "quantity": 2 }]
}

Success response (201 Created):

{
  "id": "inv_demo_202",
  "status": "draft",
  "currency": "USD",
  "totalMinor": 12998
}

Validation error (422 Unprocessable Content):

{
  "type": "https://api.example.test/problems/invalid-request",
  "title": "Request validation failed",
  "status": 422,
  "code": "invalid_request",
  "requestId": "req_demo_7f3a",
  "errors": [{ "field": "lines[0].quantity", "code": "must_be_positive" }]
}

A request schema can make the accepted shape and limits machine-readable:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["customerId", "currency", "lines"],
  "additionalProperties": false,
  "properties": {
    "customerId": { "type": "string", "minLength": 1 },
    "currency": { "type": "string", "enum": ["USD"] },
    "lines": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["sku", "quantity"],
        "additionalProperties": false,
        "properties": {
          "sku": { "type": "string", "minLength": 1 },
          "quantity": { "type": "integer", "minimum": 1, "maximum": 100 }
        }
      }
    }
  }
}

Make errors predictable

HTTP status communicates the broad result. A structured body can provide a stable machine-readable code and enough safe detail to correct the request. A validation response might identify a field and reason without echoing a submitted secret. Document retry behavior: a client should not retry an invalid request forever, while a transient server error may be retried with backoff.

Use 401 for absent or invalid credentials and 403 when a known caller lacks permission, unless a documented 404 policy conceals protected resources. Explain rate-limit responses and retry hints. Never expose stack traces, SQL details, internal hostnames, or policy internals.

A response may distinguish omitted and null values, especially for PATCH: omission can mean “leave unchanged” while null can mean “clear this value.” State those semantics, because a type declaration alone will not teach consumers how an update behaves. See the OpenAPI guide for expressing these contracts.

When to use this approach

Apply the practices above whenever an API has external consumers, sensitive data, or more than one independently deployed caller. Keep the mechanism proportionate: a small internal operation may need a concise contract, while a public or high-impact endpoint deserves explicit lifecycle, access, and failure behavior. Avoid adding process that no one will maintain; focus on decisions a consumer or operator must make.

Operational flow

flowchart TD
  A[Client sends request] --> B[Validate contract and identity]
  B --> C[Check permission and policy]
  C -->|Allowed| D[Process and return documented result]
  C -->|Denied| E[Return safe error]
  D --> F[Record outcome without secrets]

Implementation practice

Put the decision close to the boundary that owns it. Keep parsing, policy checks, and side effects visible in code review. A useful change includes an example request and response, a test for the expected path, and a test for a failure path. Keep external examples free of production data. Document behavior that clients need, while retaining private diagnostic detail in access-controlled logs.

Keep examples aligned with schemas

Treat examples as fixtures that can be checked, not prose snippets that are only reviewed by eye. In CI, validate request and response examples against the published schemas, then run focused tests against the implementation for valid input, boundary values, and representative invalid input. A schema check catches shape mismatches; runtime tests catch behavior the schema cannot express, such as whether a caller is authorized or a state transition is allowed.

Include at least one ordinary success example and the failure examples clients need to handle. Check that examples use synthetic identifiers and values, and that status codes, media types, field constraints, and error codes agree with the implementation. If a field is nullable, required, or constrained to an enum, make those semantics clear in both the schema and the examples.

Production failure scenarios and mitigations

  • The implementation diverges from its contract. Validate examples and run compatibility checks in CI; publish artifacts from the reviewed source.
  • A client receives an unexpected denial or error. Use stable error codes, request IDs, and clear migration or retry guidance.
  • A credential or sensitive field leaks through telemetry. Redact at ingress and application layers, restrict log access, and rotate exposed secrets.
  • A seemingly valid request causes a resource or access problem. Enforce limits and resource-specific policy, then test boundary and denied cases.

Trade-off Analysis

Choice Benefit Cost
Strict contract and validation Clear behavior and earlier mistakes caught Changes require compatibility review
Flexible behavior Easier incremental rollout Consumers may depend on undocumented behavior
Centralized policy Consistent enforcement Needs clear ownership and good domain context
Detailed telemetry Faster diagnosis Requires redaction and retention controls

Observability checklist

  • Track request volume, latency, status codes, and stable error categories by operation.
  • Correlate failures with a request ID while keeping secrets out of logs.
  • Monitor adoption, denial, validation, and retry trends relevant to this feature.
  • Alert on anomalies and review dashboards after releases.

Security and Compliance Notes

Treat examples, schemas, and error responses as published interfaces. Use synthetic values in public examples, classify fields that can contain personal or regulated data, and document which fields are collected and why. Apply authorization and validation on the server even when the schema marks a field read-only or restricted. Redact sensitive values from errors and logs, and set retention and access controls for diagnostic data to match applicable policy. If a contract changes how personal data is collected or exposed, involve the privacy or compliance owner before release.

Security notes and pitfalls

Use TLS and least privilege. Do not trust client-supplied identity, ownership, or permission claims without verification. Keep credentials and sensitive payloads out of URLs, examples, analytics, and error messages. Apply the same server-side rules to alternate routes and batch operations. Watch for stale documentation, overly broad access, silent coercion, and tests that cover only successful requests.

Recap checklist

  • Describe behavior clients can rely on and validate it in review or CI.
  • Cover the normal path and failure behavior with practical examples.
  • Check access and resource limits at the server boundary.
  • Keep telemetry useful while removing sensitive values.
  • Assign an owner for changes, incidents, and follow-up.

Quick Recap Checklist

  • Provide realistic examples for common success and failure cases.
  • Define field types, required values, constraints, and nullability.
  • Give errors stable codes and a predictable response shape.
  • Keep secrets and private data out of examples and error messages.

Interview Questions

1. Why should an API make this behavior explicit?

Explicit behavior lets consumers implement against a stable expectation and gives maintainers something concrete to review and test. Hidden assumptions tend to become production failures.

2. What is a useful failure test?

Test a realistic invalid, expired, unauthorized, or incompatible request and assert the status, stable error shape, and absence of sensitive data. The exact case depends on the API concern this article covers.

3. What should operators observe after a release?

Track request outcomes, latency, errors, adoption, and security-relevant denials for the changed operation. Use request IDs for diagnosis and keep credentials and private payloads out of telemetry.

4. How do required and nullable describe different field rules?

Required means the property must be present. Nullable means that a present property may contain null. A field can be optional but non-null when present, or required and nullable; document the intended combination.

5. Why might a schema format such as date-time need runtime validation too?

Tools may interpret or enforce format annotations differently. The service still needs to validate accepted values and apply business rules, such as requiring an explicit timezone.

6. How can a team keep published examples from drifting away from the API?

Store examples with the contract or tests, validate them against schemas in CI, and test representative examples against the implementation. Review changes to examples alongside changes to behavior.

7. Why keep an error code stable if the human-readable message can change?

Clients can branch on a stable code while messages are clarified, localized, or rewritten for users. Treating prose as a machine signal makes harmless copy edits risky.

8. What should a field-level validation error tell a client?

Identify the field and provide a stable reason code plus safe guidance the client can act on. Avoid echoing secrets or unrestricted input in the response.

9. How should API documentation describe enum fields as values evolve?

List supported values and explain whether clients should tolerate unknown values. Adding a value can break exhaustive client switches, so document compatibility expectations and test consumers that parse the enum.

Further Reading

Conclusion

Reliable API behavior depends on clear contracts and careful operations. Keep the choices visible to consumers, automate the checks that can catch drift, and make failures diagnosable without exposing sensitive information.

Category

Related Posts

API Request, Response, and Error Shapes Clients Can Trust

Design consistent API request and response envelopes, validation errors, and problem details so client developers can handle success and failure reliably.

#api-design #http #error-handling

Functions, Modules, and Error Handling

Learn to shape backend functions and modules, handle failures clearly, and build services that are easier to test, operate, and change.

#backend #typescript #code-organization

API Clients, Servers, and Network Boundaries Explained

Understand what API clients and servers each own, how network boundaries fail, and how timeouts, retries, and trust boundaries shape reliable integrations.

#api-design #networking #distributed-systems