For the complete documentation index, see llms.txt. This page is also available as Markdown.

Partial-Open (FAK) (coming soon)

By default, a quote opens atomically: the order either fills its full requested notional in a single fill-or-kill (FOK) match, or it reverts and the user is fully refunded — no position is created. Thin markets often can't absorb the full size in one match, so atomic opens on them fail more often than they need to.

Partial-open lets the user accept a smaller fill. Set allow_partial_fill: true on the quote and the position opens at the size that actually filled, down to an optional min_fill_bps floor.

Enablement

Partial-open is on by default — there is no feature flag to turn on. It is gated only by a server-side kill switch. If that switch is active, a partial-open request is rejected with quote_fak_order_type_disabled (HTTP 403); fall back to an atomic order (omit allow_partial_fill).

Request fields

Both fields live on the quote/offer/draft-quote request body:

Field
Type
Required
Notes

allow_partial_fill

boolean

no

false (default) = atomic. true opts into partial-open.

min_fill_bps

integer

no

Minimum acceptable fill, in basis points. Only valid with allow_partial_fill: true.

min_fill_bps rules (all enforced at quote creation, before any order is placed):

  • Range 2000–5000 (20%–50%).

  • Multiple of 500 (5% steps).

  • At least the floor cap (see below).

Omit both fields for normal atomic behaviour — nothing changes.

The min_fill_bps floor cap

A partial fill must never open a position below the protocol minimums. Because min_fill_bps is the worst-case fraction that can fill, the backend rejects any value that could breach a minimum. The floor is computed purely from the request — no market data, no fill required:

If min_fill_bps < floor_min_fill_bps, the request is rejected with quote_min_fill_bps_below_floor (see Errors). The collateral bound dominates at high leverage; the notional bound dominates at low leverage (below ~4x), where a small fraction of a small notional would otherwise fall under the minimum order size. When the floor exceeds the 5000 (50%) maximum, no partial fill is viable and the order must be atomic.

Lifecycle

  1. Floor leg. The backend posts an FOK sized at the requested floor (floor_token_units = floor(target_token_units × min_fill_bps / 10000)). If it never fills within the retry budget, the position is fully reverted — all collateral, origination fee, and prepaid venue fee are refunded — and the customer gateway emits PARTIAL_OPEN_FLOOR_MISSED.

  2. Chase the remainder. Once the floor fills, the backend posts up to 3 fill-and-kill (FAK) retries (5s apart) for the unfilled remainder. Each fulfilled retry emits PARTIAL_OPEN_PROGRESS with the cumulative fill amount.

  3. Finalize. When the retry budget is exhausted (or cumulative fill reaches the full target), finalizeOpenPartial shrinks the on-chain position to the actually-filled size while preserving the originally signed leverage. Unused collateral, borrowed amount, and venue fee are refunded proportionally.

WebSocket notifications

Subscribe to the customer gateway notification event (see WebSocket Events):

Code
When

PARTIAL_OPEN_PROGRESS

After each fill (floor + each retry). Payload: cumulative_filled_making_amount, target_making_amount, filled_bps, attempt_number.

PARTIAL_OPEN_FLOOR_MISSED

The floor FOK never filled; the position was reverted and fully refunded.

Use PARTIAL_OPEN_PROGRESS to drive a "filling… X%" indicator; treat PARTIAL_OPEN_FLOOR_MISSED as a terminal failure (order didn't fill, user refunded).

Position display

The position shrinks to the actual fill, but the requested size is preserved separately:

  • origination_* fields = the full requested size the user signed.

  • current_* fields = the actual filled size the position opened at.

A 60% fill of a $60 request opens a ~$36 position. Render current_* as the live position; optionally show requested vs filled. Leverage is preserved across the shrink. The offer and position responses also echo allow_partial_fill and min_fill_bps.

Errors

All partial-open validation happens at quote creation, before any order is placed:

Code
Status
When

quote_min_fill_bps_requires_fak

400

min_fill_bps sent without allow_partial_fill: true.

quote_min_fill_bps_out_of_range

400

min_fill_bps outside 20005000. Params: min_fill_bps, absolute_min_bps, max_bps.

quote_min_fill_bps_step_invalid

400

min_fill_bps not divisible by 500. Params: min_fill_bps, step_bps.

quote_min_fill_bps_below_floor

400

min_fill_bps would shrink the position below the minimum collateral or notional. Params: min_fill_bps, floor_min_fill_bps, bound_by, requested_collateral_usd_pips, requested_notional_usd_pips.

quote_fak_order_type_disabled

403

Partial-open temporarily disabled by a server kill switch. Omit allow_partial_fill for an atomic order.

See Error Handling for the full quote-rejection table.

Last updated