Release candidate — 1.0.0-rc.7
StitchAPI
GuidesValidation & drift

Validation

Validate params, query, body, headers, and the response, failing fast before the request when input is wrong.

Use validation when you want a stitch to reject bad input before it leaves the process and to verify the response once it arrives — input is checked before the request, so wrong params, query, body, or headers fail fast with no network call.

Example

import {  } from 'stitchapi';
import {  } from 'zod';

const  = <{ : number; : string }>({
    : 'POST',
    : 'https://api.example.com',
    : '/users',
    : { : .({ : .() }) },
    : .({ : .(), : .() }),
});

A bad body rejects before the POST is sent; a response that doesn't match output rejects after. Either way the stitch throws STITCH_VALIDATION, and the stitch<T> generic keeps the resolved value typed as { id: number; name: string }.

Options

input is a map of { params, query, body, headers }, each an optional Validator. Every entry present is validated against the call input before the request — the fail-fast guarantee — so the request never goes out with input the API would reject.

A declared slot also shapes the request: the request is built from the value the schema returned, so whatever it coerces, defaults or strips is what goes on the wire. A z.object(...) strips unknown keys by default, so an extra key a caller tacked onto a declared slot never reaches the API — which matters most when the caller is untrusted, such as a model calling through the MCP surface.

A schema that transforms therefore reshapes the request. This is how a stitch maps your field names onto the API's — the call argument is typed from the schema's input side, so callers keep the house shape while the wire gets the API's. See Reshaping the request.

A schema constrains one slot. An undeclared slot stays a full passthrough, so declaring params does nothing about query. And a query pair written into the endpoint (?tenant=acme) is a default that input.query overrides — declare the slot if callers must not move it.

output is a single Validator that checks the response body after it returns. (Pass a drift() spec here instead to report changes without throwing — see Schema drift detection.)

Anti-pattern: don't reach for a strict output validator to catch upstream API changes — an additive, non-breaking change to the response then throws STITCH_VALIDATION and breaks the call. Pass a drift() spec to output instead, so changes are reported without failing the request. See Schema drift detection.

input and output accept the schema directly — a raw z.object(...), any Standard Schema validator (Valibot, ArkType), or a plain predicate. Each slot's type accepts the schema as written, and the engine adapts it internally, so there's no cast at the call site.

See Reference → Config types for every field on input and output.

See also

On this page