← Blog

Claude Tool Use JSON Schema Validation Guide

2026-10-27 · 5 min read · SubToAPI Team

When you give Claude a tool definition, it uses the JSON schema in that definition to decide what arguments to generate and how to structure them. "Claude tool use JSON schema validation" usually means one of two things: either you want to know how Claude validates the arguments it produces against your schema, or you're hitting errors because Claude returned arguments that don't match your schema and you need to fix it.

The short answer: Claude does not run a formal JSON Schema validator against its own output before sending it back to you. It uses the schema as a strong structural guide during generation, but the burden of validating the final tool call arguments against your schema is on your application code. This matters because malformed or incomplete arguments can slip through, especially with complex nested schemas, enums, or required fields that depend on other fields.

How tool use schemas actually work

When you call the Messages API with a tools array, each tool has a name, description, and an input_schema field written in standard JSON Schema (draft-07 style, using type, properties, required, enum, etc.). Claude reads this schema as part of the prompt context, not as a hard runtime constraint enforced by a separate validation engine. The model is trained to produce JSON that matches the schema shape, but it's still a generative process — not a guarantee.

A minimal tool definition looks like this:

{
  "name": "create_invoice",
  "description": "Create a new invoice for a customer",
  "input_schema": {
    "type": "object",
    "properties": {
      "customer_id": { "type": "string" },
      "amount_cents": { "type": "integer", "minimum": 1 },
      "currency": { "type": "string", "enum": ["USD", "EUR", "GBP"] },
      "due_date": { "type": "string", "format": "date" }
    },
    "required": ["customer_id", "amount_cents", "currency"]
  }
}

Claude will generally respect required fields and enum constraints well, because those are explicit, low-ambiguity instructions. Where things get fragile is with:

Why you still need a validator in your code

Because the model generates rather than validates, you should always run the tool call arguments through a real JSON Schema validator before executing any side effects (writing to a database, calling a payment API, sending an email). This is standard practice regardless of which LLM provider you use, and it protects you from:

In Node.js, a common pattern uses ajv:

import Ajv from "ajv";
const ajv = new Ajv();

const schema = {
  type: "object",
  properties: {
    customer_id: { type: "string" },
    amount_cents: { type: "integer", minimum: 1 },
    currency: { type: "string", enum: ["USD", "EUR", "GBP"] }
  },
  required: ["customer_id", "amount_cents", "currency"]
};

const validate = ajv.compile(schema);

function handleToolCall(toolInput) {
  if (!validate(toolInput)) {
    // Return a tool_result with an error so Claude can retry
    return { error: true, details: validate.errors };
  }
  // proceed with the validated input
}

If validation fails, the recommended pattern in the Claude API is to return a tool_result content block with an error message describing exactly what was wrong. Claude will typically self-correct on the next turn and resend corrected arguments, because it now has explicit feedback instead of guessing.

Practical tips for more reliable schema adherence

Where SubToAPI fits in

If you're already calling tool use through SubToAPI, the schema validation responsibility is the same — SubToAPI proxies your Messages API calls with your sub_live_... key and returns Claude's raw tool call output, including usage metadata, so you can run your own validation layer exactly as you would against the direct API. See the tool use docs for request and response shapes, and the messages docs for how tool results are returned in streaming and non-streaming modes. SubToAPI doesn't add a schema validator on top of Claude's output — that stays your responsibility — but it does give you clean, consistent JSON you can plug straight into ajv or your validator of choice without reformatting.

questions

Does Claude guarantee tool call arguments match my JSON schema exactly? No. Claude uses the schema as a strong guide during generation but doesn't run a separate validation pass on its own output. You should validate arguments yourself before executing any side effects.

What's the best way to handle a tool call that fails validation? Return a tool_result content block describing the validation error. Claude will typically read the error and resend corrected arguments on the next turn.

Which JSON Schema features does Claude respect most reliably? Flat required fields and enum constraints are the most consistently respected. Conditional logic (if/then), deep nesting, and format strings like date or email are weaker and should be double-checked in your own validator.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →