Skip to content

Getting started ​

Install ​

bash
npm install @klappay/types zod

zod is a peer expectation, not bundled — every schema exported here is a zod schema, so if you already depend on any of them directly you already have it.

What this package actually is ​

Two things, exported side by side for every resource:

  • A Zod schema (ChargeSchema, CreateChargeSchema, WebhookPayloadSchema, ...) — use it to validate data at runtime, not just to satisfy the type checker.
  • An inferred TypeScript type for the same shape (Charge, CreateChargeInput, ...), exported alongside its schema.

Both come from the same source — the schema is the source of truth, the type is z.infer<typeof Schema> on top of it. There is no separate hand-written type anywhere in this package that could drift from its schema.

A request-body/query schema that has a default or transform (e.g. CreateChargeSchema.mode, ListChargesSchema.limit) also exports a *Request type — z.input<typeof Schema> instead of z.infer, i.e. the shape before Zod applies defaults/transforms. Use the *Input type for a value you already parsed (every field a default fills in is guaranteed present); use *Request for a value you're building to send (those same fields are optional, since the schema fills them in for you). CreateChargeInput/CreateChargeRequest, ListChargesInput/ListChargesRequest, and their equivalents on every other list endpoint are the concrete examples.

This package has no HTTP client, no fetch, no networking of any kind — it only describes shapes. If you want a client that actually calls the API for you (with typed errors, retries, real-time polling helpers), an official SDK is built on top of this package — available at github.com/klappay; see the live API reference for details. Use @klappay/types directly when you're calling the API yourself (a different language's types, a codegen step, validating a webhook payload in a framework the SDK doesn't fit) and just want the contracts.

Typing an API response ​

ts
import type { Charge } from '@klappay/types'

async function getCharge(id: string): Promise<Charge> {
  const res = await fetch(`${API_BASE_URL}/v1/charges/${id}`, {
    headers: { Authorization: `Bearer ${process.env.KLAP_API_KEY}` },
  })
  return res.json()
}

Validating a response or webhook payload at runtime ​

A type only helps at compile time — it says nothing about what actually came back over the wire. Parse anything you don't fully control through its schema:

ts
import { WebhookPayloadSchema } from '@klappay/types'

app.post('/webhooks/klap', (req, res) => {
  const payload = WebhookPayloadSchema.parse(req.body)
  // payload.data is `unknown` here — this schema only validates the
  // envelope (id/event/createdAt). See webhooks.md for how to narrow
  // `data` per event with TypedWebhookPayload.
  res.sendStatus(200)
})

This package only validates shape — it never verifies the X-Klappay-Signature HMAC header on a webhook request. Do that yourself (or use an official SDK's constructEvent(), which does both at once — available at github.com/klappay, see the live API reference for details) before trusting the payload came from Klappay.

Finding the type you need ​

Every exported schema/type lives in exactly one topic file below — if you're not sure where something is, it's one of these:

DocCovers
charges.mdCharge, CreateChargeInput, ListChargesInput, PaginatedCharges, ChargeStatusEvent, plus the read-only TimelineEvent view. Also covers the shared PaginationQuerySchema/paginatedSchema() primitives every list endpoint is built from
webhooks.mdEvery WebhookEventType, category grouping, CreateWebhookInput, Webhook, WebhookPayload, TypedWebhookPayload, WebhookDelivery
sandbox.mdSandboxTriggerInput, TriggerableChargeEvent
tokens-and-networks.mdToken, Network, TOKEN_ADDRESSES, EVM_NETWORKS, and every other chain/token constant
errors-and-health.mdErrorPayload (every non-2xx response shape) and Health

Where to go next ​

Read this package's own README.md first if you haven't — it covers install and the two usage patterns (typing vs. runtime validation) at a glance. This docs/ folder is for finding a specific schema quickly once you already know roughly what you're looking for.

For LLMs and agents ​

This site (built from these same files with VitePress) publishes llms.txt — a link index of every doc page — and llms-full.txt — the full content of every doc page concatenated into one plain-text file. Point an agent, RAG pipeline, or MCP server at either as a lightweight way to give it this package's whole documentation without scraping HTML. Both regenerate on every deploy, so they never drift from what's on this page. The live API itself is separately machine- readable too — /v1/openapi.json is the same OpenAPI document the Scalar reference renders.

Every link above is deliberately relative, not a hardcoded api.klappay.com URL — this same file is served on more than one domain (production and stage), and a relative link resolves against whichever one the page is actually being viewed on. [text](/llms.txt)-style markdown links get VitePress's own base (/types/) prepended automatically, which is what's wanted for llms.txt/llms-full.txt (they live under /types/) — but /v1/openapi.json does not live under /types/, so it's a raw HTML <a> tag instead, specifically to bypass that automatic prepending (markdown link syntax has no way to opt out of it). llms.txt/ llms-full.txt's own generated internal links are the one place an absolute domain is unavoidable (an agent that only fetched the raw text file has no page origin to resolve a relative link against) — that one comes from PUBLIC_URL at Docker build time, see docs-types/.vitepress/config.mts and docs/operations.md.

Public docs for @klappay/types, mirrored from this package's own docs/ folder.