Types
Every request and response is a Pydantic model generated from the OpenAPI spec. Models tolerate new server fields instead of rejecting them.
Requests and responses are Pydantic v2 models in ellipsis.models, generated from the same OpenAPI spec the API reference is built from. Your editor and mypy see the real field names and types.
from ellipsis import models
def summarize(session: models.Session) -> str:
return f"{session.id} {session.status}"Responses are envelopes
A response model wraps the resource rather than being it. sessions.get() returns a SessionResponse whose session is the Session:
response = client.sessions.get("session_7Hq2mX4p")
session = response.session
print(session.status)The session handle unwraps this for you: handle.session is already a Session. Each operation's exact response model is named on its API reference page.
New server fields do not break you
Every generated model allows extra fields. A response carrying a field this version of the SDK has never heard of parses cleanly, and the unknown field is reachable on the model. Additive server changes are not a version break, so an SDK that rejected them would break on a routine release.
The same rule applies to enum-like values. Fields that are open vocabularies, such as a record's source or an error code, are typed as str even where the value set is documented, because new values ship without a contract change. Handle the values you know and fall through on the rest.
Optional means Union with None
A field the API may omit is typed Union[T, None] and defaults to None. Check before use rather than assuming presence:
if session.surface is not None:
print(session.surface.status)Datetimes and money
Timestamps are datetime, parsed from the API's ISO 8601 strings. Money is a float in dollars, so a budget.session of 5.00 is five dollars.
Passing models back in
Methods take plain keyword arguments, not request models, so there is nothing to construct for a call:
client.sessions.start(prompt="Fix the flaky test", repository="acme/api")Where a nested structure is required, pass the generated model or a dict; both validate against the same schema.