Structured JSON (askJson)
Get typed, validated JSON from Claude in a single call. Available on both the client and sessions.
claude.askJson(prompt, schema, options?)
import { claude } from "@pivanov/claude-wire";
import { z } from "zod";
const schema = z.object({
sentiment: z.enum(["positive", "negative", "neutral"]),
confidence: z.number().min(0).max(1),
});
const { data, raw } = await claude.askJson(
"Analyze sentiment: 'This library is great!'",
schema,
);
console.log(data.sentiment); // "positive"
console.log(data.confidence); // 0.95
console.log(raw.costUsd); // 0.001session.askJson(prompt, schema, options?)
Same API, but within a persistent session:
const session = claude.session({ model: "sonnet" });
const { data } = await session.askJson(
"List the exports of src/index.ts as JSON",
z.object({ exports: z.array(z.string()) }),
);
console.log(data.exports);
await session.close();Schema Input
askJson accepts two kinds of schema:
Standard Schema objects (recommended)
Any object that implements the Standard Schema protocol -- Zod, Valibot, ArkType, and others. Provides full TypeScript inference and runtime validation.
import { z } from "zod";
// Zod
const { data } = await claude.askJson("...", z.object({ name: z.string() }));
// ^? { name: string }Raw JSON Schema strings
A JSON Schema string forwarded to Claude Code via --json-schema. The CLI constrains the model output to match the schema. No runtime validation is performed SDK-side -- the model's compliance is trusted.
const schema = JSON.stringify({
type: "object",
properties: { name: { type: "string" } },
required: ["name"],
});
const { data } = await claude.askJson<{ name: string }>("...", schema);Return Type
interface IJsonResult<T> {
data: T; // parsed and validated result
raw: TAskResult; // full result with text, cost, tokens, events
}Error Handling
Throws JsonValidationError when parsing or validation fails:
import { JsonValidationError } from "@pivanov/claude-wire";
try {
const { data } = await claude.askJson("...", schema);
} catch (error) {
if (error instanceof JsonValidationError) {
console.error("Raw response:", error.rawText);
console.error("Issues:", error.issues);
// issues: [{ message: "Expected string, received number", path: ["name"] }]
}
}JsonValidationError properties:
rawText: string-- the raw text that failed to parse or validateissues: ReadonlyArray<{ message?: string; path?: ReadonlyArray<string | number> }>-- structured validation issues
Fence Stripping
Claude sometimes wraps JSON in markdown fences (```json ... ```). askJson automatically strips these before parsing, so you don't need to handle that case.
Options
askJson accepts all the same options as ask() -- model, cwd, maxCostUsd, signal, etc. See Client options.