Trading APIs
All requests should be made using the POST HTTP method.
Order
Create Order
FULL ENDPOINT: full/v1/create_order
LITE ENDPOINT: lite/v1/create_order
Create an order on the orderbook for this trading account.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
ordero |
Order | True | The order to create |
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
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
order_idoi |
string | False0 |
[Filled by GRVT Backend] A unique 128-bit identifier for the order, deterministically generated within the GRVT backend |
sub_account_idsa |
string | True | The subaccount initiating the order |
is_marketim |
boolean | Falsefalse |
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_forceti |
TimeInForce | True | Four supported types of orders: GTT, IOC, AON, FOK:
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK) |
post_onlypo |
boolean | Falsefalse |
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. In this case, order creation is currently subject to a speedbump of 25ms to ensure orders are matched against updated orderbook quotes. |
reduce_onlyro |
boolean | Falsefalse |
If True, Order must reduce the position size, or be cancelled |
legsl |
[OrderLeg] | True | The legs present in this order The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice |
signatures |
Signature | True | The signature approving this order |
metadatam |
OrderMetadata | True | Order Metadata, ignored by the smart contract, and unsigned by the client |
states1 |
OrderState | False'' |
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client |
builderb |
string | True | The main account ID of the builder |
builder_feebf |
string | True | Builder fee charged for this order, expressed as a percentage (e.g., 0.001 means 0.001%). |
TimeInForce
| Must Fill All | Can Fill Partial | |
|---|---|---|
| Must Fill Immediately | FOK | IOC |
| Can Fill Till Time | AON | GTC |
| Value | Description |
|---|---|
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 |
RETAIL_PRICE_IMPROVEMENT = 5 |
RPI - A GTT + PostOnly maker order, that can only be taken by non-algorithmic UI users. |
OrderLeg
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The instrument to trade in this leg |
sizes |
string | True | The total number of assets to trade in this leg, expressed in base asset decimal units. |
limit_pricelp |
string | False0 |
The limit price of the order leg, expressed in 9 decimals.This is the number of quote currency units to pay/receive for this leg. This should be null/0 if the order is a market order |
is_buying_assetib |
boolean | True | Specifies if the order leg is a buy or sell |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
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.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
client_order_idco |
string | True | 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^63 - 1] To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^63, 2^64 - 1] When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId |
create_timect |
string | False0 |
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds |
triggert |
TriggerOrderMetadata | False `` |
Trigger fields are used to support any type of trigger order such as TP/SL |
brokerb |
BrokerTag | False `` |
Specifies the broker who brokered the order |
TriggerOrderMetadata
Contains metadata related to trigger orders, such as Take Profit (TP) or Stop Loss (SL).
Trigger orders are used to automatically execute an order when a predefined price condition is met, allowing traders to implement risk management strategies.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_typett |
TriggerType | True | Type of the trigger order. eg: Take Profit, Stop Loss, etc |
tpslt |
TPSLOrderMetadata | True | Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders. |
TriggerType
Defines the type of trigger order used in trading, such as Take Profit or Stop Loss.
Trigger orders allow execution based on pre-defined price conditions rather than immediate market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Not a trigger order. The order executes normally without any trigger conditions. |
TAKE_PROFIT = 1 |
Take Profit Order - Executes when the price reaches a specified level to secure profits. |
STOP_LOSS = 2 |
Stop Loss Order - Executes when the price reaches a specified level to limit losses. |
TPSLOrderMetadata
Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_bytb |
TriggerBy | True | Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order |
trigger_pricetp |
string | True | The Trigger Price of the order, expressed in 9 decimals. |
close_positioncp |
boolean | True | If True, the order will close the position when the trigger price is reached |
is_split_positionis |
boolean | True | If True, the order will be treated as part of a position's split-TP/SL set, subject to aggregate size/count limits. |
TriggerBy
Defines the price type that activates a Take Profit (TP) or Stop Loss (SL) order.
Trigger orders are executed when the selected price type reaches the specified trigger price.Different price types ensure flexibility in executing strategies based on market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
no trigger condition |
INDEX = 1 |
INDEX - Order is activated when the index price reaches the trigger price |
LAST = 2 |
LAST - Order is activated when the last trade price reaches the trigger price |
MID = 3 |
MID - Order is activated when the mid price reaches the trigger price |
MARK = 4 |
MARK - Order is activated when the mark price reaches the trigger price |
BrokerTag
BrokerTag is a tag for the broker that the order is sent from.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
COIN_ROUTES = 1 |
CoinRoutes |
ALERTATRON = 2 |
Alertatron |
ORIGAMI = 3 |
Origami |
OrderState
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
statuss |
OrderStatus | True | The status of the order |
reject_reasonrr |
OrderRejectReason | True | The reason for rejection or cancellation |
book_sizebs |
[string] | True | The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs |
traded_sizets |
[string] | True | The total number of assets traded. Sorted in same order as Order.Legs |
update_timeut |
string | True | Time at which the order was updated by GRVT, expressed in unix nanoseconds |
avg_fill_priceaf |
[string] | True | The average fill price of the order. Sorted in same order as Order.Legs |
OrderStatus
| Value | Description |
|---|---|
PENDING = 1 |
Order has been sent to the matching engine and is pending a transition to open/filled/rejected. |
OPEN = 2 |
Order is actively matching on the matching engine, could be unfilled or partially filled. |
FILLED = 3 |
Order is fully filled and hence closed. Taker Orders can transition directly from pending to filled, without going through open. |
REJECTED = 4 |
Order is rejected by matching engine since if fails a particular check (See OrderRejectReason). Once an order is open, it cannot be rejected. |
CANCELLED = 5 |
Order is cancelled by the user using one of the supported APIs (See OrderRejectReason). Before an order is open, it cannot be cancelled. |
OrderRejectReason
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
order is not cancelled or rejected |
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' |
MARKET_CANCEL = 4 |
the market order was cancelled after no/partial fill. Lower precedence than other TimeInForce cancel reasons |
IOC_CANCEL = 5 |
the IOC order was cancelled after no/partial fill |
AON_CANCEL = 6 |
the AON order was cancelled as it could not be fully matched |
FOK_CANCEL = 7 |
the FOK order was cancelled as it could not be fully matched |
EXPIRED = 8 |
the order was cancelled as it has expired |
FAIL_POST_ONLY = 9 |
the post-only order could not be posted into the orderbook |
FAIL_REDUCE_ONLY = 10 |
the reduce-only order would have caused position size to increase |
MM_PROTECTION = 11 |
the order was cancelled due to market maker protection trigger |
SELF_TRADE_PROTECTION = 12 |
the order was cancelled due to self-trade protection trigger |
SELF_MATCHED_SUBACCOUNT = 13 |
the order matched with another order from the same sub account |
OVERLAPPING_CLIENT_ORDER_ID = 14 |
an active order on your sub account shares the same clientOrderId |
BELOW_MARGIN = 15 |
the order will bring the sub account below initial margin requirement |
LIQUIDATION = 16 |
the sub account is liquidated (and all open orders are cancelled by Gravity) |
INSTRUMENT_INVALID = 17 |
instrument is invalid or not found on Gravity |
INSTRUMENT_DEACTIVATED = 18 |
instrument is no longer tradable on Gravity. (typically due to a market halt, or instrument expiry) |
SYSTEM_FAILOVER = 19 |
system failover resulting in loss of order state |
UNAUTHORISED = 20 |
the credentials used (userSession/apiKeySession/walletSignature) is not authorised to perform the action |
SESSION_KEY_EXPIRED = 21 |
the session key used to sign the order expired |
SUB_ACCOUNT_NOT_FOUND = 22 |
the subaccount does not exist |
NO_TRADE_PERMISSION = 23 |
the signature used to sign the order has no trade permission |
UNSUPPORTED_TIME_IN_FORCE = 24 |
the order payload does not contain a supported TimeInForce value |
MULTI_LEGGED_ORDER = 25 |
the order has multiple legs, but multiple legs are not supported by this venue |
EXCEED_MAX_POSITION_SIZE = 26 |
the order would have caused the subaccount to exceed the max position size |
EXCEED_MAX_SIGNATURE_EXPIRATION = 27 |
the signature supplied is more than 30 days in the future |
MARKET_ORDER_WITH_LIMIT_PRICE = 28 |
the market order has a limit price set |
CLIENT_CANCEL_ON_DISCONNECT_TRIGGERED = 29 |
client cancel on disconnect triggered |
OCO_COUNTER_PART_TRIGGERED = 30 |
the OCO counter part order was triggered |
REDUCE_ONLY_LIMIT = 31 |
the remaining order size was cancelled because it exceeded current position size |
CLIENT_REPLACE = 32 |
the order was replaced by a client replace request |
DERISK_MUST_BE_IOC = 33 |
the derisk order must be an IOC order |
DERISK_MUST_BE_REDUCE_ONLY = 34 |
the derisk order must be a reduce-only order |
DERISK_NOT_SUPPORTED = 35 |
derisk is not supported |
INVALID_ORDER_TYPE = 36 |
the order type is invalid |
CURRENCY_NOT_DEFINED = 37 |
the currency is not defined |
INVALID_CHAIN_ID = 38 |
the chain ID is invalid |
BUILDER_ORDER_FEE_EXCEED = 39 |
Builder fee exceed the limit |
BUILDER_ORDER_FEE_NEGATIVE = 40 |
Builder fee is below 0 |
BUILDER_ORDER_BUILDER_NOT_AUTHORIZED = 41 |
Builder is not an authorized builder for client |
BUILDER_ORDER_BUILDER_NOT_EXIST = 42 |
Builder does not exist |
TRADE_PRICE_WORSE_THAN_BANKRUPTCY_PRICE = 44 |
the trade price is worse than the bankruptcy price |
TOO_MANY_MAKER_ORDERS = 45 |
the order was cancelled due to matching with too many maker orders |
REDUCE_ONLY_NOT_SUPPORTED_FOR_SPOT_ORDER = 46 |
reduce-only order is not supported for spot order |
TPSL_NOT_SUPPORTED_FOR_SPOT_ORDER = 47 |
tpsl is not supported for spot order |
SPOT_ORDER_NOT_SUPPORTED = 48 |
spot order is not supported |
INSUFFICIENT_BALANCE = 49 |
the subaccount has insufficient balance |
SPOT_TRADING_BLOCKED_DURING_SOCIALIZED_LOSS = 50 |
spot trading is blocked during socialized loss (SLOW) |
BELOW_MARGIN_WITH_PENALTY_DEVIATION = 51 |
the order will bring the sub account below initial margin requirement considering wide price deviation |
Query
Full Request
{
"order": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
}
{
"o": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Order | True | The created order |
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
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
order_idoi |
string | False0 |
[Filled by GRVT Backend] A unique 128-bit identifier for the order, deterministically generated within the GRVT backend |
sub_account_idsa |
string | True | The subaccount initiating the order |
is_marketim |
boolean | Falsefalse |
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_forceti |
TimeInForce | True | Four supported types of orders: GTT, IOC, AON, FOK:
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK) |
post_onlypo |
boolean | Falsefalse |
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. In this case, order creation is currently subject to a speedbump of 25ms to ensure orders are matched against updated orderbook quotes. |
reduce_onlyro |
boolean | Falsefalse |
If True, Order must reduce the position size, or be cancelled |
legsl |
[OrderLeg] | True | The legs present in this order The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice |
signatures |
Signature | True | The signature approving this order |
metadatam |
OrderMetadata | True | Order Metadata, ignored by the smart contract, and unsigned by the client |
states1 |
OrderState | False'' |
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client |
builderb |
string | True | The main account ID of the builder |
builder_feebf |
string | True | Builder fee charged for this order, expressed as a percentage (e.g., 0.001 means 0.001%). |
TimeInForce
| Must Fill All | Can Fill Partial | |
|---|---|---|
| Must Fill Immediately | FOK | IOC |
| Can Fill Till Time | AON | GTC |
| Value | Description |
|---|---|
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 |
RETAIL_PRICE_IMPROVEMENT = 5 |
RPI - A GTT + PostOnly maker order, that can only be taken by non-algorithmic UI users. |
OrderLeg
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The instrument to trade in this leg |
sizes |
string | True | The total number of assets to trade in this leg, expressed in base asset decimal units. |
limit_pricelp |
string | False0 |
The limit price of the order leg, expressed in 9 decimals.This is the number of quote currency units to pay/receive for this leg. This should be null/0 if the order is a market order |
is_buying_assetib |
boolean | True | Specifies if the order leg is a buy or sell |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
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.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
client_order_idco |
string | True | 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^63 - 1] To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^63, 2^64 - 1] When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId |
create_timect |
string | False0 |
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds |
triggert |
TriggerOrderMetadata | False `` |
Trigger fields are used to support any type of trigger order such as TP/SL |
brokerb |
BrokerTag | False `` |
Specifies the broker who brokered the order |
TriggerOrderMetadata
Contains metadata related to trigger orders, such as Take Profit (TP) or Stop Loss (SL).
Trigger orders are used to automatically execute an order when a predefined price condition is met, allowing traders to implement risk management strategies.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_typett |
TriggerType | True | Type of the trigger order. eg: Take Profit, Stop Loss, etc |
tpslt |
TPSLOrderMetadata | True | Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders. |
TriggerType
Defines the type of trigger order used in trading, such as Take Profit or Stop Loss.
Trigger orders allow execution based on pre-defined price conditions rather than immediate market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Not a trigger order. The order executes normally without any trigger conditions. |
TAKE_PROFIT = 1 |
Take Profit Order - Executes when the price reaches a specified level to secure profits. |
STOP_LOSS = 2 |
Stop Loss Order - Executes when the price reaches a specified level to limit losses. |
TPSLOrderMetadata
Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_bytb |
TriggerBy | True | Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order |
trigger_pricetp |
string | True | The Trigger Price of the order, expressed in 9 decimals. |
close_positioncp |
boolean | True | If True, the order will close the position when the trigger price is reached |
is_split_positionis |
boolean | True | If True, the order will be treated as part of a position's split-TP/SL set, subject to aggregate size/count limits. |
TriggerBy
Defines the price type that activates a Take Profit (TP) or Stop Loss (SL) order.
Trigger orders are executed when the selected price type reaches the specified trigger price.Different price types ensure flexibility in executing strategies based on market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
no trigger condition |
INDEX = 1 |
INDEX - Order is activated when the index price reaches the trigger price |
LAST = 2 |
LAST - Order is activated when the last trade price reaches the trigger price |
MID = 3 |
MID - Order is activated when the mid price reaches the trigger price |
MARK = 4 |
MARK - Order is activated when the mark price reaches the trigger price |
BrokerTag
BrokerTag is a tag for the broker that the order is sent from.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
COIN_ROUTES = 1 |
CoinRoutes |
ALERTATRON = 2 |
Alertatron |
ORIGAMI = 3 |
Origami |
OrderState
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
statuss |
OrderStatus | True | The status of the order |
reject_reasonrr |
OrderRejectReason | True | The reason for rejection or cancellation |
book_sizebs |
[string] | True | The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs |
traded_sizets |
[string] | True | The total number of assets traded. Sorted in same order as Order.Legs |
update_timeut |
string | True | Time at which the order was updated by GRVT, expressed in unix nanoseconds |
avg_fill_priceaf |
[string] | True | The average fill price of the order. Sorted in same order as Order.Legs |
OrderStatus
| Value | Description |
|---|---|
PENDING = 1 |
Order has been sent to the matching engine and is pending a transition to open/filled/rejected. |
OPEN = 2 |
Order is actively matching on the matching engine, could be unfilled or partially filled. |
FILLED = 3 |
Order is fully filled and hence closed. Taker Orders can transition directly from pending to filled, without going through open. |
REJECTED = 4 |
Order is rejected by matching engine since if fails a particular check (See OrderRejectReason). Once an order is open, it cannot be rejected. |
CANCELLED = 5 |
Order is cancelled by the user using one of the supported APIs (See OrderRejectReason). Before an order is open, it cannot be cancelled. |
OrderRejectReason
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
order is not cancelled or rejected |
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' |
MARKET_CANCEL = 4 |
the market order was cancelled after no/partial fill. Lower precedence than other TimeInForce cancel reasons |
IOC_CANCEL = 5 |
the IOC order was cancelled after no/partial fill |
AON_CANCEL = 6 |
the AON order was cancelled as it could not be fully matched |
FOK_CANCEL = 7 |
the FOK order was cancelled as it could not be fully matched |
EXPIRED = 8 |
the order was cancelled as it has expired |
FAIL_POST_ONLY = 9 |
the post-only order could not be posted into the orderbook |
FAIL_REDUCE_ONLY = 10 |
the reduce-only order would have caused position size to increase |
MM_PROTECTION = 11 |
the order was cancelled due to market maker protection trigger |
SELF_TRADE_PROTECTION = 12 |
the order was cancelled due to self-trade protection trigger |
SELF_MATCHED_SUBACCOUNT = 13 |
the order matched with another order from the same sub account |
OVERLAPPING_CLIENT_ORDER_ID = 14 |
an active order on your sub account shares the same clientOrderId |
BELOW_MARGIN = 15 |
the order will bring the sub account below initial margin requirement |
LIQUIDATION = 16 |
the sub account is liquidated (and all open orders are cancelled by Gravity) |
INSTRUMENT_INVALID = 17 |
instrument is invalid or not found on Gravity |
INSTRUMENT_DEACTIVATED = 18 |
instrument is no longer tradable on Gravity. (typically due to a market halt, or instrument expiry) |
SYSTEM_FAILOVER = 19 |
system failover resulting in loss of order state |
UNAUTHORISED = 20 |
the credentials used (userSession/apiKeySession/walletSignature) is not authorised to perform the action |
SESSION_KEY_EXPIRED = 21 |
the session key used to sign the order expired |
SUB_ACCOUNT_NOT_FOUND = 22 |
the subaccount does not exist |
NO_TRADE_PERMISSION = 23 |
the signature used to sign the order has no trade permission |
UNSUPPORTED_TIME_IN_FORCE = 24 |
the order payload does not contain a supported TimeInForce value |
MULTI_LEGGED_ORDER = 25 |
the order has multiple legs, but multiple legs are not supported by this venue |
EXCEED_MAX_POSITION_SIZE = 26 |
the order would have caused the subaccount to exceed the max position size |
EXCEED_MAX_SIGNATURE_EXPIRATION = 27 |
the signature supplied is more than 30 days in the future |
MARKET_ORDER_WITH_LIMIT_PRICE = 28 |
the market order has a limit price set |
CLIENT_CANCEL_ON_DISCONNECT_TRIGGERED = 29 |
client cancel on disconnect triggered |
OCO_COUNTER_PART_TRIGGERED = 30 |
the OCO counter part order was triggered |
REDUCE_ONLY_LIMIT = 31 |
the remaining order size was cancelled because it exceeded current position size |
CLIENT_REPLACE = 32 |
the order was replaced by a client replace request |
DERISK_MUST_BE_IOC = 33 |
the derisk order must be an IOC order |
DERISK_MUST_BE_REDUCE_ONLY = 34 |
the derisk order must be a reduce-only order |
DERISK_NOT_SUPPORTED = 35 |
derisk is not supported |
INVALID_ORDER_TYPE = 36 |
the order type is invalid |
CURRENCY_NOT_DEFINED = 37 |
the currency is not defined |
INVALID_CHAIN_ID = 38 |
the chain ID is invalid |
BUILDER_ORDER_FEE_EXCEED = 39 |
Builder fee exceed the limit |
BUILDER_ORDER_FEE_NEGATIVE = 40 |
Builder fee is below 0 |
BUILDER_ORDER_BUILDER_NOT_AUTHORIZED = 41 |
Builder is not an authorized builder for client |
BUILDER_ORDER_BUILDER_NOT_EXIST = 42 |
Builder does not exist |
TRADE_PRICE_WORSE_THAN_BANKRUPTCY_PRICE = 44 |
the trade price is worse than the bankruptcy price |
TOO_MANY_MAKER_ORDERS = 45 |
the order was cancelled due to matching with too many maker orders |
REDUCE_ONLY_NOT_SUPPORTED_FOR_SPOT_ORDER = 46 |
reduce-only order is not supported for spot order |
TPSL_NOT_SUPPORTED_FOR_SPOT_ORDER = 47 |
tpsl is not supported for spot order |
SPOT_ORDER_NOT_SUPPORTED = 48 |
spot order is not supported |
INSUFFICIENT_BALANCE = 49 |
the subaccount has insufficient balance |
SPOT_TRADING_BLOCKED_DURING_SOCIALIZED_LOSS = 50 |
spot trading is blocked during socialized loss (SLOW) |
BELOW_MARGIN_WITH_PENALTY_DEVIATION = 51 |
the order will bring the sub account below initial margin requirement considering wide price deviation |
Success
Full Response
{
"result": {
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
}
{
"r": {
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1004 | 404 | Data Not Found |
| 1005 | 500 | Unknown Error |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 1400 | 403 | Signer does not have trade permission |
| 1009 | 503 | We are temporarily deactivating this API endpoint, please try again later |
| 1012 | 400 | Invalid signature chain ID |
| 2000 | 403 | Signature is from an unauthorized signer |
| 2001 | 403 | Signature has expired |
| 2002 | 403 | Signature does not match payload |
| 2003 | 403 | Order sub account does not match logged in user |
| 2004 | 403 | Signature is from an expired session key |
| 2006 | 403 | Signature R/S must have exactly 64 characters long without 0x prefix |
| 2005 | 403 | Signature V must be 27/28 |
| 2007 | 403 | Signature S must be in the lower half of the curve |
| 2010 | 400 | Order ID should be empty when creating an order |
| 2011 | 400 | Client Order ID should be supplied when creating an order |
| 2012 | 400 | Client Order ID overlaps with existing active order |
| 2030 | 400 | Orderbook Orders must have a TimeInForce of GTT/IOC/FOK |
| 2031 | 400 | RFQ Orders must have a TimeInForce of GTT/AON/IOC/FOK |
| 2032 | 400 | Post Only can only be set to true for GTT/AON orders |
| 2020 | 400 | Market Order must always be supplied without a limit price |
| 2021 | 400 | Limit Order must always be supplied with a limit price |
| 2040 | 400 | Order must contain at least one leg |
| 2041 | 400 | Order Legs must be sorted by Derivative.Instrument/Underlying/BaseCurrency/Expiration/StrikePrice |
| 2042 | 400 | Orderbook Orders must contain only one leg |
| 2050 | 400 | Order state must be empty upon creation |
| 2051 | 400 | Order execution metadata must be empty upon creation |
| 2060 | 400 | Order Legs contain one or more inactive derivative |
| 2061 | 400 | Unsupported Instrument Requested |
| 2062 | 400 | Order size smaller than min size |
| 2063 | 400 | Order size smaller than min block size in block trade venue |
| 2064 | 400 | Invalid limit price tick |
| 2065 | 400 | Order size too granular |
| 2066 | 400 | Order below minimum notional. Please try again with a higher price or size. |
| 2067 | 400 | Order below minimum notional. Please try reducing your position again with a higher price or size. |
| 2070 | 400 | Liquidation Order is not supported |
| 2080 | 400 | Insufficient margin to create order |
| 2081 | 400 | Order Fill would result in exceeding maximum position size |
| 2082 | 400 | Pre-order check failed |
| 2084 | 400 | Post-order check failed |
| 2083 | 400 | Order Fill would result in exceeding maximum position size under current configurable leverage tier |
| 2090 | 429 | Max open orders exceeded |
| 2110 | 400 | Invalid trigger by |
| 2111 | 400 | Unsupported trigger by |
| 2112 | 400 | Invalid trigger order |
| 2113 | 400 | Trigger price must be non-zero |
| 2114 | 400 | Invalid position linked TPSL orders, position linked TPSL must be a reduce-only order |
| 2115 | 400 | Invalid position linked TPSL orders, position linked TPSL must not have smaller size than the position |
| 2116 | 400 | Position linked TPSL order for this asset already exists |
| 2117 | 400 | Position linked TPSL orders must be created from web or mobile clients |
| 2242 | 400 | Split TPSL functionality not supported; you may be using a deprecated API, or this functionality is temporarily disabled |
| 3004 | 500 | Instrument does not have a valid maintenance margin configuration |
| 3005 | 500 | Instrument's underlying currency does not have a valid balance decimal configuration |
| 3006 | 500 | Instrument's quote currency does not have a valid balance decimal configuration |
| 2400 | 400 | Reduce only order with no position |
| 2401 | 400 | Reduce only order must not increase position size |
| 2402 | 400 | Reduce only order size exceeds maximum allowed value |
| 7304 | 400 | Only position-reducing orders (reduce_only as true) allowed for this asset right now. |
| 2450 | 400 | Spot order is not supported |
| 2451 | 400 | Spot order must not be a reduce-only order |
| 2452 | 400 | Spot order must not be a TPSL order |
| 2453 | 400 | Spot trading is blocked during socialized loss |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/create_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"order": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/create_order",
"params": {
"order": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/create_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"o": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/create_order",
"p": {
"o": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/create_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"order": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/create_order",
"params": {
"order": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/create_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"o": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/create_order",
"p": {
"o": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/create_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"order": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/create_order",
"params": {
"order": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/create_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"o": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/create_order",
"p": {
"o": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
},
"i": 123
}
' -w 360
Cancel Order
FULL ENDPOINT: full/v1/cancel_order
LITE ENDPOINT: lite/v1/cancel_order
Cancel an order on the orderbook for this trading account. Either order_id or client_order_id must be provided.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The subaccount ID cancelling the order |
order_idoi |
string | False0 |
Cancel the order with this order_id |
client_order_idco |
string | False0 |
Cancel the order with this client_order_id |
time_to_live_mstt |
string | False100 |
Specifies the time-to-live (in milliseconds) for this cancellation. During this period, any order creation with a matching client_order_id will be cancelled and not be added to the GRVT matching engine.This mechanism helps mitigate time-of-flight issues where cancellations might arrive before the corresponding orders. Hence, cancellation by order_id ignores this field as the exchange can only assign order_ids to already-processed order creations.The duration cannot be negative, is rounded down to the nearest 100ms (e.g., '670' -> '600', '30' -> '0') and capped at 5 seconds (i.e., '5000').Value of '0' or omission results in the default time-to-live value being applied.If the caller requests multiple successive cancellations for a given order, such that the time-to-live windows overlap, only the first request will be considered. |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042",
"time_to_live_ms": "500"
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042",
"tt": "500"
}
Used to acknowledge a request has been received and will be processed
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Ack | True | The Ack Object |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"result": {
"ack": "true"
}
}
{
"r": {
"a": "true"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 2300 | 400 | Order cancel time-to-live settings currently disabled. |
| 2301 | 400 | Order cancel time-to-live exceeds maximum allowed value. |
| 3021 | 400 | Either order ID or client order ID must be supplied |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/cancel_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042",
"time_to_live_ms": "500"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_order",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042",
"time_to_live_ms": "500"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/cancel_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042",
"tt": "500"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_order",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042",
"tt": "500"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/cancel_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042",
"time_to_live_ms": "500"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_order",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042",
"time_to_live_ms": "500"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/cancel_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042",
"tt": "500"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_order",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042",
"tt": "500"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/cancel_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042",
"time_to_live_ms": "500"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_order",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042",
"time_to_live_ms": "500"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/cancel_order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042",
"tt": "500"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_order",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042",
"tt": "500"
},
"i": 123
}
' -w 360
Cancel All Orders
FULL ENDPOINT: full/v1/cancel_all_orders
LITE ENDPOINT: lite/v1/cancel_all_orders
Cancel all orders on the orderbook for this trading account. This may not match new orders in flight.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The subaccount ID cancelling all orders |
kindk |
[Kind] | Falseall |
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be cancelled |
baseb |
[string] | Falseall |
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be cancelled |
quoteq |
[string] | Falseall |
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only entries matching the filter will be cancelled |
Kind
The list of asset kinds that are supported on the GRVT exchange
| Value | Description |
|---|---|
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 |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
Used to acknowledge a request has been received and will be processed
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Ack | True | The Ack Object |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"result": {
"ack": "true"
}
}
{
"r": {
"a": "true"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/cancel_all_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_all_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/cancel_all_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_all_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/cancel_all_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_all_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/cancel_all_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_all_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/cancel_all_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_all_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/cancel_all_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_all_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
Get Order
FULL ENDPOINT: full/v1/order
LITE ENDPOINT: lite/v1/order
Retrieve the order for the account. Either order_id or client_order_id must be provided.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The subaccount ID to filter by |
order_idoi |
string | False0 |
Filter for order_id |
client_order_idco |
string | False0 |
Filter for client_order_id |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042"
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042"
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Order | True | The order object for the requested filter |
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
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
order_idoi |
string | False0 |
[Filled by GRVT Backend] A unique 128-bit identifier for the order, deterministically generated within the GRVT backend |
sub_account_idsa |
string | True | The subaccount initiating the order |
is_marketim |
boolean | Falsefalse |
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_forceti |
TimeInForce | True | Four supported types of orders: GTT, IOC, AON, FOK:
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK) |
post_onlypo |
boolean | Falsefalse |
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. In this case, order creation is currently subject to a speedbump of 25ms to ensure orders are matched against updated orderbook quotes. |
reduce_onlyro |
boolean | Falsefalse |
If True, Order must reduce the position size, or be cancelled |
legsl |
[OrderLeg] | True | The legs present in this order The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice |
signatures |
Signature | True | The signature approving this order |
metadatam |
OrderMetadata | True | Order Metadata, ignored by the smart contract, and unsigned by the client |
states1 |
OrderState | False'' |
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client |
builderb |
string | True | The main account ID of the builder |
builder_feebf |
string | True | Builder fee charged for this order, expressed as a percentage (e.g., 0.001 means 0.001%). |
TimeInForce
| Must Fill All | Can Fill Partial | |
|---|---|---|
| Must Fill Immediately | FOK | IOC |
| Can Fill Till Time | AON | GTC |
| Value | Description |
|---|---|
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 |
RETAIL_PRICE_IMPROVEMENT = 5 |
RPI - A GTT + PostOnly maker order, that can only be taken by non-algorithmic UI users. |
OrderLeg
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The instrument to trade in this leg |
sizes |
string | True | The total number of assets to trade in this leg, expressed in base asset decimal units. |
limit_pricelp |
string | False0 |
The limit price of the order leg, expressed in 9 decimals.This is the number of quote currency units to pay/receive for this leg. This should be null/0 if the order is a market order |
is_buying_assetib |
boolean | True | Specifies if the order leg is a buy or sell |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
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.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
client_order_idco |
string | True | 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^63 - 1] To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^63, 2^64 - 1] When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId |
create_timect |
string | False0 |
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds |
triggert |
TriggerOrderMetadata | False `` |
Trigger fields are used to support any type of trigger order such as TP/SL |
brokerb |
BrokerTag | False `` |
Specifies the broker who brokered the order |
TriggerOrderMetadata
Contains metadata related to trigger orders, such as Take Profit (TP) or Stop Loss (SL).
Trigger orders are used to automatically execute an order when a predefined price condition is met, allowing traders to implement risk management strategies.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_typett |
TriggerType | True | Type of the trigger order. eg: Take Profit, Stop Loss, etc |
tpslt |
TPSLOrderMetadata | True | Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders. |
TriggerType
Defines the type of trigger order used in trading, such as Take Profit or Stop Loss.
Trigger orders allow execution based on pre-defined price conditions rather than immediate market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Not a trigger order. The order executes normally without any trigger conditions. |
TAKE_PROFIT = 1 |
Take Profit Order - Executes when the price reaches a specified level to secure profits. |
STOP_LOSS = 2 |
Stop Loss Order - Executes when the price reaches a specified level to limit losses. |
TPSLOrderMetadata
Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_bytb |
TriggerBy | True | Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order |
trigger_pricetp |
string | True | The Trigger Price of the order, expressed in 9 decimals. |
close_positioncp |
boolean | True | If True, the order will close the position when the trigger price is reached |
is_split_positionis |
boolean | True | If True, the order will be treated as part of a position's split-TP/SL set, subject to aggregate size/count limits. |
TriggerBy
Defines the price type that activates a Take Profit (TP) or Stop Loss (SL) order.
Trigger orders are executed when the selected price type reaches the specified trigger price.Different price types ensure flexibility in executing strategies based on market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
no trigger condition |
INDEX = 1 |
INDEX - Order is activated when the index price reaches the trigger price |
LAST = 2 |
LAST - Order is activated when the last trade price reaches the trigger price |
MID = 3 |
MID - Order is activated when the mid price reaches the trigger price |
MARK = 4 |
MARK - Order is activated when the mark price reaches the trigger price |
BrokerTag
BrokerTag is a tag for the broker that the order is sent from.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
COIN_ROUTES = 1 |
CoinRoutes |
ALERTATRON = 2 |
Alertatron |
ORIGAMI = 3 |
Origami |
OrderState
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
statuss |
OrderStatus | True | The status of the order |
reject_reasonrr |
OrderRejectReason | True | The reason for rejection or cancellation |
book_sizebs |
[string] | True | The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs |
traded_sizets |
[string] | True | The total number of assets traded. Sorted in same order as Order.Legs |
update_timeut |
string | True | Time at which the order was updated by GRVT, expressed in unix nanoseconds |
avg_fill_priceaf |
[string] | True | The average fill price of the order. Sorted in same order as Order.Legs |
OrderStatus
| Value | Description |
|---|---|
PENDING = 1 |
Order has been sent to the matching engine and is pending a transition to open/filled/rejected. |
OPEN = 2 |
Order is actively matching on the matching engine, could be unfilled or partially filled. |
FILLED = 3 |
Order is fully filled and hence closed. Taker Orders can transition directly from pending to filled, without going through open. |
REJECTED = 4 |
Order is rejected by matching engine since if fails a particular check (See OrderRejectReason). Once an order is open, it cannot be rejected. |
CANCELLED = 5 |
Order is cancelled by the user using one of the supported APIs (See OrderRejectReason). Before an order is open, it cannot be cancelled. |
OrderRejectReason
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
order is not cancelled or rejected |
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' |
MARKET_CANCEL = 4 |
the market order was cancelled after no/partial fill. Lower precedence than other TimeInForce cancel reasons |
IOC_CANCEL = 5 |
the IOC order was cancelled after no/partial fill |
AON_CANCEL = 6 |
the AON order was cancelled as it could not be fully matched |
FOK_CANCEL = 7 |
the FOK order was cancelled as it could not be fully matched |
EXPIRED = 8 |
the order was cancelled as it has expired |
FAIL_POST_ONLY = 9 |
the post-only order could not be posted into the orderbook |
FAIL_REDUCE_ONLY = 10 |
the reduce-only order would have caused position size to increase |
MM_PROTECTION = 11 |
the order was cancelled due to market maker protection trigger |
SELF_TRADE_PROTECTION = 12 |
the order was cancelled due to self-trade protection trigger |
SELF_MATCHED_SUBACCOUNT = 13 |
the order matched with another order from the same sub account |
OVERLAPPING_CLIENT_ORDER_ID = 14 |
an active order on your sub account shares the same clientOrderId |
BELOW_MARGIN = 15 |
the order will bring the sub account below initial margin requirement |
LIQUIDATION = 16 |
the sub account is liquidated (and all open orders are cancelled by Gravity) |
INSTRUMENT_INVALID = 17 |
instrument is invalid or not found on Gravity |
INSTRUMENT_DEACTIVATED = 18 |
instrument is no longer tradable on Gravity. (typically due to a market halt, or instrument expiry) |
SYSTEM_FAILOVER = 19 |
system failover resulting in loss of order state |
UNAUTHORISED = 20 |
the credentials used (userSession/apiKeySession/walletSignature) is not authorised to perform the action |
SESSION_KEY_EXPIRED = 21 |
the session key used to sign the order expired |
SUB_ACCOUNT_NOT_FOUND = 22 |
the subaccount does not exist |
NO_TRADE_PERMISSION = 23 |
the signature used to sign the order has no trade permission |
UNSUPPORTED_TIME_IN_FORCE = 24 |
the order payload does not contain a supported TimeInForce value |
MULTI_LEGGED_ORDER = 25 |
the order has multiple legs, but multiple legs are not supported by this venue |
EXCEED_MAX_POSITION_SIZE = 26 |
the order would have caused the subaccount to exceed the max position size |
EXCEED_MAX_SIGNATURE_EXPIRATION = 27 |
the signature supplied is more than 30 days in the future |
MARKET_ORDER_WITH_LIMIT_PRICE = 28 |
the market order has a limit price set |
CLIENT_CANCEL_ON_DISCONNECT_TRIGGERED = 29 |
client cancel on disconnect triggered |
OCO_COUNTER_PART_TRIGGERED = 30 |
the OCO counter part order was triggered |
REDUCE_ONLY_LIMIT = 31 |
the remaining order size was cancelled because it exceeded current position size |
CLIENT_REPLACE = 32 |
the order was replaced by a client replace request |
DERISK_MUST_BE_IOC = 33 |
the derisk order must be an IOC order |
DERISK_MUST_BE_REDUCE_ONLY = 34 |
the derisk order must be a reduce-only order |
DERISK_NOT_SUPPORTED = 35 |
derisk is not supported |
INVALID_ORDER_TYPE = 36 |
the order type is invalid |
CURRENCY_NOT_DEFINED = 37 |
the currency is not defined |
INVALID_CHAIN_ID = 38 |
the chain ID is invalid |
BUILDER_ORDER_FEE_EXCEED = 39 |
Builder fee exceed the limit |
BUILDER_ORDER_FEE_NEGATIVE = 40 |
Builder fee is below 0 |
BUILDER_ORDER_BUILDER_NOT_AUTHORIZED = 41 |
Builder is not an authorized builder for client |
BUILDER_ORDER_BUILDER_NOT_EXIST = 42 |
Builder does not exist |
TRADE_PRICE_WORSE_THAN_BANKRUPTCY_PRICE = 44 |
the trade price is worse than the bankruptcy price |
TOO_MANY_MAKER_ORDERS = 45 |
the order was cancelled due to matching with too many maker orders |
REDUCE_ONLY_NOT_SUPPORTED_FOR_SPOT_ORDER = 46 |
reduce-only order is not supported for spot order |
TPSL_NOT_SUPPORTED_FOR_SPOT_ORDER = 47 |
tpsl is not supported for spot order |
SPOT_ORDER_NOT_SUPPORTED = 48 |
spot order is not supported |
INSUFFICIENT_BALANCE = 49 |
the subaccount has insufficient balance |
SPOT_TRADING_BLOCKED_DURING_SOCIALIZED_LOSS = 50 |
spot trading is blocked during socialized loss (SLOW) |
BELOW_MARGIN_WITH_PENALTY_DEVIATION = 51 |
the order will bring the sub account below initial margin requirement considering wide price deviation |
Success
Full Response
{
"result": {
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}
}
{
"r": {
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 1004 | 404 | Data Not Found |
| 3021 | 400 | Either order ID or client order ID must be supplied |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/order",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/order",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/order",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/order",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/order",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"order_id": "0x1028403",
"client_order_id": "23042"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/order' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/order",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"oi": "0x1028403",
"co": "23042"
},
"i": 123
}
' -w 360
Open Orders
FULL ENDPOINT: full/v1/open_orders
LITE ENDPOINT: lite/v1/open_orders
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The subaccount ID to filter by |
kindk |
[Kind] | Falseall |
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned |
baseb |
[string] | Falseall |
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned |
quoteq |
[string] | Falseall |
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only entries matching the filter will be returned |
Kind
The list of asset kinds that are supported on the GRVT exchange
| Value | Description |
|---|---|
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 |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
Retrieves all open orders for the account. This may not match new orders in flight.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[Order] | True | The Open Orders matching the request filter |
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
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
order_idoi |
string | False0 |
[Filled by GRVT Backend] A unique 128-bit identifier for the order, deterministically generated within the GRVT backend |
sub_account_idsa |
string | True | The subaccount initiating the order |
is_marketim |
boolean | Falsefalse |
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_forceti |
TimeInForce | True | Four supported types of orders: GTT, IOC, AON, FOK:
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK) |
post_onlypo |
boolean | Falsefalse |
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. In this case, order creation is currently subject to a speedbump of 25ms to ensure orders are matched against updated orderbook quotes. |
reduce_onlyro |
boolean | Falsefalse |
If True, Order must reduce the position size, or be cancelled |
legsl |
[OrderLeg] | True | The legs present in this order The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice |
signatures |
Signature | True | The signature approving this order |
metadatam |
OrderMetadata | True | Order Metadata, ignored by the smart contract, and unsigned by the client |
states1 |
OrderState | False'' |
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client |
builderb |
string | True | The main account ID of the builder |
builder_feebf |
string | True | Builder fee charged for this order, expressed as a percentage (e.g., 0.001 means 0.001%). |
TimeInForce
| Must Fill All | Can Fill Partial | |
|---|---|---|
| Must Fill Immediately | FOK | IOC |
| Can Fill Till Time | AON | GTC |
| Value | Description |
|---|---|
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 |
RETAIL_PRICE_IMPROVEMENT = 5 |
RPI - A GTT + PostOnly maker order, that can only be taken by non-algorithmic UI users. |
OrderLeg
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The instrument to trade in this leg |
sizes |
string | True | The total number of assets to trade in this leg, expressed in base asset decimal units. |
limit_pricelp |
string | False0 |
The limit price of the order leg, expressed in 9 decimals.This is the number of quote currency units to pay/receive for this leg. This should be null/0 if the order is a market order |
is_buying_assetib |
boolean | True | Specifies if the order leg is a buy or sell |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
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.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
client_order_idco |
string | True | 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^63 - 1] To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^63, 2^64 - 1] When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId |
create_timect |
string | False0 |
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds |
triggert |
TriggerOrderMetadata | False `` |
Trigger fields are used to support any type of trigger order such as TP/SL |
brokerb |
BrokerTag | False `` |
Specifies the broker who brokered the order |
TriggerOrderMetadata
Contains metadata related to trigger orders, such as Take Profit (TP) or Stop Loss (SL).
Trigger orders are used to automatically execute an order when a predefined price condition is met, allowing traders to implement risk management strategies.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_typett |
TriggerType | True | Type of the trigger order. eg: Take Profit, Stop Loss, etc |
tpslt |
TPSLOrderMetadata | True | Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders. |
TriggerType
Defines the type of trigger order used in trading, such as Take Profit or Stop Loss.
Trigger orders allow execution based on pre-defined price conditions rather than immediate market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Not a trigger order. The order executes normally without any trigger conditions. |
TAKE_PROFIT = 1 |
Take Profit Order - Executes when the price reaches a specified level to secure profits. |
STOP_LOSS = 2 |
Stop Loss Order - Executes when the price reaches a specified level to limit losses. |
TPSLOrderMetadata
Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_bytb |
TriggerBy | True | Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order |
trigger_pricetp |
string | True | The Trigger Price of the order, expressed in 9 decimals. |
close_positioncp |
boolean | True | If True, the order will close the position when the trigger price is reached |
is_split_positionis |
boolean | True | If True, the order will be treated as part of a position's split-TP/SL set, subject to aggregate size/count limits. |
TriggerBy
Defines the price type that activates a Take Profit (TP) or Stop Loss (SL) order.
Trigger orders are executed when the selected price type reaches the specified trigger price.Different price types ensure flexibility in executing strategies based on market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
no trigger condition |
INDEX = 1 |
INDEX - Order is activated when the index price reaches the trigger price |
LAST = 2 |
LAST - Order is activated when the last trade price reaches the trigger price |
MID = 3 |
MID - Order is activated when the mid price reaches the trigger price |
MARK = 4 |
MARK - Order is activated when the mark price reaches the trigger price |
BrokerTag
BrokerTag is a tag for the broker that the order is sent from.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
COIN_ROUTES = 1 |
CoinRoutes |
ALERTATRON = 2 |
Alertatron |
ORIGAMI = 3 |
Origami |
OrderState
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
statuss |
OrderStatus | True | The status of the order |
reject_reasonrr |
OrderRejectReason | True | The reason for rejection or cancellation |
book_sizebs |
[string] | True | The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs |
traded_sizets |
[string] | True | The total number of assets traded. Sorted in same order as Order.Legs |
update_timeut |
string | True | Time at which the order was updated by GRVT, expressed in unix nanoseconds |
avg_fill_priceaf |
[string] | True | The average fill price of the order. Sorted in same order as Order.Legs |
OrderStatus
| Value | Description |
|---|---|
PENDING = 1 |
Order has been sent to the matching engine and is pending a transition to open/filled/rejected. |
OPEN = 2 |
Order is actively matching on the matching engine, could be unfilled or partially filled. |
FILLED = 3 |
Order is fully filled and hence closed. Taker Orders can transition directly from pending to filled, without going through open. |
REJECTED = 4 |
Order is rejected by matching engine since if fails a particular check (See OrderRejectReason). Once an order is open, it cannot be rejected. |
CANCELLED = 5 |
Order is cancelled by the user using one of the supported APIs (See OrderRejectReason). Before an order is open, it cannot be cancelled. |
OrderRejectReason
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
order is not cancelled or rejected |
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' |
MARKET_CANCEL = 4 |
the market order was cancelled after no/partial fill. Lower precedence than other TimeInForce cancel reasons |
IOC_CANCEL = 5 |
the IOC order was cancelled after no/partial fill |
AON_CANCEL = 6 |
the AON order was cancelled as it could not be fully matched |
FOK_CANCEL = 7 |
the FOK order was cancelled as it could not be fully matched |
EXPIRED = 8 |
the order was cancelled as it has expired |
FAIL_POST_ONLY = 9 |
the post-only order could not be posted into the orderbook |
FAIL_REDUCE_ONLY = 10 |
the reduce-only order would have caused position size to increase |
MM_PROTECTION = 11 |
the order was cancelled due to market maker protection trigger |
SELF_TRADE_PROTECTION = 12 |
the order was cancelled due to self-trade protection trigger |
SELF_MATCHED_SUBACCOUNT = 13 |
the order matched with another order from the same sub account |
OVERLAPPING_CLIENT_ORDER_ID = 14 |
an active order on your sub account shares the same clientOrderId |
BELOW_MARGIN = 15 |
the order will bring the sub account below initial margin requirement |
LIQUIDATION = 16 |
the sub account is liquidated (and all open orders are cancelled by Gravity) |
INSTRUMENT_INVALID = 17 |
instrument is invalid or not found on Gravity |
INSTRUMENT_DEACTIVATED = 18 |
instrument is no longer tradable on Gravity. (typically due to a market halt, or instrument expiry) |
SYSTEM_FAILOVER = 19 |
system failover resulting in loss of order state |
UNAUTHORISED = 20 |
the credentials used (userSession/apiKeySession/walletSignature) is not authorised to perform the action |
SESSION_KEY_EXPIRED = 21 |
the session key used to sign the order expired |
SUB_ACCOUNT_NOT_FOUND = 22 |
the subaccount does not exist |
NO_TRADE_PERMISSION = 23 |
the signature used to sign the order has no trade permission |
UNSUPPORTED_TIME_IN_FORCE = 24 |
the order payload does not contain a supported TimeInForce value |
MULTI_LEGGED_ORDER = 25 |
the order has multiple legs, but multiple legs are not supported by this venue |
EXCEED_MAX_POSITION_SIZE = 26 |
the order would have caused the subaccount to exceed the max position size |
EXCEED_MAX_SIGNATURE_EXPIRATION = 27 |
the signature supplied is more than 30 days in the future |
MARKET_ORDER_WITH_LIMIT_PRICE = 28 |
the market order has a limit price set |
CLIENT_CANCEL_ON_DISCONNECT_TRIGGERED = 29 |
client cancel on disconnect triggered |
OCO_COUNTER_PART_TRIGGERED = 30 |
the OCO counter part order was triggered |
REDUCE_ONLY_LIMIT = 31 |
the remaining order size was cancelled because it exceeded current position size |
CLIENT_REPLACE = 32 |
the order was replaced by a client replace request |
DERISK_MUST_BE_IOC = 33 |
the derisk order must be an IOC order |
DERISK_MUST_BE_REDUCE_ONLY = 34 |
the derisk order must be a reduce-only order |
DERISK_NOT_SUPPORTED = 35 |
derisk is not supported |
INVALID_ORDER_TYPE = 36 |
the order type is invalid |
CURRENCY_NOT_DEFINED = 37 |
the currency is not defined |
INVALID_CHAIN_ID = 38 |
the chain ID is invalid |
BUILDER_ORDER_FEE_EXCEED = 39 |
Builder fee exceed the limit |
BUILDER_ORDER_FEE_NEGATIVE = 40 |
Builder fee is below 0 |
BUILDER_ORDER_BUILDER_NOT_AUTHORIZED = 41 |
Builder is not an authorized builder for client |
BUILDER_ORDER_BUILDER_NOT_EXIST = 42 |
Builder does not exist |
TRADE_PRICE_WORSE_THAN_BANKRUPTCY_PRICE = 44 |
the trade price is worse than the bankruptcy price |
TOO_MANY_MAKER_ORDERS = 45 |
the order was cancelled due to matching with too many maker orders |
REDUCE_ONLY_NOT_SUPPORTED_FOR_SPOT_ORDER = 46 |
reduce-only order is not supported for spot order |
TPSL_NOT_SUPPORTED_FOR_SPOT_ORDER = 47 |
tpsl is not supported for spot order |
SPOT_ORDER_NOT_SUPPORTED = 48 |
spot order is not supported |
INSUFFICIENT_BALANCE = 49 |
the subaccount has insufficient balance |
SPOT_TRADING_BLOCKED_DURING_SOCIALIZED_LOSS = 50 |
spot trading is blocked during socialized loss (SLOW) |
BELOW_MARGIN_WITH_PENALTY_DEVIATION = 51 |
the order will bring the sub account below initial margin requirement considering wide price deviation |
Success
Full Response
{
"result": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}]
}
{
"r": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}]
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 1003 | 400 | Request could not be processed due to malformed syntax |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/open_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/open_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/open_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/open_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/open_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/open_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/open_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/open_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/open_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/open_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/open_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/open_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
Order History
FULL ENDPOINT: full/v1/order_history
LITE ENDPOINT: lite/v1/order_history
Retrieves the order history for the account.
Pagination works as follows:
- We perform a reverse chronological lookup, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The subaccount ID to filter by |
kindk |
[Kind] | Falseall |
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned |
baseb |
[string] | Falseall |
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned |
quoteq |
[string] | Falseall |
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only entries matching the filter will be returned |
start_timest |
string | False0 |
The start time to apply in nanoseconds. If nil, this defaults to all start times. Otherwise, only entries matching the filter will be returned |
end_timeet |
string | Falsenow() |
The end time to apply in nanoseconds. If nil, this defaults to all end times. Otherwise, only entries matching the filter will be returned |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000 |
cursorc |
string | False'' |
The cursor to indicate when to start the query from |
Kind
The list of asset kinds that are supported on the GRVT exchange
| Value | Description |
|---|---|
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 |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[Order] | True | The Open Orders matching the request filter |
nextn |
string | True | The cursor to indicate when to start the query from |
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
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
order_idoi |
string | False0 |
[Filled by GRVT Backend] A unique 128-bit identifier for the order, deterministically generated within the GRVT backend |
sub_account_idsa |
string | True | The subaccount initiating the order |
is_marketim |
boolean | Falsefalse |
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_forceti |
TimeInForce | True | Four supported types of orders: GTT, IOC, AON, FOK:
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK) |
post_onlypo |
boolean | Falsefalse |
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. In this case, order creation is currently subject to a speedbump of 25ms to ensure orders are matched against updated orderbook quotes. |
reduce_onlyro |
boolean | Falsefalse |
If True, Order must reduce the position size, or be cancelled |
legsl |
[OrderLeg] | True | The legs present in this order The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice |
signatures |
Signature | True | The signature approving this order |
metadatam |
OrderMetadata | True | Order Metadata, ignored by the smart contract, and unsigned by the client |
states1 |
OrderState | False'' |
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client |
builderb |
string | True | The main account ID of the builder |
builder_feebf |
string | True | Builder fee charged for this order, expressed as a percentage (e.g., 0.001 means 0.001%). |
TimeInForce
| Must Fill All | Can Fill Partial | |
|---|---|---|
| Must Fill Immediately | FOK | IOC |
| Can Fill Till Time | AON | GTC |
| Value | Description |
|---|---|
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 |
RETAIL_PRICE_IMPROVEMENT = 5 |
RPI - A GTT + PostOnly maker order, that can only be taken by non-algorithmic UI users. |
OrderLeg
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The instrument to trade in this leg |
sizes |
string | True | The total number of assets to trade in this leg, expressed in base asset decimal units. |
limit_pricelp |
string | False0 |
The limit price of the order leg, expressed in 9 decimals.This is the number of quote currency units to pay/receive for this leg. This should be null/0 if the order is a market order |
is_buying_assetib |
boolean | True | Specifies if the order leg is a buy or sell |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
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.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
client_order_idco |
string | True | 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^63 - 1] To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^63, 2^64 - 1] When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId |
create_timect |
string | False0 |
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds |
triggert |
TriggerOrderMetadata | False `` |
Trigger fields are used to support any type of trigger order such as TP/SL |
brokerb |
BrokerTag | False `` |
Specifies the broker who brokered the order |
TriggerOrderMetadata
Contains metadata related to trigger orders, such as Take Profit (TP) or Stop Loss (SL).
Trigger orders are used to automatically execute an order when a predefined price condition is met, allowing traders to implement risk management strategies.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_typett |
TriggerType | True | Type of the trigger order. eg: Take Profit, Stop Loss, etc |
tpslt |
TPSLOrderMetadata | True | Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders. |
TriggerType
Defines the type of trigger order used in trading, such as Take Profit or Stop Loss.
Trigger orders allow execution based on pre-defined price conditions rather than immediate market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Not a trigger order. The order executes normally without any trigger conditions. |
TAKE_PROFIT = 1 |
Take Profit Order - Executes when the price reaches a specified level to secure profits. |
STOP_LOSS = 2 |
Stop Loss Order - Executes when the price reaches a specified level to limit losses. |
TPSLOrderMetadata
Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_bytb |
TriggerBy | True | Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order |
trigger_pricetp |
string | True | The Trigger Price of the order, expressed in 9 decimals. |
close_positioncp |
boolean | True | If True, the order will close the position when the trigger price is reached |
is_split_positionis |
boolean | True | If True, the order will be treated as part of a position's split-TP/SL set, subject to aggregate size/count limits. |
TriggerBy
Defines the price type that activates a Take Profit (TP) or Stop Loss (SL) order.
Trigger orders are executed when the selected price type reaches the specified trigger price.Different price types ensure flexibility in executing strategies based on market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
no trigger condition |
INDEX = 1 |
INDEX - Order is activated when the index price reaches the trigger price |
LAST = 2 |
LAST - Order is activated when the last trade price reaches the trigger price |
MID = 3 |
MID - Order is activated when the mid price reaches the trigger price |
MARK = 4 |
MARK - Order is activated when the mark price reaches the trigger price |
BrokerTag
BrokerTag is a tag for the broker that the order is sent from.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
COIN_ROUTES = 1 |
CoinRoutes |
ALERTATRON = 2 |
Alertatron |
ORIGAMI = 3 |
Origami |
OrderState
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
statuss |
OrderStatus | True | The status of the order |
reject_reasonrr |
OrderRejectReason | True | The reason for rejection or cancellation |
book_sizebs |
[string] | True | The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs |
traded_sizets |
[string] | True | The total number of assets traded. Sorted in same order as Order.Legs |
update_timeut |
string | True | Time at which the order was updated by GRVT, expressed in unix nanoseconds |
avg_fill_priceaf |
[string] | True | The average fill price of the order. Sorted in same order as Order.Legs |
OrderStatus
| Value | Description |
|---|---|
PENDING = 1 |
Order has been sent to the matching engine and is pending a transition to open/filled/rejected. |
OPEN = 2 |
Order is actively matching on the matching engine, could be unfilled or partially filled. |
FILLED = 3 |
Order is fully filled and hence closed. Taker Orders can transition directly from pending to filled, without going through open. |
REJECTED = 4 |
Order is rejected by matching engine since if fails a particular check (See OrderRejectReason). Once an order is open, it cannot be rejected. |
CANCELLED = 5 |
Order is cancelled by the user using one of the supported APIs (See OrderRejectReason). Before an order is open, it cannot be cancelled. |
OrderRejectReason
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
order is not cancelled or rejected |
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' |
MARKET_CANCEL = 4 |
the market order was cancelled after no/partial fill. Lower precedence than other TimeInForce cancel reasons |
IOC_CANCEL = 5 |
the IOC order was cancelled after no/partial fill |
AON_CANCEL = 6 |
the AON order was cancelled as it could not be fully matched |
FOK_CANCEL = 7 |
the FOK order was cancelled as it could not be fully matched |
EXPIRED = 8 |
the order was cancelled as it has expired |
FAIL_POST_ONLY = 9 |
the post-only order could not be posted into the orderbook |
FAIL_REDUCE_ONLY = 10 |
the reduce-only order would have caused position size to increase |
MM_PROTECTION = 11 |
the order was cancelled due to market maker protection trigger |
SELF_TRADE_PROTECTION = 12 |
the order was cancelled due to self-trade protection trigger |
SELF_MATCHED_SUBACCOUNT = 13 |
the order matched with another order from the same sub account |
OVERLAPPING_CLIENT_ORDER_ID = 14 |
an active order on your sub account shares the same clientOrderId |
BELOW_MARGIN = 15 |
the order will bring the sub account below initial margin requirement |
LIQUIDATION = 16 |
the sub account is liquidated (and all open orders are cancelled by Gravity) |
INSTRUMENT_INVALID = 17 |
instrument is invalid or not found on Gravity |
INSTRUMENT_DEACTIVATED = 18 |
instrument is no longer tradable on Gravity. (typically due to a market halt, or instrument expiry) |
SYSTEM_FAILOVER = 19 |
system failover resulting in loss of order state |
UNAUTHORISED = 20 |
the credentials used (userSession/apiKeySession/walletSignature) is not authorised to perform the action |
SESSION_KEY_EXPIRED = 21 |
the session key used to sign the order expired |
SUB_ACCOUNT_NOT_FOUND = 22 |
the subaccount does not exist |
NO_TRADE_PERMISSION = 23 |
the signature used to sign the order has no trade permission |
UNSUPPORTED_TIME_IN_FORCE = 24 |
the order payload does not contain a supported TimeInForce value |
MULTI_LEGGED_ORDER = 25 |
the order has multiple legs, but multiple legs are not supported by this venue |
EXCEED_MAX_POSITION_SIZE = 26 |
the order would have caused the subaccount to exceed the max position size |
EXCEED_MAX_SIGNATURE_EXPIRATION = 27 |
the signature supplied is more than 30 days in the future |
MARKET_ORDER_WITH_LIMIT_PRICE = 28 |
the market order has a limit price set |
CLIENT_CANCEL_ON_DISCONNECT_TRIGGERED = 29 |
client cancel on disconnect triggered |
OCO_COUNTER_PART_TRIGGERED = 30 |
the OCO counter part order was triggered |
REDUCE_ONLY_LIMIT = 31 |
the remaining order size was cancelled because it exceeded current position size |
CLIENT_REPLACE = 32 |
the order was replaced by a client replace request |
DERISK_MUST_BE_IOC = 33 |
the derisk order must be an IOC order |
DERISK_MUST_BE_REDUCE_ONLY = 34 |
the derisk order must be a reduce-only order |
DERISK_NOT_SUPPORTED = 35 |
derisk is not supported |
INVALID_ORDER_TYPE = 36 |
the order type is invalid |
CURRENCY_NOT_DEFINED = 37 |
the currency is not defined |
INVALID_CHAIN_ID = 38 |
the chain ID is invalid |
BUILDER_ORDER_FEE_EXCEED = 39 |
Builder fee exceed the limit |
BUILDER_ORDER_FEE_NEGATIVE = 40 |
Builder fee is below 0 |
BUILDER_ORDER_BUILDER_NOT_AUTHORIZED = 41 |
Builder is not an authorized builder for client |
BUILDER_ORDER_BUILDER_NOT_EXIST = 42 |
Builder does not exist |
TRADE_PRICE_WORSE_THAN_BANKRUPTCY_PRICE = 44 |
the trade price is worse than the bankruptcy price |
TOO_MANY_MAKER_ORDERS = 45 |
the order was cancelled due to matching with too many maker orders |
REDUCE_ONLY_NOT_SUPPORTED_FOR_SPOT_ORDER = 46 |
reduce-only order is not supported for spot order |
TPSL_NOT_SUPPORTED_FOR_SPOT_ORDER = 47 |
tpsl is not supported for spot order |
SPOT_ORDER_NOT_SUPPORTED = 48 |
spot order is not supported |
INSUFFICIENT_BALANCE = 49 |
the subaccount has insufficient balance |
SPOT_TRADING_BLOCKED_DURING_SOCIALIZED_LOSS = 50 |
spot trading is blocked during socialized loss (SLOW) |
BELOW_MARGIN_WITH_PENALTY_DEVIATION = 51 |
the order will bring the sub account below initial margin requirement considering wide price deviation |
Success
Full Response
{
"result": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"next": "Qw0918="
}
{
"r": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/order_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/order_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/order_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/order_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/order_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/order_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/order_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/order_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/order_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/order_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/order_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/order_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
Cancel On Disconnect
FULL ENDPOINT: full/v1/cancel_on_disconnect
LITE ENDPOINT: lite/v1/cancel_on_disconnect
Auto-Cancel All Open Orders when the countdown time hits zero.
Market Maker inputs a countdown time parameter in milliseconds (e.g. 120000 for 120s) rounded down to the smallest second follows the following logic:
- Market Maker initially entered a value between 0 -> 1000, which is rounded to 0: will result in termination of their COD
- Market Maker initially entered a value between 1001 -> 300_000, which is rounded to the nearest second: will result in refresh of their COD
- Market Maker initially entered a value bigger than 300_000, which will result in error (upper bound)
Market Maker will send a heartbeat message by calling the endpoint at specific intervals (ex. every 30 seconds) to the server to refresh the count down.
If the server does not receive a heartbeat message within the countdown time, it will cancel all open orders for the specified Sub Account ID.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The subaccount ID cancelling the orders for |
countdown_timect |
string | False1000 |
Countdown time in milliseconds (ex. 120000 for 120s). 0 to disable the timer. Does not accept negative values. Minimum acceptable value is 1,000. Maximum acceptable value is 300,000 |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"countdown_time": 300
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"ct": 300
}
Used to acknowledge a request has been received and will be processed
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Ack | True | The Ack Object |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"result": {
"ack": "true"
}
}
{
"r": {
"a": "true"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 6000 | 400 | Countdown time is bigger than 300s supported |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/cancel_on_disconnect' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"countdown_time": 300
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_on_disconnect",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"countdown_time": 300
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/cancel_on_disconnect' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"ct": 300
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_on_disconnect",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"ct": 300
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/cancel_on_disconnect' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"countdown_time": 300
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_on_disconnect",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"countdown_time": 300
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/cancel_on_disconnect' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"ct": 300
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_on_disconnect",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"ct": 300
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/cancel_on_disconnect' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"countdown_time": 300
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/cancel_on_disconnect",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"countdown_time": 300
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/cancel_on_disconnect' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"ct": 300
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/cancel_on_disconnect",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"ct": 300
},
"i": 123
}
' -w 360
Bulk Orders
FULL ENDPOINT: full/v2/bulk_orders
LITE ENDPOINT: lite/v2/bulk_orders
Bulk create, cancel, or cancel-replace orders for a single subaccount.
A cancel-replace is a cancel of the old order plus a create of a new one. The new order is assigned a new order_id; the cancelled order_id is terminated. Clients must track the new order_id from the response.
Rules
- Up to 100 entries in each of orders, order_ids, and client_order_ids
- All create orders must target the same instrument
- client_order_ids within orders must be unique
- order_ids and client_order_ids are mutually exclusive; supplying both is rejected
- Rate limits: N creates consume N create_order tokens; any cancels consume 1 cancel_order token
BulkCreate
Populate orders only; leave order_ids and client_order_ids empty. A batch may not mix multiple normal orders with trigger orders.
To mark an order as TP or SL, populate its metadata.trigger field; see TriggerOrderMetadata for details.
A 'parent' order is a normal order whose linked TP/SL trigger orders become active once the parent is fully filled.
Supported combinations:
- Normal orders (non-TPSL): one or many orders
- Standalone TP: 1 TP order
- Standalone SL: 1 SL order
- OCO (2 orders: 1 TP + 1 SL): same asset, same size, same side
- OTO (2 orders: parent + 1 trigger): 1 parent + 1 TP or SL order. Same asset and size. Parent side is opposite of the trigger side.
- OTOCO (3 orders: parent + TP + SL): 1 parent + 1 TP order + 1 SL order. Same asset and size across all three. Parent side is opposite of TP and SL sides.
BulkCancel
Leave orders empty; populate either order_ids or client_order_ids (not both). Targets can be normal orders, standalone TP/SL, or members of an OCO/OTO/OTOCO group. Passing any member id of a grouped TPSL order cancels the whole group.
BulkCancelReplace
Populate orders together with order_ids or client_order_ids. Ids below refer to entries in whichever id list you chose.
Normal orders (non-TPSL): the batch is processed as all cancels first, then all creates.
TPSL: #creates must equal #cancels, and one request may modify only one group. For OTO and OTOCO, only the trigger part is replaceable — the parent order is not included in orders or in the cancel id list, and stays on the book unchanged.
- Standalone TP / Standalone SL: cancel 1 id (the existing trigger order) + create 1 new trigger order with matching triggerType.
- OCO: cancel both ids of the existing OCO group (the TP and SL) + create 2 new orders (1 TP + 1 SL); shape conditions same as BulkCreate OCO.
- OTO: cancel the id of the existing trigger order in the OTO group + create 1 new trigger order. The new trigger is linked to the same parent.
- OTOCO: cancel both ids of the existing OTOCO group (the TP and SL) + create 2 new orders (1 TP + 1 SL); shape conditions same as BulkCreate OCO. The new TP and SL are linked to the same parent.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The subaccount ID of the user creating the request |
orderso |
[Order] | True | Orders to create or replace, supply up to 100 orders |
order_i_dsoi |
[string] | True | The order IDs of the orders to cancel or replace, supply up to 100 orderIDs (if both orderIDs and clientOrderIDs are provided, we will reject the payload) |
client_order_i_dsco |
[string] | True | The client order IDs of the orders to cancel or replace, supply up to 100 clientOrderIDs (if both orderIDs and clientOrderIDs are provided, we will reject the payload) |
time_to_live_mstt |
string | False100 |
Specifies the time-to-live (in milliseconds) for this cancellation. During this period, any order creation with a matching client_order_id will be cancelled and not be added to the GRVT matching engine.This mechanism helps mitigate time-of-flight issues where cancellations might arrive before the corresponding orders. Hence, cancellation by order_id ignores this field as the exchange can only assign order_ids to already-processed order creations.The duration cannot be negative, is rounded down to the nearest 100ms (e.g., '670' -> '600', '30' -> '0') and capped at 5 seconds (i.e., '5000').Value of '0' or omission results in the default time-to-live value being applied.If the caller requests multiple successive cancellations for a given order, such that the time-to-live windows overlap, only the first request will be considered. |
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
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
order_idoi |
string | False0 |
[Filled by GRVT Backend] A unique 128-bit identifier for the order, deterministically generated within the GRVT backend |
sub_account_idsa |
string | True | The subaccount initiating the order |
is_marketim |
boolean | Falsefalse |
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_forceti |
TimeInForce | True | Four supported types of orders: GTT, IOC, AON, FOK:
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK) |
post_onlypo |
boolean | Falsefalse |
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. In this case, order creation is currently subject to a speedbump of 25ms to ensure orders are matched against updated orderbook quotes. |
reduce_onlyro |
boolean | Falsefalse |
If True, Order must reduce the position size, or be cancelled |
legsl |
[OrderLeg] | True | The legs present in this order The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice |
signatures |
Signature | True | The signature approving this order |
metadatam |
OrderMetadata | True | Order Metadata, ignored by the smart contract, and unsigned by the client |
states1 |
OrderState | False'' |
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client |
builderb |
string | True | The main account ID of the builder |
builder_feebf |
string | True | Builder fee charged for this order, expressed as a percentage (e.g., 0.001 means 0.001%). |
TimeInForce
| Must Fill All | Can Fill Partial | |
|---|---|---|
| Must Fill Immediately | FOK | IOC |
| Can Fill Till Time | AON | GTC |
| Value | Description |
|---|---|
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 |
RETAIL_PRICE_IMPROVEMENT = 5 |
RPI - A GTT + PostOnly maker order, that can only be taken by non-algorithmic UI users. |
OrderLeg
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The instrument to trade in this leg |
sizes |
string | True | The total number of assets to trade in this leg, expressed in base asset decimal units. |
limit_pricelp |
string | False0 |
The limit price of the order leg, expressed in 9 decimals.This is the number of quote currency units to pay/receive for this leg. This should be null/0 if the order is a market order |
is_buying_assetib |
boolean | True | Specifies if the order leg is a buy or sell |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
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.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
client_order_idco |
string | True | 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^63 - 1] To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^63, 2^64 - 1] When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId |
create_timect |
string | False0 |
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds |
triggert |
TriggerOrderMetadata | False `` |
Trigger fields are used to support any type of trigger order such as TP/SL |
brokerb |
BrokerTag | False `` |
Specifies the broker who brokered the order |
TriggerOrderMetadata
Contains metadata related to trigger orders, such as Take Profit (TP) or Stop Loss (SL).
Trigger orders are used to automatically execute an order when a predefined price condition is met, allowing traders to implement risk management strategies.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_typett |
TriggerType | True | Type of the trigger order. eg: Take Profit, Stop Loss, etc |
tpslt |
TPSLOrderMetadata | True | Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders. |
TriggerType
Defines the type of trigger order used in trading, such as Take Profit or Stop Loss.
Trigger orders allow execution based on pre-defined price conditions rather than immediate market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Not a trigger order. The order executes normally without any trigger conditions. |
TAKE_PROFIT = 1 |
Take Profit Order - Executes when the price reaches a specified level to secure profits. |
STOP_LOSS = 2 |
Stop Loss Order - Executes when the price reaches a specified level to limit losses. |
TPSLOrderMetadata
Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_bytb |
TriggerBy | True | Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order |
trigger_pricetp |
string | True | The Trigger Price of the order, expressed in 9 decimals. |
close_positioncp |
boolean | True | If True, the order will close the position when the trigger price is reached |
is_split_positionis |
boolean | True | If True, the order will be treated as part of a position's split-TP/SL set, subject to aggregate size/count limits. |
TriggerBy
Defines the price type that activates a Take Profit (TP) or Stop Loss (SL) order.
Trigger orders are executed when the selected price type reaches the specified trigger price.Different price types ensure flexibility in executing strategies based on market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
no trigger condition |
INDEX = 1 |
INDEX - Order is activated when the index price reaches the trigger price |
LAST = 2 |
LAST - Order is activated when the last trade price reaches the trigger price |
MID = 3 |
MID - Order is activated when the mid price reaches the trigger price |
MARK = 4 |
MARK - Order is activated when the mark price reaches the trigger price |
BrokerTag
BrokerTag is a tag for the broker that the order is sent from.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
COIN_ROUTES = 1 |
CoinRoutes |
ALERTATRON = 2 |
Alertatron |
ORIGAMI = 3 |
Origami |
OrderState
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
statuss |
OrderStatus | True | The status of the order |
reject_reasonrr |
OrderRejectReason | True | The reason for rejection or cancellation |
book_sizebs |
[string] | True | The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs |
traded_sizets |
[string] | True | The total number of assets traded. Sorted in same order as Order.Legs |
update_timeut |
string | True | Time at which the order was updated by GRVT, expressed in unix nanoseconds |
avg_fill_priceaf |
[string] | True | The average fill price of the order. Sorted in same order as Order.Legs |
OrderStatus
| Value | Description |
|---|---|
PENDING = 1 |
Order has been sent to the matching engine and is pending a transition to open/filled/rejected. |
OPEN = 2 |
Order is actively matching on the matching engine, could be unfilled or partially filled. |
FILLED = 3 |
Order is fully filled and hence closed. Taker Orders can transition directly from pending to filled, without going through open. |
REJECTED = 4 |
Order is rejected by matching engine since if fails a particular check (See OrderRejectReason). Once an order is open, it cannot be rejected. |
CANCELLED = 5 |
Order is cancelled by the user using one of the supported APIs (See OrderRejectReason). Before an order is open, it cannot be cancelled. |
OrderRejectReason
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
order is not cancelled or rejected |
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' |
MARKET_CANCEL = 4 |
the market order was cancelled after no/partial fill. Lower precedence than other TimeInForce cancel reasons |
IOC_CANCEL = 5 |
the IOC order was cancelled after no/partial fill |
AON_CANCEL = 6 |
the AON order was cancelled as it could not be fully matched |
FOK_CANCEL = 7 |
the FOK order was cancelled as it could not be fully matched |
EXPIRED = 8 |
the order was cancelled as it has expired |
FAIL_POST_ONLY = 9 |
the post-only order could not be posted into the orderbook |
FAIL_REDUCE_ONLY = 10 |
the reduce-only order would have caused position size to increase |
MM_PROTECTION = 11 |
the order was cancelled due to market maker protection trigger |
SELF_TRADE_PROTECTION = 12 |
the order was cancelled due to self-trade protection trigger |
SELF_MATCHED_SUBACCOUNT = 13 |
the order matched with another order from the same sub account |
OVERLAPPING_CLIENT_ORDER_ID = 14 |
an active order on your sub account shares the same clientOrderId |
BELOW_MARGIN = 15 |
the order will bring the sub account below initial margin requirement |
LIQUIDATION = 16 |
the sub account is liquidated (and all open orders are cancelled by Gravity) |
INSTRUMENT_INVALID = 17 |
instrument is invalid or not found on Gravity |
INSTRUMENT_DEACTIVATED = 18 |
instrument is no longer tradable on Gravity. (typically due to a market halt, or instrument expiry) |
SYSTEM_FAILOVER = 19 |
system failover resulting in loss of order state |
UNAUTHORISED = 20 |
the credentials used (userSession/apiKeySession/walletSignature) is not authorised to perform the action |
SESSION_KEY_EXPIRED = 21 |
the session key used to sign the order expired |
SUB_ACCOUNT_NOT_FOUND = 22 |
the subaccount does not exist |
NO_TRADE_PERMISSION = 23 |
the signature used to sign the order has no trade permission |
UNSUPPORTED_TIME_IN_FORCE = 24 |
the order payload does not contain a supported TimeInForce value |
MULTI_LEGGED_ORDER = 25 |
the order has multiple legs, but multiple legs are not supported by this venue |
EXCEED_MAX_POSITION_SIZE = 26 |
the order would have caused the subaccount to exceed the max position size |
EXCEED_MAX_SIGNATURE_EXPIRATION = 27 |
the signature supplied is more than 30 days in the future |
MARKET_ORDER_WITH_LIMIT_PRICE = 28 |
the market order has a limit price set |
CLIENT_CANCEL_ON_DISCONNECT_TRIGGERED = 29 |
client cancel on disconnect triggered |
OCO_COUNTER_PART_TRIGGERED = 30 |
the OCO counter part order was triggered |
REDUCE_ONLY_LIMIT = 31 |
the remaining order size was cancelled because it exceeded current position size |
CLIENT_REPLACE = 32 |
the order was replaced by a client replace request |
DERISK_MUST_BE_IOC = 33 |
the derisk order must be an IOC order |
DERISK_MUST_BE_REDUCE_ONLY = 34 |
the derisk order must be a reduce-only order |
DERISK_NOT_SUPPORTED = 35 |
derisk is not supported |
INVALID_ORDER_TYPE = 36 |
the order type is invalid |
CURRENCY_NOT_DEFINED = 37 |
the currency is not defined |
INVALID_CHAIN_ID = 38 |
the chain ID is invalid |
BUILDER_ORDER_FEE_EXCEED = 39 |
Builder fee exceed the limit |
BUILDER_ORDER_FEE_NEGATIVE = 40 |
Builder fee is below 0 |
BUILDER_ORDER_BUILDER_NOT_AUTHORIZED = 41 |
Builder is not an authorized builder for client |
BUILDER_ORDER_BUILDER_NOT_EXIST = 42 |
Builder does not exist |
TRADE_PRICE_WORSE_THAN_BANKRUPTCY_PRICE = 44 |
the trade price is worse than the bankruptcy price |
TOO_MANY_MAKER_ORDERS = 45 |
the order was cancelled due to matching with too many maker orders |
REDUCE_ONLY_NOT_SUPPORTED_FOR_SPOT_ORDER = 46 |
reduce-only order is not supported for spot order |
TPSL_NOT_SUPPORTED_FOR_SPOT_ORDER = 47 |
tpsl is not supported for spot order |
SPOT_ORDER_NOT_SUPPORTED = 48 |
spot order is not supported |
INSUFFICIENT_BALANCE = 49 |
the subaccount has insufficient balance |
SPOT_TRADING_BLOCKED_DURING_SOCIALIZED_LOSS = 50 |
spot trading is blocked during socialized loss (SLOW) |
BELOW_MARGIN_WITH_PENALTY_DEVIATION = 51 |
the order will bring the sub account below initial margin requirement considering wide price deviation |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"orders": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"order_i_ds": [null],
"client_order_i_ds": [null],
"time_to_live_ms": "500"
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"o": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"oi": [null],
"co": [null],
"tt": "500"
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
orderso |
[Order] | True | The orders in same order as requested |
cancel_acksca |
[Ack] | True | A list of acks for the cancelled orders |
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
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
order_idoi |
string | False0 |
[Filled by GRVT Backend] A unique 128-bit identifier for the order, deterministically generated within the GRVT backend |
sub_account_idsa |
string | True | The subaccount initiating the order |
is_marketim |
boolean | Falsefalse |
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_forceti |
TimeInForce | True | Four supported types of orders: GTT, IOC, AON, FOK:
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK) |
post_onlypo |
boolean | Falsefalse |
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. In this case, order creation is currently subject to a speedbump of 25ms to ensure orders are matched against updated orderbook quotes. |
reduce_onlyro |
boolean | Falsefalse |
If True, Order must reduce the position size, or be cancelled |
legsl |
[OrderLeg] | True | The legs present in this order The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice |
signatures |
Signature | True | The signature approving this order |
metadatam |
OrderMetadata | True | Order Metadata, ignored by the smart contract, and unsigned by the client |
states1 |
OrderState | False'' |
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client |
builderb |
string | True | The main account ID of the builder |
builder_feebf |
string | True | Builder fee charged for this order, expressed as a percentage (e.g., 0.001 means 0.001%). |
TimeInForce
| Must Fill All | Can Fill Partial | |
|---|---|---|
| Must Fill Immediately | FOK | IOC |
| Can Fill Till Time | AON | GTC |
| Value | Description |
|---|---|
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 |
RETAIL_PRICE_IMPROVEMENT = 5 |
RPI - A GTT + PostOnly maker order, that can only be taken by non-algorithmic UI users. |
OrderLeg
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The instrument to trade in this leg |
sizes |
string | True | The total number of assets to trade in this leg, expressed in base asset decimal units. |
limit_pricelp |
string | False0 |
The limit price of the order leg, expressed in 9 decimals.This is the number of quote currency units to pay/receive for this leg. This should be null/0 if the order is a market order |
is_buying_assetib |
boolean | True | Specifies if the order leg is a buy or sell |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
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.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
client_order_idco |
string | True | 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^63 - 1] To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^63, 2^64 - 1] When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId |
create_timect |
string | False0 |
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds |
triggert |
TriggerOrderMetadata | False `` |
Trigger fields are used to support any type of trigger order such as TP/SL |
brokerb |
BrokerTag | False `` |
Specifies the broker who brokered the order |
TriggerOrderMetadata
Contains metadata related to trigger orders, such as Take Profit (TP) or Stop Loss (SL).
Trigger orders are used to automatically execute an order when a predefined price condition is met, allowing traders to implement risk management strategies.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_typett |
TriggerType | True | Type of the trigger order. eg: Take Profit, Stop Loss, etc |
tpslt |
TPSLOrderMetadata | True | Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders. |
TriggerType
Defines the type of trigger order used in trading, such as Take Profit or Stop Loss.
Trigger orders allow execution based on pre-defined price conditions rather than immediate market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Not a trigger order. The order executes normally without any trigger conditions. |
TAKE_PROFIT = 1 |
Take Profit Order - Executes when the price reaches a specified level to secure profits. |
STOP_LOSS = 2 |
Stop Loss Order - Executes when the price reaches a specified level to limit losses. |
TPSLOrderMetadata
Contains metadata for Take Profit (TP) and Stop Loss (SL) trigger orders.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
trigger_bytb |
TriggerBy | True | Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order |
trigger_pricetp |
string | True | The Trigger Price of the order, expressed in 9 decimals. |
close_positioncp |
boolean | True | If True, the order will close the position when the trigger price is reached |
is_split_positionis |
boolean | True | If True, the order will be treated as part of a position's split-TP/SL set, subject to aggregate size/count limits. |
TriggerBy
Defines the price type that activates a Take Profit (TP) or Stop Loss (SL) order.
Trigger orders are executed when the selected price type reaches the specified trigger price.Different price types ensure flexibility in executing strategies based on market conditions.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
no trigger condition |
INDEX = 1 |
INDEX - Order is activated when the index price reaches the trigger price |
LAST = 2 |
LAST - Order is activated when the last trade price reaches the trigger price |
MID = 3 |
MID - Order is activated when the mid price reaches the trigger price |
MARK = 4 |
MARK - Order is activated when the mark price reaches the trigger price |
BrokerTag
BrokerTag is a tag for the broker that the order is sent from.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
COIN_ROUTES = 1 |
CoinRoutes |
ALERTATRON = 2 |
Alertatron |
ORIGAMI = 3 |
Origami |
OrderState
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
statuss |
OrderStatus | True | The status of the order |
reject_reasonrr |
OrderRejectReason | True | The reason for rejection or cancellation |
book_sizebs |
[string] | True | The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs |
traded_sizets |
[string] | True | The total number of assets traded. Sorted in same order as Order.Legs |
update_timeut |
string | True | Time at which the order was updated by GRVT, expressed in unix nanoseconds |
avg_fill_priceaf |
[string] | True | The average fill price of the order. Sorted in same order as Order.Legs |
OrderStatus
| Value | Description |
|---|---|
PENDING = 1 |
Order has been sent to the matching engine and is pending a transition to open/filled/rejected. |
OPEN = 2 |
Order is actively matching on the matching engine, could be unfilled or partially filled. |
FILLED = 3 |
Order is fully filled and hence closed. Taker Orders can transition directly from pending to filled, without going through open. |
REJECTED = 4 |
Order is rejected by matching engine since if fails a particular check (See OrderRejectReason). Once an order is open, it cannot be rejected. |
CANCELLED = 5 |
Order is cancelled by the user using one of the supported APIs (See OrderRejectReason). Before an order is open, it cannot be cancelled. |
OrderRejectReason
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
order is not cancelled or rejected |
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' |
MARKET_CANCEL = 4 |
the market order was cancelled after no/partial fill. Lower precedence than other TimeInForce cancel reasons |
IOC_CANCEL = 5 |
the IOC order was cancelled after no/partial fill |
AON_CANCEL = 6 |
the AON order was cancelled as it could not be fully matched |
FOK_CANCEL = 7 |
the FOK order was cancelled as it could not be fully matched |
EXPIRED = 8 |
the order was cancelled as it has expired |
FAIL_POST_ONLY = 9 |
the post-only order could not be posted into the orderbook |
FAIL_REDUCE_ONLY = 10 |
the reduce-only order would have caused position size to increase |
MM_PROTECTION = 11 |
the order was cancelled due to market maker protection trigger |
SELF_TRADE_PROTECTION = 12 |
the order was cancelled due to self-trade protection trigger |
SELF_MATCHED_SUBACCOUNT = 13 |
the order matched with another order from the same sub account |
OVERLAPPING_CLIENT_ORDER_ID = 14 |
an active order on your sub account shares the same clientOrderId |
BELOW_MARGIN = 15 |
the order will bring the sub account below initial margin requirement |
LIQUIDATION = 16 |
the sub account is liquidated (and all open orders are cancelled by Gravity) |
INSTRUMENT_INVALID = 17 |
instrument is invalid or not found on Gravity |
INSTRUMENT_DEACTIVATED = 18 |
instrument is no longer tradable on Gravity. (typically due to a market halt, or instrument expiry) |
SYSTEM_FAILOVER = 19 |
system failover resulting in loss of order state |
UNAUTHORISED = 20 |
the credentials used (userSession/apiKeySession/walletSignature) is not authorised to perform the action |
SESSION_KEY_EXPIRED = 21 |
the session key used to sign the order expired |
SUB_ACCOUNT_NOT_FOUND = 22 |
the subaccount does not exist |
NO_TRADE_PERMISSION = 23 |
the signature used to sign the order has no trade permission |
UNSUPPORTED_TIME_IN_FORCE = 24 |
the order payload does not contain a supported TimeInForce value |
MULTI_LEGGED_ORDER = 25 |
the order has multiple legs, but multiple legs are not supported by this venue |
EXCEED_MAX_POSITION_SIZE = 26 |
the order would have caused the subaccount to exceed the max position size |
EXCEED_MAX_SIGNATURE_EXPIRATION = 27 |
the signature supplied is more than 30 days in the future |
MARKET_ORDER_WITH_LIMIT_PRICE = 28 |
the market order has a limit price set |
CLIENT_CANCEL_ON_DISCONNECT_TRIGGERED = 29 |
client cancel on disconnect triggered |
OCO_COUNTER_PART_TRIGGERED = 30 |
the OCO counter part order was triggered |
REDUCE_ONLY_LIMIT = 31 |
the remaining order size was cancelled because it exceeded current position size |
CLIENT_REPLACE = 32 |
the order was replaced by a client replace request |
DERISK_MUST_BE_IOC = 33 |
the derisk order must be an IOC order |
DERISK_MUST_BE_REDUCE_ONLY = 34 |
the derisk order must be a reduce-only order |
DERISK_NOT_SUPPORTED = 35 |
derisk is not supported |
INVALID_ORDER_TYPE = 36 |
the order type is invalid |
CURRENCY_NOT_DEFINED = 37 |
the currency is not defined |
INVALID_CHAIN_ID = 38 |
the chain ID is invalid |
BUILDER_ORDER_FEE_EXCEED = 39 |
Builder fee exceed the limit |
BUILDER_ORDER_FEE_NEGATIVE = 40 |
Builder fee is below 0 |
BUILDER_ORDER_BUILDER_NOT_AUTHORIZED = 41 |
Builder is not an authorized builder for client |
BUILDER_ORDER_BUILDER_NOT_EXIST = 42 |
Builder does not exist |
TRADE_PRICE_WORSE_THAN_BANKRUPTCY_PRICE = 44 |
the trade price is worse than the bankruptcy price |
TOO_MANY_MAKER_ORDERS = 45 |
the order was cancelled due to matching with too many maker orders |
REDUCE_ONLY_NOT_SUPPORTED_FOR_SPOT_ORDER = 46 |
reduce-only order is not supported for spot order |
TPSL_NOT_SUPPORTED_FOR_SPOT_ORDER = 47 |
tpsl is not supported for spot order |
SPOT_ORDER_NOT_SUPPORTED = 48 |
spot order is not supported |
INSUFFICIENT_BALANCE = 49 |
the subaccount has insufficient balance |
SPOT_TRADING_BLOCKED_DURING_SOCIALIZED_LOSS = 50 |
spot trading is blocked during socialized loss (SLOW) |
BELOW_MARGIN_WITH_PENALTY_DEVIATION = 51 |
the order will bring the sub account below initial margin requirement considering wide price deviation |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"orders": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"cancel_acks": [{
"ack": "true"
}]
}
{
"o": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"ca": [{
"a": "true"
}]
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1004 | 404 | Data Not Found |
| 1005 | 500 | Unknown Error |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 1400 | 403 | Signer does not have trade permission |
| 1009 | 503 | We are temporarily deactivating this API endpoint, please try again later |
| 1012 | 400 | Invalid signature chain ID |
| 2000 | 403 | Signature is from an unauthorized signer |
| 2001 | 403 | Signature has expired |
| 2002 | 403 | Signature does not match payload |
| 2003 | 403 | Order sub account does not match logged in user |
| 2004 | 403 | Signature is from an expired session key |
| 2006 | 403 | Signature R/S must have exactly 64 characters long without 0x prefix |
| 2005 | 403 | Signature V must be 27/28 |
| 2007 | 403 | Signature S must be in the lower half of the curve |
| 2010 | 400 | Order ID should be empty when creating an order |
| 2011 | 400 | Client Order ID should be supplied when creating an order |
| 2012 | 400 | Client Order ID overlaps with existing active order |
| 2030 | 400 | Orderbook Orders must have a TimeInForce of GTT/IOC/FOK |
| 2031 | 400 | RFQ Orders must have a TimeInForce of GTT/AON/IOC/FOK |
| 2032 | 400 | Post Only can only be set to true for GTT/AON orders |
| 2020 | 400 | Market Order must always be supplied without a limit price |
| 2021 | 400 | Limit Order must always be supplied with a limit price |
| 2040 | 400 | Order must contain at least one leg |
| 2041 | 400 | Order Legs must be sorted by Derivative.Instrument/Underlying/BaseCurrency/Expiration/StrikePrice |
| 2042 | 400 | Orderbook Orders must contain only one leg |
| 2050 | 400 | Order state must be empty upon creation |
| 2051 | 400 | Order execution metadata must be empty upon creation |
| 2060 | 400 | Order Legs contain one or more inactive derivative |
| 2061 | 400 | Unsupported Instrument Requested |
| 2062 | 400 | Order size smaller than min size |
| 2063 | 400 | Order size smaller than min block size in block trade venue |
| 2064 | 400 | Invalid limit price tick |
| 2065 | 400 | Order size too granular |
| 2066 | 400 | Order below minimum notional. Please try again with a higher price or size. |
| 2067 | 400 | Order below minimum notional. Please try reducing your position again with a higher price or size. |
| 2070 | 400 | Liquidation Order is not supported |
| 2080 | 400 | Insufficient margin to create order |
| 2081 | 400 | Order Fill would result in exceeding maximum position size |
| 2082 | 400 | Pre-order check failed |
| 2084 | 400 | Post-order check failed |
| 2083 | 400 | Order Fill would result in exceeding maximum position size under current configurable leverage tier |
| 2090 | 429 | Max open orders exceeded |
| 2110 | 400 | Invalid trigger by |
| 2111 | 400 | Unsupported trigger by |
| 2112 | 400 | Invalid trigger order |
| 2113 | 400 | Trigger price must be non-zero |
| 2114 | 400 | Invalid position linked TPSL orders, position linked TPSL must be a reduce-only order |
| 2115 | 400 | Invalid position linked TPSL orders, position linked TPSL must not have smaller size than the position |
| 2116 | 400 | Position linked TPSL order for this asset already exists |
| 2117 | 400 | Position linked TPSL orders must be created from web or mobile clients |
| 2242 | 400 | Split TPSL functionality not supported; you may be using a deprecated API, or this functionality is temporarily disabled |
| 3004 | 500 | Instrument does not have a valid maintenance margin configuration |
| 3005 | 500 | Instrument's underlying currency does not have a valid balance decimal configuration |
| 3006 | 500 | Instrument's quote currency does not have a valid balance decimal configuration |
| 2400 | 400 | Reduce only order with no position |
| 2401 | 400 | Reduce only order must not increase position size |
| 2402 | 400 | Reduce only order size exceeds maximum allowed value |
| 7304 | 400 | Only position-reducing orders (reduce_only as true) allowed for this asset right now. |
| 2450 | 400 | Spot order is not supported |
| 2451 | 400 | Spot order must not be a reduce-only order |
| 2452 | 400 | Spot order must not be a TPSL order |
| 2453 | 400 | Spot trading is blocked during socialized loss |
| 2233 | 400 | Both order ID and client order ID cannot be provided |
| 2234 | 400 | Bulk create orders must have the same instrument |
| 2235 | 400 | Bulk orders count exceeds the maximum allowed |
| 2236 | 400 | Bulk orders does not support trigger order |
| 2237 | 400 | Bulk orders must be from API source |
| 2238 | 400 | Split TPSL orders must not be position-linked TPSL |
| 2239 | 400 | Split TPSL orders must be reduce-only |
| 2240 | 400 | If creating split TPSL orders, can only specify split TPSL orders in the creation array |
| 2241 | 400 | Split TPSL order count exceeds maximum allowed set size |
| 2243 | 400 | Split TPSL set already exists for this asset. Please modify the existing set of split TPSL orders. |
| 2244 | 400 | Split TPSL creation only allowed for instruments with already-existing positions. |
| 2245 | 400 | Split TPSL creation exceeds position size. |
| 2246 | 400 | Split TPSL modification requires all existing split TPSL orders to be cancelled |
| 2222 | 400 | Order is not a TPSL order |
| 2232 | 400 | Invalid position linked TPSL orders, position linked TPSL must not have order linkage |
| 2413 | 400 | Replace order failed, number of orders provided does not match the number of orders to replace |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v2/bulk_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"orders": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"order_i_ds": [null],
"client_order_i_ds": [null],
"time_to_live_ms": "500"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v2/bulk_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"orders": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"order_i_ds": [null],
"client_order_i_ds": [null],
"time_to_live_ms": "500"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v2/bulk_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"o": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"oi": [null],
"co": [null],
"tt": "500"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v2/bulk_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"o": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"oi": [null],
"co": [null],
"tt": "500"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v2/bulk_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"orders": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"order_i_ds": [null],
"client_order_i_ds": [null],
"time_to_live_ms": "500"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v2/bulk_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"orders": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"order_i_ds": [null],
"client_order_i_ds": [null],
"time_to_live_ms": "500"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v2/bulk_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"o": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"oi": [null],
"co": [null],
"tt": "500"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v2/bulk_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"o": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"oi": [null],
"co": [null],
"tt": "500"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v2/bulk_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"orders": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"order_i_ds": [null],
"client_order_i_ds": [null],
"time_to_live_ms": "500"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v2/bulk_orders",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"orders": [{
"order_id": "0x1234567890abcdef",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"is_market": false,
"time_in_force": "GOOD_TILL_TIME",
"post_only": false,
"reduce_only": false,
"legs": [{
"instrument": "BTC_USDT_Perp",
"size": "10.5",
"limit_price": "65038.01",
"is_buying_asset": true
}],
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"metadata": {
"client_order_id": "23042",
"create_time": "1697788800000000000",
"trigger": {
"trigger_type": "TAKE_PROFIT",
"tpsl": {
"trigger_by": "LAST",
"trigger_price": "65038.10",
"close_position": false,
"is_split_position": false
}
},
"broker": "BROKER_CODE"
},
"state": {
"status": "PENDING",
"reject_reason": "CLIENT_CANCEL",
"book_size": ["10.5"],
"traded_size": ["1.5"],
"update_time": "1697788800000000000",
"avg_fill_price": ["60000.4"]
},
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee": "0.001"
}],
"order_i_ds": [null],
"client_order_i_ds": [null],
"time_to_live_ms": "500"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v2/bulk_orders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"o": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"oi": [null],
"co": [null],
"tt": "500"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v2/bulk_orders",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"o": [{
"oi": "0x1234567890abcdef",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"im": false,
"ti": "GOOD_TILL_TIME",
"po": false,
"ro": false,
"l": [{
"i": "BTC_USDT_Perp",
"s": "10.5",
"lp": "65038.01",
"ib": true
}],
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"m": {
"co": "23042",
"ct": "1697788800000000000",
"t": {
"tt": "TAKE_PROFIT",
"t": {
"tb": "LAST",
"tp": "65038.10",
"cp": false,
"is": false
}
},
"b": "BROKER_CODE"
},
"s1": {
"s": "PENDING",
"rr": "CLIENT_CANCEL",
"bs": ["10.5"],
"ts": ["1.5"],
"ut": "1697788800000000000",
"af": ["60000.4"]
},
"b": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": "0.001"
}],
"oi": [null],
"co": [null],
"tt": "500"
},
"i": 123
}
' -w 360
Execution
Fill History
FULL ENDPOINT: full/v1/fill_history
LITE ENDPOINT: lite/v1/fill_history
Query for all historical fills made by a single account. A single order can be matched multiple times, hence there is no real way to uniquely identify a trade.
Pagination works as follows:
- We perform a reverse chronological lookup, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to request for |
kindk |
[Kind] | Falseall |
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned |
baseb |
[string] | Falseall |
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned |
quoteq |
[string] | Falseall |
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only entries matching the filter will be returned |
start_timest |
string | False0 |
The start time to apply in unix nanoseconds. If nil, this defaults to all start times. Otherwise, only entries matching the filter will be returned |
end_timeet |
string | Falsenow() |
The end time to apply in unix nanoseconds. If nil, this defaults to all end times. Otherwise, only entries matching the filter will be returned |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000 |
cursorc |
string | False'' |
The cursor to indicate when to start the query from |
Kind
The list of asset kinds that are supported on the GRVT exchange
| Value | Description |
|---|---|
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 |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[Fill] | True | The private trades matching the request asset |
nextn |
string | True | The cursor to indicate when to start the query from |
Fill
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
sub_account_idsa |
string | True | The sub account ID that participated in the trade |
instrumenti |
string | True | The instrument being represented |
is_buyerib |
boolean | True | The side that the subaccount took on the trade |
is_takerit |
boolean | True | The role that the subaccount took on the trade |
sizes |
string | True | The number of assets being traded, expressed in base asset decimal units |
pricep |
string | True | The traded price, expressed in 9 decimals |
mark_pricemp |
string | FalseNone |
The mark price of the instrument at point of trade, expressed in 9 decimals |
index_priceip |
string | True | The index price of the instrument at point of trade, expressed in 9 decimals |
interest_rateir |
string | True | The interest rate of the underlying at point of trade, expressed in centibeeps (1/100th of a basis point) |
forward_pricefp |
string | FalseNone |
[Options] The forward price of the option at point of trade, expressed in 9 decimals |
realized_pnlrp |
string | True | The realized PnL of the trade, expressed in quote asset decimal units (0 if increasing position size) |
feef |
string | True | The fees paid on the trade, expressed in quote asset decimal unit (negative if maker rebate applied) |
fee_ratefr |
string | True | The fee rate paid on the trade |
trade_idti |
string | True | A trade identifier, globally unique, and monotonically increasing (not by 1).All trades sharing a single taker execution share the same first component (before -), and event_time.trade_id is guaranteed to be consistent across MarketData Trade and Trading Fill. |
order_idoi |
string | True | An order identifier |
venuev |
Venue | True | The venue where the trade occurred |
is_liquidationil |
boolean | True | If the trade was a liquidation |
client_order_idco |
string | True | 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^63 - 1] To prevent any conflicts, client machines should generate a random clientOrderID in the range [2^63, 2^64 - 1] When GRVT Backend receives an order with an overlapping clientOrderID, we will reject the order with rejectReason set to overlappingClientOrderId |
signers1 |
string | True | The address (public key) of the wallet signing the payload |
brokerb |
BrokerTag | False `` |
Specifies the broker who brokered the order |
is_rpiir1 |
boolean | True | If the trade is a RPI trade |
builderb1 |
string | True | The main account ID of the builder. referred to Order.builder |
builder_fee_ratebf |
string | True | Builder fee percentage charged for this order. referred to Order.builder builderFee |
builder_feebf1 |
string | True | The builder fee paid on the trade, expressed in quote asset decimal unit. referred to Trade.builderFee |
fee_currencyfc |
string | True | The currency of the fee paid on the trade |
Venue
The list of Trading Venues that are supported on the GRVT exchange
| Value | Description |
|---|---|
ORDERBOOK = 1 |
the trade is cleared on the orderbook venue |
RFQ = 2 |
the trade is cleared on the RFQ venue |
BrokerTag
BrokerTag is a tag for the broker that the order is sent from.
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
COIN_ROUTES = 1 |
CoinRoutes |
ALERTATRON = 2 |
Alertatron |
ORIGAMI = 3 |
Origami |
Success
Full Response
{
"result": [{
"event_time": "1697788800000000000",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"is_buyer": true,
"is_taker": true,
"size": "0.30",
"price": "65038.01",
"mark_price": "65038.01",
"index_price": "65038.01",
"interest_rate": 0.0003,
"forward_price": "65038.01",
"realized_pnl": "2400.50",
"fee": "9.75",
"fee_rate": 0.0003,
"trade_id": "209358-2",
"order_id": "0x10000101000203040506",
"venue": "ORDERBOOK",
"is_liquidation": false,
"client_order_id": "23042",
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"broker": "UNSPECIFIED",
"is_rpi": false,
"builder": "'$GRVT_MAIN_ACCOUNT_ID'",
"builder_fee_rate": 0.001,
"builder_fee": "0.2",
"fee_currency": "USDT"
}],
"next": "Qw0918="
}
{
"r": [{
"et": "1697788800000000000",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"ib": true,
"it": true,
"s": "0.30",
"p": "65038.01",
"mp": "65038.01",
"ip": "65038.01",
"ir": 0.0003,
"fp": "65038.01",
"rp": "2400.50",
"f": "9.75",
"fr": 0.0003,
"ti": "209358-2",
"oi": "0x10000101000203040506",
"v": "ORDERBOOK",
"il": false,
"co": "23042",
"s1": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"b": "UNSPECIFIED",
"ir1": false,
"b1": "'$GRVT_MAIN_ACCOUNT_ID'",
"bf": 0.001,
"bf1": "0.2",
"fc": "USDT"
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/fill_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/fill_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/fill_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/fill_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/fill_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/fill_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
Funding Payment History
FULL ENDPOINT: full/v1/funding_payment_history
LITE ENDPOINT: lite/v1/funding_payment_history
ApiFundingPaymentHistoryRequest
Query for all historical funding payments made by a single account.
Pagination works as follows:
- We perform a reverse chronological lookup, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to request for |
instrumenti |
string | Falseall |
The perpetual instrument to filter for |
start_timest |
string | False0 |
The start time to apply in unix nanoseconds. If nil, this defaults to all start times. Otherwise, only entries matching the filter will be returned |
end_timeet |
string | Falsenow() |
The end time to apply in unix nanoseconds. If nil, this defaults to all end times. Otherwise, only entries matching the filter will be returned |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000 |
cursorc |
string | False'' |
The cursor to indicate when to start the query from |
kindk |
[Kind] | Falseall |
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned |
baseb |
[string] | Falseall |
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned |
quoteq |
[string] | Falseall |
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only entries matching the filter will be returned |
Kind
The list of asset kinds that are supported on the GRVT exchange
| Value | Description |
|---|---|
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 |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": "",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
ApiFundingPaymentHistoryResponse
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[FundingPayment] | True | The funding payments matching the request asset |
nextn |
string | True | The cursor to indicate when to start the query from |
FundingPayment
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
sub_account_idsa |
string | True | The sub account ID that made the funding payment |
instrumenti |
string | True | The perpetual instrument being funded |
currencyc |
string | True | The currency of the funding payment |
amounta |
string | True | The amount of the funding payment. Positive if paid, negative if received |
tx_idti |
string | True | The transaction ID of the funding payment. Funding payments can be triggered by a trade, transfer, or liquidation. The tx_id will match the corresponding trade_id or tx_id. |
Success
Full Response
{
"result": [{
"event_time": "1697788800000000000",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"currency": "USDT",
"amount": "9.75",
"tx_id": "209358"
}],
"next": "Qw0918="
}
{
"r": [{
"et": "1697788800000000000",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"c": "USDT",
"a": "9.75",
"ti": "209358"
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 3007 | 400 | API is not applicable for spot instruments |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/funding_payment_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/funding_payment_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/funding_payment_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": "",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/funding_payment_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": "",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/funding_payment_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/funding_payment_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/funding_payment_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": "",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/funding_payment_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": "",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/funding_payment_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/funding_payment_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/funding_payment_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": "",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/funding_payment_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": "",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
Position
Positions
FULL ENDPOINT: full/v1/positions
LITE ENDPOINT: lite/v1/positions
Query the positions of a sub account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to request for |
kindk |
[Kind] | Falseall |
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned |
baseb |
[string] | Falseall |
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned |
quoteq |
[string] | Falseall |
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only entries matching the filter will be returned |
Kind
The list of asset kinds that are supported on the GRVT exchange
| Value | Description |
|---|---|
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 |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[Positions] | True | The positions matching the request filter |
Positions
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
sub_account_idsa |
string | True | The sub account ID that participated in the trade |
instrumenti |
string | True | The instrument being represented |
sizes |
string | True | The size of the position, expressed in base asset decimal units. Negative for short positions |
notionaln |
string | True | The notional value of the position, negative for short assets, expressed in quote asset decimal units |
entry_priceep |
string | True | The entry price of the position, expressed in 9 decimalsWhenever increasing the size of a position, the entry price is updated to the new average entry price new_entry_price = (old_entry_price * old_size + trade_price * trade_size) / (old_size + trade_size) |
exit_priceep1 |
string | True | The exit price of the position, expressed in 9 decimalsWhenever decreasing the size of a position, the exit price is updated to the new average exit price new_exit_price = (old_exit_price * old_exit_trade_size + trade_price * trade_size) / (old_exit_trade_size + trade_size) |
mark_pricemp |
string | True | The mark price of the position, expressed in 9 decimals |
unrealized_pnlup |
string | True | The unrealized PnL of the position, expressed in quote asset decimal unitsunrealized_pnl = (mark_price - entry_price) * size |
realized_pnlrp |
string | True | The realized PnL of the position, expressed in quote asset decimal unitsrealized_pnl = (exit_price - entry_price) * exit_trade_size |
total_pnltp |
string | True | The total PnL of the position, expressed in quote asset decimal unitstotal_pnl = realized_pnl + unrealized_pnl |
roir |
string | True | The ROI of the position, expressed as a percentageroi = (total_pnl / (entry_price * abs(size))) * 100^ |
quote_index_priceqi |
string | True | The index price of the quote currency. (reported in USD) |
est_liquidation_priceel |
string | True | The estimated liquidation price |
leveragel |
string | True | The current leverage value for this position |
cumulative_feecf |
string | True | The cumulative fee paid on the position, expressed in quote asset decimal units |
cumulative_realized_funding_paymentcr |
string | True | The cumulative realized funding payment of the position, expressed in quote asset decimal units. Positive if paid, negative if received |
margin_typemt |
PositionMarginType | True | The margin type of the position |
isolated_balanceib |
string | FalseNone |
[IsolatedOnly] The wallet balance reserved for this isolated margin position, expressed in quote asset decimal units. If this positions is liquidated, this is the maximal balance that can be lost |
isolated_imii |
string | FalseNone |
[IsolatedOnly] The initial margin of the isolated margin position, expressed in quote asset decimal units. The total_equity required to open more size in the position |
isolated_mmim |
string | FalseNone |
[IsolatedOnly] The maintenance margin of the isolated margin position, expressed in quote asset decimal units. The total_equity required to avoid liquidation of the position |
PositionMarginType
| Value | Description |
|---|---|
ISOLATED = 1 |
Isolated Margin Mode: each position is allocated a fixed amount of collateral |
CROSS = 2 |
Cross Margin Mode: uses all available funds in your account as collateral across all cross margin positions |
Success
Full Response
{
"result": [{
"event_time": "1697788800000000000",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"size": "2635000.50",
"notional": "2635000.50",
"entry_price": "65038.01",
"exit_price": "65038.01",
"mark_price": "65038.01",
"unrealized_pnl": "135000.50",
"realized_pnl": "-35000.30",
"total_pnl": "100000.20",
"roi": "10.20",
"quote_index_price": "1.0000102",
"est_liquidation_price": 60000.25,
"leverage": "10",
"cumulative_fee": "100000.20",
"cumulative_realized_funding_payment": "100000.20",
"margin_type": "cross",
"isolated_balance": "100000.20",
"isolated_im": "100000.20",
"isolated_mm": "100000.20"
}]
}
{
"r": [{
"et": "1697788800000000000",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"s": "2635000.50",
"n": "2635000.50",
"ep": "65038.01",
"ep1": "65038.01",
"mp": "65038.01",
"up": "135000.50",
"rp": "-35000.30",
"tp": "100000.20",
"r": "10.20",
"qi": "1.0000102",
"el": 60000.25,
"l": "10",
"cf": "100000.20",
"cr": "100000.20",
"mt": "cross",
"ib": "100000.20",
"ii": "100000.20",
"im": "100000.20"
}]
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 3007 | 400 | API is not applicable for spot instruments |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/positions' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/positions",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/positions' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/positions",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/positions' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/positions",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/positions' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/positions",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/positions' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/positions",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/positions' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/positions",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"]
},
"i": 123
}
' -w 360
Position History
FULL ENDPOINT: full/v1/position_history
LITE ENDPOINT: lite/v1/position_history
Query for position lifecycle records for a single sub account.
Returns both fully closed positions and positions that are still open but have been partially reduced (PARTIALLY_CLOSED).
Results are ordered as follows: partially closed positions (most recently opened first), then fully closed positions (most recently closed first).
Partially closed positions are included only when all of the following are true:
start_timeis unset (partially closed positions have no close time)end_timeis unset (partially closed positions have no close time)cursoris unset (they are only returned on the initial page)statusis nil or includesPARTIALLY_CLOSED
Pagination works as follows:
- We perform a reverse chronological lookup by position-close time, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to request for |
start_timest |
string | False0 |
Start of the close-time range in unix nanoseconds. If nil, defaults to no lower bound. Only positions with close_time >= start_time are returned. Does not apply to partially closed positions (they have no close time and will be excluded when this field is set) |
end_timeet |
string | Falsenow() |
End of the close-time range in unix nanoseconds. If nil, defaults to now. Only positions with close_time <= end_time are returned. Does not apply to partially closed positions (they have no close time and will be excluded when this field is set) |
kindk |
[Kind] | Falseall |
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only positions matching the filter will be returned |
baseb |
[string] | Falseall |
The base filter to apply. If nil, this defaults to all bases. Otherwise, only positions matching the filter will be returned |
quoteq |
[string] | Falseall |
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only positions matching the filter will be returned |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000. Applies to fully closed positions only; limit excludes any matching partially-closed positions |
cursorc |
string | False'' |
The cursor to indicate when to start the next page query from. Partially closed positions are only returned on the initial page (when cursor is unset) |
statuss |
[PositionCloseStatus] | Falseall |
The status filter to apply. If nil, this defaults to all statuses. Otherwise, only positions matching the filter will be returned |
is_longil |
boolean | Falsefalse |
Set to true to filter for long positions. If both is_long and is_short are false (default), positions of both directions are returned |
is_shortis |
boolean | Falsefalse |
Set to true to filter for short positions. If both is_long and is_short are false (default), positions of both directions are returned |
margin_typemt |
[PositionMarginType] | Falseall |
The margin type filter to apply. If nil, this defaults to all margin types. Otherwise, only positions matching the filter will be returned |
Kind
The list of asset kinds that are supported on the GRVT exchange
| Value | Description |
|---|---|
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 |
PositionCloseStatus
| Value | Description |
|---|---|
CLOSED = 1 |
Position fully closed via reducing trade or flip |
LIQUIDATED = 2 |
Position closed via liquidation |
SETTLED = 3 |
Position closed via settlement |
PARTIALLY_CLOSED = 4 |
Position partially closed |
PositionMarginType
| Value | Description |
|---|---|
ISOLATED = 1 |
Isolated Margin Mode: each position is allocated a fixed amount of collateral |
CROSS = 2 |
Cross Margin Mode: uses all available funds in your account as collateral across all cross margin positions |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"limit": 500,
"cursor": "",
"status": ["CLOSED", "LIQUIDATED"],
"is_long": null,
"is_short": null,
"margin_type": ["CROSS", "ISOLATED"]
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"l": 500,
"c": "",
"s": ["CLOSED", "LIQUIDATED"],
"il": null,
"is": null,
"mt": ["CROSS", "ISOLATED"]
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[ApiPositionHistory] | True | Position lifecycle records matching the request filters. Partially closed positions appear first (most recently opened first), followed by fully closed positions (most recently closed first) |
nextn |
string | True | The cursor to indicate when to start the query from |
ApiPositionHistory
A position lifecycle record.
When status is PARTIALLY_CLOSED, the position is still open. Fields that describe the close event (close_time, position_close_mark_price) will be omitted, and leverage reflects the current value
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | Trading account ID which held this position |
instrumenti |
string | True | Asset this position was for |
open_timeot |
string | True | Timestamp of first trade that opened this lifecycle |
statuss |
PositionCloseStatus | True | |
is_longil |
boolean | True | True if the closed position was long |
margin_typemt |
PositionMarginType | True | |
close_timect |
string | FalseNone |
Timestamp when the position lifecycle ended. Omitted when status is PARTIALLY_CLOSED |
entry_priceep |
string | True | Average entry price at 9 decimals |
exit_priceep1 |
string | True | Average exit price at 9 decimals |
position_close_mark_pricepc |
string | FalseNone |
Mark price at close. Omitted when status is PARTIALLY_CLOSED |
realized_pnlrp |
string | True | Cumulative realized PnL in quote currency |
cumulative_feecf |
string | True | Cumulative fees in quote currency |
cumulative_realized_funding_paymentcr |
string | True | Cumulative realized funding payment in quote currency |
closed_volume_basecv |
string | True | Sum of abs(reducingTradeSize) across all reducing trades |
closed_volume_quotecv1 |
string | True | Sum of abs(reducingTradeSize) * tradePrice across all reducing trades |
max_open_interest_basemo |
string | True | Max absolute position size reached during lifecycle |
max_open_interest_quotemo1 |
string | True | Max abs(size) * entryVWAP reached during lifecycle |
cumulative_initial_marginci |
string | True | Sum of markPrice * abs(tradeSize) / leverage for position-increasing trades |
max_initial_marginmi |
string | True | High-water mark of cumulativeInitialMargin during lifecycle |
leveragel |
string | True | Leverage at time of close. When status is PARTIALLY_CLOSED, this is the current leverage |
unrealized_pnlup |
string | FalseNone |
The unrealized PnL of the position, expressed in quote asset decimal unitsunrealized_pnl = (mark_price - entry_price) * size where size is signed (negative for short positions)Only present when status is PARTIALLY_CLOSED |
PositionCloseStatus
| Value | Description |
|---|---|
CLOSED = 1 |
Position fully closed via reducing trade or flip |
LIQUIDATED = 2 |
Position closed via liquidation |
SETTLED = 3 |
Position closed via settlement |
PARTIALLY_CLOSED = 4 |
Position partially closed |
PositionMarginType
| Value | Description |
|---|---|
ISOLATED = 1 |
Isolated Margin Mode: each position is allocated a fixed amount of collateral |
CROSS = 2 |
Cross Margin Mode: uses all available funds in your account as collateral across all cross margin positions |
Success
Full Response
{
"result": [{
"sub_account_id": null,
"instrument": null,
"open_time": null,
"status": "CLOSED",
"is_long": null,
"margin_type": "SIMPLE_CROSS_MARGIN",
"close_time": null,
"entry_price": null,
"exit_price": null,
"position_close_mark_price": null,
"realized_pnl": null,
"cumulative_fee": null,
"cumulative_realized_funding_payment": null,
"closed_volume_base": null,
"closed_volume_quote": null,
"max_open_interest_base": null,
"max_open_interest_quote": null,
"cumulative_initial_margin": null,
"max_initial_margin": null,
"leverage": null,
"unrealized_pnl": null
}],
"next": "Qw0918="
}
{
"r": [{
"sa": null,
"i": null,
"ot": null,
"s": "CLOSED",
"il": null,
"mt": "SIMPLE_CROSS_MARGIN",
"ct": null,
"ep": null,
"ep1": null,
"pc": null,
"rp": null,
"cf": null,
"cr": null,
"cv": null,
"cv1": null,
"mo": null,
"mo1": null,
"ci": null,
"mi": null,
"l": null,
"up": null
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 3007 | 400 | API is not applicable for spot instruments |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/position_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"limit": 500,
"cursor": "",
"status": ["CLOSED", "LIQUIDATED"],
"is_long": null,
"is_short": null,
"margin_type": ["CROSS", "ISOLATED"]
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/position_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"limit": 500,
"cursor": "",
"status": ["CLOSED", "LIQUIDATED"],
"is_long": null,
"is_short": null,
"margin_type": ["CROSS", "ISOLATED"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/position_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"l": 500,
"c": "",
"s": ["CLOSED", "LIQUIDATED"],
"il": null,
"is": null,
"mt": ["CROSS", "ISOLATED"]
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/position_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"l": 500,
"c": "",
"s": ["CLOSED", "LIQUIDATED"],
"il": null,
"is": null,
"mt": ["CROSS", "ISOLATED"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/position_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"limit": 500,
"cursor": "",
"status": ["CLOSED", "LIQUIDATED"],
"is_long": null,
"is_short": null,
"margin_type": ["CROSS", "ISOLATED"]
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/position_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"limit": 500,
"cursor": "",
"status": ["CLOSED", "LIQUIDATED"],
"is_long": null,
"is_short": null,
"margin_type": ["CROSS", "ISOLATED"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/position_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"l": 500,
"c": "",
"s": ["CLOSED", "LIQUIDATED"],
"il": null,
"is": null,
"mt": ["CROSS", "ISOLATED"]
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/position_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"l": 500,
"c": "",
"s": ["CLOSED", "LIQUIDATED"],
"il": null,
"is": null,
"mt": ["CROSS", "ISOLATED"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/position_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"limit": 500,
"cursor": "",
"status": ["CLOSED", "LIQUIDATED"],
"is_long": null,
"is_short": null,
"margin_type": ["CROSS", "ISOLATED"]
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/position_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"kind": ["PERPETUAL"],
"base": ["BTC", "ETH"],
"quote": ["USDT", "USDC"],
"limit": 500,
"cursor": "",
"status": ["CLOSED", "LIQUIDATED"],
"is_long": null,
"is_short": null,
"margin_type": ["CROSS", "ISOLATED"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/position_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"l": 500,
"c": "",
"s": ["CLOSED", "LIQUIDATED"],
"il": null,
"is": null,
"mt": ["CROSS", "ISOLATED"]
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/position_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"k": ["PERPETUAL"],
"b": ["BTC", "ETH"],
"q": ["USDT", "USDC"],
"l": 500,
"c": "",
"s": ["CLOSED", "LIQUIDATED"],
"il": null,
"is": null,
"mt": ["CROSS", "ISOLATED"]
},
"i": 123
}
' -w 360
Set Position Config
FULL ENDPOINT: full/v1/set_position_config
LITE ENDPOINT: lite/v1/set_position_config
ApiSetSubAccountPositionMarginConfigRequest
Sets the margin type and leverage configuration for a specific position (instrument) within a sub account.
This configuration is applied per-instrument, allowing different margin settings for different positions.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to set the margin type and leverage for |
instrumenti |
string | True | The instrument of the position to set the margin type and leverage for |
margin_typemt |
PositionMarginType | True | The margin type to set for the position |
leveragel |
string | True | The leverage to set for the position |
signatures |
Signature | True | The signature of this operation |
PositionMarginType
| Value | Description |
|---|---|
ISOLATED = 1 |
Isolated Margin Mode: each position is allocated a fixed amount of collateral |
CROSS = 2 |
Cross Margin Mode: uses all available funds in your account as collateral across all cross margin positions |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"margin_type": "ISOLATED",
"leverage": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"mt": "ISOLATED",
"l": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
ApiSetSubAccountPositionMarginConfigResponse
The response to set the margin type and leverage for a position
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Whether the margin type and leverage was acked |
Success
Full Response
{
"ack": "true"
}
{
"a": "true"
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1004 | 404 | Data Not Found |
| 2102 | 400 | Margin type change failed, has open position for this instrument |
| 2103 | 400 | Margin type change failed, has open orders for this instrument |
| 2101 | 400 | Vaults cannot configure leverage |
| 2104 | 400 | Margin type not supported |
| 2105 | 400 | Margin type change failed |
| 2100 | 400 | Invalid initial leverage |
| 2107 | 400 | Attempted to set leverage below minimum |
| 2108 | 400 | Attempted to set leverage above maximum |
| 3007 | 400 | API is not applicable for spot instruments |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/set_position_config' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"margin_type": "ISOLATED",
"leverage": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_position_config",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"margin_type": "ISOLATED",
"leverage": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/set_position_config' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"mt": "ISOLATED",
"l": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_position_config",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"mt": "ISOLATED",
"l": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/set_position_config' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"margin_type": "ISOLATED",
"leverage": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_position_config",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"margin_type": "ISOLATED",
"leverage": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/set_position_config' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"mt": "ISOLATED",
"l": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_position_config",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"mt": "ISOLATED",
"l": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/set_position_config' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"margin_type": "ISOLATED",
"leverage": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_position_config",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"margin_type": "ISOLATED",
"leverage": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/set_position_config' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"mt": "ISOLATED",
"l": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_position_config",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"mt": "ISOLATED",
"l": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
Add Position Margin
FULL ENDPOINT: full/v1/add_position_margin
LITE ENDPOINT: lite/v1/add_position_margin
ApiAddIsolatedPositionMarginRequest
The request to add margin to a isolated position
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to add isolated margin in or remove margin from |
instrumenti |
string | True | The instrument to add margin into, or remove margin from |
amounta |
string | True | The amount of margin to add to the position, positive to add, negative to remove, expressed in quote asset decimal units |
signatures |
Signature | True | The signature of this operation |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"amount": "123456.78",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"a": "123456.78",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
ApiAddIsolatedPositionMarginResponse
The response to add margin to a isolated position
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
successs |
boolean | True | Whether the margin mode and leverage was set successfully |
Success
Full Response
{
"success": "true"
}
{
"s": "true"
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1004 | 404 | Data Not Found |
| 7450 | 400 | Add margin failed |
| 7451 | 400 | Add margin to empty position |
| 7452 | 400 | Add margin to non isolated position |
| 7453 | 400 | Max addable amount exceeded |
| 7454 | 400 | Max removable amount exceeded |
| 3007 | 400 | API is not applicable for spot instruments |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/add_position_margin' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"amount": "123456.78",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/add_position_margin",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"amount": "123456.78",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/add_position_margin' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"a": "123456.78",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/add_position_margin",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"a": "123456.78",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/add_position_margin' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"amount": "123456.78",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/add_position_margin",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"amount": "123456.78",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/add_position_margin' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"a": "123456.78",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/add_position_margin",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"a": "123456.78",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/add_position_margin' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"amount": "123456.78",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/add_position_margin",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"amount": "123456.78",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/add_position_margin' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"a": "123456.78",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/add_position_margin",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"a": "123456.78",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
Get Position Margin Limits
FULL ENDPOINT: full/v1/get_position_margin_limits
LITE ENDPOINT: lite/v1/get_position_margin_limits
ApiGetIsolatedPositionMarginLimitsRequest
The request to get the max addable and removable amount for an isolated position
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to get the margin limits for |
instrumenti |
string | True | The isolated position asset to get the margin limits for |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp"
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp"
}
ApiGetIsolatedPositionMarginLimitsResponse
The response to get the max addable and removable amount for an isolated position request
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The isolated position asset |
max_addable_amountma |
string | True | The max addable amount that can be added to the isolated position, expressed in quote asset decimal units |
max_removable_amountmr |
string | True | The max removable amount that can be removed from the isolated position, expressed in quote asset decimal units |
Success
Full Response
{
"instrument": "BTC_USDT_Perp",
"max_addable_amount": "123456.78",
"max_removable_amount": "123456.78"
}
{
"i": "BTC_USDT_Perp",
"ma": "123456.78",
"mr": "123456.78"
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1004 | 404 | Data Not Found |
| 7455 | 400 | Not isolated margin position |
| 3007 | 400 | API is not applicable for spot instruments |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/get_position_margin_limits' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_position_margin_limits",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/get_position_margin_limits' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_position_margin_limits",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/get_position_margin_limits' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_position_margin_limits",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/get_position_margin_limits' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_position_margin_limits",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/get_position_margin_limits' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_position_margin_limits",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/get_position_margin_limits' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_position_margin_limits",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp"
},
"i": 123
}
' -w 360
Transfer
Deposit History
FULL ENDPOINT: full/v1/deposit_history
LITE ENDPOINT: lite/v1/deposit_history
The request to get the historical deposits of an account
The history is returned in reverse chronological order
Both finalized and pending deposits are returned, and pending deposits are indicated by an empty confirmedTime field.
Pagination works as follows:
- We perform a reverse chronological lookup, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
currencyc |
[string] | True | The token currency to query for, if nil or empty, return all deposits. Otherwise, only entries matching the filter will be returned |
start_timest |
string | False0 |
The start time to query for in unix nanoseconds |
end_timeet |
string | Falsenow() |
The end time to query for in unix nanoseconds |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000 |
cursorc1 |
string | False'' |
The cursor to indicate when to start the next query from |
main_account_idma |
string | False `` |
Main account ID being queried. By default, applies the requestor's main account ID. |
Query
Full Request
{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
}
{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[DepositHistory] | True | The deposit history matching the request account |
nextn |
string | False'' |
The cursor to indicate when to start the next query from |
DepositHistory
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
l_1_hashl1 |
string | True | The L1 txHash of the deposit |
l_2_hashl2 |
string | True | The L2 txHash of the deposit |
to_account_idta |
string | True | The account to deposit into |
currencyc |
string | True | The token currency to deposit |
num_tokensnt |
string | True | The number of tokens to deposit |
initiated_timeit |
string | True | The timestamp when the deposit was initiated on L1 in unix nanoseconds |
confirmed_timect |
string | True | The timestamp when the deposit was confirmed on L2 in unix nanoseconds, empty if the deposit is pending. |
from_addressfa |
string | True | The address of the sender |
Success
Full Response
{
"result": [{
"l_1_hash": "0x10000101000203040506",
"l_2_hash": "0x10000101000203040506",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"initiated_time": "1697788800000000000",
"confirmed_time": "1697788800000000000",
"from_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0"
}],
"next": "Qw0918="
}
{
"r": [{
"l1": "0x10000101000203040506",
"l2": "0x10000101000203040506",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"it": "1697788800000000000",
"ct": "1697788800000000000",
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0"
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/deposit_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/deposit_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/deposit_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/deposit_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/deposit_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/deposit_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/deposit_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/deposit_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/deposit_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/deposit_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/deposit_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/deposit_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
},
"i": 123
}
' -w 360
Transfer
FULL ENDPOINT: full/v1/transfer
LITE ENDPOINT: lite/v1/transfer
This API allows you to transfer funds in multiple different ways
- Between SubAccounts within your Main Account
- Between your MainAccount and your SubAccounts
- To other MainAccounts that you have previously allowlisted
For fast withdrawals, funds must be sent to the designated funding account address. Please ensure you use the correct address based on the environment:
Production Environment Address:
[To be updated, not ready yet]
This address should be specified as the
to_account_id in your API requests for transferring funds using the transfer API. Ensure accurate input to avoid loss of funds or use the UI.NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
from_account_idfa |
string | True | The main account to transfer from |
from_sub_account_idfs |
string | True | The subaccount to transfer from (0 if transferring from main account) |
to_account_idta |
string | True | The main account to deposit into |
to_sub_account_idts |
string | True | The subaccount to transfer to (0 if transferring to main account) |
currencyc |
string | True | The token currency to transfer |
num_tokensnt |
string | True | The number of tokens to transfer, quoted in tokenCurrency decimal units |
signatures |
Signature | True | The signature of the transfer |
transfer_typett |
TransferType | True | The type of transfer |
transfer_metadatatm |
string | True | The metadata of the transfer |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
TransferType
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Deprecated: use standard instead. Legacy value for transfers created before transfer types were introduced. |
STANDARD = 1 |
Standard transfer that has nothing to do with bridging |
FAST_ARB_DEPOSIT = 2 |
Fast Arb Deposit Metadata type |
FAST_ARB_WITHDRAWAL = 3 |
Fast Arb Withdrawal Metadata type |
NON_NATIVE_BRIDGE_DEPOSIT = 4 |
Transfer type for non native bridging deposit |
NON_NATIVE_BRIDGE_WITHDRAWAL = 5 |
Transfer type for non native bridging withdrawal |
ADHOC_INCENTIVE = 6 |
Transfer type for adhoc incentive |
REFERRAL_INCENTIVE = 7 |
Transfer type for referral incentive |
TRADING_DEPOSIT_YIELD_INCENTIVE = 8 |
Transfer type for trading deposit yield incentive |
WalletType
| Value | Description |
|---|---|
FUNDING = 1 |
Funding wallet |
SPOT = 2 |
Spot wallet |
FUTURES = 3 |
Futures wallet |
WalletType
| Value | Description |
|---|---|
FUNDING = 1 |
Funding wallet |
SPOT = 2 |
Spot wallet |
FUTURES = 3 |
Futures wallet |
Query
Full Request
{
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"from_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"transfer_type": "UNSPECIFIED",
"transfer_metadata": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
}
{
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"fs": "'$GRVT_SUB_ACCOUNT_ID'",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"ts": "'$GRVT_SUB_ACCOUNT_ID'",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"tt": "UNSPECIFIED",
"tm": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
}
Used to acknowledge a transfer request outcome
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
ApiTransferAck | True | The Transfer response object |
ApiTransferAck
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the transfer has been successfully processed. If true, a tx_id will be returned. If false, an error will be returned. |
tx_idti |
string | True | The transaction ID of the transfer. This is only returned if the transfer is successful. |
Success
Full Response
{
"result": {
"ack": "true",
"tx_id": "1028403"
}
}
{
"r": {
"a": "true",
"ti": "1028403"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 5000 | 400 | Transfer Metadata does not match the expected structure. |
| 5001 | 400 | Transfer Provider does not match the expected provider. |
| 4002 | 400 | Transfer failed with an unrefined failure reason, please report to GRVT |
| 5002 | 400 | Direction of the transfer does not match the expected direction. |
| 5003 | 400 | Endpoint account ID is invalid. |
| 5004 | 400 | Funding account does not exist in our system. |
| 5005 | 400 | Invalid ChainID for the transfer request. |
| 7100 | 500 | Unknown transaction type |
| 7101 | 400 | Transfer account not found |
| 7102 | 400 | Transfer sub-account not found |
| 7103 | 500 | Charged trading fee below the config minimum |
| 7104 | 400 | Transfer sub-account doesn't belong to the transfer main account |
| 4004 | 400 | Both transfer wallet types must be provided |
| 4005 | 400 | Invalid wallet type for funding account |
| 4006 | 400 | Invalid wallet type for sub account |
| 4008 | 400 | Currency is not allowed in the target wallet type |
| 4007 | 400 | Transfer failed because signature is an exact duplicate of another recently-observed transfer. |
| 4009 | 400 | Please specify the transfer type |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/transfer' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"from_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"transfer_type": "UNSPECIFIED",
"transfer_metadata": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/transfer",
"params": {
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"from_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"transfer_type": "UNSPECIFIED",
"transfer_metadata": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/transfer' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"fs": "'$GRVT_SUB_ACCOUNT_ID'",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"ts": "'$GRVT_SUB_ACCOUNT_ID'",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"tt": "UNSPECIFIED",
"tm": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/transfer",
"p": {
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"fs": "'$GRVT_SUB_ACCOUNT_ID'",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"ts": "'$GRVT_SUB_ACCOUNT_ID'",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"tt": "UNSPECIFIED",
"tm": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/transfer' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"from_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"transfer_type": "UNSPECIFIED",
"transfer_metadata": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/transfer",
"params": {
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"from_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"transfer_type": "UNSPECIFIED",
"transfer_metadata": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/transfer' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"fs": "'$GRVT_SUB_ACCOUNT_ID'",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"ts": "'$GRVT_SUB_ACCOUNT_ID'",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"tt": "UNSPECIFIED",
"tm": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/transfer",
"p": {
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"fs": "'$GRVT_SUB_ACCOUNT_ID'",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"ts": "'$GRVT_SUB_ACCOUNT_ID'",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"tt": "UNSPECIFIED",
"tm": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/transfer' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"from_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"transfer_type": "UNSPECIFIED",
"transfer_metadata": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/transfer",
"params": {
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"from_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"transfer_type": "UNSPECIFIED",
"transfer_metadata": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/transfer' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"fs": "'$GRVT_SUB_ACCOUNT_ID'",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"ts": "'$GRVT_SUB_ACCOUNT_ID'",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"tt": "UNSPECIFIED",
"tm": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/transfer",
"p": {
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"fs": "'$GRVT_SUB_ACCOUNT_ID'",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"ts": "'$GRVT_SUB_ACCOUNT_ID'",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"tt": "UNSPECIFIED",
"tm": "{\"provider\":\"XY\",\"direction\":\"WITHDRAWAL\",\"provider_tx_id\":\"txn123456\",\"chainid\":\"42161\",\"endpoint\":\"0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0\"}"
},
"i": 123
}
' -w 360
Transfer History
FULL ENDPOINT: full/v1/transfer_history
LITE ENDPOINT: lite/v1/transfer_history
The request to get the historical transfers of an account
The history is returned in reverse chronological order
Pagination works as follows:
- We perform a reverse chronological lookup, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
currencyc |
[string] | True | The token currency to query for, if nil or empty, return all transfers. Otherwise, only entries matching the filter will be returned |
start_timest |
string | False0 |
The start time to query for in unix nanoseconds |
end_timeet |
string | Falsenow() |
The end time to query for in unix nanoseconds |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000 |
cursorc1 |
string | False'' |
The cursor to indicate when to start the next query from |
tx_idti |
string | False0 |
The transaction ID to query for |
main_account_idma |
string | False `` |
Main account ID being queried. By default, applies the requestor's main account ID. |
transfer_typestt |
[TransferType] | False[] |
The transfer type to filters for. If the list is empty, return all transfer types. |
TransferType
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Deprecated: use standard instead. Legacy value for transfers created before transfer types were introduced. |
STANDARD = 1 |
Standard transfer that has nothing to do with bridging |
FAST_ARB_DEPOSIT = 2 |
Fast Arb Deposit Metadata type |
FAST_ARB_WITHDRAWAL = 3 |
Fast Arb Withdrawal Metadata type |
NON_NATIVE_BRIDGE_DEPOSIT = 4 |
Transfer type for non native bridging deposit |
NON_NATIVE_BRIDGE_WITHDRAWAL = 5 |
Transfer type for non native bridging withdrawal |
ADHOC_INCENTIVE = 6 |
Transfer type for adhoc incentive |
REFERRAL_INCENTIVE = 7 |
Transfer type for referral incentive |
TRADING_DEPOSIT_YIELD_INCENTIVE = 8 |
Transfer type for trading deposit yield incentive |
Query
Full Request
{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"tx_id": "1028403",
"main_account_id": null,
"transfer_types": ["UNSPECIFIED"]
}
{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ti": "1028403",
"ma": null,
"tt": ["UNSPECIFIED"]
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[TransferHistory] | True | The transfer history matching the request account |
nextn |
string | False'' |
The cursor to indicate when to start the next query from |
TransferHistory
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
tx_idti |
string | True | The transaction ID of the transfer |
from_account_idfa |
string | True | The account to transfer from |
from_sub_account_idfs |
string | True | The subaccount to transfer from (0 if transferring from main account) |
to_account_idta |
string | True | The account to deposit into |
to_sub_account_idts |
string | True | The subaccount to transfer to (0 if transferring to main account) |
currencyc |
string | True | The token currency to transfer |
num_tokensnt |
string | True | The number of tokens to transfer |
signatures |
Signature | True | The signature of the transfer |
event_timeet |
string | True | The timestamp of the transfer in unix nanoseconds |
transfer_typett |
TransferType | True | The type of transfer |
transfer_metadatatm |
string | True | The metadata of the transfer |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
TransferType
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
Deprecated: use standard instead. Legacy value for transfers created before transfer types were introduced. |
STANDARD = 1 |
Standard transfer that has nothing to do with bridging |
FAST_ARB_DEPOSIT = 2 |
Fast Arb Deposit Metadata type |
FAST_ARB_WITHDRAWAL = 3 |
Fast Arb Withdrawal Metadata type |
NON_NATIVE_BRIDGE_DEPOSIT = 4 |
Transfer type for non native bridging deposit |
NON_NATIVE_BRIDGE_WITHDRAWAL = 5 |
Transfer type for non native bridging withdrawal |
ADHOC_INCENTIVE = 6 |
Transfer type for adhoc incentive |
REFERRAL_INCENTIVE = 7 |
Transfer type for referral incentive |
TRADING_DEPOSIT_YIELD_INCENTIVE = 8 |
Transfer type for trading deposit yield incentive |
WalletType
| Value | Description |
|---|---|
FUNDING = 1 |
Funding wallet |
SPOT = 2 |
Spot wallet |
FUTURES = 3 |
Futures wallet |
WalletType
| Value | Description |
|---|---|
FUNDING = 1 |
Funding wallet |
SPOT = 2 |
Spot wallet |
FUTURES = 3 |
Futures wallet |
Success
Full Response
{
"result": [{
"tx_id": "1028403",
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"from_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"to_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"event_time": "1697788800000000000",
"transfer_type": "STANDARD",
"transfer_metadata": null
}],
"next": "Qw0918="
}
{
"r": [{
"ti": "1028403",
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"fs": "'$GRVT_SUB_ACCOUNT_ID'",
"ta": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"ts": "'$GRVT_SUB_ACCOUNT_ID'",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"et": "1697788800000000000",
"tt": "STANDARD",
"tm": null
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/transfer_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"tx_id": "1028403",
"main_account_id": null,
"transfer_types": ["UNSPECIFIED"]
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/transfer_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"tx_id": "1028403",
"main_account_id": null,
"transfer_types": ["UNSPECIFIED"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/transfer_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ti": "1028403",
"ma": null,
"tt": ["UNSPECIFIED"]
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/transfer_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ti": "1028403",
"ma": null,
"tt": ["UNSPECIFIED"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/transfer_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"tx_id": "1028403",
"main_account_id": null,
"transfer_types": ["UNSPECIFIED"]
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/transfer_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"tx_id": "1028403",
"main_account_id": null,
"transfer_types": ["UNSPECIFIED"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/transfer_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ti": "1028403",
"ma": null,
"tt": ["UNSPECIFIED"]
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/transfer_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ti": "1028403",
"ma": null,
"tt": ["UNSPECIFIED"]
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/transfer_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"tx_id": "1028403",
"main_account_id": null,
"transfer_types": ["UNSPECIFIED"]
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/transfer_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"tx_id": "1028403",
"main_account_id": null,
"transfer_types": ["UNSPECIFIED"]
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/transfer_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ti": "1028403",
"ma": null,
"tt": ["UNSPECIFIED"]
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/transfer_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ti": "1028403",
"ma": null,
"tt": ["UNSPECIFIED"]
},
"i": 123
}
' -w 360
Withdrawal
FULL ENDPOINT: full/v1/withdrawal
LITE ENDPOINT: lite/v1/withdrawal
Leverage this API to initialize a withdrawal from GRVT's Hyperchain onto Ethereum.
Do take note that the bridging process does take time. The GRVT UI will help you keep track of bridging progress, and notify you once its complete.
If not withdrawing the entirety of your balance, there is a minimum withdrawal amount. Currently that amount is ~25 USDT.
Withdrawal fees also apply to cover the cost of the Ethereum transaction.
Note that your funds will always remain in self-custory throughout the withdrawal process. At no stage does GRVT gain control over your funds.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
from_account_idfa |
string | True | The main account to withdraw from |
to_eth_addresste |
string | True | The Ethereum wallet to withdraw into |
currencyc |
string | True | The token currency to withdraw |
num_tokensnt |
string | True | The number of tokens to withdraw, quoted in tokenCurrency decimal units |
signatures |
Signature | True | The signature of the withdrawal |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
Query
Full Request
{
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_eth_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
{
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
Used to acknowledge a request has been received and will be processed
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Ack | True | The Ack Object |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"result": {
"ack": "true"
}
}
{
"r": {
"a": "true"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 4010 | 400 | This wallet is not supported. Please try another wallet. |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/withdrawal' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_eth_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/withdrawal",
"params": {
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_eth_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/withdrawal' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/withdrawal",
"p": {
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/withdrawal' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_eth_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/withdrawal",
"params": {
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_eth_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/withdrawal' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/withdrawal",
"p": {
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/withdrawal' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_eth_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/withdrawal",
"params": {
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_eth_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/withdrawal' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/withdrawal",
"p": {
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
Withdrawal History
FULL ENDPOINT: full/v1/withdrawal_history
LITE ENDPOINT: lite/v1/withdrawal_history
The request to get the historical withdrawals of an account
The history is returned in reverse chronological order
Both finalized and pending withdrawals are returned, and pending withdrawals are indicated by an empty l1Hash field.
Pagination works as follows:
- We perform a reverse chronological lookup, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
currencyc |
[string] | True | The token currency to query for, if nil or empty, return all withdrawals. Otherwise, only entries matching the filter will be returned |
start_timest |
string | False0 |
The start time to query for in unix nanoseconds |
end_timeet |
string | Falsenow() |
The end time to query for in unix nanoseconds |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000 |
cursorc1 |
string | False'' |
The cursor to indicate when to start the next query from |
main_account_idma |
string | False `` |
Main account ID being queried. By default, applies the requestor's main account ID. |
Query
Full Request
{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
}
{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[WithdrawalHistory] | True | The withdrawals history matching the request account |
nextn |
string | False'' |
The cursor to indicate when to start the next query from |
WithdrawalHistory
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
tx_idti |
string | True | The transaction ID of the withdrawal |
from_account_idfa |
string | True | The subaccount to withdraw from |
to_eth_addresste |
string | True | The ethereum address to withdraw to |
currencyc |
string | True | The token currency to withdraw |
num_tokensnt |
string | True | The number of tokens to withdraw |
signatures |
Signature | True | The signature of the withdrawal |
event_timeet |
string | True | The timestamp of the withdrawal in unix nanoseconds |
l_1_hashl1 |
string | False'' |
The finalized withdrawal transaction hash on L1, empty if the withdrawal is 'pending'. |
l_2_hashl2 |
string | True | The transaction hash on L2 |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
Success
Full Response
{
"result": [{
"tx_id": "1028403",
"from_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"to_eth_address": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"currency": "USDT",
"num_tokens": "1500.0",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
},
"event_time": "1697788800000000000",
"l_1_hash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"l_2_hash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}],
"next": "Qw0918="
}
{
"r": [{
"ti": "1028403",
"fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"c": "USDT",
"nt": "1500.0",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
},
"et": "1697788800000000000",
"l1": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"l2": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/withdrawal_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/withdrawal_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/withdrawal_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/withdrawal_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/withdrawal_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/withdrawal_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/withdrawal_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/withdrawal_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/withdrawal_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/withdrawal_history",
"params": {
"currency": ["USDT", "USDC"],
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": "",
"main_account_id": null
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/withdrawal_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/withdrawal_history",
"p": {
"c": ["USDT", "USDC"],
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c1": "",
"ma": null
},
"i": 123
}
' -w 360
Account
Sub Account Summary
FULL ENDPOINT: full/v1/account_summary
LITE ENDPOINT: lite/v1/account_summary
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The subaccount ID to filter by |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
}
Query for sub-account details, including base currency balance, all derivative positions, margin levels, and P&L.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
SubAccount | True | The sub account matching the request sub account |
SubAccount
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
sub_account_idsa |
string | True | The sub account ID this entry refers to |
margin_typemt |
MarginType | True | The type of margin algorithm this subaccount uses |
settle_currencysc |
string | True | The settlement, margin, and reporting currency of this account. This subaccount can only open positions quoted in this currency In the future, when users select a Multi-Currency Margin Type, this will be USD All other assets are converted to this currency for the purpose of calculating margin |
unrealized_pnlup |
string | True | The total unrealized PnL of all positions owned by this subaccount, denominated in quote currency decimal units.unrealized_pnl = sum(position.unrealized_pnl * position.quote_index_price) / settle_index_price |
total_equityte |
string | True | The notional value of your account if all positions are closed, excluding trading fees (reported in settle_currency).total_equity = sum(spot_balance.balance * spot_balance.index_price) / settle_index_price + unrealized_pnl |
initial_marginim |
string | True | The total_equity required to open positions in the account (reported in settle_currency).Computation is different depending on account's margin_type |
maintenance_marginmm |
string | True | The total_equity required to avoid liquidation of positions in the account (reported in settle_currency).Computation is different depending on account's margin_type |
available_balanceab |
string | True | The notional value available to transfer out of the trading account into the funding account (reported in settle_currency).available_balance = total_equity - initial_margin - min(unrealized_pnl, 0) |
spot_balancessb |
[SpotBalance] | True | The list of spot assets owned by this sub account, and their balances |
positionsp |
[Positions] | True | The list of positions owned by this sub account |
settle_index_pricesi |
string | True | The index price of the settle currency. (reported in USD) |
is_vaultiv |
boolean | FalseNone |
Whether this sub account is a vault |
vault_im_additionsvi |
string | FalseNone |
Total amount of IM (reported in settle_currency) deducted from the vault due to redemptions nearing the end of their redemption period |
derisk_margindm |
string | True | The derisk margin of this sub account |
derisk_to_maintenance_margin_ratiodt |
string | True | The derisk margin to maintenance margin ratio of this sub account |
total_cross_equitytc |
string | True | The total equity of this sub account for cross margin |
cross_unrealized_pnlcu |
string | True | The unrealized PnL of this sub account for cross margin |
sub_account_modesa1 |
SubAccountMode | True | The mode of the sub account |
margin_balancemb |
string | True | The margin balance of this sub account for cross margin |
MarginType
| Value | Description |
|---|---|
SIMPLE_CROSS_MARGIN = 2 |
Simple Cross Margin Mode: all assets have a predictable margin impact, the whole subaccount shares a single margin |
PORTFOLIO_CROSS_MARGIN = 3 |
Portfolio Cross Margin Mode: asset margin impact is analysed on portfolio level, the whole subaccount shares a single margin |
SpotBalance
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
currencyc |
string | True | The currency you hold a spot balance in |
balanceb |
string | True | This currency's balance in this trading account. |
index_priceip |
string | True | The index price of this currency. (reported in USD) |
entry_priceep |
string | True | The entry price of this spot currency. (reported in USD) |
realized_pnlrp |
string | True | The realized PnL of this spot currency. (reported in USD) |
unrealized_pnlup |
string | True | The unrealized PnL of this spot currency. (reported in USD) |
available_to_transferat |
string | True | The available to transfer amount of this spot currency. |
Positions
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
sub_account_idsa |
string | True | The sub account ID that participated in the trade |
instrumenti |
string | True | The instrument being represented |
sizes |
string | True | The size of the position, expressed in base asset decimal units. Negative for short positions |
notionaln |
string | True | The notional value of the position, negative for short assets, expressed in quote asset decimal units |
entry_priceep |
string | True | The entry price of the position, expressed in 9 decimalsWhenever increasing the size of a position, the entry price is updated to the new average entry price new_entry_price = (old_entry_price * old_size + trade_price * trade_size) / (old_size + trade_size) |
exit_priceep1 |
string | True | The exit price of the position, expressed in 9 decimalsWhenever decreasing the size of a position, the exit price is updated to the new average exit price new_exit_price = (old_exit_price * old_exit_trade_size + trade_price * trade_size) / (old_exit_trade_size + trade_size) |
mark_pricemp |
string | True | The mark price of the position, expressed in 9 decimals |
unrealized_pnlup |
string | True | The unrealized PnL of the position, expressed in quote asset decimal unitsunrealized_pnl = (mark_price - entry_price) * size |
realized_pnlrp |
string | True | The realized PnL of the position, expressed in quote asset decimal unitsrealized_pnl = (exit_price - entry_price) * exit_trade_size |
total_pnltp |
string | True | The total PnL of the position, expressed in quote asset decimal unitstotal_pnl = realized_pnl + unrealized_pnl |
roir |
string | True | The ROI of the position, expressed as a percentageroi = (total_pnl / (entry_price * abs(size))) * 100^ |
quote_index_priceqi |
string | True | The index price of the quote currency. (reported in USD) |
est_liquidation_priceel |
string | True | The estimated liquidation price |
leveragel |
string | True | The current leverage value for this position |
cumulative_feecf |
string | True | The cumulative fee paid on the position, expressed in quote asset decimal units |
cumulative_realized_funding_paymentcr |
string | True | The cumulative realized funding payment of the position, expressed in quote asset decimal units. Positive if paid, negative if received |
margin_typemt |
PositionMarginType | True | The margin type of the position |
isolated_balanceib |
string | FalseNone |
[IsolatedOnly] The wallet balance reserved for this isolated margin position, expressed in quote asset decimal units. If this positions is liquidated, this is the maximal balance that can be lost |
isolated_imii |
string | FalseNone |
[IsolatedOnly] The initial margin of the isolated margin position, expressed in quote asset decimal units. The total_equity required to open more size in the position |
isolated_mmim |
string | FalseNone |
[IsolatedOnly] The maintenance margin of the isolated margin position, expressed in quote asset decimal units. The total_equity required to avoid liquidation of the position |
PositionMarginType
| Value | Description |
|---|---|
ISOLATED = 1 |
Isolated Margin Mode: each position is allocated a fixed amount of collateral |
CROSS = 2 |
Cross Margin Mode: uses all available funds in your account as collateral across all cross margin positions |
SubAccountMode
| Value | Description |
|---|---|
SINGLE_ASSET_MODE = 1 |
Single asset mode: the subaccount is only allowed to hold one asset as collateral |
Success
Full Response
{
"result": {
"event_time": "1697788800000000000",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"margin_type": "SIMPLE_CROSS_MARGIN",
"settle_currency": "USDT",
"unrealized_pnl": "123456.78",
"total_equity": "123456.78",
"initial_margin": "123456.78",
"maintenance_margin": "123456.78",
"available_balance": "123456.78",
"spot_balances": [{
"currency": "USDT",
"balance": "123456.78",
"index_price": "1.0000102",
"entry_price": "1.0",
"realized_pnl": "0.0",
"unrealized_pnl": "0.0",
"available_to_transfer": "0.0"
}],
"positions": [{
"event_time": "1697788800000000000",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"size": "2635000.50",
"notional": "2635000.50",
"entry_price": "65038.01",
"exit_price": "65038.01",
"mark_price": "65038.01",
"unrealized_pnl": "135000.50",
"realized_pnl": "-35000.30",
"total_pnl": "100000.20",
"roi": "10.20",
"quote_index_price": "1.0000102",
"est_liquidation_price": 60000.25,
"leverage": "10",
"cumulative_fee": "100000.20",
"cumulative_realized_funding_payment": "100000.20",
"margin_type": "cross",
"isolated_balance": "100000.20",
"isolated_im": "100000.20",
"isolated_mm": "100000.20"
}],
"settle_index_price": "1.0000102",
"is_vault": false,
"vault_im_additions": "123456.78",
"derisk_margin": "185185.77",
"derisk_to_maintenance_margin_ratio": "1.5",
"total_cross_equity": "123456.78",
"cross_unrealized_pnl": "123456.78",
"sub_account_mode": "SINGLE_ASSET_MODE",
"margin_balance": "123456.78"
}
}
{
"r": {
"et": "1697788800000000000",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"mt": "SIMPLE_CROSS_MARGIN",
"sc": "USDT",
"up": "123456.78",
"te": "123456.78",
"im": "123456.78",
"mm": "123456.78",
"ab": "123456.78",
"sb": [{
"c": "USDT",
"b": "123456.78",
"ip": "1.0000102",
"ep": "1.0",
"rp": "0.0",
"up": "0.0",
"at": "0.0"
}],
"p": [{
"et": "1697788800000000000",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"s": "2635000.50",
"n": "2635000.50",
"ep": "65038.01",
"ep1": "65038.01",
"mp": "65038.01",
"up": "135000.50",
"rp": "-35000.30",
"tp": "100000.20",
"r": "10.20",
"qi": "1.0000102",
"el": 60000.25,
"l": "10",
"cf": "100000.20",
"cr": "100000.20",
"mt": "cross",
"ib": "100000.20",
"ii": "100000.20",
"im": "100000.20"
}],
"si": "1.0000102",
"iv": false,
"vi": "123456.78",
"dm": "185185.77",
"dt": "1.5",
"tc": "123456.78",
"cu": "123456.78",
"sa1": "SINGLE_ASSET_MODE",
"mb": "123456.78"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/account_summary",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/account_summary",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/account_summary",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/account_summary",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/account_summary",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/account_summary",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
},
"i": 123
}
' -w 360
Sub Account History
FULL ENDPOINT: full/v1/account_history
LITE ENDPOINT: lite/v1/account_history
The request to get the history of a sub account
SubAccount Summary values are snapshotted once every hour
No snapshots are taken if the sub account has no activity in the hourly window
History is preserved only for the last 30 days
Pagination works as follows:
- We perform a reverse chronological lookup, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to request for |
start_timest |
string | False0 |
Start time of sub account history in unix nanoseconds |
end_timeet |
string | Falsenow() |
End time of sub account history in unix nanoseconds |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000 |
cursorc |
string | False'' |
The cursor to indicate when to start the next query from |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[SubAccount] | True | The sub account history matching the request sub account |
nextn |
string | True | The cursor to indicate when to start the next query from |
SubAccount
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
sub_account_idsa |
string | True | The sub account ID this entry refers to |
margin_typemt |
MarginType | True | The type of margin algorithm this subaccount uses |
settle_currencysc |
string | True | The settlement, margin, and reporting currency of this account. This subaccount can only open positions quoted in this currency In the future, when users select a Multi-Currency Margin Type, this will be USD All other assets are converted to this currency for the purpose of calculating margin |
unrealized_pnlup |
string | True | The total unrealized PnL of all positions owned by this subaccount, denominated in quote currency decimal units.unrealized_pnl = sum(position.unrealized_pnl * position.quote_index_price) / settle_index_price |
total_equityte |
string | True | The notional value of your account if all positions are closed, excluding trading fees (reported in settle_currency).total_equity = sum(spot_balance.balance * spot_balance.index_price) / settle_index_price + unrealized_pnl |
initial_marginim |
string | True | The total_equity required to open positions in the account (reported in settle_currency).Computation is different depending on account's margin_type |
maintenance_marginmm |
string | True | The total_equity required to avoid liquidation of positions in the account (reported in settle_currency).Computation is different depending on account's margin_type |
available_balanceab |
string | True | The notional value available to transfer out of the trading account into the funding account (reported in settle_currency).available_balance = total_equity - initial_margin - min(unrealized_pnl, 0) |
spot_balancessb |
[SpotBalance] | True | The list of spot assets owned by this sub account, and their balances |
positionsp |
[Positions] | True | The list of positions owned by this sub account |
settle_index_pricesi |
string | True | The index price of the settle currency. (reported in USD) |
is_vaultiv |
boolean | FalseNone |
Whether this sub account is a vault |
vault_im_additionsvi |
string | FalseNone |
Total amount of IM (reported in settle_currency) deducted from the vault due to redemptions nearing the end of their redemption period |
derisk_margindm |
string | True | The derisk margin of this sub account |
derisk_to_maintenance_margin_ratiodt |
string | True | The derisk margin to maintenance margin ratio of this sub account |
total_cross_equitytc |
string | True | The total equity of this sub account for cross margin |
cross_unrealized_pnlcu |
string | True | The unrealized PnL of this sub account for cross margin |
sub_account_modesa1 |
SubAccountMode | True | The mode of the sub account |
margin_balancemb |
string | True | The margin balance of this sub account for cross margin |
MarginType
| Value | Description |
|---|---|
SIMPLE_CROSS_MARGIN = 2 |
Simple Cross Margin Mode: all assets have a predictable margin impact, the whole subaccount shares a single margin |
PORTFOLIO_CROSS_MARGIN = 3 |
Portfolio Cross Margin Mode: asset margin impact is analysed on portfolio level, the whole subaccount shares a single margin |
SpotBalance
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
currencyc |
string | True | The currency you hold a spot balance in |
balanceb |
string | True | This currency's balance in this trading account. |
index_priceip |
string | True | The index price of this currency. (reported in USD) |
entry_priceep |
string | True | The entry price of this spot currency. (reported in USD) |
realized_pnlrp |
string | True | The realized PnL of this spot currency. (reported in USD) |
unrealized_pnlup |
string | True | The unrealized PnL of this spot currency. (reported in USD) |
available_to_transferat |
string | True | The available to transfer amount of this spot currency. |
Positions
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
sub_account_idsa |
string | True | The sub account ID that participated in the trade |
instrumenti |
string | True | The instrument being represented |
sizes |
string | True | The size of the position, expressed in base asset decimal units. Negative for short positions |
notionaln |
string | True | The notional value of the position, negative for short assets, expressed in quote asset decimal units |
entry_priceep |
string | True | The entry price of the position, expressed in 9 decimalsWhenever increasing the size of a position, the entry price is updated to the new average entry price new_entry_price = (old_entry_price * old_size + trade_price * trade_size) / (old_size + trade_size) |
exit_priceep1 |
string | True | The exit price of the position, expressed in 9 decimalsWhenever decreasing the size of a position, the exit price is updated to the new average exit price new_exit_price = (old_exit_price * old_exit_trade_size + trade_price * trade_size) / (old_exit_trade_size + trade_size) |
mark_pricemp |
string | True | The mark price of the position, expressed in 9 decimals |
unrealized_pnlup |
string | True | The unrealized PnL of the position, expressed in quote asset decimal unitsunrealized_pnl = (mark_price - entry_price) * size |
realized_pnlrp |
string | True | The realized PnL of the position, expressed in quote asset decimal unitsrealized_pnl = (exit_price - entry_price) * exit_trade_size |
total_pnltp |
string | True | The total PnL of the position, expressed in quote asset decimal unitstotal_pnl = realized_pnl + unrealized_pnl |
roir |
string | True | The ROI of the position, expressed as a percentageroi = (total_pnl / (entry_price * abs(size))) * 100^ |
quote_index_priceqi |
string | True | The index price of the quote currency. (reported in USD) |
est_liquidation_priceel |
string | True | The estimated liquidation price |
leveragel |
string | True | The current leverage value for this position |
cumulative_feecf |
string | True | The cumulative fee paid on the position, expressed in quote asset decimal units |
cumulative_realized_funding_paymentcr |
string | True | The cumulative realized funding payment of the position, expressed in quote asset decimal units. Positive if paid, negative if received |
margin_typemt |
PositionMarginType | True | The margin type of the position |
isolated_balanceib |
string | FalseNone |
[IsolatedOnly] The wallet balance reserved for this isolated margin position, expressed in quote asset decimal units. If this positions is liquidated, this is the maximal balance that can be lost |
isolated_imii |
string | FalseNone |
[IsolatedOnly] The initial margin of the isolated margin position, expressed in quote asset decimal units. The total_equity required to open more size in the position |
isolated_mmim |
string | FalseNone |
[IsolatedOnly] The maintenance margin of the isolated margin position, expressed in quote asset decimal units. The total_equity required to avoid liquidation of the position |
PositionMarginType
| Value | Description |
|---|---|
ISOLATED = 1 |
Isolated Margin Mode: each position is allocated a fixed amount of collateral |
CROSS = 2 |
Cross Margin Mode: uses all available funds in your account as collateral across all cross margin positions |
SubAccountMode
| Value | Description |
|---|---|
SINGLE_ASSET_MODE = 1 |
Single asset mode: the subaccount is only allowed to hold one asset as collateral |
Success
Full Response
{
"result": [{
"event_time": "1697788800000000000",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"margin_type": "SIMPLE_CROSS_MARGIN",
"settle_currency": "USDT",
"unrealized_pnl": "123456.78",
"total_equity": "123456.78",
"initial_margin": "123456.78",
"maintenance_margin": "123456.78",
"available_balance": "123456.78",
"spot_balances": [{
"currency": "USDT",
"balance": "123456.78",
"index_price": "1.0000102",
"entry_price": "1.0",
"realized_pnl": "0.0",
"unrealized_pnl": "0.0",
"available_to_transfer": "0.0"
}],
"positions": [{
"event_time": "1697788800000000000",
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"size": "2635000.50",
"notional": "2635000.50",
"entry_price": "65038.01",
"exit_price": "65038.01",
"mark_price": "65038.01",
"unrealized_pnl": "135000.50",
"realized_pnl": "-35000.30",
"total_pnl": "100000.20",
"roi": "10.20",
"quote_index_price": "1.0000102",
"est_liquidation_price": 60000.25,
"leverage": "10",
"cumulative_fee": "100000.20",
"cumulative_realized_funding_payment": "100000.20",
"margin_type": "cross",
"isolated_balance": "100000.20",
"isolated_im": "100000.20",
"isolated_mm": "100000.20"
}],
"settle_index_price": "1.0000102",
"is_vault": false,
"vault_im_additions": "123456.78",
"derisk_margin": "185185.77",
"derisk_to_maintenance_margin_ratio": "1.5",
"total_cross_equity": "123456.78",
"cross_unrealized_pnl": "123456.78",
"sub_account_mode": "SINGLE_ASSET_MODE",
"margin_balance": "123456.78"
}],
"next": "Qw0918="
}
{
"r": [{
"et": "1697788800000000000",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"mt": "SIMPLE_CROSS_MARGIN",
"sc": "USDT",
"up": "123456.78",
"te": "123456.78",
"im": "123456.78",
"mm": "123456.78",
"ab": "123456.78",
"sb": [{
"c": "USDT",
"b": "123456.78",
"ip": "1.0000102",
"ep": "1.0",
"rp": "0.0",
"up": "0.0",
"at": "0.0"
}],
"p": [{
"et": "1697788800000000000",
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"s": "2635000.50",
"n": "2635000.50",
"ep": "65038.01",
"ep1": "65038.01",
"mp": "65038.01",
"up": "135000.50",
"rp": "-35000.30",
"tp": "100000.20",
"r": "10.20",
"qi": "1.0000102",
"el": 60000.25,
"l": "10",
"cf": "100000.20",
"cr": "100000.20",
"mt": "cross",
"ib": "100000.20",
"ii": "100000.20",
"im": "100000.20"
}],
"si": "1.0000102",
"iv": false,
"vi": "123456.78",
"dm": "185185.77",
"dt": "1.5",
"tc": "123456.78",
"cu": "123456.78",
"sa1": "SINGLE_ASSET_MODE",
"mb": "123456.78"
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/account_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/account_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/account_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/account_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/account_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/account_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/account_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/account_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/account_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/account_history",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/account_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/account_history",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
Aggregated Account Summary
FULL ENDPOINT: full/v1/aggregated_account_summary
LITE ENDPOINT: lite/v1/aggregated_account_summary
Used for requests that do not require any parameters
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
Query
Full Request
{
}
{
}
ApiAggregatedAccountSummaryResponse
The aggregated account summary, that reports the total equity and spot balances of a funding (main) account, and its constituent trading (sub) accounts
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
AggregatedAccountSummary | True | The aggregated account summary |
AggregatedAccountSummary
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
main_account_idma |
string | True | The main account ID of the account to which the summary belongs |
total_equityte |
string | True | Total equity of the main (+ sub) account, denominated in USD |
spot_balancessb |
[SpotBalance] | True | The list of spot assets owned by this main (+ sub) account, and their balances |
vault_investmentsvi |
[VaultInvestment] | True | The list of vault investments held by this main account |
total_sub_account_balancets |
string | True | Deprecated: Use totalSubAccountEquity instead |
total_sub_account_equityts1 |
string | True | Total equity of the sub accounts, denominated in USD |
total_vault_investments_balancetv |
string | True | Total amount of the vault investments, denominated in USD |
total_sub_account_available_balancets2 |
string | True | Total available balance of the main account, denominated in USD |
total_usd_notional_investedtu |
string | True | Total entry (initial investment) amount of the open investments, denominated in USD |
SpotBalance
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
currencyc |
string | True | The currency you hold a spot balance in |
balanceb |
string | True | This currency's balance in this trading account. |
index_priceip |
string | True | The index price of this currency. (reported in USD) |
entry_priceep |
string | True | The entry price of this spot currency. (reported in USD) |
realized_pnlrp |
string | True | The realized PnL of this spot currency. (reported in USD) |
unrealized_pnlup |
string | True | The unrealized PnL of this spot currency. (reported in USD) |
available_to_transferat |
string | True | The available to transfer amount of this spot currency. |
VaultInvestment
Summarizes a vault investment held by a funding account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The trading account ID of the vault invested in. |
num_lp_tokensnl |
string | True | The number of shares held by the investor. |
share_pricesp |
string | True | The current share price (in USD) of this vault investment. |
usd_notional_investedun |
string | True | The USD notional invested in this vault investment. |
Success
Full Response
{
"result": {
"main_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"total_equity": "3945034.23",
"spot_balances": [{
"currency": "USDT",
"balance": "123456.78",
"index_price": "1.0000102",
"entry_price": "1.0",
"realized_pnl": "0.0",
"unrealized_pnl": "0.0",
"available_to_transfer": "0.0"
}],
"vault_investments": [{
"vault_id": 123456789,
"num_lp_tokens": 1000000,
"share_price": 1000000,
"usd_notional_invested": 1000000
}],
"total_sub_account_balance": "3945034.23",
"total_sub_account_equity": "3945034.23",
"total_vault_investments_balance": "3945034.23",
"total_sub_account_available_balance": "3945034.23",
"total_usd_notional_invested": "3945034.23"
}
}
{
"r": {
"ma": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "3945034.23",
"sb": [{
"c": "USDT",
"b": "123456.78",
"ip": "1.0000102",
"ep": "1.0",
"rp": "0.0",
"up": "0.0",
"at": "0.0"
}],
"vi": [{
"vi": 123456789,
"nl": 1000000,
"sp": 1000000,
"un": 1000000
}],
"ts": "3945034.23",
"ts1": "3945034.23",
"tv": "3945034.23",
"ts2": "3945034.23",
"tu": "3945034.23"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1001,
"message":"You are not authorized to access this functionality",
"status":403
}
{
"ri":1,
"c":1001,
"m":"You are not authorized to access this functionality",
"s":403
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/aggregated_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/aggregated_account_summary",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/aggregated_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/aggregated_account_summary",
"p": {
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/aggregated_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/aggregated_account_summary",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/aggregated_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/aggregated_account_summary",
"p": {
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/aggregated_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/aggregated_account_summary",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/aggregated_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/aggregated_account_summary",
"p": {
},
"i": 123
}
' -w 360
Funding Account Summary
FULL ENDPOINT: full/v1/funding_account_summary
LITE ENDPOINT: lite/v1/funding_account_summary
Used for requests that do not require any parameters
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
Query
Full Request
{
}
{
}
ApiFundingAccountSummaryResponse
The funding account summary, that reports the total equity and spot balances of a funding (main) account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
FundingAccountSummary | True | The funding account summary |
tiert |
ClientTier | True | Client fee tier at the time of query |
FundingAccountSummary
The funding account summary, that reports the total equity and spot balances of a funding (main) account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
main_account_idma |
string | True | The main account ID of the account to which the summary belongs |
total_equityte |
string | True | Total equity of the main account, denominated in USD |
spot_balancessb |
[SpotBalance] | True | The list of spot assets owned by this main account, and their balances |
vault_investmentsvi |
[VaultInvestment] | True | The list of vault investments held by this main account |
total_cash_balancetc |
string | True | Total balance of cash (stablecoin) currencies, denominated in USD |
total_spot_asset_balancets |
string | True | Total balance of non-cash spot currencies, denominated in USD |
SpotBalance
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
currencyc |
string | True | The currency you hold a spot balance in |
balanceb |
string | True | This currency's balance in this trading account. |
index_priceip |
string | True | The index price of this currency. (reported in USD) |
entry_priceep |
string | True | The entry price of this spot currency. (reported in USD) |
realized_pnlrp |
string | True | The realized PnL of this spot currency. (reported in USD) |
unrealized_pnlup |
string | True | The unrealized PnL of this spot currency. (reported in USD) |
available_to_transferat |
string | True | The available to transfer amount of this spot currency. |
VaultInvestment
Summarizes a vault investment held by a funding account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The trading account ID of the vault invested in. |
num_lp_tokensnl |
string | True | The number of shares held by the investor. |
share_pricesp |
string | True | The current share price (in USD) of this vault investment. |
usd_notional_investedun |
string | True | The USD notional invested in this vault investment. |
ClientTier
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
tiert |
integer | True | |
futures_taker_feeft |
integer | True | |
futures_maker_feefm |
integer | True | |
options_taker_feeot |
integer | True | |
options_maker_feeom |
integer | True |
Success
Full Response
{
"result": {
"main_account_id": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"total_equity": "3945034.23",
"spot_balances": [{
"currency": "USDT",
"balance": "123456.78",
"index_price": "1.0000102",
"entry_price": "1.0",
"realized_pnl": "0.0",
"unrealized_pnl": "0.0",
"available_to_transfer": "0.0"
}],
"vault_investments": [{
"vault_id": 123456789,
"num_lp_tokens": 1000000,
"share_price": 1000000,
"usd_notional_invested": 1000000
}],
"total_cash_balance": "1000000.00",
"total_spot_asset_balance": "500000.00"
},
"tier": {
"tier": null,
"futures_taker_fee": null,
"futures_maker_fee": null,
"options_taker_fee": null,
"options_maker_fee": null
}
}
{
"r": {
"ma": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"te": "3945034.23",
"sb": [{
"c": "USDT",
"b": "123456.78",
"ip": "1.0000102",
"ep": "1.0",
"rp": "0.0",
"up": "0.0",
"at": "0.0"
}],
"vi": [{
"vi": 123456789,
"nl": 1000000,
"sp": 1000000,
"un": 1000000
}],
"tc": "1000000.00",
"ts": "500000.00"
},
"t": {
"t": null,
"ft": null,
"fm": null,
"ot": null,
"om": null
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1001,
"message":"You are not authorized to access this functionality",
"status":403
}
{
"ri":1,
"c":1001,
"m":"You are not authorized to access this functionality",
"s":403
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/funding_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/funding_account_summary",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/funding_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/funding_account_summary",
"p": {
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/funding_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/funding_account_summary",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/funding_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/funding_account_summary",
"p": {
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/funding_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/funding_account_summary",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/funding_account_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/funding_account_summary",
"p": {
},
"i": 123
}
' -w 360
DeriskMMRatio
Set Derisk M M Ratio
FULL ENDPOINT: full/v1/set_derisk_mm_ratio
LITE ENDPOINT: lite/v1/set_derisk_mm_ratio
ApiSetDeriskToMaintenanceMarginRatioRequest
The request to set the derisk margin to maintenance margin ratio of a sub account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to set the leverage for |
ratior |
string | True | The derisk margin to maintenance margin ratio of this sub account |
signatures |
Signature | True | The signature of this operation |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"ratio": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"r": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
ApiSetDeriskToMaintenanceMarginRatioResponse
The response to set the derisk margin to maintenance margin ratio of a sub account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
successs |
boolean | True | Whether the derisk margin to maintenance margin ratio was set successfully |
Success
Full Response
{
"success": "true"
}
{
"s": "true"
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1004 | 404 | Data Not Found |
| 6100 | 400 | Derisk MM Ratio is out of range |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/set_derisk_mm_ratio' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"ratio": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_derisk_mm_ratio",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"ratio": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/set_derisk_mm_ratio' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"r": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_derisk_mm_ratio",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"r": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/set_derisk_mm_ratio' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"ratio": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_derisk_mm_ratio",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"ratio": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/set_derisk_mm_ratio' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"r": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_derisk_mm_ratio",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"r": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/set_derisk_mm_ratio' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"ratio": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_derisk_mm_ratio",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"ratio": "1.5",
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/set_derisk_mm_ratio' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"r": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_derisk_mm_ratio",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"r": "1.5",
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
Account
Get Sub Accounts
FULL ENDPOINT: full/v1/get_sub_accounts
LITE ENDPOINT: lite/v1/get_sub_accounts
Used for requests that do not require any parameters
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
Query
Full Request
{
}
{
}
Response payload containing all sub-accounts accessible within the given auth session
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idssa |
[string] | True | List of sub-account IDs accessible to the session |
Success
Full Response
{
"sub_account_ids": ["4724219064482495","2095919380","1170592370"]
}
{
"sa": ["4724219064482495","2095919380","1170592370"]
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1002 | 500 | Internal Server Error |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/get_sub_accounts' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_sub_accounts",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/get_sub_accounts' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_sub_accounts",
"p": {
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/get_sub_accounts' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_sub_accounts",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/get_sub_accounts' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_sub_accounts",
"p": {
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/get_sub_accounts' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_sub_accounts",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/get_sub_accounts' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_sub_accounts",
"p": {
},
"i": 123
}
' -w 360
InitialLeverage
Get All Initial Leverage
FULL ENDPOINT: full/v1/get_all_initial_leverage
LITE ENDPOINT: lite/v1/get_all_initial_leverage
ApiGetAllInitialLeverageRequest
The request to get the initial leverage of a sub account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to get the leverage for |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
}
ApiGetAllInitialLeverageResponse
The response to get the initial leverage of a sub account
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultsr |
[InitialLeverageResult] | True | The initial leverage of the sub account |
InitialLeverageResult
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
instrumenti |
string | True | The instrument to get the leverage for |
leveragel |
string | True | The initial leverage of this instrument |
min_leverageml |
string | True | The min leverage user can set for this instrument |
max_leverageml1 |
string | True | The max leverage user can set for this instrument |
margin_typemt |
PositionMarginType | True | The margin type of this instrument |
PositionMarginType
| Value | Description |
|---|---|
ISOLATED = 1 |
Isolated Margin Mode: each position is allocated a fixed amount of collateral |
CROSS = 2 |
Cross Margin Mode: uses all available funds in your account as collateral across all cross margin positions |
Success
Full Response
{
"results": [{
"instrument": "BTC_USDT_Perp",
"leverage": "10",
"min_leverage": "10",
"max_leverage": "50",
"margin_type": "ISOLATED"
}]
}
{
"r": [{
"i": "BTC_USDT_Perp",
"l": "10",
"ml": "10",
"ml1": "50",
"mt": "ISOLATED"
}]
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1004 | 404 | Data Not Found |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/get_all_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_all_initial_leverage",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/get_all_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_all_initial_leverage",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/get_all_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_all_initial_leverage",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/get_all_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_all_initial_leverage",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/get_all_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_all_initial_leverage",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/get_all_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_all_initial_leverage",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'"
},
"i": 123
}
' -w 360
Set Initial Leverage
FULL ENDPOINT: full/v1/set_initial_leverage
LITE ENDPOINT: lite/v1/set_initial_leverage
The request to set the initial leverage of a sub account.
DEPRECATED: This API is deprecated, use set_position_config API instead
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The sub account ID to set the leverage for |
instrumenti |
string | True | The instrument to set the leverage for |
leveragel |
string | True | The leverage to set for the sub account |
Query
Full Request
{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"leverage": "10"
}
{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"l": "10"
}
The response to set the initial leverage of a sub account.
DEPRECATED: This API is deprecated, use set_position_config API instead
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
successs |
boolean | True | Whether the leverage was set successfully |
Success
Full Response
{
"success": "true"
}
{
"s": "true"
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1004 | 404 | Data Not Found |
| 2100 | 400 | Invalid initial leverage |
| 2101 | 400 | Vaults cannot configure leverage |
| 3007 | 400 | API is not applicable for spot instruments |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/set_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"leverage": "10"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_initial_leverage",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"leverage": "10"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/set_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"l": "10"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_initial_leverage",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"l": "10"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/set_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"leverage": "10"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_initial_leverage",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"leverage": "10"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/set_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"l": "10"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_initial_leverage",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"l": "10"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/set_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"leverage": "10"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/set_initial_leverage",
"params": {
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"instrument": "BTC_USDT_Perp",
"leverage": "10"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/set_initial_leverage' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"l": "10"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/set_initial_leverage",
"p": {
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"i": "BTC_USDT_Perp",
"l": "10"
},
"i": 123
}
' -w 360
Vault
Vault Burn Tokens
FULL ENDPOINT: full/v1/vault_burn_tokens
LITE ENDPOINT: lite/v1/vault_burn_tokens
Request payload for burning tokens in a vault.
This API allows a client to burn a specified amount of tokens in a particular vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The unique identifier of the vault to burn tokens from. |
currencyc |
string | True | The currency used for the burn. This should be the vault's quote currency. |
num_tokensnt |
string | True | The number of tokens to burn. |
signatures |
Signature | True | The digital signature from the investing account. This signature must be generated by the main account ID and is used to verify the authenticity of the request. The signature must comply with AccountPermExternalTransfer permission. |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
Query
Full Request
{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
Used to acknowledge a request has been received and will be processed
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Ack | True | The Ack Object |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"result": {
"ack": "true"
}
}
{
"r": {
"a": "true"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 1009 | 503 | We are temporarily deactivating this API endpoint, please try again later |
| 2000 | 403 | Signature is from an unauthorized signer |
| 2001 | 403 | Signature has expired |
| 2002 | 403 | Signature does not match payload |
| 2004 | 403 | Signature is from an expired session key |
| 2006 | 403 | Signature R/S must have exactly 64 characters long without 0x prefix |
| 2005 | 403 | Signature V must be 27/28 |
| 2007 | 403 | Signature S must be in the lower half of the curve |
| 2008 | 403 | Signature exceeds maximum allowed duration. |
| 7000 | 400 | Vault ID provided is invalid and does not belong to any vault |
| 7005 | 400 | You are attempting to burn more vault tokens than you own. |
| 7006 | 400 | You are attempting to burn vault tokens whilst having an active redemption request. |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/vault_burn_tokens' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_burn_tokens",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/vault_burn_tokens' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_burn_tokens",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/vault_burn_tokens' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_burn_tokens",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/vault_burn_tokens' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_burn_tokens",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/vault_burn_tokens' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_burn_tokens",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/vault_burn_tokens' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_burn_tokens",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
Vault Invest
FULL ENDPOINT: full/v1/vault_invest
LITE ENDPOINT: lite/v1/vault_invest
Request payload for investing in a vault.
This API allows a client to invest a specified amount of tokens in a particular vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The unique identifier of the vault to invest in. |
currencyc |
string | True | The currency used for the investment. This should be the vault's quote currency. |
num_tokensnt |
string | True | The investment sum, in terms of the token currency specified (i.e., numTokens of '1000' with tokenCurrency of 'USDT' denotes investment of 1,000 USDT). |
signatures |
Signature | True | The digital signature from the investing account. This signature must be generated by the main account ID and is used to verify the authenticity of the request. The signature must comply with AccountPermExternalTransfer permission. |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
Query
Full Request
{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
Used to acknowledge a request has been received and will be processed
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Ack | True | The Ack Object |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"result": {
"ack": "true"
}
}
{
"r": {
"a": "true"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 1009 | 503 | We are temporarily deactivating this API endpoint, please try again later |
| 2000 | 403 | Signature is from an unauthorized signer |
| 2001 | 403 | Signature has expired |
| 2002 | 403 | Signature does not match payload |
| 2004 | 403 | Signature is from an expired session key |
| 2006 | 403 | Signature R/S must have exactly 64 characters long without 0x prefix |
| 2005 | 403 | Signature V must be 27/28 |
| 2007 | 403 | Signature S must be in the lower half of the curve |
| 2008 | 403 | Signature exceeds maximum allowed duration. |
| 4000 | 400 | Insufficient balance to complete transfer |
| 7000 | 400 | Vault ID provided is invalid and does not belong to any vault |
| 7003 | 400 | This vault has been delisted/closed. |
| 7004 | 400 | This investment would cause the vault to exceed its valuation cap. |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/vault_invest' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_invest",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/vault_invest' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_invest",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/vault_invest' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_invest",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/vault_invest' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_invest",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/vault_invest' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_invest",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/vault_invest' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_invest",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
Vault Investor Summary
FULL ENDPOINT: full/v1/vault_investor_summary
LITE ENDPOINT: lite/v1/vault_investor_summary
ApiVaultInvestorSummaryRequest
Request payload for fetching the summary of a vault investor.
This API allows a client to retrieve the summary of investments in a specific vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The unique identifier of the vault to fetch the summary for. |
Query
Full Request
{
"vault_id": "3477045127917224"
}
{
"vi": "3477045127917224"
}
ApiVaultInvestorSummaryResponse
Response payload for the summary of a vault investor.
This API provides the summary of investments in a specific vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_investor_summaryvi |
[VaultInvestorSummary] | True | The summary of investments in the vault. |
VaultInvestorSummary
Vault investor summary information.
This struct contains the summary of investments in a vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
sub_account_idsa |
string | True | The unique identifier of the vault sub account. |
num_lp_tokensnl |
string | True | The number of Vault LP tokens held by the investor. |
avg_entry_priceae |
string | True | The average entry price (in USD) of the vault LP tokens. |
current_pricecp |
string | True | The current price (in USD) of the vault LP tokens. |
total_equityte |
string | True | The current valuation (in USD) of all held vault LP tokens. |
all_time_realized_pnlat |
string | True | The all-time realized PnL (in USD) that the investor has received from the vault. |
pending_redemptionpr |
VaultRedemption | FalseNone |
The singleton pending redemption (omitted if none). |
can_burncb |
boolean | Falsetrue |
True if the requesting account is authorized to burn tokens on this vault, omitted otherwise. |
VaultRedemption
Vault redemption information.
This struct contains information about a pending redemption from a vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
num_lp_tokensnl |
string | True | The number of LP Tokens requested for redemption. |
request_valuationrv |
string | True | The valuation (in USD) of the redemption request. |
request_timert |
string | True | [Filled by GRVT Backend] Time at which the redemption request was received by GRVT in unix nanoseconds |
max_redemption_period_timestampmr |
string | True | [Filled by GRVT Backend] Time in unix nanoseconds, beyond which the request will be force-redeemed. |
cancel_blockedcb |
boolean | Falsetrue |
Omitted for redemption requests to non-cross exchange vaults. True if cancellation is blocked within the CEV allocation allowance for the user's current tier (e.g. because the user has already transferred out the spot balance underlying the redemption request). |
Success
Full Response
{
"vault_investor_summary": [{
"sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
"num_lp_tokens": 1000000,
"avg_entry_price": 1000000,
"current_price": 1000000,
"total_equity": 1000000,
"all_time_realized_pnl": 1000000,
"pending_redemption": {
"num_lp_tokens": 1000000,
"request_valuation": 1000000,
"request_time": "1697788800000000000",
"max_redemption_period_timestamp": 1727788800000000000,
"cancel_blocked": false
},
"can_burn": null
}]
}
{
"vi": [{
"sa": "'$GRVT_SUB_ACCOUNT_ID'",
"nl": 1000000,
"ae": 1000000,
"cp": 1000000,
"te": 1000000,
"at": 1000000,
"pr": {
"nl": 1000000,
"rv": 1000000,
"rt": "1697788800000000000",
"mr": 1727788800000000000,
"cb": false
},
"cb": null
}]
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 7000 | 400 | Vault ID provided is invalid and does not belong to any vault |
| 7007 | 400 | The investor is not an LP for this vault. |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/vault_investor_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_investor_summary",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/vault_investor_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_investor_summary",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/vault_investor_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_investor_summary",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/vault_investor_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_investor_summary",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/vault_investor_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_investor_summary",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/vault_investor_summary' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_investor_summary",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
Vault Redeem
FULL ENDPOINT: full/v1/vault_redeem
LITE ENDPOINT: lite/v1/vault_redeem
Request payload for redeeming from a vault.
This API allows a client to redeem a specified amount of tokens from a particular vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The unique identifier of the vault to redeem from. |
currencyc |
string | True | The currency used for the redemption. This should be the vault's quote currency. |
num_tokensnt |
string | True | The number of shares to redeem. |
signatures |
Signature | True | The digital signature from the investing account. This signature must be generated by the main account ID and is used to verify the authenticity of the request. The signature must comply with AccountPermExternalTransfer permission. |
Signature
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
signers |
string | True | The address (public key) of the wallet signing the payload |
rr |
string | True | Signature R |
ss1 |
string | True | Signature S |
vv |
integer | True | Signature V |
expiratione |
string | True | Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days |
noncen |
integer | True | 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. Range: 0 to 4,294,967,295 (uint32) |
chain_idci |
string | True | Chain ID used in EIP-712 domain. Zero value fallbacks to GRVT Chain ID. |
Query
Full Request
{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
Used to acknowledge a request has been received and will be processed
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Ack | True | The Ack Object |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"result": {
"ack": "true"
}
}
{
"r": {
"a": "true"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 7000 | 400 | Vault ID provided is invalid and does not belong to any vault |
| 7001 | 400 | Vault does not have sufficient LP token balance |
| 7002 | 400 | User has an ongoing redemption |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/vault_redeem' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_redeem",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/vault_redeem' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_redeem",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/vault_redeem' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_redeem",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/vault_redeem' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_redeem",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/vault_redeem' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_redeem",
"params": {
"vault_id": "3477045127917224",
"currency": "USDT",
"num_tokens": 1000000,
"signature": {
"signer": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"expiration": "1697788800000000000",
"nonce": 1234567890,
"chain_id": "325"
}
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/vault_redeem' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_redeem",
"p": {
"vi": "3477045127917224",
"c": "USDT",
"nt": 1000000,
"s": {
"s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
"r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
"s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
"v": 28,
"e": "1697788800000000000",
"n": 1234567890,
"ci": "325"
}
},
"i": 123
}
' -w 360
Vault Redeem Cancel
FULL ENDPOINT: full/v1/vault_redeem_cancel
LITE ENDPOINT: lite/v1/vault_redeem_cancel
Request payload for canceling a vault redemption.
This API allows a client to cancel a previously initiated redemption from a vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The unique identifier of the vault to cancel the redemption from. |
Query
Full Request
{
"vault_id": "3477045127917224"
}
{
"vi": "3477045127917224"
}
Used to acknowledge a request has been received and will be processed
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
Ack | True | The Ack Object |
Ack
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
acka |
boolean | True | Gravity has acknowledged that the request has been successfully received and it will process it in the backend |
Success
Full Response
{
"result": {
"ack": "true"
}
}
{
"r": {
"a": "true"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 7000 | 400 | Vault ID provided is invalid and does not belong to any vault |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/vault_redeem_cancel' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_redeem_cancel",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/vault_redeem_cancel' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_redeem_cancel",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/vault_redeem_cancel' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_redeem_cancel",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/vault_redeem_cancel' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_redeem_cancel",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/vault_redeem_cancel' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_redeem_cancel",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/vault_redeem_cancel' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_redeem_cancel",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
Vault Redemption Queue
FULL ENDPOINT: full/v1/vault_view_redemption_queue
LITE ENDPOINT: lite/v1/vault_view_redemption_queue
ApiVaultViewRedemptionQueueRequest
Request payload for a vault manager to view the redemption queue for their vault.
Fetches the redemption queue for a vault, ordered by descending priority.
Urgent redemption requests, defined as having been pending >90% of the manager-defined maximum redemption period, have top priority (following insertion order).
Non-urgent redemption requests are otherwise prioritized by insertion order, unless they are >5x the size of the smallest redemption request.
E.g., If FIFO ordering (all non-urgent) is 1k -> 50k -> 100k -> 20k -> 10k -> 25k, then priority ordering is 1k -> 10k -> 50k -> 20k -> 100k -> 25k.
Only displays redemption requests that are eligible for automated redemption, i.e., have been pending for the manager-defined minimum redemption period.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The unique identifier of the vault to fetch the redemption queue for. |
Query
Full Request
{
"vault_id": "3477045127917224"
}
{
"vi": "3477045127917224"
}
ApiVaultViewRedemptionQueueResponse
Response payload for a vault manager to view the redemption queue for their vault, ordered by descending priority.
Also includes counters for total redemption sizes pending as well as urgent (refer to API integration guide for more detail on redemption request classifications).
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
redemption_queuerq |
[VaultRedemptionRequest] | True | Outstanding vault redemption requests, ordered by descending priority. Excludes requests that have not yet aged past the minimum redemption period. |
pending_redemption_token_countpr |
string | True | Number of shares eligible for automated redemption (held in queue for at least the minimum redemption period). |
urgent_redemption_token_countur |
string | True | Number of shares nearing the maximum redemption period (>= 90% of maximum redemption period). |
auto_redeemable_balancear |
string | True | Amount available for automated redemption request servicing (in USD). |
share_pricesp |
string | True | Current share price (in USD). |
pre_minpm |
PreMinRedemptions | True | Dedicated section for requests yet to wait at least the minimum redemption period. |
VaultRedemptionRequest
Representation of a pending redemption request for a given vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
request_timert |
string | True | [Filled by GRVT Backend] Time at which the redemption request was received by GRVT in unix nanoseconds |
num_lp_tokensnl |
string | True | The number of shares to redeem |
max_redemption_period_timestampmr |
string | True | [Filled by GRVT Backend] Time in unix nanoseconds, beyond which the request will be force-redeemed. |
age_categoryac |
VaultRedemptionReqAgeCategory | True | Age category of this redemption request. |
is_managerim |
boolean | FalseNone |
true if this request belongs to the vault manager, omitted otherwise. |
eligible_for_auto_redemption_timestampef |
string | True | [Filled by GRVT Backend] Time in unix nanoseconds, beyond which the request will be eligible for automated redemption. |
VaultRedemptionReqAgeCategory
Denotes the age category of a given redemption request.
| Value | Description |
|---|---|
NORMAL = 1 |
This request is at least as old as the minimum redemption period, and is eligible for automated redemption. |
URGENT = 2 |
This request is nearing the maxmimum redemption period and will be factored into pre-order check margin requirements. |
OVERDUE = 3 |
This request has exceeded the maximum redemption period and will be considered for forced redemptions. |
PRE_MIN = 4 |
This request has yet to exceed the minimum redemption period, and is not yet eligible for automated redemption. |
PreMinRedemptions
Vault redemption queue section hidden from main view. All requests here have yet to age past the vault's minimum redemption period.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
requestsr |
[VaultRedemptionRequest] | True | Pre-minimum-age redemption requests, ordered by age (first element is the oldest request that is pre-minimum-age). |
token_counttc |
string | True | Number of shares in the pre-minimum-age section of the vault's redemption queue. |
VaultRedemptionRequest
Representation of a pending redemption request for a given vault.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
request_timert |
string | True | [Filled by GRVT Backend] Time at which the redemption request was received by GRVT in unix nanoseconds |
num_lp_tokensnl |
string | True | The number of shares to redeem |
max_redemption_period_timestampmr |
string | True | [Filled by GRVT Backend] Time in unix nanoseconds, beyond which the request will be force-redeemed. |
age_categoryac |
VaultRedemptionReqAgeCategory | True | Age category of this redemption request. |
is_managerim |
boolean | FalseNone |
true if this request belongs to the vault manager, omitted otherwise. |
eligible_for_auto_redemption_timestampef |
string | True | [Filled by GRVT Backend] Time in unix nanoseconds, beyond which the request will be eligible for automated redemption. |
VaultRedemptionReqAgeCategory
Denotes the age category of a given redemption request.
| Value | Description |
|---|---|
NORMAL = 1 |
This request is at least as old as the minimum redemption period, and is eligible for automated redemption. |
URGENT = 2 |
This request is nearing the maxmimum redemption period and will be factored into pre-order check margin requirements. |
OVERDUE = 3 |
This request has exceeded the maximum redemption period and will be considered for forced redemptions. |
PRE_MIN = 4 |
This request has yet to exceed the minimum redemption period, and is not yet eligible for automated redemption. |
Success
Full Response
{
"redemption_queue": [{
"request_time": "1697788800000000000",
"num_lp_tokens": "1000000",
"max_redemption_period_timestamp": "1727788800000000000",
"age_category": "NORMAL",
"is_manager": true,
"eligible_for_auto_redemption_timestamp": "1727788800000000000"
}],
"pending_redemption_token_count": "1000000",
"urgent_redemption_token_count": "0",
"auto_redeemable_balance": "0",
"share_price": "1.25",
"pre_min": {
"requests": [{
"request_time": "1697788800000000000",
"num_lp_tokens": "1000000",
"max_redemption_period_timestamp": "1727788800000000000",
"age_category": "NORMAL",
"is_manager": true,
"eligible_for_auto_redemption_timestamp": "1727788800000000000"
}],
"token_count": "1000000"
}
}
{
"rq": [{
"rt": "1697788800000000000",
"nl": "1000000",
"mr": "1727788800000000000",
"ac": "NORMAL",
"im": true,
"ef": "1727788800000000000"
}],
"pr": "1000000",
"ur": "0",
"ar": "0",
"sp": "1.25",
"pm": {
"r": [{
"rt": "1697788800000000000",
"nl": "1000000",
"mr": "1727788800000000000",
"ac": "NORMAL",
"im": true,
"ef": "1727788800000000000"
}],
"tc": "1000000"
}
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
| 7000 | 400 | Vault ID provided is invalid and does not belong to any vault |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/vault_view_redemption_queue' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_view_redemption_queue",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/vault_view_redemption_queue' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_view_redemption_queue",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/vault_view_redemption_queue' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_view_redemption_queue",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/vault_view_redemption_queue' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_view_redemption_queue",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/vault_view_redemption_queue' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "3477045127917224"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_view_redemption_queue",
"params": {
"vault_id": "3477045127917224"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/vault_view_redemption_queue' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "3477045127917224"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_view_redemption_queue",
"p": {
"vi": "3477045127917224"
},
"i": 123
}
' -w 360
Vault Manager Investment History
FULL ENDPOINT: full/v1/vault_manager_investor_history
LITE ENDPOINT: lite/v1/vault_manager_investor_history
ApiQueryVaultManagerInvestorHistoryRequest
Request for the manager to retrieve the vault investor history for their vault
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
vault_idvi |
string | True | The unique identifier of the vault to filter by |
only_own_investmentsoo |
boolean | True | Whether to only return investments made by the manager |
start_timest |
string | False0 |
Optional. Start time in unix nanoseconds |
end_timeet |
string | Falsenow() |
Optional. End time in unix nanoseconds |
Query
Full Request
{
"vault_id": "2312134",
"only_own_investments": true,
"start_time": "1697788800000000000",
"end_time": "1697788800000000000"
}
{
"vi": "2312134",
"oo": true,
"st": "1697788800000000000",
"et": "1697788800000000000"
}
ApiQueryVaultManagerInvestorHistoryResponse
Response to retrieve the vault summary for a given vault
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[ApiVaultInvestorHistory] | True | The list of vault investor history belong to the manager |
ApiVaultInvestorHistory
The vault investor history returned by the service to client
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
off_chain_account_idoc |
string | True | The off chain account id of the investor, only visible to the manager |
vault_idvi |
string | True | The unique identifier of the vault. |
typet |
VaultInvestorAction | True | The type of transaction that occurred. List of types: vaultInvest, vaultBurnLpToken, vaultRedeem |
pricep |
string | True | The price of the vault LP tokens at the time of the event. |
sizes |
string | True | The amount of Vault LP tokens invested or redeemed. |
realized_pnlrp |
string | True | The realized PnL of the vault. |
performance_feepf |
string | True | The performance fee of the vault. |
VaultInvestorAction
| Value | Description |
|---|---|
UNSPECIFIED = 0 |
|
VAULT_INVEST = 1 |
|
VAULT_BURN_LP_TOKEN = 2 |
|
VAULT_REDEEM = 3 |
Success
Full Response
{
"result": [{
"event_time": "1697788800000000000",
"off_chain_account_id": "ACC:123456",
"vault_id": "2312134",
"type": "VAULT_INVEST",
"price": "1000000",
"size": "1000000",
"realized_pnl": "1000000",
"performance_fee": "1000000"
}]
}
{
"r": [{
"et": "1697788800000000000",
"oc": "ACC:123456",
"vi": "2312134",
"t": "VAULT_INVEST",
"p": "1000000",
"s": "1000000",
"rp": "1000000",
"pf": "1000000"
}]
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/vault_manager_investor_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "2312134",
"only_own_investments": true,
"start_time": "1697788800000000000",
"end_time": "1697788800000000000"
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_manager_investor_history",
"params": {
"vault_id": "2312134",
"only_own_investments": true,
"start_time": "1697788800000000000",
"end_time": "1697788800000000000"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/vault_manager_investor_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "2312134",
"oo": true,
"st": "1697788800000000000",
"et": "1697788800000000000"
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_manager_investor_history",
"p": {
"vi": "2312134",
"oo": true,
"st": "1697788800000000000",
"et": "1697788800000000000"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/vault_manager_investor_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "2312134",
"only_own_investments": true,
"start_time": "1697788800000000000",
"end_time": "1697788800000000000"
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_manager_investor_history",
"params": {
"vault_id": "2312134",
"only_own_investments": true,
"start_time": "1697788800000000000",
"end_time": "1697788800000000000"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/vault_manager_investor_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "2312134",
"oo": true,
"st": "1697788800000000000",
"et": "1697788800000000000"
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_manager_investor_history",
"p": {
"vi": "2312134",
"oo": true,
"st": "1697788800000000000",
"et": "1697788800000000000"
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/vault_manager_investor_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vault_id": "2312134",
"only_own_investments": true,
"start_time": "1697788800000000000",
"end_time": "1697788800000000000"
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/vault_manager_investor_history",
"params": {
"vault_id": "2312134",
"only_own_investments": true,
"start_time": "1697788800000000000",
"end_time": "1697788800000000000"
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/vault_manager_investor_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"vi": "2312134",
"oo": true,
"st": "1697788800000000000",
"et": "1697788800000000000"
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/vault_manager_investor_history",
"p": {
"vi": "2312134",
"oo": true,
"st": "1697788800000000000",
"et": "1697788800000000000"
},
"i": 123
}
' -w 360
Builder
Get Authorized Builders
FULL ENDPOINT: full/v1/get_authorized_builders
LITE ENDPOINT: lite/v1/get_authorized_builders
Used for requests that do not require any parameters
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
Query
Full Request
{
}
{
}
ApiGetAuthorizedBuildersResponse
Returns list of authorized builders and the associated fee
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultsr |
[ApiAuthorizedBuilder] | True | The list of authorized builders |
ApiAuthorizedBuilder
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
builder_account_idba |
string | True | The main account ID of the builder |
max_futures_fee_ratemf |
string | True | The maximum fee rate for the authorized builder |
max_spot_fee_ratems |
string | True | The maximum fee rate for the authorized builder |
Success
Full Response
{
"results": [{
"builder_account_id": "'$GRVT_MAIN_ACCOUNT_ID'",
"max_futures_fee_rate": 0.001,
"max_spot_fee_rate": 0.0001
}]
}
{
"r": [{
"ba": "'$GRVT_MAIN_ACCOUNT_ID'",
"mf": 0.001,
"ms": 0.0001
}]
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/get_authorized_builders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_authorized_builders",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/get_authorized_builders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_authorized_builders",
"p": {
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/get_authorized_builders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_authorized_builders",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/get_authorized_builders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_authorized_builders",
"p": {
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/get_authorized_builders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/get_authorized_builders",
"params": {
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/get_authorized_builders' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/get_authorized_builders",
"p": {
},
"i": 123
}
' -w 360
Execution
Builder Fill History
FULL ENDPOINT: full/v1/builder_fill_history
LITE ENDPOINT: lite/v1/builder_fill_history
The request to get the historical builder trade of a builder
The history is returned in reverse chronological order
Pagination works as follows:
- We perform a reverse chronological lookup, starting from
end_time. Ifend_timeis not set, we start from the most recent data. - The lookup is limited to
limitrecords. If more data is requested, the response will contain anextcursor for you to query the next page. - If a
cursoris provided, it will be used to fetch results from that point onwards. - Pagination will continue until the
start_timeis reached. Ifstart_timeis not set, pagination will continue as far back as our data retention policy allows.
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
start_timest |
string | False0 |
The start time to query for in unix nanoseconds |
end_timeet |
string | Falsenow() |
The end time to query for in unix nanoseconds |
limitl |
integer | False500 |
The limit to query for. Defaults to 500; Max 1000 |
cursorc |
string | False'' |
The cursor to indicate when to start the next query from |
Query
Full Request
{
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
{
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
resultr |
[BuilderFillHistory] | True | The builder fill history matching the request builder account |
nextn |
string | False'' |
The cursor to indicate when to start the next query from |
BuilderFillHistory
NameLite |
Type | RequiredDefault |
Description |
|---|---|---|---|
event_timeet |
string | True | Time at which the event was emitted in unix nanoseconds |
off_chain_account_idoc |
string | True | The off chain account id |
instrumenti |
string | True | The instrument being represented |
is_buyerib |
boolean | True | The side that the subaccount took on the trade |
is_takerit |
boolean | True | The role that the subaccount took on the trade |
sizes |
string | True | The number of assets being traded, expressed in base asset decimal units |
pricep |
string | True | The traded price, expressed in 9 decimals |
mark_pricemp |
string | True | The mark price of the instrument at point of trade, expressed in 9 decimals |
index_priceip |
string | True | The index price of the instrument at point of trade, expressed in 9 decimals |
fee_ratefr |
string | True | Builder fee percentage charged for this order. referred to Order.builder builderFee |
feef |
string | True | The builder fee paid on the trade, expressed in quote asset decimal unit. referred to Trade.builderFee |
Success
Full Response
{
"result": [{
"event_time": "1697788800000000000",
"off_chain_account_id": "ACC:123456",
"instrument": "BTC_USDT_Perp",
"is_buyer": true,
"is_taker": true,
"size": "0.30",
"price": "65038.01",
"mark_price": "65038.01",
"index_price": "65038.01",
"fee_rate": 0.001,
"fee": null
}],
"next": "Qw0918="
}
{
"r": [{
"et": "1697788800000000000",
"oc": "ACC:123456",
"i": "BTC_USDT_Perp",
"ib": true,
"it": true,
"s": "0.30",
"p": "65038.01",
"mp": "65038.01",
"ip": "65038.01",
"fr": 0.001,
"f": null
}],
"n": "Qw0918="
}
Error Codes
| Code | HttpStatus | Description |
|---|---|---|
| 1000 | 401 | You need to authenticate prior to using this functionality |
| 1001 | 403 | You are not authorized to access this functionality |
| 1002 | 500 | Internal Server Error |
| 1003 | 400 | Request could not be processed due to malformed syntax |
| 1006 | 429 | You have surpassed the allocated rate limit for your tier |
| 1008 | 401 | Your IP has not been whitelisted for access |
Failure
Full Error Response
{
"request_id":1,
"code":1000,
"message":"You need to authenticate prior to using this functionality",
"status":401
}
{
"ri":1,
"c":1000,
"m":"You need to authenticate prior to using this functionality",
"s":401
}
Authentication
GRVT supports two authentication methods: API Key and Wallet Login (EIP-712). Both return a session cookie used to authenticate subsequent requests.
API Key Login
Provision an API key via the GRVT UI.
# These are the variables you will need to set manually
GRVT_API_KEY="<insert_key_here>"
GRVT_SUB_ACCOUNT_ID="<insert_sub_account_id_here>"
Then, choose the environment you want to authenticate against.
# staging
GRVT_AUTH_ENDPOINT="https://edge.staging.gravitymarkets.io/auth/api_key/login"
# testnet
GRVT_AUTH_ENDPOINT="https://edge.testnet.grvt.io/auth/api_key/login"
# prod
GRVT_AUTH_ENDPOINT="https://edge.grvt.io/auth/api_key/login"
Now, let’s authenticate and retrieve both the session cookie and the X-Grvt-Account-Id header value that you’ll need to access any endpoints requiring authentication.
echo $GRVT_API_KEY
echo $GRVT_SUB_ACCOUNT_ID
echo $GRVT_AUTH_ENDPOINT
RESPONSE=$(
curl $GRVT_AUTH_ENDPOINT \
-H 'Content-Type: application/json' \
-H 'Cookie: rm=true;' \
-d '{"api_key": "'$GRVT_API_KEY'"}' \
-s -i
)
GRVT_COOKIE=$(echo "$RESPONSE" | grep -i 'set-cookie:' | grep -o 'gravity=[^;]*')
GRVT_ACCOUNT_ID=$(echo "$RESPONSE" | grep 'x-grvt-account-id:' | awk '{print $2}' | tr -d '\r')
echo "$GRVT_COOKIE"
echo "$GRVT_ACCOUNT_ID"
On success, a session cookie (gravity=...) is set and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
Wallet Login
Authenticate using your EVM signing wallet via an EIP-712 typed-data signature — no API key required.
POST /auth/wallet/login
Sign the following struct with eth_signTypedData_v4:
WalletLogin(address signer, uint32 nonce, int64 expiration)
| Field | Type | Description |
|---|---|---|
signer |
address |
Your registered EVM wallet address |
nonce |
uint32 |
Random client-chosen number. Each (address, nonce) pair can only be used once. |
expiration |
int64 |
Unix timestamp in nanoseconds. Must be in the future, max 5 minutes from now. See Server Time. |
Request
The request uses the common Signature DTO shared across all signed endpoints.
{
"address": "0xYourWalletAddress",
"signature": { "signer": "0xYourWalletAddress", "v": 27, "r": "0x...", "s": "0x...", "nonce": 305419896, "expiration": "1772159636314000000", "chain_id": "326" }
}
Response
On success, a session cookie (gravity=...) is set — the same GRVT_COOKIE used by API Key Login — and the response body contains:
{
"status": "success",
"location": "",
"funding_account_address": "0xYourFundingAccountAddress",
"sub_account_id": "123456789"
}
sub_account_id is optional — present only when the API key was generated from a Trading Account.
For a full example, see the Authentication page.
REST Full
curl --location 'https://trades.staging.gravitymarkets.io/full/v1/builder_fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.staging.gravitymarkets.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/builder_fill_history",
"params": {
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.staging.gravitymarkets.io/lite/v1/builder_fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.staging.gravitymarkets.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/builder_fill_history",
"p": {
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.testnet.grvt.io/full/v1/builder_fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.testnet.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/builder_fill_history",
"params": {
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.testnet.grvt.io/lite/v1/builder_fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.testnet.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/builder_fill_history",
"p": {
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360
REST Full
curl --location 'https://trades.grvt.io/full/v1/builder_fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
}
'
JSONRPC Full
wscat -c "wss://trades.grvt.io/ws/full" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"jsonrpc": "2.0",
"method": "v1/builder_fill_history",
"params": {
"start_time": "1697788800000000000",
"end_time": "1697788800000000000",
"limit": 500,
"cursor": ""
},
"id": 123
}
' -w 360
REST Lite
curl --location 'https://trades.grvt.io/lite/v1/builder_fill_history' \
--header "Cookie: $GRVT_COOKIE" \
--header "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
--data '{
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
}
'
JSONRPC Lite
wscat -c "wss://trades.grvt.io/ws/lite" \
-H "Cookie: $GRVT_COOKIE" \
-H "X-Grvt-Account-Id: $GRVT_ACCOUNT_ID" \
-x '
{
"j": "2.0",
"m": "v1/builder_fill_history",
"p": {
"st": "1697788800000000000",
"et": "1697788800000000000",
"l": 500,
"c": ""
},
"i": 123
}
' -w 360