Subscriptions, redemptions and rollover changes: the three write operations and their limits.
Subscriptions and Redemptions
Get an estimate before subscribing
POST /v1/earn/subscription-quotes
The quote provides the value date, maturity date and estimated interest. Do not recalculate them from the annualized rate yourself. The server determines the value date, day-count convention and rounding point. For fixed-term products, estimated_interest must equal the interest actually paid at maturity; settlement recalculates it and asserts equality. An independent calculation will eventually differ after you have already shown the estimate to a user.
Quoting does not create an order row or consume a limit.
| Product | Key response fields |
|---|---|
| Flexible | value_at: accrual start time · estimated_daily_interest · first_settle_date |
| Fixed-term | value_date · maturity_date · estimated_interest · total_at_maturity |
⚠ A flexible product's disclaimer is always estimate. Do not label it “amount payable at maturity”. Flexible rates may change at any time by inserting a rate-history row; this estimate uses today's rate. A fixed-term rate is snapshotted onto the order when placed, so that estimate is the amount payable at maturity.
⚠ Redemption before accrual starts earns no interest. Flexible redemptions use LIFO, deducting funds that have not started accruing first. Display value_at to the user.
Subscribe
POST /v1/earn/subscriptions
{ "product_id": "…", "amount": "1000.00", "rollover_mode": "principal_interest" }
rollover_mode accepts three values: none · principal · principal_interest. It applies only to fixed-term products and is ignored for flexible subscriptions.
Other values return 400 invalid_request. Omitting it uses the product default.
⚠ If a product is not renewable,
principal/principal_interestis silently changed tononeduring subscription,without an error. Subsequently setting the same value through
PATCH .../rolloveris rejectedwith
earn_rollover_not_supported. The two endpoints differ here.Check the product's
renewableflag first. Hide those two options when renewal is unsupported.
Redeem
POST /v1/earn/redemptions
- Flexible: any time, using LIFO to deduct non-accruing funds first.
- Fixed-term: early redemption is unavailable to clients; this endpoint rejects fixed-term orders.
Do not display a redemption button for fixed-term positions only to reject the action afterward.
Change rollover settings
PATCH /v1/earn/orders/{id}/rollover
Changes are allowed only before maturity. An order that is settling or already settled is rejected with state_invalid.
Position and order details
GET /v1/earn/positions/{id} 活期:含**其中未起息**
GET /v1/earn/orders/{id} 定期:年化 / 预计利息 / 到期日
⚠ A fixed-term order uses its snapshotted annualized rate, not the product's current rate. Using apr_bps from GET /v1/earn/products/{id} to display historical orders would make all those displays wrong as soon as operations changes the product rate, even though both API requests return 200.
⚠ For a flexible position, pending_principal is the portion that has not started accruing. It is already included in principal, not an additional balance. This explains why funds deposited yesterday may not yet have earned interest today; without it, the interface can only offer a vague “calculating” message.
Flexible redemptions use LIFO, deducting non-accruing funds first. This value therefore also indicates how much can currently be redeemed without losing any accrued interest.
Related endpoints
POST /v1/earn/subscriptionsPOST /v1/earn/redemptionsGET /v1/earn/ordersPATCH /v1/earn/orders/{id}/rollover
Fixed-term order state machine
pending_start ──► starting ──► accruing ──► pending_settle ──► settling ──► settled
│
└──► closed
| State | Meaning | Rollover can be changed |
|---|---|---|
pending_start | Order placed; value date not yet reached | ✓ |
starting | Starting accrual | ✓ |
accruing | Interest accruing | ✓ |
pending_settle | Matured; awaiting settlement | ✓ |
settling | Settlement in progress | ✗ earn_rollover_locked |
settled | Principal and interest settled | ✗ |
closed | Closed | ✗ |
A successful subscription returns pending_start, not accruing. Fixed-term products have a value date; placing an order does not immediately start interest accrual.
⚠ Do not default these states to “processing”. Display unrecognized states as received.
Misspelled states have previously occurred (
pending_value/pending_start).Displaying them exposed the problem immediately; a fallback would have hidden it.
Flexible products have positions rather than order states: active for an open position / closed for a fully redeemed position.
The accrual interval includes the start and excludes the end
value_date (inclusive) → maturity_date (exclusive).
⚠ Counting both dates adds an extra day's interest, which users will compare against your displayed estimate.
Identifier prefixes
| Prefix | Meaning |
|---|---|
ern_ | Product |
ers_ | Flexible subscription/redemption operation |
ero_ | Fixed-term order |
Parameters accept IDs with or without their prefixes; the prefix is stripped when provided.