Repository navigation
Releases
v0.6.2
Git tag: v0.6.2. Released 2026-11-06.
- REST errors that say an order or trigger outcome is unknown now use the
same non-retryable API error as Connect. Read the order or trigger back
before retrying: the first request may still apply. Codes added by a newer
server are treated the same way. A gateway timeout
without a recognised outcome code remains a retryable transport/server
failure with an unknown outcome; reconcile before retrying a mutation.
v0.6.1
Git tag: v0.6.1. Released 2026-11-06.
- Service-unavailable responses now raise retryable server errors on Connect
for orders, withdrawals and internal transfers, matching REST. This includes
policy and fee lookups, backlogs, operations in progress and temporarily
unavailable dependencies. Policy denials and permanent precondition failures
remain non-retryable. Rate-limit errors keep their retry delay, and unknown
mutation outcomes remain non-retryable even on an unavailable response. - Keep the service code and status on Connect server errors, and preserve
the problem code and HTTP status on REST 502 and 503 server errors.
v0.6.0
Built on public contract 748066a, the contract of backend 9.2.5. Breaking changes are marked Breaking below; read them before upgrading.
Git tag: v0.6.0. Released 2026-11-05.
- Breaking: a trailing stop created with an activation price already
reached now endsFAILEDwith
TRIGGER_FAILURE_REASON_TRIGGER_WOULD_TRIGGER_IMMEDIATELY(244).
ModifyTriggerand order modifies that would make a trailing stop act at
once are refused withERROR_CODE_TRIGGER_WOULD_TRIGGER_IMMEDIATELY(302),
leaving the existing state unchanged. To start trailing from the market,
clear the activation price with a present zero. - Breaking: remove the public holds-list method, hold models and decoders.
Read aggregate held trading funds from each asset'sreservedbalance in
the balances API. Individual hold IDs and expiry times have no replacement. - Breaking: listing events for an unreadable trigger now returns the same
not-found error as reading that trigger, instead of an empty history.
Events reads retry a catching-upUNAVAILABLEwith the trigger-read policy. - Expose reserve fee rates, the next scheduled change and the full fee
breakdown. Omitted optional components remain absent and omitted account
discounts decode as an empty list. - Preserve REST problem status, code, detail and canonical type on realtime
authorization and early gateway authentication errors. - Pin execution-history continuation pages to the returned exchange order ID
so reuse of a client order ID cannot change generations between pages.
What a trading bot gains. A bot can read the product changelog of the
environment it trades on, with no API key, and find the breaking or
action-required changes published since it last looked. It can wait for a
batch replace to settle and see which items the market refused after
admission, read a trigger back right after changing it, and tell a market halt
from other cancels. It can see why a trigger's fire placed no order, read an
order's exact average price, quote used and fees, tell why an API key was
refused on either transport, and stop all automated trading in one call.
Breaking changes
- A sub-account owner-role refusal is
*errors.SubaccountOwnerRoleLockedError
rather than*errors.APIError.errors.Aswith*errors.APIErrorand
errors.AuthErrorCodestill match it; a direct type assertion does not. - A batch replace status item with no successor reports an empty
ReplacementOrderIDinstead of"0". - A session-only method refusing an API key (
AUTH_SESSION_KIND_NOT_ALLOWED)
is*errors.SessionRequiredErrorrather than*errors.APIError.
errors.Aswith*errors.APIErroranderrors.AuthErrorCodestill match
it; a direct type assertion does not. errors.AuthErrorCodereturns only auth reasons (AUTH_*). It used to
return any*errors.APIErrorcode, such as an orderERROR_CODE_*or a
Connectnot_found; readAPIError.Codefor those.SubAccounts.GettakesincludeBalancesagain, afterincludePolicy:
Get(ctx, account, subAccountID, includeAPIKeys, includeMembers, includeInvites, includePolicy, includeBalances, invitesDirection). Pass
falseto keep the previous behavior.
Added
-
client.Changelogwraps the publicchangelog.v1.ChangelogService.
ListPosts,GetPostandListChangesreturn typed
models.ChangelogPostSummary,ChangelogPost,ChangelogSection,
ChangelogChangeandChangelogChangeEntryvalues.PostsandChanges
iterate over every page, andBreakingChangesSinceand
ActionRequiredSincecollect the matching changes published since a time.
Categories, audiences and surfaces are lowercase labels, and a value newer
than the SDK reads asunknown(<n>). Change IDs are base58. An unknown slug
fails with*errors.APIErrorcodenot_found. -
Orders.WaitBatchReplacepollsGetBatchReplaceStatusuntil no item is
admitted, through the not found a new batch's status reads for a few
seconds after admission, and stops at the 60-second status window, even
with a status read in flight, with*errors.BatchReplaceWindowExpiredError
and the last status: reconcile the orders with order reads then. A canceled
or expiredctxreturnsctx.Err(). -
BatchReplaceStatusItem.ErrorCodenames an item's refusal as the
orders.v1error code a single modify returns (ERROR_CODE_POST_ONLY_CROSS
forCodePOST_ONLY_CROSS); a code newer than the SDK is kept as sent. -
Market halts: orders the halt cancels read
CancelReasonmarket_halted
(CANCEL_REASON_MARKET_HALTED, 17) on order reads and the order stream, and
triggers it ends readCancelReasonmarket_halted
(TRIGGER_CANCEL_REASON_MARKET_HALTED, 13) on trigger reads, events and
streams. A trigger refused after a halt readsFailureReason
unknown(212)until the server reportsmarket_halted. -
*errors.SubaccountOwnerRoleLockedErrorand
errors.IsSubaccountOwnerRoleLocked: a sub-account member call that targets
the owner (AUTH_SUBACCOUNT_OWNER_ROLE_LOCKED, Connect
failed_preconditionor REST 412). It unwraps to*errors.APIError, so
errors.AuthErrorCodestill reads the code; a direct type assertion to
*errors.APIErrorno longer matches it. -
Trigger events
fire_refused(EVENT_FIRE_REFUSED): a fire whose order
was refused while the trigger stayed live, for the market's state, a
position below the market's minimums, a rate limit or an account repair.
It is not terminal.TriggerEvent.FireRefusalReasonsays why, with the
FailureReasonlabels, which gainaccount_repairing. Decoded on
Triggers.ListEventsand the trigger event stream;ListEventsfilters on
fire_refused. -
errors.AuthErrorCodereads the auth reason of either transport: the
Connectauth.v1.AuthErrorDetailcode, or a REST problemcodewith the
AUTH_prefix added (UNAUTHENTICATEDreads
AUTH_AUTHENTICATION_REQUIRED). Constants for the new API-key refusals:
errors.AuthCodeSignatureInvalid,AuthCodeTimestampSkew,
AuthCodeMissingHeaders,AuthCodeKeyExpired,AuthCodeKeyDisabled,
AuthCodeIPNotAllowed,AuthCodeAPIKeyNotAccepted, plus
AuthCodeAuthenticationRequiredandAuthCodeSessionKindNotAllowed. -
*errors.SessionRequiredErroranderrors.IsSessionRequired: an API key on
a method that accepts only a session token, on every service (Connect
permission_deniedwithAUTH_SESSION_KIND_NOT_ALLOWED, REST 403). -
errors.FieldViolationanderrors.Violations(err): the fields an order
refusal names, from the orderErrorDetail, from request validation
(buf.validate.Violations, which the SDK used to drop) or from a REST
problem'sviolations.ValidationError.Violationsholds them;
Metadatakeeps itsviolation.N.*entries.models.OrderFieldViolation
is now an alias oferrors.FieldViolation. -
Order.AvgPriceE18andOrder.AvgPrice(): the exact average execution
price at 18 decimals.Order.CumNotionalandOrder.CumQuote(baseScale):
the exact quote amount of the fills.Order.FeeTotal
(models.OrderFeeTotal): the fills' net fee, set on history and
single-order reads with execution history.Order.QuoteUsed(baseScale)and
Order.QuoteUnspent(baseScale, quoteScale)say how much of a quote-amount
buy was used, fee included, once the fee total covers every fill. -
errors.IsOrderAlreadyTerminal: a cancel of an order that has already
ended, which a repeat of the cancel that ended it now also answers. -
client.StopAllTrading(services.StopAllTrading): cancels every live
trigger in scope (created, armed, running, paused, every page), then all
open orders.Orders.CancelAlland the dead-man switch cancel open orders
only, never triggers. -
Changelog surfaces
market_data,quickswapandrewards
(models.ChangelogSurfaceMarketData,ChangelogSurfaceQuickSwap,
ChangelogSurfaceRewards), andChangelogSection.Surface, the product area
a section covers.ListChangesrefuses more than 10 surfaces before
sending. -
SubAccounts.GetwithincludeBalancesreturns the sub-account's current
balances inGetSubaccountResult.Balances, amodels.BalancesListas
Balances.Listreturns. It is nil when not asked for. It needs the
READ_BALANCESaction on the sub-account or fails with PermissionDenied;
when balances cannot be read right now it fails with the retryable
AUTH_TEMPORARILY_UNAVAILABLE. -
CreateOrderRequest.SelfTradePreventionMode(expire_maker, the server
default,expire_takerorexpire_both) on create, preview and batch
create. It applies to the order's attached take-profit, stop-loss and
trailing stop orders as well. An unknown mode is refused before sending.
Order.SelfTradePreventionModereads it back, and a mode newer than this
SDK reads asunknown(<n>). -
Attached exits never trade with the order they protect: an order whose
exit fired while it still rested ends canceled withCancelReason
attached_exit_fired, and an exit order that self-trade prevention expired
against another of the account's resting orders is afire_refusedtrigger
event withFireRefusalReasonself_trade_prevented, whoseChildSeq
names that order; the leg stays armed.RejectReasonand order error codes
read the newSELF_TRADE_PREVENTEDcode, which no request is answered with.
Changed
- A trigger the halted market refuses reads
FailureReason(and a refused
fireFireRefusalReason)market_haltedon servers on this contract; it
used to readunknown(212). The SDK has no special case for 212, and any
unknown reason still reads asunknown(<n>). - Docs: a buy sized by a quote amount takes attached risk (no SDK guard ever
refused it).Order.CumNotional,CumQuoteandQuoteUsedare exact when
the pair's base quantity scale is at most 9, and can exceed the settled
quote by less than 1e-18 per fill above tha...
v0.5.1
Git tag: v0.5.1. Released 2026-11-02.
What a trading bot gains. A sell order can carry an attached trailing
stop again. On a sell order the trailing stop buys back, and the server now
requires its maximum buy-back price; TrailingStopInput.LimitPrice sends it.
Breaking changes
- None in the SDK API.
Fixed
TrailingStopInput.LimitPricesets an attached trailing stop's buy-back
limit price, the most its exit pays per unit, which also sizes the funds it
reserves. A sell order's attached trailing stop requires it, and a buy
order's must leave it nil; creates, previews and batch creates check this
before sending. It must be positive and at leastActivationPricewhen both
are set. Modify and batch replace send it as given, and the server applies
the side rule there. Order reads do not return it yet.
v0.5.0
Git tag: v0.5.0. Released 2026-11-02.
What a trading bot gains. An attached take-profit, stop-loss or trailing
stop now says when it starts protecting the position: its trigger events
include armed, once, when the parent order's first fill makes the leg live.
A bot can wait for it instead of polling the leg's status. Three new error
codes are final refusals: the request did not apply, so do not resend it
unchanged.
An environment reports armed events and the new codes once it runs this
contract: devnet first, then testnet after its next upgrade.
Breaking changes
- None in the SDK API.
Added
- Trigger events decode the new
armedevent type: an attached take-profit,
stop-loss or trailing-stop leg reports it once, when its parent order's
first fill makes the leg live (or when a leg paused before that fill
resumes). It is not terminal.Triggers.ListEventsaccepts"armed"as its
event type filter. Attached trailing stops still reportactivatedwhen
they start tracking. - Error codes
AUTH_SUBACCOUNT_OWNER_ROLE_LOCKED(the sub-account's owner
cannot be invited, re-roled or removed),
ERROR_CODE_TRIGGER_SYMBOL_MISMATCH(modify, pause or resume named a listed
pair other than the trigger's own; name the trigger's pair or omit it) and
the balance reads'ERROR_CODE_INVALID_SUBACCOUNT_ID(a zero or malformed
sub-account ID). - Generated messages add
Subaccount.removed(real-time sub-account updates
only: the caller lost access, so drop the sub-account),
TrailingStopPolicy.limit_price_ticks,Checkpoint.opening_value_usd,
ListMyRewardAwardsResponse.awards_may_changeand the Swap reason
MAX_ORDER_QUANTITY, and the trade WebSocket protobufs follow binary schema
34.
Server behaviour on this contract
- Batch replace amends an order in place, keeping its order ID and queue
priority, when an item keeps the price, does not raise the total quantity
and keeps the client order ID. Otherwise it replaces the order under a new
order ID. - An attached trailing stop on a selling order buys back, and the server now
requires its maximum buy-back price. This SDK'sAttachedRisk.TrailingStop
does not send that price yet, so place a selling order with only take-profit
and stop-loss legs until a later release adds it. A buying order's attached
trailing stop is unchanged. - Ladder outcomes: a ladder is completed once no child order remains open and
at least one reached the book; it is failed only when every child order was
rejected before reaching the book.
v0.4.0
Git tag: v0.4.0. Released 2026-11-02.
What a trading bot gains. An order now says why it ended, in the same
words everywhere. A rejected order's RejectReason is the error code the
order write API returns for the same refusal, and a canceled order's
CancelReason says why it was canceled, on order reads and on the private
order stream alike. Before, the numeric reason used the matching engine's own
numbering, which clashed with the API's error codes. OrderbookData.Available
tells a bot when a book's levels are unknown rather than empty, so it does not
quote into a book that is being rebuilt. Trigger.Version picks out the
newest copy of a trigger, and nine new error codes are final refusals: the
request did not apply, so do not resend it unchanged.
This release works on devnet now, and on testnet after testnet's next upgrade.
Reason labels in this SDK. RejectReason is the orders.v1.ErrorCode
name without its ERROR_CODE_ prefix, for example POST_ONLY_CROSS.
CancelReason is the orders.v1.CancelReason name without its
CANCEL_REASON_ prefix, in lowercase, for example user_request. The Python
and Rust SDKs format these labels differently.
Breaking changes
Client.Whiteboard,Client.PolychartandClient.Layoutare removed,
withcodecs.BoardAudienceFromLabelandcodecs.BoardRoleFromLabel.- The generated
orders.v1.OrderlosesTerminalReasonCodeand
TerminalReason, and the generatedprivatews.v1.OrderEventloses
ReasonCode. ReadRejectReasonandCancelReasoninstead. models.OrderEvent.ReasonCodeis replaced byRejectReasonand
CancelReason.SubAccounts.Getno longer takesincludeBalances.
Breaking
Client.Whiteboard,Client.PolychartandClient.Layoutare removed,
because those APIs are no longer part of the public API.codecs.BoardAudienceFromLabelandcodecs.BoardRoleFromLabelare
removed with them.- The generated
orders.v1.OrderlosesTerminalReasonCodeand
TerminalReason, and the generatedprivatews.v1.OrderEventloses
ReasonCode. Their numbers used the matching engine's own numbering, which
collides withErrorCode. Read the typedRejectReason
(orders.v1.ErrorCode) andCancelReason(orders.v1.CancelReason)
instead, or the decoded labels below. models.OrderEvent.ReasonCodeis replaced byRejectReasonand
CancelReason. A rejected order's event names its refusal as the order
write API does (for examplePOST_ONLY_CROSS). A canceled order's event
names why it ended (for exampleuser_request), and so does the replaced
event of the order a replace ended (replaced). Both are empty otherwise.SubAccounts.Getno longer takesincludeBalances: a sub-account read no
longer returns balances. Read them withBalances.Listand the sub-account ID.
Added
Order.RejectReasonandOrder.CancelReason, on order reads and on the
private order stream's snapshot and unit orders. A rejected order's
RejectReasonis theErrorCodename the order write API returns for the
same refusal, without itsERROR_CODE_prefix. A canceled order's
CancelReasonis a lowercase label such asuser_request,ioc_remainder,
stp_expire_maker,replaced,gtd_expiredoraccount_repair. Both
are empty for every other status. A value newer than this SDK decodes as
UNKNOWN_ERROR_CODE(N)orunknown(N).decode.OrderCancelReasonLabelnames anorders.v1.CancelReason.OrderbookData.Available, fromOrderbook.Getand managed order book
subscriptions. False means the book is being built or was invalidated: its
levels are unknown, not empty, so request the snapshot again later. An
environment that does not serve this release yet reports false for every
book.Trigger.Version: 1 for a trigger's first state, higher for every later
state change. Keep the copy with the highest version.- New order error codes surface as
errors.APIErrorwith that code. Each
has a known outcome:errors.IsRetryableand
errors.MutationOutcomeUnknownare false, so do not resend the same
request unchanged.ERROR_CODE_ATTACHED_LEGS_EXCEEDED: the order already carries every
attached leg it may hold, so another attached leg was refused.ERROR_CODE_FEE_ASSET_INVALID: the trigger's fee asset was not valid.ERROR_CODE_FEE_CEILING_INVALID: the trigger's maximum fee rate was not
valid.ERROR_CODE_UNSUPPORTED_FIELD_SET: the trigger set a field that must be
left unset.ERROR_CODE_TRIGGER_FIRE_LIMIT_REACHED: the trigger could not fire
again.ERROR_CODE_CONDITION_FLAGS_INVALID: the trigger's condition flags were
not valid.ERROR_CODE_CONDITION_PARAMETER_SET: the trigger set a condition
parameter its condition does not take.ERROR_CODE_TWAP_CAPACITY_REACHED: the market had no room for another
TWAP order. It is a capacity refusal, not a rate limit.ERROR_CODE_CHILD_ORDER_INCONSISTENT: the trigger's child order did not
match the order the trigger requested, so the trigger failed and its
child order was canceled. Read the trigger and the child order to see
their final state.
v0.3.0
Git tag: v0.3.0. Released 2026-10-31.
What a trading bot gains. Trade, fill, transfer and trigger-event streams
now deliver every event; before, all but one event of each batch was lost.
MarketData.GetSpotConfig returns a typed config with each pair's order
limits, including the new cap on one market order's notional, so a bot can
size orders before it sends them. Rejections say more: a duplicate client
order ID names the order that already holds it, a clock-skew rejection is the
retryable errors.TimestampSkewError, and an unsupported call is
errors.NotImplementedError. Replacement orders report the quantity they
inherited, and slippage caps match what the API accepts.
This release works on devnet today, and on testnet after testnet's next
upgrade, which brings the new private order stream.
Breaking changes
- The batched trade, fill, transfer and trigger-event streams emit each event,
and the single-event decoders (decode.MarketTradeFromBytes,
UserTradeFromBytes,LedgerTransferFromBytes,TriggerEventFromBytes)
are replaced by their...BatchFromBytesversions. decode.SpotConfigFromProtoandGetSpotConfigreturn an error for a spot
config they cannot decode instead of an empty config.- Connect
unimplementedmaps toerrors.NotImplementedErrorinstead of
errors.APIError.
Added
SpotPair.MaxMarketNotionalQuoteandPairConstraints.MaxMarketNotionalQuote:
the largest notional of one market order in quote units, valued at a buy's
protection price or a sell's reference price. Larger orders are rejected
withERROR_CODE_MAX_NOTIONAL. Empty when the pair has no cap; a malformed
value fails the spot config decode and makes the constraints unavailable.MarketData.GetSpotConfigreturns a typedmodels.SpotConfig:Assets
(models.SpotAsset),Pairs(models.SpotPair: IDs, assets, scales, tick
and step size, minimums, orderbook buckets, listing times, status labels
such ashalted, default slippage and reference drift),TsSecand the
order limits. Each pair hasMaxLimitQtyBase,MaxMarketQtyBaseand
MaxOrderNotionalQuote(decimal strings, empty when the pair has no
maximum) andMaxOpenOrdersPerPair; the config hasMaxOpenOrdersTotal.
The open-order counts are the venue's defaults for a typical account, zero
when not published; an account may have a lower limit of its own.Raw
remains the proto-JSON payloadCatalogs.HydrateSpotConfigaccepts.PairConstraintsexposes the same limits (MaxLimitQtyBase/
MaxLimitQtyScaled,MaxMarketQtyBase/MaxMarketQtyScaled,
MaxOrderNotionalQuote,MaxOpenOrdersPerPair) andMaxQuoteSlippage/
MaxQuoteSlippageTicks, the largest absolute slippage cap an order
accepts.Catalogs.MaxOpenOrdersTotal()returns the account-wide default.
A malformed limit makes the constraints unavailable rather than guessed.Order.InheritedCumQty: the filled quantity a replacement order inherited
from its predecessors;CumQtyminus it is what that generation executed.BatchReplaceAdmissionItem.ActionTakenand
BatchReplaceStatusItem.ActionTaken:replacedwhen a successor was
admitted,amendedfor a cancel-only outcome with no successor.APIError.ExistingOrderIDandBatchCreateResultItem.ExistingOrderIDname
the order already holding the client order ID on a
ERROR_CODE_CONFLICT_DUPLICATE_CLIENT_ORDER_IDrejection, when known.errors.TimestampSkewErrorfor the API-keyTIMESTAMP_SKEWrejection,
whether sent as a Connect error or as the gateway's JSON or problem JSON
body ({"code":"TIMESTAMP_SKEW"}). It carries the HTTP status.
errors.IsRetryablereports true: the request changed nothing and a retry
signs it again.errors.NotImplementedErrorfor Connectunimplementedand bare HTTP 501
responses. A bare 404 is stillerrors.RouteNotFoundError.LedgerTransfer.TransferID: the unsigned 128-bit decimal transfer ID both
legs of a transfer share.- A trailing stop's
TriggerDetails.TriggerPriceis its current threshold
once armed. realtime.SubscribeProtoBatch,services.SubscribePublicProtoBatchand
services.SubscribeAccountProtoBatchsubscribe to channels whose
publications batch events.
Changed
- Breaking:
MarketData.SubscribeTrades,Trades.Subscribe,
Transfers.SubscribeandTriggers.SubscribeEventsdecode the batched
publications the realtime channels now send and emit each event in order.
Previously a batch decoded as a single event and the rest were lost. The
single-event decodersdecode.MarketTradeFromBytes,
decode.UserTradeFromBytes,decode.LedgerTransferFromBytesand
decode.TriggerEventFromBytesare replaced byMarketTradeBatchFromBytes,
UserTradeBatchFromBytes,LedgerTransferBatchFromBytesand
TriggerEventBatchFromBytes. - Breaking:
decode.SpotConfigFromProtoreturns an error for a response
it cannot decode instead of an empty config;GetSpotConfigreturns it. - Breaking: Connect
unimplementedresponses map to
errors.NotImplementedErrorinstead oferrors.APIErrorwith code
unimplemented. MarketOverview.CreateSubscriptionwithSymbolsdrops other markets from
live and buffered publications too, not only from the snapshot.Triggers.ModifyandTriggers.Resumeno longer require a symbol. Pass nil
forsymbolandsymbolIDto target the trigger's own market; a symbol,
when set, must be that market. An API key limited to specific markets must
still pass it.- A sell market order accepts
MaxSlippageBps1 to 9999; a buy still accepts
10000. An attached trailing stop accepts 1 to 9999 on either side, and
Triggers.Modifyaccepts 1 to 9999 (0 still clears). The backend rejects
10000 on these withMAX_SLIPPAGE_INVALID.
Internal
sdk-capabilities.jsonno longer carriespublicDescriptorSha256orgeneratedAt, so a proto publication that only changesgen/andmanifest.jsonno longer makes it stale;manifest.jsonstays the single source of the descriptor hash.
v0.2.0
Git tag: v0.2.0. Covers every change since v0.1.0-alpha.56.
Versioning
- The Go, Python and Rust SDKs now share one version number and are released
together, starting at0.2.0. Versions are plain SemVer: Go tags are
vMAJOR.MINOR.PATCH(v0.2.0), with noalpha/asuffix. Until1.0.0
a minor release may change the API; a patch release does not. - Install with
go get github.com/Fabric-Labs/polyester-sdk-go@v0.2.0. The
repository is public, soGOPRIVATE/GONOSUMDBsettings are no longer
needed. The olderv0.1.0aNNtags were never valid Go module versions;
v0.1.0-alpha.56is the previous release.
Added
-
Attached take-profit, stop-loss and trailing-stop legs and standalone
stop-loss, take-profit and trailing-stop triggers can watch the market's
index price: setRiskLegInput.TriggerPriceSourceor
TrailingStopInput.TriggerPriceSource, or passtriggerPriceSourceto
Triggers.Create, as"index"(or"last", the default when empty).
Other values are refused with a validation error. Order reads now report
each attached leg'sTriggerPriceSourcewith the same labels, so a leg
read back can be sent again unchanged. -
CancelAllOrdersResult.ListingStatus:included, or
not_retained_read_open_orderson a retry with the same request ID within
120 seconds, which returns the original counts with an empty
CancelledOrders. An empty retried list does not mean nothing was
canceled; read open orders for current state. -
CancelAllAfterResult.EffectiveScope(models.DeadManSwitchScope: account
ID, symbol ID and side) describes the armed switch; nil when disabled. -
GetOrderResult.ExecutionsCompleteis true when the order's trades across
every page add up to its filled quantity, and false while a recent
execution is still being recorded. -
LifecycleFlowSummary.IsDelayedis true when an open flow has made no
progress for well beyond its expected step time. -
realtime.OrderStale.OrderIDsnames the orders that are temporarily not
current whenReasonisorder_unavailable; the rest of the view stays
current and units keep arriving. A laterOrderStalereplaces the reason
and IDs, and consumers that join a running subscription receive them. -
errors.AuthCodeTemporarilyUnavailable(AUTH_TEMPORARILY_UNAVAILABLE). -
Spot config pairs carry the venue's per-order limits in
SpotConfig.Raw:
max_limit_qty_base,max_market_qty_base,max_order_notional_quote
(each absent when the pair has no maximum) andmax_open_orders_per_pair.
Orders past the open-order limit are rejected with
ERROR_CODE_MAX_OPEN_ORDERS_PER_PAIR.
Changed
- Breaking:
errors.IsRetryablereports false for every order error code
ending in_OUTCOME_UNKNOWN(ERROR_CODE_ORDER_CREATE_OUTCOME_UNKNOWN,
ERROR_CODE_ORDER_CANCEL_OUTCOME_UNKNOWN,
ERROR_CODE_ORDER_MODIFY_OUTCOME_UNKNOWN,
ERROR_CODE_TRIGGER_CREATE_OUTCOME_UNKNOWN,
ERROR_CODE_TRIGGER_CONTROL_OUTCOME_UNKNOWN). It reported true for the
order cancel and modify codes inv0.1.0-alpha.56. The change may still
apply, so a blind retry can place a second order: read the order or trigger
back first. This matches the TypeScript SDK. errors.MutationOutcomeUnknownreports true for every order error code
ending in_OUTCOME_UNKNOWN, read from the generatedorders.v1codes, so
a code added to the API is covered when the SDK is regenerated. New in this
release:ERROR_CODE_ORDER_CREATE_OUTCOME_UNKNOWN,
ERROR_CODE_TRIGGER_CREATE_OUTCOME_UNKNOWN(a create sent but not confirmed
in time may have been accepted) and
ERROR_CODE_TRIGGER_CONTROL_OUTCOME_UNKNOWN(a trigger cancel, pause,
resume or modify).errors.IsRetryablereports true forAUTH_TEMPORARILY_UNAVAILABLE: the
request changed nothing; retry the same request.
Fixed
- The lifecycle reason
DEPOSIT_SOURCE_NOT_CONFIRMEDreads as
deposit_source_not_confirmedinstead ofunknown_reason_400. TestnetEnvironmentandEnvironmentFromName("testnet")now use
https://api.testnet.polyester.comandwss://api.testnet.polyester.com.
Earlier versions pointed atapi-testnet.polyester.com, which does not
exist, so every testnet call failed with a DNS error. The devnet preset and
transport.DefaultConfignow use the documentedapi.devnet.polyester.com
host instead ofapi-devnet.polyester.ai.- The README no longer claims
VIP.GetVIPStatusworks with an API key: the
API refuses API-key callers withpermission_denied. VIP tiers, effective
spot fees and trading rate limits do work with an API key. - The
User-Agentheader reports this SDK's module version
(polyester-sdk-go/v0.2.0). Earlier versions reported the version of the
application that imported the SDK. - README documentation links point at the public developer docs on
polyester.com.
v0.1.0a55
Changed
- Breaking:
CreateOrderRequest.AttachedRiskis*models.AttachedRiskInput
instead ofmap[string]any; the map was always rejected. - Breaking:
codecs.ModifyOrderToPrototakes a newnewAttachedRisk *models.AttachedRiskInputparameter afternewQty, and
codecs.BatchReplaceItemToProtoencodesBatchReplaceItem.NewAttachedRisk.
Passnilto keep an order's attached risk unchanged. - Breaking:
Orders.Subscribeuses the private WebSocket and returns
*realtime.Subscription[realtime.OrderStreamEvent]instead of
*realtime.Subscription[models.Order]. It returns at once and reports the
handshake asOrderStreamConnected. The previous order realtime channels,
including the batch-replace order channel, are retired; use
Orders.GetBatchReplaceStatusand the order stream's revisions for
batch-replace progress. - Breaking:
decode.OrderFromBytes, the decoder of the retired order
realtime publications, is removed. Usedecode.OrderFromProto. - A sell
trailing_stopcreate given alimitPriceis refused with a
validation error instead of ignoring it: only a buy has a maximum price. - Trigger create and modify refuse both
MaxSlippageTicksand
MaxSlippageBpstogether (previously one silently won), and a trailing
stop'sMaxSlippageBpsis limited to 1 to 9999 on either side. - Breaking:
codecs.ModifyTriggerOptions.LimitPriceis removed: a
trigger's child limit price is fixed at create, and the server refuses
any change to it. Cancel the trigger and create a new one instead. - Breaking: trading prices use 9 decimal places.
codecs.PriceTickScale
and the newmodels.PriceTickScaleare 9: one price tick is 1e-9 quote
units. This applies to order, trigger, trailing, activation, orderbook,
trade, candle, market-overview and tick-size values. Raw tick values
built for the previous 6-decimal scale are 1,000 times too small; scale
them by 1,000 or pass decimal strings. Market-overview USD amounts stay
at 1e6. - Breaking:
MaxSlippageTickson market orders, triggers, trigger
modifications and trailing-stop reads isint64, matching the 64-bit
price-delta field in the API. - Candle and market-overview base volume now use the base asset
market_data_volume_scalefromGetSpotConfig. Primary candle prices
use the fixed 9-decimal price scale. - Composite reference-candle OHLC uses the pair
reference_price_scale.
GetCandlesWithReferenceandGetCandlesColumnsWithReferencerequest
that series.MarketOverviewEntry.Volume24HBaseis the decoded decimal
when the catalog scale is known;Volume24HBaseScaledstays the integer.
Added
- Orders accept attached take-profit, stop-loss, trailing-stop and OCO
policies:CreateOrderRequest.AttachedRisk, the newOrders.ModifyWith
(ModifyParams.NewAttachedRisk), andBatchReplaceItem.NewAttachedRisk
take a typedmodels.AttachedRiskInput. Create and modify results expose
the configured legs' trigger IDs. - Trigger events label standalone trailing-stop activation as
activated,
andTriggerEventTypeFromLabelacceptsactivatedas a filter. realtime.Client.SubscribeOrdersstreams an account's orders over the
private WebSocket (/v1/ws/private, subprotocolpolyester.v1.proto).
It delivers typedrealtime.OrderStreamEventvalues:OrderSnapshot
(the full live view, installed whole),OrderReady(the stream reflects
every acknowledgement given before the subscribe; wait for it before
trusting that a missing order does not exist; once per server
subscription, so again after a resubscribe or reconnect),OrderUnit
(changed orders, removed order IDs, and order events and command outcomes
asmodels.OrderUnitEvent),OrderStale,OrderStreamConnected,
OrderStreamDisconnectedandOrderStreamError. Sequence gaps, expiring
tokens, heartbeat loss and reconnects resume from the last applied
position; subscriptions of the same account share one server
subscription.realtime.ErrClientClosedis returned bySubscribeOrders(and
Orders.Subscribe) afterClient.Close. AClosethat races a
subscribe closes the new stream.errors.RealtimeErrorcarriesCode(the server's request error, for
exampleFORBIDDEN) andCloseCode(for example 4403) for the private
order stream.- Standalone trailing stops can buy.
Triggers.Createwith
trigger_typetrailing_stopacceptssidebuy; itslimitPriceis
the buy's maximum price, the most the child pays per unit, encoded at 9
decimal places. It is required for a buy, must be positive and at least
the activation price. Trigger reads project a buy's maximum price as
Trigger.LimitPrice;Trigger.SideandDetails.TroughPriceshow the
side and the lowest price since arming. - Stop-loss and take-profit market children carry a slippage cap:
CreateTriggerOptions.MaxSlippageTicksorMaxSlippageBpsis encoded on
the market child (previously it was dropped and the pair default
applied). At most one may be set; a buy accepts 1 to 10000 bps, a sell 1
to 9999; a limit child refuses a cap. Get, list and the trigger stream
expose it asTrigger.MaxSlippage/Trigger.MaxSlippageBps. A buy
stop-loss or take-profit may use a market child. Orders.CancelAllreturnsCancelledOrders(order ID and client order
ID, oldest first, at most 200),TotalCancelledandTruncated.MarketData.GetTradesAfterwalks a symbol's trades gap-free by match ID
and returnsCompleteThroughTradeID,NextAfterTradeIDandEpochEnds.
Start at"0"; both watermarks are always decimal match IDs,"0"
included, so an empty first page's cursor is valid for the retry.VIPStatus.SettledVolumeQualityandAverageAopQualityreport how
complete each rolling 30-day metric is.errors.MutationOutcomeUnknownreports true for
ERROR_CODE_ORDER_CANCEL_OUTCOME_UNKNOWNand
ERROR_CODE_ORDER_MODIFY_OUTCOME_UNKNOWN;errors.IsRetryablereports
true for them and forERROR_CODE_ACCOUNT_REPAIRING.
Fixed
- Labels for enum values newer than this SDK version (for example a new
trigger failure reason) readunknown(<n>)instead of panicking. - Account-scoped subscriptions given no account ID now use the client's
DefaultAccountIDvalue instead of formatting its pointer. - Order reads no longer report an attached-risk leg whose state is
not_configured; the server sends that state for a leg the order
does not have.
v0.1.0-alpha.56
Changed
- Release tags now use Go module versions (
v0.1.0-alpha.56), so
go get github.com/Fabric-Labs/polyester-sdk-go@v0.1.0-alpha.56records
that version. Earlier tags such asv0.1.0a55resolve to pseudo-versions.
Fixed
- Trigger reads report a buy trailing stop's child as
OrderTypelimit
(time in forceioc) at its maximum price, as the server places it;
v0.1.0a55 reportedmarket.