ConceptsApril 5, 2026 · 5 min read

API Contract Testing: Your OpenAPI Spec as a Living Test Suite

Functional API tests verify that your endpoints return the right data. Contract tests verify that they return data in the right shape. You need both — and they're not the same thing.

Here's a scenario that happens all the time: a backend engineer changes a field name in an API response — say, user_id becomes userId — or changes a field from required to optional. The functional tests still pass because the test data still works. But the frontend breaks at runtime because it was expecting the old field name.

This is the gap that API contract testing fills.

Functional testing vs contract testing

Functional tests verify behaviour: "does POST /bookings return 201 and create a booking?" They check status codes, business logic, and data values. VigilQA's REST & GraphQL module handles these.

Contract tests verify the shape of responses against a specification: "does the response body match the schema defined in our OpenAPI spec?" They catch breaking changes — added required fields, changed types, removed properties, renamed fields — that functional tests miss because those tests don't validate schema structure.

How VigilQA's API Contract module works

Point VigilQA at your OpenAPI 3.x spec and your running API. For every endpoint defined in the spec, the contract module sends a real request and validates the actual response against the schema:

  • Status code matches the spec's defined responses
  • Response body structure matches the schema (required fields present, types correct, no undocumented additional properties if additionalProperties: false)
  • Response headers match spec definitions
  • Error responses (4xx, 5xx) match their defined schemas

What it catches in practice

The most common contract violations we see in real-world runs:

  • A field defined as string in the spec returning null in production
  • A required field missing from some responses (conditional logic that skips the field)
  • An endpoint returning a 200 with an error message body instead of the documented 4xx
  • A date field returning an ISO string in dev but a Unix timestamp in staging

Keeping spec and reality in sync

The contract test suite is only as good as your OpenAPI spec. If the spec is out of date, the tests aren't catching real drift — they're validating against a lie. The best practice is to treat the spec as the source of truth, run contract tests in CI on every merge, and fail builds on schema violations. That creates the feedback loop that keeps the spec accurate.