Start with a concrete request

Imagine a service that receives an order request with three fields: customerId, amountCents, and currency. A request containing an amount of "1250" is perfectly valid JSON. It is also a string, which our example contract deliberately rejects because the service expects an integer number of cents. The distinction belongs in the interface definition, before a database write or an external call happens.

JSON defines a data format, not the business meaning of a field. Its values include objects, arrays, strings, numbers, booleans, and null. An API contract adds requirements such as a top-level object, required fields, accepted currencies, and numerical bounds. Those requirements are choices made for the application.

{"customerId":"demo-customer","amountCents":1250,"currency":"USD"}

Make rejection useful

For this example, an empty customer identifier should produce a field-specific explanation. So should a fractional amount, an unknown currency, or an extra property. A useful error identifies what failed and what the contract expects; it should not require a caller to guess from a generic failure message.

The API Contract Lab on this site implements those choices as a small, inspectable function. It keeps parsing errors separate from contract errors, never silently converts strings into numbers, and rejects integers outside JavaScript's safe range. It is intentionally narrower than a general JSON Schema validator. That makes the example easy to understand and test.

Know what the example does not establish

A request that passes these checks has the expected shape. It does not prove that a customer exists, that the caller may place an order, or that a price is correct. A production service must apply authorization, resource limits, and domain rules on the server. Browser validation improves feedback; it cannot provide that enforcement.

The implementation uses the browser's JSON parser, so duplicate object keys are not independently reported. Keep the parser's behavior and numerical limitations in the documented contract. Tests should include malformed input, null, arrays, unexpected fields, unsafe numbers, and a known valid request. The most useful contract is one that callers can understand and maintainers can verify.

Explore the API Contract Lab ↗