Skip to content

Changelog

All notable changes to this project are documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased

0.6.0 - 2026-09-08

Async session updates are safer, request fields are checked when reassigned, and concurrent first access shares a single client resource instance. Extension code must await async-session mutators, and request-building code must assign valid values instead of relying on later server validation. See the migration notes for async session mutation and request assignment validation.

Added

  • Distributions include 286 generated companion model stubs supporting construction with snake_case names or wire aliases under both mypy and pyright. Use one naming convention per call: mixed spellings remain a static error although they are valid at runtime. Stubs are not imported at runtime. The wheel is approximately 716 KiB.

Changed

  • BREAKING: AsyncSessionManager.set_token(), clear(), and refresh() now raise TypeError instead of mutating state without the async lock, where an in-flight refresh could overwrite them. Extension code can reach the manager through client.call_context.session; migrate to await manager.aset_token(token, username), await manager.aclear(...), and await manager.arefresh(seen_generation, do_logon) with a no-argument async callback returning a token string or (token, username) pair; arefresh() returns None. For a manually seeded token that needs its own callback for a 401 refresh/replay, use await manager.acommit(token, username, alogon); aset_token() does not install that callback. The extension guide shows generation capture and type narrowing. Synchronous read accessors remain available.
  • BREAKING: Request DTOs now validate direct attribute assignment, raising Pydantic ValidationError for invalid values that previously bypassed local assignment checks. Unknown-attribute assignment now raises ValidationError with error type no_such_attribute instead of a plain ValueError and its old message; except ValueError still works, but exact type checks and message matching can break. Literal wrong-typed assignments to typed DTOs were already mypy errors; audit dynamically supplied values, Any, unchecked code, and suppressed diagnostics for the runtime change. Models remain mutable, and accepted values may be coerced by field validation. All nested models reachable from shipped request DTOs validate their own field assignments. In-place container edits, such as appending to a nested list, remain unguarded, as do model_copy(update=...) and direct __dict__ writes; validate plain mappings with nested mappings/lists using model_validate(...) for validated updates. Reassigning or validating an existing DTO instance does not deeply revalidate its internals; extension-defined nested models need their own assignment validation. No submission-time deep revalidation is added.
  • The pyright CI job is now required and runs pyright src tests, model stubtest, and selected consumer typing cases on Python 3.12. Strict mypy remains required. Stub/field parity tests check runtime model fields and aliases; catalog freshness requires the manual drift workflow.
  • Updated the documentation deployment action, actions/deploy-pages, from 5.0.0 to 5.0.1.

Fixed

  • Concurrent first access to a client resource now returns one shared instance. Resources remain lazy, and deprecated aliases retain their warnings and return the canonical resource.
  • The models, endpoints, contract, client, and all generator commands stage and format their complete output before publication. all shares one transaction across models/stubs, endpoints, contracts, and client/resources. Staging failures preserve previous files; publication errors trigger rollback, with recovery backups retained if restoration fails. Symlinked resource trees are rejected, and recovery workspaces are excluded from distributions. Publication is not atomic across directories: concurrent readers can observe rename windows, and process termination may require manual recovery. Concurrent filesystem writers are unsupported; scaffold is outside this transaction support.
  • Source distributions now include the test suite, generator fixtures, scripts, catalog pin, lockfile, and configuration/documentation assets read by the suite, so downstream packagers can run tests offline with development dependencies installed. Release artifact checks reject missing suite assets, and CI runs the suite from an extracted sdist. Live tests remain opt-in and skip by default when STONEX_LIVE is unset.

0.5.0 - 2026-09-08

This release makes order handling safer: unknown nested request fields that were silently dropped now raise validation errors, and acknowledgements without a usable status raise OrderStatusUnknownError. Migrate shared request DTOs to their Request<Name> variants, replace entry-point plugins with explicitly constructed resources, and update deprecated resource names. Migration notes cover request DTO conversion, acknowledgement errors and affected endpoints, configuration validation, and extension migration; resource renames are listed below.

Added

  • status_decoder can receive the endpoint domain keyword; legacy two-argument callables remain supported, including replacement after client construction. Migrate existing two-argument StatusDecoder annotations to LegacyStatusDecoder from stonepy._core.status; StatusDecoder is now a protocol requiring domain. Signature normalization raises TypeError("status_decoder must accept (status, status_reason) or (status, status_reason, *, domain)") when an inspectable signature accepts neither form; uninspectable signatures retain two-argument invocation.
  • CallContext.utc_now provides an injectable UTC source for HTTP-date Retry-After interpretation. FakeClock gained a timezone-aware utc_start argument and utcnow(); pass clock.utcnow as utc_now to drive HTTP-date retries with virtual time.
  • Public exceptions support pickle round-trips with arguments and diagnostic attributes intact.
  • Added client_application, fixed_margin, and trading_advisor client properties and order.get_order_including_closed(order_id, client_account_id) on both clients.
  • Public stonepy.extensions exports BaseResource, CallContext, EndpointSpec, Param, AuthPolicy, and StatusDomain. Clients and resources expose a read-only call_context property for explicitly constructed resources.
  • Export ClientConfigOverrides, a TypedDict used by ClientConfig.from_env() through Unpack so static checkers can reject unknown keywords and incompatible values. Annotate dynamic override dictionaries with ClientConfigOverrides. Consumer typing probes and an advisory pyright CI job were added; the job is non-blocking and currently reports 8 diagnostics.

Changed

  • BREAKING: Request DTOs that embed shared DTOs now use strict Request<Name> variants; unknown keys and tolerant instances in request positions raise ValidationError. Variant keys must be the exact alias or Python name. The original tolerant DTOs remain available. Mappings: ApiClientAccountWatchlistDTO -> RequestApiClientAccountWatchlistDTO, ApiClientAccountWatchlistItemDTO -> RequestApiClientAccountWatchlistItemDTO, ApiClientPreferencesOverriddenSettingSaveDTO -> RequestApiClientPreferencesOverriddenSettingSaveDTO, ApiClientPreferencesOverriddenSettingsSaveDTO -> RequestApiClientPreferencesOverriddenSettingsSaveDTO, ApiClientPreferencesOverridenSettingSaveDTO -> RequestApiClientPreferencesOverridenSettingSaveDTO, ApiClientPreferencesOverridenSettingsSaveDTO -> RequestApiClientPreferencesOverridenSettingsSaveDTO, ApiDateTimeOffsetDTO -> RequestApiDateTimeOffsetDTO, ApiFxFinancingDTO -> RequestApiFxFinancingDTO, ApiIfDoneDTOv2 -> RequestApiIfDoneDTOv2, ApiKnockoutDTO -> RequestApiKnockoutDTO, ApiMarketEodDTO -> RequestApiMarketEodDTO, ApiMarketInformationDTOv2 -> RequestApiMarketInformationDTOv2, ApiMarketInformationSaveDTO -> RequestApiMarketInformationSaveDTO, ApiMarketSpreadDTO -> RequestApiMarketSpreadDTO, ApiStepMarginBandDTO -> RequestApiStepMarginBandDTO, ApiStepMarginDTO -> RequestApiStepMarginDTO, ApiStopLimitOrderDTOv2 -> RequestApiStopLimitOrderDTOv2, ApiTradingDayTimesDTO -> RequestApiTradingDayTimesDTO, ClientPreferenceKeyDTO -> RequestClientPreferenceKeyDTO, CorporateActionsDTO -> RequestCorporateActionsDTO, IdentifierDTO -> RequestIdentifierDTO, MarketPricesDTO -> RequestMarketPricesDTO, OrderRequestDTO -> RequestOrderRequestDTO, PreferenceDTO -> RequestPreferenceDTO, Timestamp -> RequestTimestamp.
  • BREAKING: INSTRUCTION, ORDER, and EXECUTION_TEXT acknowledgements with missing, empty, null, boolean, or malformed statuses raise OrderStatusUnknownError before model validation; its status may be None. Empty acknowledgement bodies also raise this error. Raw checks follow the model's first-wins key remapping, and the validated model must retain a usable status. status_decoder=None bypasses acknowledgement checks, but an empty acknowledgement body still raises ResponseParseError during validation.
  • BREAKING: preference.delete_user_preference, preference.save_user_preference, and price_alert.save_pa return stonepy.UnspecifiedResponse; import it with from stonepy import UnspecifiedResponse for annotations or isinstance() checks. Empty bodies and JSON null become empty models; unexpected object fields are retained in model_extra. The private PassthroughResponseModel was renamed to this class.
  • BREAKING: ClientConfig validates base URLs, numeric types, ranges, and finiteness on construction, raising builtin TypeError or ValueError.
  • BREAKING: ClientConfig repr omits app_key, password, and proxy.
  • BREAKING: Async paths require an AsyncClock. CallContext.ainvoke() requires a transport with asend() and no longer falls back to synchronous invocation; synchronous-only clocks or transports raise TypeError. For hand-built contexts using AsyncSessionManager, supply an alogon callable returning an awaitable: when refresh needs that callback, alogon=None raises TypeError instead of falling back to synchronous logon. Prefer reusing AsyncStoneXClient.call_context.
  • BREAKING: Sending through an AsyncTransport after aclose() raises RuntimeError, including if it was never used.
  • BREAKING: The pydantic minimum is now 2.12 on Python 3.14 and newer; earlier Python versions retain the 2.7 minimum.
  • Package version, default user agent, and build metadata use the single version source in stonepy/_version.py.
  • The internal safe_repr helper redacts secret-named mapping values and uses ordinary repr for other objects.
  • Source distribution includes are anchored to the package and release metadata.
  • Endpoint generation rejects unresolved response types and unreviewed missing response contracts before deleting endpoint output, including when unresolved catalog references are otherwise allowed.
  • Request-type generation rejects unsupported compound request parameter annotations embedding non-root DTOs and catalog names that collide with a generated request variant. Before regenerating, use supported request DTO bindings and resolve colliding catalog names.
  • Coverage now measures branches, and pre-commit hooks run ruff, format, and mypy through the locked uv environment.
  • CI uses uv sync --locked and uv 0.12.10, checks client-regeneration drift, and requires lowest-direct dependency tests on Python 3.11 and 3.14 plus the complete installed-wheel smoke test directory.
  • Releases use pinned uv and verification tools from the locked environment, require the same-commit reusable CI workflow, and publish exactly the verified artifacts after checking source, tag, and distribution versions.
  • Documentation deployment validates strictly before publishing, and manual release versions must match an existing tag and its source version.
  • Live tests require STONEX_LIVE=1, credentials, an allowlisted HTTPS host and port, and STONEX_LIVE_CLIENT_ACCOUNT_ID matching the first returned client account. Missing credentials or the account id fail collection after opt-in; disallowed targets or account mismatches fail at setup. Runs without STONEX_LIVE=1 skip live tests. Configure contributor runs using the live-test recipe.

Deprecated

  • clientapplication, fixedmargin, tradingadvisor, and order_including_closed client properties now emit DeprecationWarning. Migrate to client_application, fixed_margin, trading_advisor, and client.order.get_order_including_closed, respectively. The old names still work, but their warnings become errors under -W error or filterwarnings = ["error"].

Removed

  • BREAKING: Removed entry-point plugin discovery, ClientConfig.enable_plugins, ClientConfig.allow_overrides, client.plugin(), requires_stonepy, and ABI_VERSION. Remove plugin registrations and configuration; import BaseResource from stonepy.extensions and construct MyResource(client.call_context) instead.
  • Removed the private BucketedSlidingWindowLimiter helper.

Fixed

  • BREAKING: price_alert.get_pa now sends its filters in the query string. A demo API probe confirmed that query alertId filtered the results while the previous body binding returned both probe alerts regardless of it.
  • Session managers expose atomic generation/header snapshots, which authentication replay uses to prevent a peer refresh from causing a stale token to be replayed without refreshing it.
  • Manual logon snapshots its validated request; session managers commit its token and replay callback together. The callback survives logoff and is replaced only by a successful manual logon; failed refreshes leave session state intact and only successful refreshes coalesce.
  • ClientConfig.from_env() uses dataclass defaults for fields not provided by the environment or overrides. Unknown override names still raise TypeError, even when their value is None. Invalid non-None base_url overrides now reach constructor validation and raise TypeError("base_url must be a string") instead of AttributeError.
  • Generator Ruff formatting is independent of the current working directory and uses the source checkout's absolute project configuration.
  • --allow-unfrozen-catalog no longer silently skips override-consumption validation; fixture and exploratory catalogs must explicitly pass --skip-override-validation to skip it.
  • Consistency lint validates override consumption and rejects missing or empty resources directories; fixture catalogs can explicitly use --skip-override-validation.
  • Generated contract tests compare the first dump with independent expected values and assert response-model identity, including list item and scalar wrapper types.
  • ApiTradeOrderResponseDTO.Status documentation names the instruction domain and distinguishes nested order lifecycle status values.
  • Clarify frozen-catalog endpoint coverage, authentication replay with zero retries, non-2xx ErrorCode 4011 handling, and httpx request logging at INFO in the documentation.
  • Document that the bundled generator requires dev tools and the repository pyproject.toml; run generator commands from a source checkout or editable install. The generator stays in the wheel.
  • Bound session concurrency test waits and isolate live preference and watchlist round-trips with per-test names.
  • Require full commit SHA pins for workflow actions.
  • GetPA live probes compare query and body filters using temporary alert ids, check the production binding, and clean up by id.
  • Strict live xfails restrict expected failures to contract mismatches. MD-M5 probes classify known contract rejections, including HTTP 404, while preserving authentication, throttling, server, and transport failures.

Security

  • BREAKING: ClientConfig rejects base_url values containing embedded credentials.
  • BREAKING: DTO validation errors hide input values; response parse errors report validation locations and types or a generic decode failure. Fallback API errors report the reason phrase and body length instead of echoing the body; raw bodies remain available in diagnostic attributes. Use structured exception attributes instead of matching exception text.
  • Secret redaction uses one SECRET_KEYS vocabulary for mappings, headers, URL queries, and generated model representations.

0.4.1 - 2026-08-29

Added

  • Python 3.14 is now tested in CI and declared in the package classifiers.

Changed

  • simplejson is now allowed up to (but excluding) 5.0; simplejson 4.x keeps the Python-level API unchanged and passes the full suite.
  • The hatchling build backend is bounded to >=1.32,<2 for compatibility across metadata-version changes.
  • Locked development and documentation dependencies were refreshed (including the cryptography, pymdown-extensions, and setuptools security updates), and every workflow now uses astral-sh/setup-uv v10.0.1.

Fixed

  • Documentation corrected against the 0.4.0 source after a full claim audit: manual log_on() installs a refresh callable, the 401/ErrorCode-4011 authentication replay applies to every endpoint while transport/5xx/429 retries stay idempotency-gated, retry_budget_seconds is a pre-sleep admission check, the stop-limit order recipe validates, and several scope claims (exception hierarchy, secret masking, DTO naming, Pydantic coverage) are now precise.

0.4.0 - 2026-08-29

Changed

  • BREAKING: Eight CI Connect response properties documented as lists now decode as lists instead of scalar DTOs: community actions, wall items for users, wall sub-items, followed and following users, top holders and their users, and multiple-user details.
  • BREAKING: ApiUserDynamicProfileDTO.number_followed, number_following, and last_traded_market_id now decode as integers instead of their incorrect catalog types.
  • BREAKING: order.get_orders(client_account_id=...) now accepts an integer, matching the documented client-account identifier.
  • BREAKING: An explicit server Retry-After is now authoritative and uncapped for 429 and retryable 5xx responses. Computed exponential backoff retains its 30-second cap, and a server delay beyond the remaining retry budget fails immediately without sleeping.

Fixed

  • AlertNotification now includes the documented None_ = 0 member, and NewTradeOrderRequestDTO permits the documented optional OrderReference and Source fields to be omitted.
  • ClientCommunicationMessageUpdate is marked retry-unsafe because it saves a client response; automatic retry can no longer duplicate that write.
  • Generator override tables now fail closed when an entry is stale or unconsumed. The consistency lint loudly reports when catalog checks are skipped and returns a friendly error for an invalid configured catalog instead of using a developer-specific path or traceback.
  • A failed proactive session refresh now logs one secret-free stonepy.pipeline warning and tries the request with the existing token, preserving reactive 401 recovery.

0.3.0 - 2026-07-13

Changed

  • BREAKING: The proactive client-side rate limit now applies one aggregate rate_limit_max / rate_limit_window_seconds window across all endpoint resource groups, matching CIAPI's documented server-wide 500-request/5-second budget. Resource groups no longer receive independent windows that can multiply aggregate traffic.
  • BREAKING: An undocumented instruction status, unknown save_order text status, or numeric save_order status now raises the new OrderStatusUnknownError instead of warning and returning an indeterminate response. The exception is not an OrderRejectedError: the order may or may not have been placed, and callers must verify order state before resubmitting.
  • BREAKING: Business-status rejection checking now runs only on endpoints with an explicit placement/simulation acknowledgement domain. Read endpoints no longer raise OrderRejectedError merely because returned current or historical data contains a rejected stored order status.

Fixed

  • Trade/order placement responses now decode top-level ApiTradeOrderResponseDTO.Status and StatusReason as InstructionStatus/InstructionStatusReason; only nested Orders[] uses OrderStatus/OrderStatusReason. This prevents instruction RedCard (2) from being mistaken for an accepted order lifecycle value, and instruction Pending (5) from raising a false OrderRejectedError (which could prompt a resubmit and a doubled order).
  • save_order no longer crashes with ValueError when the API returns its documented text Status; Success returns and Failure raises OrderRejectedError with the response reason.
  • The client-side rate limiter is now thread-safe.
  • A throttled (HTTP 429) retry without a Retry-After header now waits at least the one second the CIAPI basics guide requires before resending.
  • The generator no longer silently falls back to a developer-specific catalog path; catalog-consuming commands now require --catalog-root or STONEPY_CATALOG.
  • get_client_preferences_list no longer requires a meaningless string argument and no longer sends the keys filter twice (a breaking signature fix).
  • Logging out via delete_session now clears the locally stored session token, but only when the deleted session is the one currently stored.
  • A logon response without a session token (or with an empty or whitespace-only one) now raises AuthenticationError instead of silently storing an empty token; a failed manual log_on no longer disables automatic session refresh; calling an authenticated endpoint on an unconfigured client raises the new ConfigurationError instead of a bare RuntimeError.
  • Credential and token fields on generated models are excluded from repr().
  • Docs: fixed the broken testing-guide example (renamed DTO, pre-0.2.2 URL) and the watchlist recipe (single ApiClientAccountWatchlistDTO, not a list); corrected endpoint and resource-group counts; removed the pipx instructions and the stale SECURITY table.

0.2.6 - 2026-06-29

Fixed

  • POST endpoints whose request DTO was mislabeled as a query parameter now send it as the JSON body. As shipped they serialized the DTO into the query string with no body and the API rejected them (HTTP 415 / 400 "content-type not supported"). Affects order.list_active_orders, news.list_news_headlines, and client_preference.save_client_preference_overridden_settings (#33).
  • preference.delete_user_preference now sends its Preferences argument as a query parameter (the live API rejects the body form), matching the earlier watchlist.delete_watchlist fix (#33).
  • price_alert.delete_pa now returns bool. The endpoint returns a bare scalar (true) but was typed as ResponseModel, so it raised a response-parse error even though the delete succeeded (#33).
  • ListNewsHeadlinesRequestDTO filter fields are now optional, so the request can be constructed with a single filter as the endpoint documents (previously all fields were required, making it impossible to build) (#33).

0.2.5 - 2026-06-29

Added

  • Support for endpoints whose success body is a bare top-level JSON scalar, via a ScalarResponse[T] response wrapper (the generated wrapper returns the plain value).

Fixed

  • user_account.get_charting_enabled now returns bool. The endpoint returns a bare scalar (true), but it was typed as a ResponseModel, so every call raised a response-parse error (a return-type change) (#24).

0.2.4 - 2026-06-29

Added

  • First-class support for endpoints whose success body is a bare top-level JSON array, via a ListResponse[Item] response wrapper. The pipeline validates each element and the wrapper returns a plain list[Item].
  • Live write round-trips (save + read-back + delete) for client preferences and watchlists, now that their request models are correct.

Fixed

  • order.get_orders and order.get_order_history now return list[EnrichedOrderDTO] / list[OrderHistoryDTO]. The API returns a bare JSON array, but they were typed as single objects, so every call raised a response-parse error (a return-type change) (#24).
  • client_preference.save_client_preference and watchlist.save_watchlist now succeed. Their request bodies wrap a single object (ClientPreference, Watchlist), but the models typed them as lists, so the API rejected every call with HTTP 400 (#24).
  • watchlist.delete_watchlist now sends its ClientAccountId / WatchlistId as query parameters rather than in the body, which the live API requires (a body request 400s) (#24).

0.2.3 - 2026-06-28

Added

  • A live contract-test suite (tests/live/) that exercises the generated client against the real CIAPI demo account, run nightly and on demand by a new live GitHub Actions workflow. It is skipped unless STONEX_* credentials are configured, so the normal test run is unaffected. It caught the two response-parsing fixes below and a set of model mismatches tracked in #24.

Fixed

  • Response models now parse CIAPI's v2 camelCase JSON. The generated models alias fields with the catalog's PascalCase, but the v2 endpoints return camelCase, so with extra="ignore" the typed client silently dropped the body to all-None (for example watchlist.get_watchlists and the client_preference lookups returned empty). ResponseModel now matches response keys to field aliases case-insensitively, at every nesting level.
  • Datetime fields now parse the ISO 8601 values v2 endpoints return (for example 2026-06-29T21:05:00Z), in addition to the v1 WCF /Date(ms)/ format.
  • Correct four response field types the frozen catalog mistypes, verified against the live API, so the affected endpoints parse instead of raising: news story ids are strings (Reuters URNs), a news payload is a list of stories, a market carries a list of spreads, and market state is a single enum. This fixes news.get_news, news.get_news_headlines, news.get_market_report_headlines, market.get_market_information, and market.list_market_information_search (#24).
  • user_account.get_client_and_trading_account() now returns the populated account data. The endpoint returns the AccountResult fields flat at the top level, but the declared response model wrapped them under an account_result key, so the typed client always parsed an all-None result. The method now returns AccountResult directly (a return-type change) (#24).

0.2.2 - 2026-06-28

Fixed

  • Correct the request path for the v2 endpoints across the market, message, client_preference, order, preference, watchlist, session, price_alert, and user_account resource groups. The frozen catalog composed each path as /{target}{uri_template}, doubling the resource segment the v2 uri_template already carries (for example /market/v2/market/...), so every one returned 404. The generator now emits the documented /v2/... template for v2 endpoints, served under the existing /TradingAPI base. Routes were verified against the live CIAPI demo (#15, #16, #17, #18, #19, #20, #21).
  • Correct three v2 order/preference routes whose upstream uri_template is itself wrong: order.get_active_stop_limit_order now calls the v1-style /order/{orderId}/activeStopLimitOrder (the 0.2.0 /order/v2/... override also 404s), order.get_open_position calls /v2/order/{orderId}/openPosition, order.save_order posts to /v2/order, and user_preference.get_user_preference calls the singular /v2/Preference (the catalog pluralised it to /v2/Preferences) (#18, #19).

0.2.1 - 2026-06-28

Fixed

  • session.log_on now calls the host-root /v2/session endpoint that CIAPI actually serves, instead of the unreachable /session/v2/Session that returned 401 against the documented base URL (#8).
  • user_account.get_client_and_trading_account now calls the host-root /v2/UserAccount/ClientAndTradingAccount endpoint instead of the doubled /userAccount/v2/userAccount/ClientAndTradingAccount path (#9).
  • margin.get_client_account_margin now calls the v1 /margin/ClientAccountMargin endpoint (under the /TradingAPI base) that CIAPI serves, instead of the /margin/v2/margin/... path that 404s (#10).

Added

  • EndpointSpec.host_rooted: endpoints flagged host-rooted resolve their path against the server host root (scheme and host of base_url) rather than the configured base path, so CIAPI's /v2 session and account endpoints can be reached from the same base_url as the /TradingAPI resources.

0.2.0 - 2026-06-27

Added

  • Docstrings throughout the public API, sourced from the upstream StoneX catalog: every generated model now has a class summary and a per-field description, and every endpoint binding has a summary. Field descriptions flow into each model's JSON schema via Pydantic's use_attribute_docstrings, so the same prose powers the docs site, editor tooltips, and model_json_schema().
  • Full docstring coverage across the hand-written core (configuration, errors, transport, request pipeline, session management, retry and rate-limit policies, codecs, and plugins), including Attributes/Raises sections on the public exception types.
  • A tests/test_self_documentation.py suite that guards the documentation contract: every model, enum, resource group, and exported symbol stays documented, and field descriptions keep reaching the JSON schema.
  • 56 new resource methods covering the full v2 endpoint surface, exposed on the synchronous and asynchronous clients. New resource groups pm, fixedmargin, tradingadvisor, client_preference, and order_including_closed, plus new methods on order (simulate, update, trade, historical/changed/by-reference queries, trades wall), market, news, message, margin, session (validate_session), and user_account (social actions, multi-user lookups, followers, top holders, trader search). Each method has sync and async tests.
  • 30 new DTO models for the v2 responses and requests, each with auto-generated reference pages.

Changed

  • Model reference pages now render each model class directly instead of wrapping it in a module heading, and the API overview links to the full per-model reference rather than duplicating a handful of examples inline.
  • Deploy the documentation site with GitHub Actions (upload-pages-artifact + deploy-pages, both on Node 24) instead of the legacy branch builder, eliminating the Node.js 20 deprecation warning from Pages builds.
  • Regenerated the model and endpoint layer against StoneX catalog afa936e (128 endpoints and 267 data types, up from 72 and 240). Several models gained correct request/response classification, resolved type references, and required-ness. Three DTOs adopted their v2 names (GetMarketInformationResponseDTO, ApiClientCommunicationUpdateRequestDTO, and ApiSaveWatchlistRequestDTO became …v2), and get_order, get_open_position, and get_active_stop_limit_order now take the v2 client_account_id parameter.

Fixed

  • Generator robustness against the larger catalog: alias the lowercase bool type to the catalog's boolean, omit the unused Param import from parameter-free endpoint modules, annotate unwrappable long generated lines with # noqa: E501, and restore the dropped array marker on the News headline list fields so they deserialize as lists.
  • Correct the GetActiveStopLimitOrder v2 endpoint path. The upstream StoneX doc page has a typo in its URI template (/v2{orderId}/…, missing the slash every sibling v2 order endpoint has), which would have made the client request a non-existent path; a curated generator override now emits the correct /order/v2/{orderId}/activeStopLimitOrder.

0.1.3 - 2026-06-27

Added

  • Documentation guides: a configuration reference, resilience (timeouts, retries, and rate limiting), logging and secret redaction, extensibility and plugins, testing, and a recipes cookbook.
  • A dedicated installation page covering pip, uv, and pipx, the optional extras, and the typing guarantee.
  • Auto-generated API reference pages for every DTO and enum in stonepy.models.
  • Community health files: CODE_OF_CONDUCT.md, issue templates, a pull request template, and CODEOWNERS.

Changed

  • Expanded the README with a feature overview, a project status notice, install options, and a support section.
  • mkdocstrings now renders inherited members, so the resource-group reference pages list their methods.

Fixed

  • Corrected the list_market_search_paginated call in the quickstart, and made the README and error-handling examples self-contained and runnable.

0.1.2 - 2026-06-27

Changed

  • Harden the Dependabot configuration so published runtime version caps are preserved, and fix a setup-uv cache race in CI.
  • Bump dev tooling (pytest, ruff).

0.1.1 - 2026-06-27

Added

  • Documentation and Changelog project URLs.
  • A security policy (SECURITY.md) and Dependabot configuration.
  • Operating System :: OS Independent and Programming Language :: Python :: 3 :: Only classifiers.

Changed

  • Pin all GitHub Actions to commit SHAs and bump them to Node 24 releases.

Removed

  • The redundant License :: OSI Approved :: MIT License classifier, in favour of the PEP 639 SPDX license expression.

0.1.0 - 2026-06-18

Added

  • Initial StoneX CIAPI v2 client release.
  • Generated endpoint bindings, DTO models, synchronous and asynchronous clients, retry handling, rate-limit handling, and typed resource groups.