Skip to content

Bank reads and electronic statements (in development)

This page describes the current contract for nine Bank APIs. They are disabled by default. Validation is limited to local synthetic scenarios; live Bank behavior is unverified. Production native materials, runtime input providers and service readiness are not fully connected. Registered endpoints do not establish that the distributed application can log in to a bank or serve these requests.

The scope covers account, asset and transaction reads, plus statement generation and download. It does not provide remote login, account opening, KYC or fund transfers.

Local startup configuration

Bank startup requires --bank-native-package, --bank-environment, and --bank-language together. The following options record known local runtime observations; they do not replace required package materials. Missing prerequisites are reported before authentication.

Every option also has a flat TOML/XML key with hyphens replaced by underscores, such as bank_native_app_data_root. Explicit CLI values take precedence. These observation options have no environment-variable inputs or inferred defaults. Observation files and directories must use absolute paths and remain separate from the OpenD-owned workspace.

CLI options Contract
--bank-native-app-data-root, --bank-native-sdk-workspace Separate native application-data and SDK workspace directories
--bank-distribution-area, --bank-release-app-version Required together; the latter takes explicit true or false
--bank-native-platform-primary, --bank-native-platform-guaranteed Observed Platform primary and guaranteed origins
--bank-native-bank-primary, --bank-native-bank-guaranteed Observed Bank origins; supply all four route observations, using none for a confirmed absent guarantee
--bank-http-timeout-ms, --bank-http-proxy-type Required together; proxy types are no-override, socks4, socks5, http-tunnel
--bank-http-proxy-host, --bank-http-proxy-port Required for a proxy; forbidden with no-override
--bank-http-proxy-user-file, --bank-http-proxy-password-file Required for a proxy; exact UTF-8 file contents, without trimming whitespace or line endings; an empty file records an empty value
--bank-native-common-config-file, --bank-native-developer-ini Observed native configuration files; a supplied path does not establish content compatibility

no-override retains the transport library's proxy-environment behavior; it does not force a direct connection. Entirely absent observation groups remain missing. Partial groups, unknown enums, invalid numbers, or relative observation paths are configuration errors. The Bank password is entered locally with echo disabled. Cancellation prevents the next authentication operation.

Endpoints and permissions

API REST POST MCP CLI
Account information /api/get-bank-account-info futu_get_bank_account_info get-bank-account-info
Demand assets /api/get-bank-demand-assets futu_get_bank_demand_assets get-bank-demand-assets
Accounts by status /api/get-bank-accounts-by-status futu_get_bank_accounts_by_status get-bank-accounts-by-status
Transaction filters /api/get-bank-transaction-filters futu_get_bank_transaction_filters get-bank-transaction-filters
Transactions /api/get-bank-transactions futu_get_bank_transactions get-bank-transactions
Transaction detail /api/get-bank-transaction-detail futu_get_bank_transaction_detail get-bank-transaction-detail
Combined assets /api/get-bank-assets futu_get_bank_assets get-bank-assets
Generate statement /api/generate-bank-statement futu_generate_bank_statement generate-bank-statement
Download statement /api/download-bank-statement futu_download_bank_statement download-bank-statement

All nine require an authenticated acc:read API key, including in compatibility mode. Account restrictions, including explicit and resolved restrictions, card-number, market, symbol and trade-side restrictions must all be absent. An explicitly empty collection is still a configured restriction and cannot authorize whole-owner Bank data. Key expiry, machine binding and current permissions continue to apply.

Reads and downloads depend on the desktop_phase2_reads and bank_external_services runtime conditions. Generation additionally depends on bank_statement_generation. Use --enable-desktop-phase2-reads, --enable-bank-external-services, and --enable-bank-statement-generation for explicit opt-in. The latter two also accept the enable_bank_external_services / enable_bank_statement_generation configuration keys or FUTU_ENABLE_BANK_EXTERNAL_SERVICES / FUTU_ENABLE_BANK_STATEMENT_GENERATION environment variables (true or false). All default to off; generation does not implicitly enable reads. Enabling them cannot replace a valid Bank session and complete production initialization.

REST takes a flat JSON body and an Authorization: Bearer credential, using snake_case fields. MCP takes individual typed arguments, not c2s_json; its authenticated context or explicit api_key must identify the caller whose key is forwarded. CLI uses --rest-url, --api-key or their corresponding environment variables. Credentials are excluded from business JSON.

Gateway/gRPC use the corresponding Protobuf Request.c2s. Local public protocol IDs follow the table order, from 0x7F200031 through 0x7F200039; these are not Bank server command numbers.

Every request requires extension_version: 1. Unknown fields, incorrect types and unsupported versions are rejected. Requests cannot override user identity, source information or connection credentials.

Seven read contracts

The following fields are additional to the required version. Required booleans must be explicit; false is valid.

API Arguments
get-bank-account-info No additional arguments
get-bank-demand-assets Required boolean is_need_exchange_amount
get-bank-accounts-by-status Optional string array statuses; empty means all; order and duplicates are retained
get-bank-transaction-filters No additional arguments
get-bank-transactions Required page_size (1–100), page_flag (string, may be empty); optional min_amount, max_amount, start_time_ms, end_time_ms, filter_type_list, keyword
get-bank-transaction-detail Required nonempty transaction_id; optional business_type, sub_business_type, business_id
get-bank-assets Required currency and valuation_options

Amount bounds are strings and retain decimal precision; they are not converted to floating point. Time bounds are signed millisecond integers, not date strings. Page flags are opaque strings: an initial request may use an empty string; subsequent requests use the returned value.

Each filter_type_list item requires type_key and optionally includes a key_list string array. Use types and values from the current filter response. Filter and observed-record eligibility is checked against the current session. Detail arguments must identify a currently available transaction or related record. A web-detail destination is not automatically converted into this API, and an arbitrary link does not authorize a read.

valuation_options requires currency, use_before_price, use_after_price, use_overnight_price and use_option_combo. All four booleans must be explicit. Outer currency and valuation currency are separate fields. Quote rights and overnight availability come from the current session; a request cannot assert them.

This example illustrates request shape and requires complete readiness to succeed:

{
  "extension_version": 1,
  "page_size": 20,
  "page_flag": "",
  "min_amount": "0.0100",
  "filter_type_list": []
}

Responses retain missing fields, empty strings, list order, duplicates and monetary text. Public binary fields use standard Base64 in JSON and bytes in Protobuf; missing and empty bytes are distinct. Nonzero results may still contain s2c. Keep the complete response; do not fill missing monetary values with zero or treat partial data as complete success.

Generate a statement

generate-bank-statement additionally requires nonempty transaction_id and an explicit, nonempty caller-supplied intent_key. The transaction must belong to the current available records. CLI and MCP do not generate an intent key automatically.

{"transaction_id":"sample-transaction","intent_key":"sample-statement-intent","extension_version":1}

The authenticated subject, caller, environment and intent identify a stable receipt. Repeating the request reads existing history; changing the transaction associated with the same intent conflicts. Unknown execution is never automatically replayed.

s2c.receipt contains receipt_id, intent_key, state and optional file_id and result_code. file_id is read-only association metadata, not a download argument.

state Meaning Outer result
prepared Recorded; submission is not confirmed Nonzero
submitted_unknown Execution cannot be determined Nonzero, receipt retained
awaiting_association No usable nonempty file association yet Nonzero, missing or empty association retained
generated Nonempty file association obtained ret_type: 0
rejected Generation request is known to be rejected Nonzero, receipt retained

Known diagnostics retain their full 64-bit value in result_code. Only values representable as 32-bit integers also appear in outer err_code. Missing diagnostics remain absent, not zero. A diagnostic on submitted_unknown does not make execution certain.

Download by receipt

download-bank-statement accepts only nonempty receipt_id and the version field. The current subject and caller must be authorized for that receipt. The API resolves an existing generated file association; it accepts no URL, file ID or server path and never triggers regeneration.

{"receipt_id":"sample-receipt","extension_version":1}

Download uses current verified HTTP authentication. A business TCP disconnection alone does not require regeneration. A changed subject, failed authentication, permission, source, store or relevant runtime-condition change can still reject the request or final output. Download does not depend on the generation switch.

s2c.result contains receipt_id, state and optional http_status, native_transfer_code, transport_error, filename and content.

state Result
downloaded HTTP 200 with complete nonempty bytes; ret_type: 0, Base64 content
empty_body HTTP 200 with an empty body; nonzero, no file content
http_failure Non-200 HTTP status; nonzero, actual status retained
transfer_failure Transfer incomplete; nonzero, transfer code and any observed HTTP status retained, no partial bytes
transport_error Other classified transport failure; nonzero, no invented status or transfer code

Download uses these separate diagnostic fields rather than presenting HTTP or transport codes as Bank business err_code values.

filename.state is available, unsafe or unsupported. Other optional fields are source_name, safe_basename, origin, unsafe_reason and unsupported_reason. Origin is extended_header, plain_header or transaction_fallback. Complete content may still be returned when a filename is unsafe or cannot be reliably projected; no safe filename is invented.

CLI output

These examples illustrate argument shapes, not production login or enablement:

futucli generate-bank-statement --rest-url "$FUTU_REST_URL" \
  --api-key "$FUTU_API_KEY" --extension-version 1 \
  --transaction-id sample-transaction --intent-key sample-statement-intent

futucli download-bank-statement --rest-url "$FUTU_REST_URL" \
  --api-key "$FUTU_API_KEY" --extension-version 1 \
  --receipt-id sample-receipt --output-file ./statement.bin

Default output is complete JSON, including failed receipts and Base64 content. A file is saved only for an explicit --output-file destination and a complete successful download; existing targets are never overwritten. Empty bodies, partial transfers and failed responses create no destination file. The caller chooses the path; server filenames do not select a directory or overwrite a file.