Longport OpenAPI SDK for Rust

July 1, 2026 ยท View on GitHub

Crates.io version docs.rs docs Unsafe Rust forbidden rustc 1.89.0+

longport provides an easy-to-use interface for invoking Longport OpenAPI.

Context Types

ContextDescription
QuoteContextReal-time quotes, candlesticks, options, warrants, watchlists, push subscriptions
TradeContextOrders, positions, account balance, executions, cash flow
AssetContextAccount statement download
ContentContextNews, community topics
FundamentalContextFinancial reports, analyst ratings, dividends, valuation, company overview, shareholders
MarketContextMarket status, broker holdings, A/H premium, trade statistics, anomaly alerts, index constituents
CalendarContextFinancial calendar (earnings, dividends, splits, IPOs, macro data, market closures)
PortfolioContextExchange rates, portfolio P&L analysis
AlertContextPrice alert management (add/enable/disable/delete)
DCAContextDollar-cost averaging plan management
SharelistContextCommunity sharelist management

Documentation

Examples

Runnable examples live in examples/rust/:

  • examples/rust/account_asset/src/main.rs
  • examples/rust/http_client/src/main.rs
  • examples/rust/subscribe_quote/src/main.rs
  • examples/rust/subscribe_candlesticks/src/main.rs
  • examples/rust/submit_order/src/main.rs
  • examples/rust/today_orders/src/main.rs

Quickstart

Add dependencies to Cargo.toml

[dependencies]
longport = "4.0.0"

Authentication

Longport OpenAPI supports two authentication methods:

OAuth 2.0 uses Bearer tokens without requiring HMAC signatures. The token is persisted automatically at ~/.longport/openapi/tokens/<client_id> (%USERPROFILE%\.longport\openapi\tokens\<client_id> on Windows) and refreshed transparently on every request.

Step 1: Register an OAuth Client

Register an OAuth client to obtain your client_id:

bash / macOS / Linux

curl -X POST https://openapi.longportapp.com/oauth2/register \
  -H "Content-Type: application/json" \
  -d '{
    "client_name": "My Application",
    "redirect_uris": ["http://localhost:60355/callback"],
    "grant_types": ["authorization_code", "refresh_token"]
  }'

PowerShell (Windows)

Invoke-RestMethod -Method Post -Uri https://openapi.longportapp.com/oauth2/register `
  -ContentType "application/json" `
  -Body '{
    "client_name": "My Application",
    "redirect_uris": ["http://localhost:60355/callback"],
    "grant_types": ["authorization_code", "refresh_token"]
  }'

Response:

{
  "client_id": "your-client-id-here",
  "client_secret": null,
  "client_name": "My Application",
  "redirect_uris": ["http://localhost:60355/callback"]
}

Step 2: Build an OAuth handle and create Config

use std::sync::Arc;
use longport::{Config, oauth::OAuthBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Loads an existing token from ~/.longport/openapi/tokens/<client_id>.
    // If none exists or it is expired, opens the browser authorization flow.
    // Token refresh is handled automatically on every subsequent request.
    let oauth = OAuthBuilder::new("your-client-id")
        // .callback_port(8080)  // optional, default 60355
        .build(|url| println!("Open this URL to authorize: {url}"))
        .await?;

    let config = Arc::new(Config::from_oauth(oauth));

    // Use config to create contexts...
    Ok(())
}

Benefits:

  • No shared secret required
  • No per-request signature calculation
  • Token lifecycle (load, refresh, persist) managed automatically

2. Legacy API Key (Environment Variables)

For backward compatibility you can use the traditional API key method.

Setting environment variables (macOS/Linux)

export LONGPORT_APP_KEY="App Key get from user center"
export LONGPORT_APP_SECRET="App Secret get from user center"
export LONGPORT_ACCESS_TOKEN="Access Token get from user center"

Setting environment variables (Windows)

setx LONGPORT_APP_KEY "App Key get from user center"
setx LONGPORT_APP_SECRET "App Secret get from user center"
setx LONGPORT_ACCESS_TOKEN "Access Token get from user center"

Other environment variables

NameDescription
LONGPORT_LANGUAGELanguage identifier, zh-CN, zh-HK or en (Default: en)
LONGPORT_HTTP_URLHTTP endpoint url (Default: https://openapi.longportapp.com)
LONGPORT_QUOTE_WS_URLQuote websocket endpoint url (Default: wss://openapi-quote.longportapp.com/v2)
LONGPORT_TRADE_WS_URLTrade websocket endpoint url (Default: wss://openapi-trade.longportapp.com/v2)
LONGPORT_ENABLE_OVERNIGHTEnable overnight quote, true or false (Default: false)
LONGPORT_PUSH_CANDLESTICK_MODErealtime or confirmed (Default: realtime)
LONGPORT_PRINT_QUOTE_PACKAGESPrint quote packages when connected, true or false (Default: true)
LONGPORT_LOG_PATHSet the path of the log files (Default: no logs)

Quote API (Get basic information of securities)

Using OAuth 2.0 (Recommended):

use std::sync::Arc;
use longport::{Config, QuoteContext, oauth::OAuthBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let oauth = OAuthBuilder::new("your-client-id")
        .build(|url| println!("Open this URL to authorize: {url}"))
        .await?;
    let config = Arc::new(Config::from_oauth(oauth));

    // Create a context for quote APIs
    let (ctx, _) = QuoteContext::new(config);

    // Get basic information of securities
    let resp = ctx
        .quote(["700.HK", "AAPL.US", "TSLA.US", "NFLX.US"])
        .await?;
    println!("{:?}", resp);

    Ok(())
}

Using legacy API key (environment variables):

use std::sync::Arc;
use longport::{Config, QuoteContext};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration from environment variables
    let config = Arc::new(Config::from_apikey_env()?);

    // Create a context for quote APIs
    let (ctx, _) = QuoteContext::new(config.clone());

    // Get basic information of securities
    let resp = ctx
        .quote(["700.HK", "AAPL.US", "TSLA.US", "NFLX.US"])
        .await?;
    println!("{:?}", resp);

    Ok(())
}

Quote API (Subscribe quotes)

use std::sync::Arc;
use longport::{quote::SubFlags, Config, QuoteContext};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration from environment variables
    let config = Arc::new(Config::from_apikey_env()?);

    // Create a context for quote APIs
    let (ctx, mut receiver) = QuoteContext::new(config);

    // Subscribe
    ctx.subscribe(["700.HK"], SubFlags::QUOTE).await?;

    // Receive push events
    while let Some(event) = receiver.recv().await {
        println!("{:?}", event);
    }

    Ok(())
}

Trade API (Submit order)

use std::sync::Arc;
use longport::{
    decimal,
    trade::{OrderSide, OrderType, SubmitOrderOptions, TimeInForceType},
    Config, TradeContext,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration from environment variables
    let config = Arc::new(Config::from_apikey_env()?);

    // Create a context for trade APIs
    let (ctx, _) = TradeContext::new(config);

    // Submit order
    let opts = SubmitOrderOptions::new(
        "700.HK",
        OrderType::LO,
        OrderSide::Buy,
        decimal!(500),
        TimeInForceType::Day,
    )
    .submitted_price(decimal!(50i32))
    .remark("Hello from Rust SDK".to_string());

    let resp = ctx.submit_order(opts).await?;
    println!("{:?}", resp);

    Ok(())
}

Troubleshooting

  • Windows setx requires a new terminal; use set for the current cmd.exe session.
  • If you don't see push events, keep the process alive (receiver loop / sleep).
  • For debugging, set LONGPORT_LOG_PATH to enable SDK logs.

Crate features

To avoid compiling unused dependencies, longport gates certain features, all of which are disabled by default:

FeatureDescription
blockingProvides the blocking client API.

License

Licensed under either of