Skip to main content

Overview

ViscribeAI validates parsed model output before returning result.data. The model is still asked for structured JSON through the provider request, but the SDK also checks the returned object locally. If the object does not match the requested schema, ViscribeAI raises StructuredOutputValidationError instead of returning invalid data. Validation runs after response parsing and before the result wrapper is created. Malformed JSON is still a parse error, model refusals are still refusal errors, and incomplete provider responses are still finish-reason errors. ViscribeAI also checks strict schemas before sending the request. If a schema is outside the OpenAI Structured Outputs subset, ViscribeAI raises StructuredOutputSchemaError with the schema path and a suggested fix.

Effective schema

ViscribeAI validates against the same effective schema it uses for structured output requests.
  • Simple fields are converted into an object JSON Schema.
  • JSON Schema inputs are validated as JSON Schema.
  • Python Pydantic model schemas are validated with Pydantic.
  • TypeScript Zod schemas are converted to JSON Schema for the model request and validated with Zod after parsing.
  • Strict mode is enabled by default.
Simple field definitions are intentionally strict: every field is required, values may be null, array fields are capped at five items, and additional properties are rejected. When you pass raw JSON Schema with strict mode enabled, ViscribeAI tightens object schemas by marking object properties as required and rejecting additional properties when the schema does not already specify that behavior. With strict=False in Python or strict: false in TypeScript, ViscribeAI validates against the JSON Schema you provided without that extra tightening. For TypeScript Zod schemas, strict mode follows the provider structured-output rule that object fields must be present. Use nullable fields such as z.string().nullish() when a value may be absent or empty.

Provider compatibility

With strict mode enabled, ViscribeAI accepts the OpenAI Structured Outputs subset:
  • root schemas must be objects
  • nested unions must use anyOf; root-level unions are rejected
  • every object property must be required
  • every object must use additionalProperties: false
  • arrays must define an items schema
  • unsupported composition such as allOf, oneOf, not, and conditional schemas is rejected
  • tuple arrays, pattern-based object keys, and uniqueness/member constraints are left to application validation
  • documented schema size limits are checked before the request is sent
Set strict=False in Python or strict: false in TypeScript only when you need to bypass this provider-compatibility check for a custom backend.

Python

Python supports Pydantic models, simple fields, and JSON Schema dictionaries.
Pydantic schemas are validated with model_validate. A successful result returns a Pydantic model instance.
from pydantic import BaseModel, Field
from viscribe import StructuredOutputSchemaError, StructuredOutputValidationError
from viscribe.images import extract


class Receipt(BaseModel):
    merchant_name: str | None = Field(description="Store or business name")
    total_amount: float | None = Field(description="Final receipt total")


try:
    result = extract(
        image_path="examples/receipt.png",
        output_schema=Receipt,
        instruction="Extract the visible receipt fields.",
    )
    print(result.data.model_dump())
except StructuredOutputSchemaError as error:
    print(f"Unsupported schema: {error}")
except StructuredOutputValidationError as error:
    print(f"Invalid extracted data: {error}")

TypeScript

TypeScript supports simple fields, JSON Schema objects, and Zod schemas. Simple fields and JSON Schema are validated with AJV. Zod schemas are validated with Zod, and a successful result returns Zod-parsed data.
import { z } from "zod/v4";
import { images, StructuredOutputSchemaError, StructuredOutputValidationError } from "viscribe";

const Receipt = z.object({
  merchant_name: z.string().nullish(),
  total_amount: z.number().nullish(),
});

try {
  const result = await images.extract({
    imagePath: "examples/receipt.png",
    outputSchema: Receipt,
    instruction: "Extract the visible receipt fields.",
  });

  console.log(result.data.merchant_name);
} catch (error) {
  if (error instanceof StructuredOutputSchemaError) {
    console.error("Unsupported schema:", error.message);
  }
  if (error instanceof StructuredOutputValidationError) {
    console.error("Invalid extracted data:", error.message);
  }
  throw error;
}

What validation catches

Validation catches schema mismatches such as:
  • missing required fields
  • values with the wrong type
  • array values that exceed simple field limits
  • extra object properties when strict mode rejects them
  • invalid data returned through SDK-compatible custom clients
Provider-compatibility checks catch schema issues such as:
  • root Zod unions or discriminated unions
  • raw JSON Schema with additionalProperties: true
  • unsupported composition such as allOf or oneOf
  • array schemas without items
Validation confirms that the output shape matches the schema. It cannot prove that every extracted value is factually correct, so high-stakes workflows should still include review, confidence fields, or downstream checks.