Skip to main content
Schemas are the contracts that tools return in OpenTools. They define the shape of data that flows between providers, tools, and models ensuring that the same tool behaves consistently regardless of where the data comes from. Instead of handling raw provider responses, OpenTools tools always return structured, validated schemas that your application and your model can rely on.

What is a schema?

A schema is a typed data model that represents the result of a tool call. Schemas describe what fields exist, which fields are optional, how values are formatted and what data is considered canonical (universal to those belonging to the domain). In OpenTools, schemas are defined using strongly typed models and validated at runtime. If a provider returns malformed or unexpected data, it fails early instead of silently leaking into your agent logic.

Why schemas exist

Providers rarely agree on how data should look. For example, some “accounts” across trading providers might use different field names or represent numbers as strings/floats. Others include inconsistent timestamps for different timezones or return extra metadata that is found nowhere else. Schemas exist to solve this by enforcing a canonical shape.Your agent logic cares about how that structure should look and it should not break so that you can incorporate many different providers in a plug and play fashion depending on user needs. So, put simply, an Account should look like an Account.

A quick example: Account

Every schema in OpenTools is built around a clear separation between canonical fields and provider fields. Data from APIs, as mentioned, is almost always expressed differently meaning it might not be as simple as fitting into a defined schema. Our canonical fields define the contract your application relies on. These provider_fields preserve raw metadata without polluting that contract that you may need. Here is a view of the schema:
class Account(TradingModel):
    provider: str | None
    id: str | None
    status: str | None
    currency: str | None
    cash: str | None
    buying_power: str | None
    equity: str | None
    created_at: datetime | None
    provider_fields: dict[str, Any]

Next steps