BuildStrict tool arguments

Strict tool arguments

⚠️
Preview — this feature is being built; the design below is the spec.

Without strict mode, the model usually writes tool arguments that match your schema, but not always: a field can be missing, a number can arrive as a string, an extra key can appear. With function.strict: true, Syntic guarantees that the arguments string parses as JSON and matches the schema exactly, so your code can use it without defensive checks for shape (you still check the values).

When to use it

  • Tools that write data or take actions, where a wrong shape is costly.
  • Pipelines where tool arguments feed straight into typed code.
  • Forcing structured output through a single tool with tool_choice.

Strict mode uses the same validator as JSON output with json_schema.

Endpoint and auth

POST https://app.syntic.ai/v1/chat/completions (and Messages), Authorization: Bearer sk_live_....

Request field

FieldTypeDefaultDetails
tools[].function.strictbooleanfalseGuarantee that arguments match parameters.

Schema rules in strict mode

The schema must follow the supported subset, plus:

  • Every object sets "additionalProperties": false.
  • Every property is listed in required. Make a value optional with a union that includes null: "type": ["string", "null"].
  • The root is an object.

A schema that breaks these rules returns 400 schema_not_strict before the model runs, so mistakes show up during development, not in production.

How it is enforced

  1. Where the model supports constrained generation, arguments can only follow the schema.
  2. Otherwise Syntic validates the finished arguments. On a mismatch it asks the model to correct them once (billed).
  3. If they still do not match, the request fails with 422 tool_arguments_invalid. Arguments that do not match are never returned to you.

Response

Unchanged from normal tool calling: function.arguments is a JSON string. In strict mode it is guaranteed to parse and validate.

Examples

curl https://app.syntic.ai/v1/chat/completions \
  -H "Authorization: Bearer $SYNTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Amara S1.2",
    "stream": false,
    "tools": [{
      "type": "function",
      "function": {
        "name": "create_refund",
        "description": "Refund part or all of an order.",
        "strict": true,
        "parameters": {
          "type": "object",
          "properties": {
            "order_number": { "type": "string", "pattern": "^[0-9]{6}$" },
            "amount_pence": { "type": "integer", "minimum": 1 },
            "reason": { "type": "string", "enum": ["damaged", "late", "wrong_item", "other"] },
            "note": { "type": ["string", "null"], "maxLength": 200 }
          },
          "required": ["order_number", "amount_pence", "reason", "note"],
          "additionalProperties": false
        }
      }
    }],
    "messages": [{ "role": "user", "content": "Order 582131 arrived crushed, please refund the £12.50 pot." }]
  }'

Errors

Unified envelope.

StatuscodeparamCause
400schema_not_stricttools[i].function.parameters...Missing additionalProperties: false or a required entry.
400invalid_tool_schematools[i].function.parametersUses an unsupported schema feature.
400strict_not_supportedmodelThe model does not support strict tools (capabilities.strict_tools).
422tool_arguments_invalidpath inside the argumentsStill invalid after one correction.
{
  "error": {
    "type": "invalid_request",
    "code": "tool_arguments_invalid",
    "message": "Arguments for create_refund did not match the schema: /amount_pence must be integer.",
    "param": "/amount_pence"
  },
  "request_id": "req_01JBXJ8"
}

Limits

Same as JSON output, counted per tool. Streaming works; in strict mode argument fragments are held back until the whole call has been validated, so the first fragment arrives a little later.

Build notes for the platform team

  • Build together with json_schema output: one validator, one schema cache.
  • Record the correction retry in usage and header x-syntic-schema-retries.
Was this page helpful?