Skip to content

Trading Websocket

Request Format

Subscription to the following streams all follow this payload format:

{
    "stream": streamName,
    "feed": [feed1, feed2], // feed3, feed4, ...
    "method": "subscribe",
    "is_full": true
}

streamName is listed below each of the streams.

feed is an "Feed Selectors" which are the options joined together by -. For example, 123-PERPETUAL for the order stream denotes order updates for subaccount 123 for all perpetual instruments.

is_full is a boolean that denotes whether a "full" stream or "lite" stream will be returned.

Response Format

The response format for each of the streams is as follows:

{
    "stream": streamName,
    "subs": [feed1, feed2], // feed3, feed4, ...
    "unsubs": [feed5, feed6], // feed7, feed8, ...
}

streamName is the name of the stream that was specified in the request.

subs is an array of feeds that have been successfully subscribed to the stream.

unsubs is an array of feeds that have been unsubscribed from the stream as a result of the subscription. This can happen as an example of subscribing to the same stream with a "broader" parameter. For example, subscribing to 123-PERPETUAL and then subscribing to 123 will result in the 123-PERPETUAL feed being unsubscribed.

Order

Subscribes to a feed of order updates pertaining to orders made by your account.

Each Order can be uniquely identified by its order_id.

Stream Name: order
Feed Selector Example: 123-PERPETUAL-BTC-USDT@a
Order Feed Selector
Name Lite Type Description
sub_account_id sa uint64 The subaccount ID to filter by
kind k Kind The kind filter to apply.
underlying u Currency The underlying filter to apply.
quote q Currency The quote filter to apply.
state_filter sf OrderStateFilter create only, update only, all
Kind

The list of asset kinds that are supported on the GRVT exchange
Kind:

  • PERPETUAL = 1: the perpetual asset kind
  • FUTURE = 2: the future asset kind
  • CALL = 3: the call option asset kind
  • PUT = 4: the put option asset kind

Currency

The list of Currencies that are supported on the GRVT exchange
Currency:

  • USDC = 2: the USDC token
  • USDT = 3: the USDT token
  • ETH = 4: the ETH token
  • BTC = 5: the BTC token

OrderStateFilter

OrderStateFilter:

  • C = 1: create only filter
  • U = 2: update only filter
  • A = 3: create and update filter

Order Data Schema
Name Lite Type Description
stream s string Stream name
sequence_number sn uint64 A running sequence number that determines global message order within the specific stream
feed f Order The order object being created or updated
Order

Order is a typed payload used throughout the GRVT platform to express all orderbook, RFQ, and liquidation orders.
GRVT orders are capable of expressing both single-legged, and multi-legged orders by default.
This increases the learning curve slightly but reduces overall integration load, since the order payload is used across all GRVT trading venues.
Given GRVT's trustless settlement model, the Order payload also carries the signature, required to trade the order on our ZKSync Hyperchain.

All fields in the Order payload (except id, metadata, and state) are trustlessly enforced on our Hyperchain.
This minimizes the amount of trust users have to offer to GRVT

Name Lite Type Description
order_id oi uint128 [Filled by GRVT Backend] A unique 128-bit identifier for the order, deterministically generated within the GRVT backend
sub_account_id sa uint64 The subaccount initiating the order
is_market im bool If the order is a market order
Market Orders do not have a limit price, and are always executed according to the maker order price.
Market Orders must always be taker orders
time_in_force ti TimeInForce Four supported types of orders: GTT, IOC, AON, FOK:

  • PARTIAL EXECUTION = GTT / IOC - allows partial size execution on each leg

  • FULL EXECUTION = AON / FOK - only allows full size execution on all legs

  • TAKER ONLY = IOC / FOK - only allows taker orders

  • MAKER OR TAKER = GTT / AON - allows maker or taker orders

Exchange only supports (GTT, IOC, FOK)
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK)
taker_fee_percentage_cap tf int32 The taker fee percentage cap signed by the order.
This is the maximum taker fee percentage the order sender is willing to pay for the order.
Expressed in 1/100th of a basis point. Eg. 100 = 1bps, 10,000 = 1%
maker_fee_percentage_cap mf int32 Same as TakerFeePercentageCap, but for the maker fee. Negative for maker rebates
post_only po bool If True, Order must be a maker order. It has to fill the orderbook instead of match it.
If False, Order can be either a maker or taker order.

reduce_only ro bool If True, Order must reduce the position size, or be cancelled
legs l [OrderLeg] The legs present in this order
The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice
signature s Signature The signature approving this order
metadata m OrderMetadata Order Metadata, ignored by the smart contract, and unsigned by the client
state s1 OrderState [Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client
TimeInForce
Must Fill All Can Fill Partial
Must Fill Immediately FOK IOC
Can Fill Till Time AON GTC


TimeInForce:

  • GOOD_TILL_TIME = 1: GTT - Remains open until it is cancelled, or expired
  • ALL_OR_NONE = 2: AON - Either fill the whole order or none of it (Block Trades Only)
  • IMMEDIATE_OR_CANCEL = 3: IOC - Fill the order as much as possible, when hitting the orderbook. Then cancel it
  • FILL_OR_KILL = 4: FOK - Both AoN and IoC. Either fill the full order when hitting the orderbook, or cancel it

OrderLeg
Name Lite Type Description
instrument i string The instrument to trade in this leg
size s uint64 The total number of assets to trade in this leg, expressed in underlying asset decimal units.
limit_price lp uint64 The limit price of the order leg, expressed in 9 decimals.
This is the total amount of base currency to pay/receive for all legs.
oco_limit_price ol uint64 If a OCO order is specified, this must contain the other limit price
User must sign both limit prices. Depending on which trigger condition is activated, a different limit price is used
The smart contract will always validate both limit prices, by arranging them in ascending order
is_buying_asset ib bool Specifies if the order leg is a buy or sell
Signature
Name Lite Type Description
signer s uint256 The address (public key) of the wallet signing the payload
r r uint256 Signature R
s s1 uint256 Signature S
v v uint8 Signature V
expiration e Timestamp Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce n uint32 Users can randomly generate this value, used as a signature deconflicting key.
ie. You can send the same exact instruction twice with different nonces.
When the same nonce is used, the same payload will generate the same signature.
Our system will consider the payload a duplicate, and ignore it.
OrderMetadata

Metadata fields are used to support Backend only operations. These operations are not trustless by nature.
Hence, fields in here are never signed, and is never transmitted to the smart contract.

Name Lite Type Description
client_order_id co uint32 A unique identifier for the active order within a subaccount, specified by the client
This is used to identify the order in the client's system
This field can be used for order amendment/cancellation, but has no bearing on the smart contract layer
This field will not be propagated to the smart contract, and should not be signed by the client
This value must be unique for all active orders in a subaccount, or amendment/cancellation will not work as expected
Gravity UI will generate a random clientOrderID for each order in the range [0, 2^31 - 1]
To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^31, 2^32 - 1]

When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId
create_time ct Timestamp [Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds
OrderState
Name Lite Type Description
status s OrderStatus The status of the order
reject_reason rr OrderRejectReason The reason for rejection or cancellation
book_size bs [uint64] The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs
traded_size ts [uint64] The total number of assets traded. Sorted in same order as Order.Legs
update_time ut Timestamp Time at which the order was updated by GRVT, expressed in unix nanoseconds
OrderStatus

OrderStatus:

  • PENDING = 1: Order is waiting for Trigger Condition to be hit
  • OPEN = 2: Order is actively matching on the orderbook, could be unfilled or partially filled
  • FILLED = 3: Order is fully filled and hence closed
  • REJECTED = 4: Order is rejected by GRVT Backend since if fails a particular check (See OrderRejectReason)
  • CANCELLED = 5: Order is cancelled by the user using one of the supported APIs (See OrderRejectReason)

OrderRejectReason

OrderRejectReason:

  • CLIENT_CANCEL = 1: client called a Cancel API
  • CLIENT_BULK_CANCEL = 2: client called a Bulk Cancel API
  • CLIENT_SESSION_END = 3: client called a Session Cancel API, or set the WebSocket connection to 'cancelOrdersOnTerminate'
  • INSTRUMENT_DEACTIVATED = 4: instrument is no longer tradable on Gravity. (typically due to a market halt, or instrument expiry)
  • MM_PROTECTION = 5: market maker protection triggered
  • EXPIRED = 6: the order has expired
  • BELOW_MARGIN = 7: the order will bring the sub account below initial margin requirement
  • LIQUIDATION = 8: the sub account is liquidated (and all open orders are cancelled by Gravity)
  • SYSTEM_FAILOVER = 9: system failover resulting in loss of order state
  • CONFLICTING_SIGNATURE_HASH = 10: a previous order shares the same signature hash as your current order (typically when you submit the same signature twice)
  • OVERLAPPING_CLIENT_ORDER_ID = 11: an active order on your sub account shares the same clientOrderId
  • RFQ_CANCELLED = 12: the RFQ has been cancelled
  • AXE_CANCELLED = 13: the AXE has been cancelled
  • INVALID_ORDER = 14: the order payload contains one or more validation error (Trading Server will reply with a more specific error)
  • UNAUTHORISED = 15: the credentials used (userSession/apiKeySession/walletSignature) is not authorised to perform the action
  • FAIL_POST_ONLY = 16: when post-only order enters orderbook as a taker order
  • FAIL_REDUCE_ONLY = 17: when reduce-only order causes position size to increase
  • INVALID_TRIGGER_PRICE = 18: trigger price is on the wrong side of the trigger condition
  • RFQ_EXPIRED = 19: the RFQ has expired
  • AXE_EXPIRED = 20: the AXE has expired
  • FAIL_FOK = 21: the FOK order could not be fully matched
  • FAIL_AON = 22: the AON order could not be fully matched
  • SELF_MATCHED_SUBACCOUNT = 23: the order matched with another order from the same sub account
  • SIGNATURE_SIZE_EXCEEDED = 24: the signature size exceeds the maximum allowed size
  • SUB_ACCOUNT_NOT_FOUND = 25: the subaccount does not exist
  • BAD_SIGNATURE = 26: the signature is invalid
  • SIZE_NON_ZERO_ON_UNMACHED_LEG = 27: maker order size is non-zero on an unmatched leg
  • TRADE_SAME_SIDE = 28: the order trades with another order on the same side
  • TRADE_PRICE_DOES_NOT_CROSS = 29: the order trades with another order but the price does not cross
  • NO_LEG = 30: the order has no legs
  • MARKET_ORDER_ON_MAKER_SIDE = 31: market order on maker side
  • TIME_IN_FORCE_REQUIRE_TAKER = 32: time in force requires taker
  • ASSET_QUOTE_NOT_MATCHING = 33: asset quote not matching
  • MISSING_MARK_PRICE = 34: missing mark price
  • MISSING_INDEX_PRICE = 35: missing index price
  • SESSION_KEY_EXPIRED = 36: session key expired
  • DUPLICATE_LEG_ASSET = 37: duplicate leg asset
  • CHARGED_FEE_ABOVE_SIGNED_AMOUNT = 38: charged fee above signed amount
  • CHARGED_FEE_BELOW_MIN = 39: charged fee below minimum
  • NO_TRADE_PERMISSION = 40: no trade permission
  • NOT_MATCHED_AGAINS_TAKER_LEGS = 41: a maker order without any leg that is matched (size > 0) against at least 1 taker leg
  • ORDER_NOT_FULLY_MATCHED = 42: AON/FOK order not fully matched
  • ASSET_EXPIRED = 43: asset expired
  • NUM_LEGS_SIZE_MATCHED_MISMATCH = 44: number of legs and number of legs mismatch, eg: 2 legs, but sizeMatched is [1,2,3]

Example

{
    "stream": "order",
    "sequence_number": 12782,
    "feed": {
    {
        "order_id": "0x0123456789abcdef0123456789abcdef", // uint128 = 32 bytes
        "sub_account_id": 1,
        "is_market": false,
        "time_in_force": "GTT",
        "limit_price": "1000000000", // uint64
        "oco_limit_price": "1100000000", // uint64
        "taker_fee_percentage_cap": 500, // 5bps uint32
        "maker_fee_percentage_cap": 300, // 3bps uint32
        "post_only": true,
        "reduce_only": false,
        "is_paying_base_currency": true,
        "legs": [
            {
                "instrument": "BTC_USDT_Perp",
                "size": 10000000, // uint64
                "limit_price": 1000000, // uint64
                "oco_limit_price": 10000000, // uint64
                "is_buying_asset": true
            }
        ],
        "signature": {
            "r": "0x54730fcf60f37072926ba182d17e55e21104fbc22886d876a7e8b191b2d456f", // uint128 = 64 bytes
            "s": "0x1f32f41a809b2f2b888bddc2bdbf5ef709403a00d4e5e23dbaef09e55130464", // uint128 = 64 bytes
            "v": 27, // uint8
            "expiration": "1689526957000000" // uint64
        },
        "metadata": {
            "client_order_id": 2183798, // uint32
            "type": "OCO_LIMIT",
            "take_profit_trigger_condition": 1, // INDEX uint32
            "stop_loss_trigger_condition": 1, // INDEX uint32
            "take_profit_trigger_price": "1070000000", // uint64
            "stop_loss_trigger_price": "1020000000" // uint64
        },
        "state": {
            "status": 2, // OPEN uint32
            "reject_reason": 0, // NONE uint32
            "num_contracts_left": "500000000", // uint64
            "book_size": [1, 2, 3, 5], // []uint64
            "traded_size": [1, 2, 3, 5], // []uint64
            "update_time": 1000000000
        }
    }
}
Generic System Errors

We Adopt the GRPC error code system.

Failed API calls always return an error code. In some APIs, API level error codes will also be returned.

{
    "code": 3,
    "msg":"INVALID_ARGUMENT",
    "api_code": 1001,
    "api_msg": "INVALID_TIME_IN_FORCE"
}
Code Number Description
OK 0 Not an error; returned on success.
CANCELLED 1 The operation was cancelled, typically by the caller.
UNKNOWN 2 Unknown error. For example, this error may be returned when a Status value received from another address space belongs to an error space that is not known in this address space. Also errors raised by APIs that do not return enough error information may be converted to this error.
INVALID_ARGUMENT 3 The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the system (e.g., a malformed file name).
DEADLINE_EXCEEDED 4 The deadline expired before the operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long
NOT_FOUND 5 Some requested entity (e.g., file or directory) was not found. Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented allowlist, NOT_FOUND may be used. If a request is denied for some users within a class of users, such as user-based access control, PERMISSION_DENIED must be used.
ALREADY_EXISTS 6 The entity that a client attempted to create (e.g., file or directory) already exists.
PERMISSION_DENIED 7 The caller does not have permission to execute the specified operation. PERMISSION_DENIED must not be used for rejections caused by exhausting some resource (use RESOURCE_EXHAUSTED instead for those errors). PERMISSION_DENIED must not be used if the caller can not be identified (use UNAUTHENTICATED instead for those errors). This error code does not imply the request is valid or the requested entity exists or satisfies other pre-conditions.
RESOURCE_EXHAUSTED 8 Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space.
FAILED_PRECONDITION 9 The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc. Service implementors can use the following guidelines to decide between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: (a) Use UNAVAILABLE if the client can retry just the failing call. (b) Use ABORTED if the client should retry at a higher level (e.g., when a client-specified test-and-set fails, indicating the client should restart a read-modify-write sequence). (c) Use FAILED_PRECONDITION if the client should not retry until the system state has been explicitly fixed. E.g., if an "rmdir" fails because the directory is non-empty, FAILED_PRECONDITION should be returned since the client should not retry unless the files are deleted from the directory.
ABORTED 10 The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE.
OUT_OF_RANGE 11 The operation was attempted past the valid range. E.g., seeking or reading past end-of-file. Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state changes. For example, a 32-bit file system will generate INVALID_ARGUMENT if asked to read at an offset that is not in the range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from an offset past the current file size. There is a fair bit of overlap between FAILED_PRECONDITION and OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error) when it applies so that callers who are iterating through a space can easily look for an OUT_OF_RANGE error to detect when they are done.
UNIMPLEMENTED 12 The operation is not implemented or is not supported/enabled in this service.
INTERNAL 13 Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors.
UNAVAILABLE 14 The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations.
DATA_LOSS 15 Unrecoverable data loss or corruption.
UNAUTHENTICATED 16 The request does not have valid authentication credentials for the operation.

Position

Subscribes to a feed of position updates.

Stream Name: positions
Feed Selector Example: 123-PERPETUAL-BTC-USDT
Position Feed Selector
Name Lite Type Description
sub_account_id sa uint64 The subaccount ID to filter by
kind k Kind The kind filter to apply.
underlying u Currency The underlying filter to apply.
quote q Currency The quote filter to apply.
Kind

The list of asset kinds that are supported on the GRVT exchange
Kind:

  • PERPETUAL = 1: the perpetual asset kind
  • FUTURE = 2: the future asset kind
  • CALL = 3: the call option asset kind
  • PUT = 4: the put option asset kind

Currency

The list of Currencies that are supported on the GRVT exchange
Currency:

  • USDC = 2: the USDC token
  • USDT = 3: the USDT token
  • ETH = 4: the ETH token
  • BTC = 5: the BTC token

Position Data Schema
Name Lite Type Description
stream s string Stream name
sequence_number sn uint64 A running sequence number that determines global message order within the specific stream
feed f Positions A Position being created or updated matching the request filter
Positions
Name Lite Type Description
event_time et Timestamp Time at which the event was emitted in unix nanoseconds
sub_account_id sa uint64 The sub account ID that participated in the trade
instrument i string The instrument being represented
balance b int64 The balance of the position, expressed in underlying asset decimal units. Negative for short positions
value v int64 The value of the position, negative for short assets, expressed in quote asset decimal units
entry_price ep uint64 The entry price of the position, expressed in 9 decimals
Whenever increasing the balance of a position, the entry price is updated to the new average entry price
newEntryPrice = (oldEntryPrice * oldBalance + tradePrice * tradeBalance) / (oldBalance + tradeBalance)
exit_price ep1 uint64 The exit price of the position, expressed in 9 decimals
Whenever decreasing the balance of a position, the exit price is updated to the new average exit price
newExitPrice = (oldExitPrice * oldExitBalance + tradePrice * tradeBalance) / (oldExitBalance + tradeBalance)
mark_price mp uint64 The mark price of the position, expressed in 9 decimals
unrealized_pnl up int64 The unrealized PnL of the position, expressed in quote asset decimal units
unrealizedPnl = (markPrice - entryPrice) * balance
realized_pnl rp int64 The realized PnL of the position, expressed in quote asset decimal units
realizedPnl = (exitPrice - entryPrice) * exitBalance
pnl p int64 The total PnL of the position, expressed in quote asset decimal units
totalPnl = realizedPnl + unrealizedPnl
roi r float32 The ROI of the position, expressed as a percentage
roi = (pnl / (entryPrice * balance)) * 100

Example

{
    "stream": "positions",
    "sequence_number": 12782,
    "feed": {
    {
        "sub_account_id": "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", // uint128 = 64 bytes
        "margin_type": 3, // PORTFOLIO_CROSS_MARGIN uint32
        "quote_currency": 1, // USDC uint32
        "pending_deposit": "450000000", // uint64
        "derivative_positions": [
            {
                "derivative": {
                    "instrument": 3, // CALL uint8
                    "underlying": 4, // ETH uint8
                    "quote": 1, // USDC uint8
                    "expiration": "1689526957000000", // uint64
                    "strike_price": "1000000000", // uint64
                },
                "contract_balance": "1000000000", // uint64
                "unrealized_pnl":"4452000000"
            },
            {
                "derivative": {
                    "instrument": 4, // PUT uint8
                    "underlying": 4, // ETH uint8
                    "quote": 1, // USDC uint8
                    "expiration": "1689529888000000", // uint64
                    "strike_price": "1000000000", // uint64
                },
                "contract_balance": "-1000000000", // uint64
                "unrealized_pnl":"1000000000"
            }
        ],
        "unrealized_pnl": "3452000000", // uint64
        "initial_margin": ["1269146471088859254", 0.45],
        "maintanence_margin": ["269146471088859254", 0.08],
        "current_margin": ["1569146471088859254", 0.56],
        "is_under_liquidation": false
    }
}
Generic System Errors

We Adopt the GRPC error code system.

Failed API calls always return an error code. In some APIs, API level error codes will also be returned.

{
    "code": 3,
    "msg":"INVALID_ARGUMENT",
    "api_code": 1001,
    "api_msg": "INVALID_TIME_IN_FORCE"
}
Code Number Description
OK 0 Not an error; returned on success.
CANCELLED 1 The operation was cancelled, typically by the caller.
UNKNOWN 2 Unknown error. For example, this error may be returned when a Status value received from another address space belongs to an error space that is not known in this address space. Also errors raised by APIs that do not return enough error information may be converted to this error.
INVALID_ARGUMENT 3 The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the system (e.g., a malformed file name).
DEADLINE_EXCEEDED 4 The deadline expired before the operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long
NOT_FOUND 5 Some requested entity (e.g., file or directory) was not found. Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented allowlist, NOT_FOUND may be used. If a request is denied for some users within a class of users, such as user-based access control, PERMISSION_DENIED must be used.
ALREADY_EXISTS 6 The entity that a client attempted to create (e.g., file or directory) already exists.
PERMISSION_DENIED 7 The caller does not have permission to execute the specified operation. PERMISSION_DENIED must not be used for rejections caused by exhausting some resource (use RESOURCE_EXHAUSTED instead for those errors). PERMISSION_DENIED must not be used if the caller can not be identified (use UNAUTHENTICATED instead for those errors). This error code does not imply the request is valid or the requested entity exists or satisfies other pre-conditions.
RESOURCE_EXHAUSTED 8 Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space.
FAILED_PRECONDITION 9 The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc. Service implementors can use the following guidelines to decide between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: (a) Use UNAVAILABLE if the client can retry just the failing call. (b) Use ABORTED if the client should retry at a higher level (e.g., when a client-specified test-and-set fails, indicating the client should restart a read-modify-write sequence). (c) Use FAILED_PRECONDITION if the client should not retry until the system state has been explicitly fixed. E.g., if an "rmdir" fails because the directory is non-empty, FAILED_PRECONDITION should be returned since the client should not retry unless the files are deleted from the directory.
ABORTED 10 The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE.
OUT_OF_RANGE 11 The operation was attempted past the valid range. E.g., seeking or reading past end-of-file. Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state changes. For example, a 32-bit file system will generate INVALID_ARGUMENT if asked to read at an offset that is not in the range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from an offset past the current file size. There is a fair bit of overlap between FAILED_PRECONDITION and OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error) when it applies so that callers who are iterating through a space can easily look for an OUT_OF_RANGE error to detect when they are done.
UNIMPLEMENTED 12 The operation is not implemented or is not supported/enabled in this service.
INTERNAL 13 Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors.
UNAVAILABLE 14 The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations.
DATA_LOSS 15 Unrecoverable data loss or corruption.
UNAUTHENTICATED 16 The request does not have valid authentication credentials for the operation.

Trade

Subscribes to a feed of trade updates. All trades fulfilled on Orderbook, RFQ venues will provide an update here.

Stream Name: trade
Feed Selector Example: 123-PERPETUAL-BTC-USDT
Private Trade Feed Selector
Name Lite Type Description
sub_account_id sa uint64 The sub account ID to request for
kind k Kind The kind filter to apply.
underlying u Currency The underlying filter to apply.
quote q Currency The quote filter to apply.
Kind

The list of asset kinds that are supported on the GRVT exchange
Kind:

  • PERPETUAL = 1: the perpetual asset kind
  • FUTURE = 2: the future asset kind
  • CALL = 3: the call option asset kind
  • PUT = 4: the put option asset kind

Currency

The list of Currencies that are supported on the GRVT exchange
Currency:

  • USDC = 2: the USDC token
  • USDT = 3: the USDT token
  • ETH = 4: the ETH token
  • BTC = 5: the BTC token

Private Trade Data Schema
Name Lite Type Description
stream s string The websocket channel to which the response is sent
sequence_number sn uint64 A running sequence number that determines global message order within the specific stream
feed f PrivateTrade A private trade matching the request filter
PrivateTrade
Name Lite Type Description
event_time et Timestamp Time at which the event was emitted in unix nanoseconds
sub_account_id sa uint64 The sub account ID that participated in the trade
instrument i string The instrument being represented
is_buyer ib bool The side that the subaccount took on the trade
is_taker it bool The role that the subaccount took on the trade
size s uint64 The number of assets being traded, expressed in underlying asset decimal units
price p uint64 The traded price, expressed in 9 decimals
mark_price mp uint64 The mark price of the instrument at point of trade, expressed in 9 decimals
index_price ip uint64 The index price of the instrument at point of trade, expressed in 9 decimals
interest_rate ir int32 The interest rate of the underlying at point of trade, expressed in centibeeps (1/100th of a basis point)
forward_price fp uint64 [Options] The forward price of the option at point of trade, expressed in 9 decimals
realized_pnl rp int64 The realized PnL of the trade, expressed in quote asset decimal units (0 if increasing position size)
fee f int64 The fees paid on the trade, expressed in quote asset decimal unit (negative if maker rebate applied)
fee_rate fr int32 The fee rate paid on the trade
trade_id ti uint64 A trade identifier
order_id oi uint128 An order identifier
venue v Venue The venue where the trade occurred
Venue

The list of Trading Venues that are supported on the GRVT exchange
Venue:

  • ORDERBOOK = 1: the trade is cleared on the orderbook venue
  • RFQ = 2: the trade is cleared on the RFQ venue
  • AXE = 3: the trade is cleared on the AXE venue

Example

{
    "stream": "trade",
    "sequence_number": 12782,
    "feed": {
    {
        "event_time": 1707971008,
        "sub_account_id": 1,
        "instrument": "BTC_USDT_PERP",
        "is_buyer": true,
        "is_taker": false,
        "price": 10000000,
        "mark_price": 10000000,
        "realized_pnl": 60000,
        "fee": 1000,
        "fee_rate": 10000,
        "trade_id": 1,
        "order_id": "0x0123456789abcdef0123456789abcdef", // uint128 = 32 bytes
        "venue": 2,
        "greeks":
        {
            "underlying_price": 34796430000,
            "risk_free_rate": 5000,
            "delta": 75.3432,
            "gamma": 0.367,
            "iv": 0.234,
            "vega": 60.23425,
            "volga": 6.742,
            "vanna": 0.234,
            "theta": 0.0126,
            "rho": 34.234
        }
    }
}
Generic System Errors

We Adopt the GRPC error code system.

Failed API calls always return an error code. In some APIs, API level error codes will also be returned.

{
    "code": 3,
    "msg":"INVALID_ARGUMENT",
    "api_code": 1001,
    "api_msg": "INVALID_TIME_IN_FORCE"
}
Code Number Description
OK 0 Not an error; returned on success.
CANCELLED 1 The operation was cancelled, typically by the caller.
UNKNOWN 2 Unknown error. For example, this error may be returned when a Status value received from another address space belongs to an error space that is not known in this address space. Also errors raised by APIs that do not return enough error information may be converted to this error.
INVALID_ARGUMENT 3 The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the system (e.g., a malformed file name).
DEADLINE_EXCEEDED 4 The deadline expired before the operation could complete. For operations that change the state of the system, this error may be returned even if the operation has completed successfully. For example, a successful response from a server could have been delayed long
NOT_FOUND 5 Some requested entity (e.g., file or directory) was not found. Note to server developers: if a request is denied for an entire class of users, such as gradual feature rollout or undocumented allowlist, NOT_FOUND may be used. If a request is denied for some users within a class of users, such as user-based access control, PERMISSION_DENIED must be used.
ALREADY_EXISTS 6 The entity that a client attempted to create (e.g., file or directory) already exists.
PERMISSION_DENIED 7 The caller does not have permission to execute the specified operation. PERMISSION_DENIED must not be used for rejections caused by exhausting some resource (use RESOURCE_EXHAUSTED instead for those errors). PERMISSION_DENIED must not be used if the caller can not be identified (use UNAUTHENTICATED instead for those errors). This error code does not imply the request is valid or the requested entity exists or satisfies other pre-conditions.
RESOURCE_EXHAUSTED 8 Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system is out of space.
FAILED_PRECONDITION 9 The operation was rejected because the system is not in a state required for the operation's execution. For example, the directory to be deleted is non-empty, an rmdir operation is applied to a non-directory, etc. Service implementors can use the following guidelines to decide between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: (a) Use UNAVAILABLE if the client can retry just the failing call. (b) Use ABORTED if the client should retry at a higher level (e.g., when a client-specified test-and-set fails, indicating the client should restart a read-modify-write sequence). (c) Use FAILED_PRECONDITION if the client should not retry until the system state has been explicitly fixed. E.g., if an "rmdir" fails because the directory is non-empty, FAILED_PRECONDITION should be returned since the client should not retry unless the files are deleted from the directory.
ABORTED 10 The operation was aborted, typically due to a concurrency issue such as a sequencer check failure or transaction abort. See the guidelines above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE.
OUT_OF_RANGE 11 The operation was attempted past the valid range. E.g., seeking or reading past end-of-file. Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system state changes. For example, a 32-bit file system will generate INVALID_ARGUMENT if asked to read at an offset that is not in the range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from an offset past the current file size. There is a fair bit of overlap between FAILED_PRECONDITION and OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error) when it applies so that callers who are iterating through a space can easily look for an OUT_OF_RANGE error to detect when they are done.
UNIMPLEMENTED 12 The operation is not implemented or is not supported/enabled in this service.
INTERNAL 13 Internal errors. This means that some invariants expected by the underlying system have been broken. This error code is reserved for serious errors.
UNAVAILABLE 14 The service is currently unavailable. This is most likely a transient condition, which can be corrected by retrying with a backoff. Note that it is not always safe to retry non-idempotent operations.
DATA_LOSS 15 Unrecoverable data loss or corruption.
UNAUTHENTICATED 16 The request does not have valid authentication credentials for the operation.