Skip to content

Common and portfolio reminders

Enable reads with gateway option --enable-desktop-phase2-reads; settings also require --enable-desktop-phase2-writes. Both default to off and add no API-key permissions. Live backend behavior remains unverified.

Operation REST POST MCP CLI Scope
Legacy settings /api/common-reminder-settings futu_get_common_reminder_settings common-reminder-settings qot:read
Modern items /api/common-reminder-items futu_get_common_reminder_items common-reminder-items qot:read
Business descriptions /api/common-reminder-business-info futu_get_common_reminder_business_info common-reminder-business-info qot:read
Explicit settings /api/set-common-reminders futu_set_common_reminders set-common-reminders qot:write

Gateway, REST, MCP, CLI and generic gRPC share public messages. Explicit extension_version: 1 is required. CLI/MCP accept --c2s-json / c2s_json; writes forward the actual caller's API key through the configured REST endpoint.

Reads

{"extension_version":1}

The legacy query optionally accepts stock_id, market, type, count, from. IDs may identify business entities rather than securities. Missing has_more is not proof of a complete result.

{"extension_version":1,"count":0,"next_id":0}

The modern query requires explicit count and next_id; count=0 requests all. Optional fields are pri_id, sub_id, market, types. Preserve the cursor exactly. Missing and empty sub_id are different identities. Raw types, integer states, timestamps and pagination fields retain presence and precision.

Business enrichment has its own not_requested, available, rejected or unavailable state; failure does not discard primary items. For the standalone business query, each items entry requires pri_id and signed type, with optional sub_id. correspondence records original versus encoded identities, response indices and ambiguity. Encoding does not merge reminder identities.

A business rejection returns nonzero ret_type while retaining the original code in s2c, including large unsigned values. CLI prints the full response before exiting unsuccessfully; MCP returns an error containing the full JSON. Transport, decode and identity failures are separate.

Settings

Select exactly one nonempty legacy or modern variant and provide a nonempty intent_key.

{"extension_version":1,"intent_key":"REPLACE_WITH_NEW_INTENT_KEY","legacy":{"stock_id":0,"operation":2,"settings":[{"type":3,"is_open":1}]}}

⚠️ stock_id=0 is a placeholder. Obtain the actual business identifier first. Legacy is_open is a raw uint64, commonly 0 off or 1 on, not a JSON boolean.

{"extension_version":1,"intent_key":"REPLACE_WITH_NEW_INTENT_KEY","items":[{"type":7,"is_open":false,"pri_id":"REPLACE_FROM_CURRENT_USER_QUERY","sub_id":"","operation":2}]}

⚠️ Replace the identity with actual current-user query data or a real business identifier. Modern is_open is an explicit JSON boolean. Operation 1 deletes and 2 updates; creation also uses update.

Proven creation paths cover financial analysis, portfolio, IPO first trading day and overall analysis. Financial analysis creation requires current high-level entitlement; overall analysis checks actual instrument eligibility. An enum alone does not establish support for creating other types. Existing items follow their proven identity and operation contracts. Portfolio and security IDs can coincide and must not be interchanged. Missing identities or unsafe type conversions are rejected rather than guessed.

Inspect s2c.receipt.ack_state: ack_success, ack_rejected or submitted_unknown. A global rejection does not prove per-item rollback. Readback is independent and never resolves an unknown acknowledgement. Reusing an intent does not resend; changing its request conflicts. Unknown holds only overlapping targets.

Updates

Qot_UpdateCommonReminders is a notification, not a request. TCP uses recvNotify; REST WebSocket carries the existing broadcast event with body_b64; gRPC carries notify with binary body. Decode with the public proto.

Updates identify owner epoch, revision and scope invalidation/refresh results. Their sequence is separate from price reminders. Only active queries refresh in the background; advancing a page replaces that interest, and disconnect/user changes clean it up. Read-off still records invalidation without making requests. Failures do not loop indefinitely.