Skip to main content

stonepy

PyPI version Python versions CI Docs License: MIT

Python client for the StoneX (CIAPI) v2 trading API.

📖 Documentation: https://aaronmgn.github.io/stonepy/

Features

  • Fully typed. Every request and response is a Pydantic v2 model, and the package ships a py.typed marker, so editors autocomplete fields and mypy checks your calls.
  • Sync and async. Identical APIs on StoneXClient and AsyncStoneXClient.
  • Complete coverage. All 128 documented CIAPI endpoints across 19 resource groups, using the v2 variant of every endpoint that has one.
  • Batteries included. Automatic session refresh, configurable retries, client-side rate limiting, secret redaction in logs, and a clear exception hierarchy.

Project status: stonepy is pre-1.0 (alpha). The public API may change between minor releases until 1.0; pin a version for production use.

Installation

pip install stonepy

Or with uv:

uv add stonepy

Requires Python >= 3.11. stonepy ships type information (PEP 561 py.typed), so it works out of the box with mypy and pyright.

Quickstart

from stonepy import ClientConfig, StoneXClient
from stonepy.models import ApiLogOnRequestDTO

config = ClientConfig(base_url="https://ciapi.cityindex.com/TradingAPI")

with StoneXClient(config) as client:
    session = client.session.log_on(
        ApiLogOnRequestDTO(
            UserName="username",
            Password="password",
            AppKey="app-key",
            AppVersion="stonepy",
            AppComments="",
        )
    )
    print(session.status_code)

Environment-based configuration is also available:

from stonepy import ClientConfig, StoneXClient

config = ClientConfig.from_env()

with StoneXClient(config) as client:
    print(client.session)

ClientConfig.from_env() reads STONEX_BASE_URL, STONEX_APP_KEY, STONEX_USERNAME, and STONEX_PASSWORD. STONEX_BASE_URL is required unless base_url= is passed.

Authentication and Sessions

Calling client.session.log_on(...) establishes the authenticated session token that the client attaches to every subsequent request. The token is held by the client for the life of its context manager.

If you supply app_key, username, and password on ClientConfig (directly or via ClientConfig.from_env()), the client also refreshes the session automatically: it re-authenticates as a synchronous pre-request step once the stored token reaches ClientConfig.proactive_refresh_seconds (default 1080.0, i.e. 18 minutes), and transparently re-logs-on if a request is rejected with an expired-session error. If proactive refresh fails with a stonepy error, the client logs a warning and tries the request with the existing token so the reactive 401 path can still recover it. Without configured credentials you must call log_on yourself and manage re-authentication.

config = ClientConfig(
    base_url="https://ciapi.cityindex.com/TradingAPI",
    app_key="app-key",
    username="username",
    password="password",
)  # credentials present -> automatic proactive session refresh

Async Usage

from stonepy import AsyncStoneXClient, ClientConfig
from stonepy.models import ApiLogOnRequestDTO

config = ClientConfig(base_url="https://ciapi.cityindex.com/TradingAPI")

async with AsyncStoneXClient(config) as client:
    session = await client.session.log_on(
        ApiLogOnRequestDTO(
            UserName="username",
            Password="password",
            AppKey="app-key",
            AppVersion="stonepy",
            AppComments="",
        )
    )
    print(session.status_code)

Use aclose() for async clients when not using async with; use close() for sync clients.

Error Handling

All library exceptions inherit from StoneXError.

from stonepy import (
    ClientConfig,
    RateLimitError,
    StoneXAPIError,
    StoneXClient,
    StoneXError,
)
from stonepy.models import ApiLogOnRequestDTO

config = ClientConfig(base_url="https://ciapi.cityindex.com/TradingAPI")

try:
    with StoneXClient(config) as client:
        client.session.log_on(
            ApiLogOnRequestDTO(
                UserName="username",
                Password="password",
                AppKey="app-key",
                AppVersion="stonepy",
                AppComments="",
            )
        )
except RateLimitError as exc:
    print(exc.retry_after)
except StoneXAPIError as exc:
    print(exc.http_status, exc.error_code, exc.error_message)
except StoneXError as exc:
    print(exc)

Important subclasses include AuthenticationError, RateLimitError, OrderRejectedError, OrderStatusUnknownError, ResponseParseError, StoneXAPIError, and TransportError.

Pagination

Paginated API methods return the page DTO documented by StoneX. For example, client.market.list_market_search_paginated(...) accepts page, page_size, and order_by keyword arguments and returns ListMarketSearchPaginatedResponseDTO:

page = client.market.list_market_search_paginated(
    "gold",
    search_by_market_code=False,
    search_by_market_name=True,
    spread_product_type=True,
    cfd_product_type=True,
    binary_product_type=False,
    ascending_order=True,
    include_options=False,
    client_account_id=12345,
    page=0,
    page_size=100,
)
print(page.total_number_of_results)

API Reference

Full documentation - the guides and a complete API reference - is published at https://aaronmgn.github.io/stonepy/.

Development

uv venv
uv sync --extra dev
uv run pytest -q
uv run ruff check .
uv run ruff format --check .
uv run mypy

See CONTRIBUTING.md for the full contributor guide and CODE_OF_CONDUCT.md, and CHANGELOG.md for release notes.

Support

AI Use Disclaimer

Portions of this project, including the generated API bindings, DTO models, and documentation, were produced with the assistance of AI tooling and reviewed by a human maintainer. The library is tested against the StoneX CIAPI v2 contract but is provided "as is", without warranty of any kind (see LICENSE).

stonepy is unofficial and is not affiliated with, endorsed by, or supported by StoneX, City Index, or GAIN Capital. Trading carries financial risk; validate all behaviour against the official API documentation before using it with a live account.

Metadata

Release files for stonepy 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stonepy 0.4.0
File Size Uploaded
stonepy-0.4.0.tar.gz 203.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stonepy 0.4.0
File Interpreter ABI Platform
stonepy-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 685.2 kB

Release files / stonepy-0.4.0.tar.gz

Download URL stonepy-0.4.0.tar.gz
Size 203.4 kB
Tags Source
SHA-256 checksum
How to use checksums
d1cfeed3dcf55cb22b197d7c6651f846c62269dfeac6ba52d33aa2c3085aaaf6
BLAKE2b-256 checksum
How to use checksums
ba8ac4a62d606fd7dd614a77875e54747e524d13fb26ce4163b162c9844d25ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

Release files / stonepy-0.4.0-py3-none-any.whl

Download URL stonepy-0.4.0-py3-none-any.whl
Size 481.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
441402cdc8ea876da0549a29852da08a24dcfef9a296d8804838e6d29ca5c7da
BLAKE2b-256 checksum
How to use checksums
5473e98ec8876b5aaab89c9164d0528e27a7ec019e76d8b264eed9b7e013ae4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page