Documentation Index
Fetch the complete documentation index at: https://docs.dottxt.ai/llms.txt
Use this file to discover all available pages before exploring further.
TypeBox is a TypeScript library where types are JSON Schema objects. No export step is needed; the schema you write is the schema you send.
Install
npm install @sinclair/typebox ai @ai-sdk/openai
Basic usage
TypeBox types produce JSON Schema directly. Pass them to the Vercel AI SDK’s jsonSchema() wrapper to use with dottxt:
import { Type, Static } from "@sinclair/typebox";
import { createOpenAI } from "@ai-sdk/openai";
import { generateObject, jsonSchema } from "ai";
const Contact = Type.Object({
name: Type.String(),
email: Type.String(),
role: Type.String(),
}, { additionalProperties: false });
type Contact = Static<typeof Contact>;
const dottxt = createOpenAI({
baseURL: "https://api.dottxt.ai/v1",
apiKey: process.env.DOTTXT_API_KEY!,
});
const { object } = await generateObject({
model: dottxt.chat("openai/gpt-oss-20b"),
schema: jsonSchema<Contact>(Contact),
schemaName: "contact",
prompt: "Extract: John Smith <john@acme.com>, VP Engineering",
});
console.log(object.name);
Adding constraints
TypeBox methods map directly to JSON Schema keywords:
const UserProfile = Type.Object({
username: Type.String({ minLength: 3, maxLength: 20, pattern: "^[a-z0-9_]+$" }),
bio: Type.String({ maxLength: 200 }),
role: Type.Union([
Type.Literal("admin"),
Type.Literal("editor"),
Type.Literal("viewer"),
]),
}, { additionalProperties: false });
Optional and nullable fields
const Lead = Type.Object({
name: Type.String(),
email: Type.String(),
company: Type.Optional(Type.Union([Type.String(), Type.Null()])),
phone: Type.Optional(Type.Union([Type.String(), Type.Null()])),
}, { additionalProperties: false });
Type.Optional() removes the field from required. Type.Union([Type.String(), Type.Null()]) allows null.
Arrays
const Survey = Type.Object({
question: Type.String(),
options: Type.Array(Type.String(), { minItems: 2, maxItems: 6 }),
tags: Type.Array(Type.String(), { maxItems: 5 }),
}, { additionalProperties: false });
Nested objects
const Address = Type.Object({
street: Type.String(),
city: Type.String(),
country: Type.String(),
}, { additionalProperties: false });
const Customer = Type.Object({
name: Type.String(),
billing_address: Address,
shipping_address: Address,
}, { additionalProperties: false });
Type mapping
| TypeBox | JSON Schema | TypeScript |
|---|
Type.String() | {"type": "string"} | string |
Type.Number() | {"type": "number"} | number |
Type.Integer() | {"type": "integer"} | number |
Type.Boolean() | {"type": "boolean"} | boolean |
Type.Null() | {"type": "null"} | null |
Type.Array(T) | {"type": "array", "items": T} | T[] |
Type.Literal("x") | {"const": "x"} | "x" |
Type.Union([A, B]) | {"anyOf": [A, B]} | A | B |
Type.Optional(T) | removes from required | T | undefined |
Type.Object({...}) | {"type": "object", ...} | {...} |
Notes
- Pass
{ additionalProperties: false } as the second argument to Type.Object() when you want strict object schemas. TypeBox does not set this by default, so omit it only when you intentionally want an open object.
- TypeBox types are plain objects, so
JSON.stringify(Contact) gives you the JSON Schema directly.
Static<typeof Schema> extracts the TypeScript type from a TypeBox schema, giving you type safety on both ends.
Next steps