JSON to Types

A webhook payload to TypeScript

Event envelopes usually nest the interesting data two levels down, and the type name should follow.

Input

{
  "id": "evt_123",
  "type": "invoice.paid",
  "created": 1735689600,
  "data": {
    "object": {
      "id": "in_456",
      "amountPaid": 2000,
      "currency": "usd"
    }
  }
}

An object with 2 nested shapes.

3 interfaces · 8 fields · 3 levels deep

Where this sample is ambiguous

  • Note

    Whole numbers are still `number`

    Every numeric value in the sample was a whole number, but JSON has a single number type and cannot express the difference. The output uses `number`.

    Fix: If a field is genuinely an integer, tighten it by hand: `z.number().int()`.

TypeScript

export interface Root {
  id: string;
  type: string;
  created: number;
  data: Data;
}

export interface Data {
  object: Object;
}

export interface Object {
  id: string;
  amountPaid: number;
  currency: string;
}

Zod

import { z } from 'zod';

export const ObjectSchema = z.object({
  id: z.string(),
  amountPaid: z.number(),
  currency: z.string(),
});

export const DataSchema = z.object({
  object: ObjectSchema,
});

export const RootSchema = z.object({
  id: z.string(),
  type: z.string(),
  created: z.number(),
  data: DataSchema,
});

Convert your own JSON

Paste a sample on the home page, or call the API or MCP server. This page is also available as markdown.

Related examples