Schemas & types
What is schema inference?
Every time a webhook arrives at your endpoint, Splithook walks the JSON body recursively and updates an inferred schema for that (endpoint, event_type) pair. After a few events, you have a type-safe picture of exactly what the provider sends — without reading their docs.
What the schema records
For each field path (e.g. data.object.amount):
| Property | Description |
|---|---|
| Observed types | number, string, boolean, null, object, array |
| Sample values | Up to 3 representative values |
| Frequency | Fraction of events where this field was present |
| First seen | Timestamp of the first observation |
| Last seen | Timestamp of the most recent observation |
Fields present in every event get frequency 1.0. Optional fields (e.g. data.object.dispute) have lower frequencies and are marked as optional (?) in the TypeScript output.
Viewing schemas
Schemas (sidebar) → select an event type. You see the full field tree with types, samples, and frequencies.
Use the event type selector to switch between charge.failed, payment_intent.succeeded, etc. Each event type has its own independent schema.
Exporting TypeScript
Click Copy TypeScript from the schema view. Splithook generates a TypeScript interface from the inferred schema:
interface StripeChargeFailedEvent {
id: string;
object: 'event';
type: 'charge.failed';
livemode: boolean;
created: number;
data: {
object: {
id: string;
amount: number;
currency: string;
status: 'failed';
failure_code: string | null;
failure_message: string | null;
customer: string | null;
metadata: Record<string, string>;
};
};
}
Rules for the generated interface:
- Fields present in < 80% of observed events are marked optional (
?). - Fields observed with multiple types become union types (
string | null). - Nested objects are inlined (no
$ref). - Arrays are typed as
T[]whereTis inferred from the first non-null element seen.
Schema diff
The Diff tab in the endpoint view compares two schema snapshots side by side. This is useful for detecting breaking changes — a field that was always a string suddenly appearing as string | null is a signal your handler needs updating.
Select two events from the feed → Compare schemas.
Limitations
- Schema inference only works on valid JSON bodies. Non-JSON payloads (form-encoded, binary) are stored but not inferred.
- Very deeply nested objects (> 10 levels) are truncated at the schema level.
- The schema reflects observed reality — it's not a guarantee of what the provider can send, only what you've seen so far. Send more events to improve coverage.
Schema freshness
The schema is updated on every incoming webhook, not on a schedule. A newly created DocPage entity shows a "fresh" badge until it has been viewed at least once — the same concept applies to schemas that haven't received new data in > 7 days (shown with a stale badge).