esi-openapi 0.2.0

Rust API for EVE Online's ESI, based on the OpenAPI specification (fork of rfesi)
Documentation

esi-openapi

CI Crates.io Docs.rs License

Rust API for EVE Online's ESI, built on the ESI OpenAPI 3.1 specification.

Origin

This crate is a fork of rfesi by Matt Boulanger (Celeo), starting from rfesi 0.50.2.

rfesi resolved endpoints through ESI's Swagger 2.0 spec, which CCP has retired. esi-openapi migrates it to:

  • the OpenAPI spec at https://esi.evetech.net/meta/openapi.json,
  • the X-Compatibility-Date versioning header,
  • the new rate-limit headers (X-Ratelimit-*, 429 + Retry-After).

Versioning restarts at 0.1.0. The public API of the endpoint groups is kept, so moving from rfesi is mostly a matter of replacing use rfesi:: with use esi_openapi::. See CHANGELOG.md for the mapping from rfesi's snake_case operation IDs to the OpenAPI ones.

Many thanks to Celeo and the rfesi contributors for the original work.

Installing

Add the latest version to your Cargo.toml.

This crate has several features that are enabled by default.

  • If you don't want or need random SSO state string generation, you can disable the "random_state" feature.
  • If you don't want or need SSO token verification, you can disable the "validate_jwt" feature.
  • Requests use rustls for TLS through the "rustls-tls" feature, which is enabled by default. The "default-tls" feature from rfesi has been removed.

Using

Docs link.

Coverage

All 233 operations of the ESI OpenAPI spec (compatibility date 2026-08-18) have a function in an endpoint group, reached through Esi::group_*(). tests/conformance.rs checks this against resources/test/openapi.json and also that each function uses the HTTP method, path placeholders, query keys and response fields of the spec. Anything newer can be called with Esi::get_endpoint_for_op_id and Esi::query, and PRs are welcome.

Beyond the endpoints:

  • Esi::fetch_all_pages and Esi::fetch_all_cursor walk paginated listings; Esi::query_with_pages also returns X-Pages.
  • EsiBuilder::enable_cache(true) turns on a response cache that revalidates with ETag / Last-Modified and honors x-client-cache-ttl. cache_max_entries and cache_max_bytes bound its size.
  • Esi::post_chunked and the bulk lookups (get_affiliation, get_names, asset names and locations) split lists longer than the spec's maximum into several requests.
  • EsiBuilder::rate_limit_policy(RateLimitPolicy::Wait { .. } | Fail) throttles requests against the rate limits ESI reports instead of provoking 429s (off by default).
  • Esi::ensure_spec_fresh reloads the spec only when it is stale.
  • EsiBuilder::language and EsiBuilder::tenant set Accept-Language and X-Tenant.
  • Esi::required_scopes, Esi::missing_scopes, Esi::required_roles and Esi::declared_rate_limits read the scopes, roles and rate limits that the spec declares for each operation.
  • EsiError::Gone reports resources ESI keeps as tombstones.

Compatibility date

Requests carry an X-Compatibility-Date header that pins the ESI response schemas. The default is COMPATIBILITY_DATE_DEFAULT (2026-08-18); override it with EsiBuilder::compatibility_date. The dates ESI accepts are listed at https://esi.evetech.net/meta/compatibility-dates.

Rate limits

ESI rate-limits routes per group with a token bucket. After each response, esi.rate_limit_status("market").await returns the latest RateLimitStatus for that group, and a 429 response comes back as EsiError::RateLimited { group, retry_after_secs }. Routes not yet moved to the new limiter still use the error limit, checked with esi.is_error_limited().await.

Developing

Requirements

  • Git
  • A recent version of Rust

Steps

git clone https://github.com/rafaga/esi-openapi
cd esi-openapi
cargo test

Authenticated tests

The endpoints that act for a character are tested against the live ESI API in tests/authenticated.rs. Those tests read credentials from a .env file at the crate root, which is excluded in .gitignore. Never commit it.

  1. Create an application at the EVE developers site with the callback URL and the scopes listed in .env.example.

  2. Copy .env.example to .env and fill in ESI_CLIENT_ID (and ESI_CLIENT_SECRET, unless you use the PKCE flow).

  3. Log in once to store a refresh token in .env:

    cargo run --example auth_get_refresh_token
    
  4. Run the tests. They run with a plain cargo test whenever .env has a client ID and a refresh token, and are skipped (with a message) otherwise. To see the result for each endpoint:

    cargo test --test authenticated -- --nocapture
    

EVE SSO may rotate the refresh token on use; the tests write the new one back to .env. Without a configured .env (for example in CI) the tests print why and pass without calling ESI.

License

Licensed under either of

at your option, the same as rfesi. The original copyright notices are kept in both license files.

Contributing

Please feel free to contribute. Please open an issue first (or comment on an existing one) so that I know that you want to add/change something.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.