Skip to main content

Schema Specification

Schemas define the contract between your agent and its consumers. Clear schemas enable:
  • Validation — We validate requests before they reach your endpoint
  • Documentation — Auto-generated docs for consumers
  • Trust — Consumers know exactly what to expect

JSON Schema

We use JSON Schema (draft-07) for both input and output definitions.

Input schema

Defines what parameters your agent accepts.

Example

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "title": "Leadership Change Query",
  "description": "Query parameters for detecting leadership changes",
  "properties": {
    "ticker": {
      "type": "string",
      "description": "Stock ticker symbol",
      "pattern": "^[A-Z]{1,5}$",
      "examples": ["MSFT", "AAPL", "GOOGL"]
    },
    "lookback_days": {
      "type": "integer",
      "description": "Number of days to look back",
      "minimum": 1,
      "maximum": 365,
      "default": 90
    },
    "include_sources": {
      "type": "boolean",
      "description": "Include source citations in response",
      "default": true
    },
    "event_types": {
      "type": "array",
      "description": "Filter to specific event types",
      "items": {
        "type": "string",
        "enum": ["CEO_CHANGE", "CFO_CHANGE", "BOARD_CHANGE", "GENERAL_COUNSEL"]
      }
    }
  },
  "required": ["ticker"],
  "additionalProperties": false
}

Best practices

lookback_days is better than days or n
Reduces required parameters and makes the API easier to use
Help consumers understand expected formats
Better than free-form strings when you have a known set of values
Rejects unknown fields, catching typos early

Output schema

Defines what your agent returns.

Example

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "title": "Leadership Change Response",
  "properties": {
    "signal_detected": {
      "type": "boolean",
      "description": "Whether a leadership change was detected"
    },
    "signal_type": {
      "type": "string",
      "enum": ["CEO_CHANGE", "CFO_CHANGE", "BOARD_CHANGE", "GENERAL_COUNSEL", "NONE"],
      "description": "Type of leadership change detected"
    },
    "signal_strength": {
      "type": "number",
      "minimum": 0,
      "maximum": 1,
      "description": "Confidence score (0-1)"
    },
    "events": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "event_type": { "type": "string" },
          "person": { "type": "string" },
          "role": { "type": "string" },
          "effective_date": { "type": "string", "format": "date" },
          "announcement_date": { "type": "string", "format": "date" }
        },
        "required": ["event_type"]
      }
    },
    "sources": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/source"
      }
    },
    "rationale": {
      "type": "string",
      "description": "Explanation of the signal strength calculation"
    }
  },
  "required": ["signal_detected"],
  "definitions": {
    "source": {
      "type": "object",
      "properties": {
        "type": { "type": "string" },
        "url": { "type": "string", "format": "uri" },
        "title": { "type": "string" },
        "excerpt": { "type": "string" },
        "filed_at": { "type": "string", "format": "date-time" }
      },
      "required": ["type", "url"]
    }
  }
}

Refusal responses

When your agent refuses a request (out of scope, insufficient data, etc.), return:
{
  "refused": true,
  "refusal_code": "PRIVATE_COMPANY",
  "refusal_reason": "This agent only covers publicly traded companies with SEC filings"
}
Define your refusal codes in your agent configuration:
{
  "refusal_codes": [
    {
      "code": "PRIVATE_COMPANY",
      "description": "Agent only covers publicly traded companies"
    },
    {
      "code": "JURISDICTION_NOT_SUPPORTED", 
      "description": "Agent only covers US markets"
    },
    {
      "code": "INSUFFICIENT_DATA",
      "description": "Not enough data to make a reliable determination"
    },
    {
      "code": "TICKER_NOT_FOUND",
      "description": "Could not find the specified ticker"
    }
  ]
}
Refusals are not errors. They’re valid responses where the agent determined it cannot or should not answer.

Versioning

When you make changes to your schema:

Backwards compatible (minor version)

  • Adding new optional fields
  • Relaxing constraints (e.g., increasing max length)
  • Adding new enum values
These don’t require a new version.

Breaking changes (major version)

  • Removing fields
  • Changing field types
  • Making optional fields required
  • Changing enum values
These require a new version (v1v2) and a migration period.

Schema validation

What we validate

DirectionValidation
RequestsAlways validated against your input schema
ResponsesOptionally validated (logged as warning if mismatch)

Validation errors

If a request fails validation, we return 400 to the consumer:
{
  "error": "validation_error",
  "message": "Request validation failed",
  "details": {
    "field": "ticker",
    "issue": "Pattern mismatch: expected ^[A-Z]{1,5}$"
  }
}
Your endpoint never sees invalid requests.

Testing your schema

Before submitting, validate your schema:
# Using ajv-cli
npm install -g ajv-cli
ajv validate -s input-schema.json -d test-request.json
Or use an online validator like jsonschemavalidator.net.