Skip to content

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

ApiCreateOrderRequest

Create an order on the orderbook for this trading account.

Name
Lite
Type Required
Default
Description
order
o
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

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

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

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

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

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

Exchange only supports (GTT, IOC, FOK)
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK)
post_only
po
boolean False
false
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_only
ro
boolean False
false
If True, Order must reduce the position size, or be cancelled
legs
l
[OrderLeg] True The legs present in this order
The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice
signature
s
Signature True The signature approving this order
metadata
m
OrderMetadata True Order Metadata, ignored by the smart contract, and unsigned by the client
state
s1
OrderState False
''
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client
builder
b
string True The main account ID of the builder
builder_fee
bf
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
Name
Lite
Type Required
Default
Description
instrument
i
string True The instrument to trade in this leg
size
s
string True The total number of assets to trade in this leg, expressed in base asset decimal units.
limit_price
lp
string False
0
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_asset
ib
boolean True Specifies if the order leg is a buy or sell
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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.

Name
Lite
Type Required
Default
Description
client_order_id
co
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_time
ct
string False
0
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds
trigger
t
TriggerOrderMetadata False
``
Trigger fields are used to support any type of trigger order such as TP/SL
broker
b
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.


Name
Lite
Type Required
Default
Description
trigger_type
tt
TriggerType True Type of the trigger order. eg: Take Profit, Stop Loss, etc
tpsl
t
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.

Name
Lite
Type Required
Default
Description
trigger_by
tb
TriggerBy True Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order
trigger_price
tp
string True The Trigger Price of the order, expressed in 9 decimals.
close_position
cp
boolean True If True, the order will close the position when the trigger price is reached
is_split_position
is
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
Name
Lite
Type Required
Default
Description
status
s
OrderStatus True The status of the order
reject_reason
rr
OrderRejectReason True The reason for rejection or cancellation
book_size
bs
[string] True The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs
traded_size
ts
[string] True The total number of assets traded. Sorted in same order as Order.Legs
update_time
ut
string True Time at which the order was updated by GRVT, expressed in unix nanoseconds
avg_fill_price
af
[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"
    }
}
Lite Request
{
    "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"
    }
}

ApiCreateOrderResponse

Name
Lite
Type Required
Default
Description
result
r
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

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

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

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

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

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

Exchange only supports (GTT, IOC, FOK)
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK)
post_only
po
boolean False
false
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_only
ro
boolean False
false
If True, Order must reduce the position size, or be cancelled
legs
l
[OrderLeg] True The legs present in this order
The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice
signature
s
Signature True The signature approving this order
metadata
m
OrderMetadata True Order Metadata, ignored by the smart contract, and unsigned by the client
state
s1
OrderState False
''
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client
builder
b
string True The main account ID of the builder
builder_fee
bf
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
Name
Lite
Type Required
Default
Description
instrument
i
string True The instrument to trade in this leg
size
s
string True The total number of assets to trade in this leg, expressed in base asset decimal units.
limit_price
lp
string False
0
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_asset
ib
boolean True Specifies if the order leg is a buy or sell
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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.

Name
Lite
Type Required
Default
Description
client_order_id
co
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_time
ct
string False
0
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds
trigger
t
TriggerOrderMetadata False
``
Trigger fields are used to support any type of trigger order such as TP/SL
broker
b
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.


Name
Lite
Type Required
Default
Description
trigger_type
tt
TriggerType True Type of the trigger order. eg: Take Profit, Stop Loss, etc
tpsl
t
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.

Name
Lite
Type Required
Default
Description
trigger_by
tb
TriggerBy True Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order
trigger_price
tp
string True The Trigger Price of the order, expressed in 9 decimals.
close_position
cp
boolean True If True, the order will close the position when the trigger price is reached
is_split_position
is
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
Name
Lite
Type Required
Default
Description
status
s
OrderStatus True The status of the order
reject_reason
rr
OrderRejectReason True The reason for rejection or cancellation
book_size
bs
[string] True The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs
traded_size
ts
[string] True The total number of assets traded. Sorted in same order as Order.Legs
update_time
ut
string True Time at which the order was updated by GRVT, expressed in unix nanoseconds
avg_fill_price
af
[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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiCancelOrderRequest

Cancel an order on the orderbook for this trading account. Either order_id or client_order_id must be provided.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The subaccount ID cancelling the order
order_id
oi
string False
0
Cancel the order with this order_id
client_order_id
co
string False
0
Cancel the order with this client_order_id
time_to_live_ms
tt
string False
100
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"
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "oi": "0x1028403",
    "co": "23042",
    "tt": "500"
}

AckResponse

Used to acknowledge a request has been received and will be processed

Name
Lite
Type Required
Default
Description
result
r
Ack True The Ack Object
Ack
Name
Lite
Type Required
Default
Description
ack
a
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiCancelAllOrdersRequest

Cancel all orders on the orderbook for this trading account. This may not match new orders in flight.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The subaccount ID cancelling all orders
kind
k
[Kind] False
all
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be cancelled
base
b
[string] False
all
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be cancelled
quote
q
[string] False
all
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"]
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "k": ["PERPETUAL"],
    "b": ["BTC", "ETH"],
    "q": ["USDT", "USDC"]
}

AckResponse

Used to acknowledge a request has been received and will be processed

Name
Lite
Type Required
Default
Description
result
r
Ack True The Ack Object
Ack
Name
Lite
Type Required
Default
Description
ack
a
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiGetOrderRequest

Retrieve the order for the account. Either order_id or client_order_id must be provided.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The subaccount ID to filter by
order_id
oi
string False
0
Filter for order_id
client_order_id
co
string False
0
Filter for client_order_id

Query

Full Request

{
    "sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'",
    "order_id": "0x1028403",
    "client_order_id": "23042"
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "oi": "0x1028403",
    "co": "23042"
}

ApiGetOrderResponse

Name
Lite
Type Required
Default
Description
result
r
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

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

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

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

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

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

Exchange only supports (GTT, IOC, FOK)
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK)
post_only
po
boolean False
false
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_only
ro
boolean False
false
If True, Order must reduce the position size, or be cancelled
legs
l
[OrderLeg] True The legs present in this order
The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice
signature
s
Signature True The signature approving this order
metadata
m
OrderMetadata True Order Metadata, ignored by the smart contract, and unsigned by the client
state
s1
OrderState False
''
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client
builder
b
string True The main account ID of the builder
builder_fee
bf
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
Name
Lite
Type Required
Default
Description
instrument
i
string True The instrument to trade in this leg
size
s
string True The total number of assets to trade in this leg, expressed in base asset decimal units.
limit_price
lp
string False
0
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_asset
ib
boolean True Specifies if the order leg is a buy or sell
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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.

Name
Lite
Type Required
Default
Description
client_order_id
co
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_time
ct
string False
0
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds
trigger
t
TriggerOrderMetadata False
``
Trigger fields are used to support any type of trigger order such as TP/SL
broker
b
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.


Name
Lite
Type Required
Default
Description
trigger_type
tt
TriggerType True Type of the trigger order. eg: Take Profit, Stop Loss, etc
tpsl
t
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.

Name
Lite
Type Required
Default
Description
trigger_by
tb
TriggerBy True Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order
trigger_price
tp
string True The Trigger Price of the order, expressed in 9 decimals.
close_position
cp
boolean True If True, the order will close the position when the trigger price is reached
is_split_position
is
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
Name
Lite
Type Required
Default
Description
status
s
OrderStatus True The status of the order
reject_reason
rr
OrderRejectReason True The reason for rejection or cancellation
book_size
bs
[string] True The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs
traded_size
ts
[string] True The total number of assets traded. Sorted in same order as Order.Legs
update_time
ut
string True Time at which the order was updated by GRVT, expressed in unix nanoseconds
avg_fill_price
af
[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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiOpenOrdersRequest

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The subaccount ID to filter by
kind
k
[Kind] False
all
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned
base
b
[string] False
all
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned
quote
q
[string] False
all
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"]
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "k": ["PERPETUAL"],
    "b": ["BTC", "ETH"],
    "q": ["USDT", "USDC"]
}

ApiOpenOrdersResponse

Retrieves all open orders for the account. This may not match new orders in flight.

Name
Lite
Type Required
Default
Description
result
r
[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

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

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

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

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

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

Exchange only supports (GTT, IOC, FOK)
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK)
post_only
po
boolean False
false
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_only
ro
boolean False
false
If True, Order must reduce the position size, or be cancelled
legs
l
[OrderLeg] True The legs present in this order
The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice
signature
s
Signature True The signature approving this order
metadata
m
OrderMetadata True Order Metadata, ignored by the smart contract, and unsigned by the client
state
s1
OrderState False
''
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client
builder
b
string True The main account ID of the builder
builder_fee
bf
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
Name
Lite
Type Required
Default
Description
instrument
i
string True The instrument to trade in this leg
size
s
string True The total number of assets to trade in this leg, expressed in base asset decimal units.
limit_price
lp
string False
0
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_asset
ib
boolean True Specifies if the order leg is a buy or sell
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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.

Name
Lite
Type Required
Default
Description
client_order_id
co
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_time
ct
string False
0
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds
trigger
t
TriggerOrderMetadata False
``
Trigger fields are used to support any type of trigger order such as TP/SL
broker
b
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.


Name
Lite
Type Required
Default
Description
trigger_type
tt
TriggerType True Type of the trigger order. eg: Take Profit, Stop Loss, etc
tpsl
t
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.

Name
Lite
Type Required
Default
Description
trigger_by
tb
TriggerBy True Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order
trigger_price
tp
string True The Trigger Price of the order, expressed in 9 decimals.
close_position
cp
boolean True If True, the order will close the position when the trigger price is reached
is_split_position
is
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
Name
Lite
Type Required
Default
Description
status
s
OrderStatus True The status of the order
reject_reason
rr
OrderRejectReason True The reason for rejection or cancellation
book_size
bs
[string] True The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs
traded_size
ts
[string] True The total number of assets traded. Sorted in same order as Order.Legs
update_time
ut
string True Time at which the order was updated by GRVT, expressed in unix nanoseconds
avg_fill_price
af
[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"
    }]
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiOrderHistoryRequest

Retrieves the order history for the account.

Pagination works as follows:

  • We perform a reverse chronological lookup, starting from end_time. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The subaccount ID to filter by
kind
k
[Kind] False
all
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned
base
b
[string] False
all
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned
quote
q
[string] False
all
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only entries matching the filter will be returned
start_time
st
string False
0
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_time
et
string False
now()
The end time to apply in nanoseconds. If nil, this defaults to all end times. Otherwise, only entries matching the filter will be returned
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000
cursor
c
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": ""
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "k": ["PERPETUAL"],
    "b": ["BTC", "ETH"],
    "q": ["USDT", "USDC"],
    "st": "1697788800000000000",
    "et": "1697788800000000000",
    "l": 500,
    "c": ""
}

ApiOrderHistoryResponse

Name
Lite
Type Required
Default
Description
result
r
[Order] True The Open Orders matching the request filter
next
n
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

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

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

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

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

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

Exchange only supports (GTT, IOC, FOK)
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK)
post_only
po
boolean False
false
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_only
ro
boolean False
false
If True, Order must reduce the position size, or be cancelled
legs
l
[OrderLeg] True The legs present in this order
The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice
signature
s
Signature True The signature approving this order
metadata
m
OrderMetadata True Order Metadata, ignored by the smart contract, and unsigned by the client
state
s1
OrderState False
''
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client
builder
b
string True The main account ID of the builder
builder_fee
bf
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
Name
Lite
Type Required
Default
Description
instrument
i
string True The instrument to trade in this leg
size
s
string True The total number of assets to trade in this leg, expressed in base asset decimal units.
limit_price
lp
string False
0
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_asset
ib
boolean True Specifies if the order leg is a buy or sell
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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.

Name
Lite
Type Required
Default
Description
client_order_id
co
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_time
ct
string False
0
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds
trigger
t
TriggerOrderMetadata False
``
Trigger fields are used to support any type of trigger order such as TP/SL
broker
b
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.


Name
Lite
Type Required
Default
Description
trigger_type
tt
TriggerType True Type of the trigger order. eg: Take Profit, Stop Loss, etc
tpsl
t
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.

Name
Lite
Type Required
Default
Description
trigger_by
tb
TriggerBy True Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order
trigger_price
tp
string True The Trigger Price of the order, expressed in 9 decimals.
close_position
cp
boolean True If True, the order will close the position when the trigger price is reached
is_split_position
is
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
Name
Lite
Type Required
Default
Description
status
s
OrderStatus True The status of the order
reject_reason
rr
OrderRejectReason True The reason for rejection or cancellation
book_size
bs
[string] True The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs
traded_size
ts
[string] True The total number of assets traded. Sorted in same order as Order.Legs
update_time
ut
string True Time at which the order was updated by GRVT, expressed in unix nanoseconds
avg_fill_price
af
[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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiCancelOnDisconnectRequest

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.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The subaccount ID cancelling the orders for
countdown_time
ct
string False
1000
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
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "ct": 300
}

AckResponse

Used to acknowledge a request has been received and will be processed

Name
Lite
Type Required
Default
Description
result
r
Ack True The Ack Object
Ack
Name
Lite
Type Required
Default
Description
ack
a
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiBulkOrdersRequest

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.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The subaccount ID of the user creating the request
orders
o
[Order] True Orders to create or replace, supply up to 100 orders
order_i_ds
oi
[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_ds
co
[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_ms
tt
string False
100
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

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

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

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

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

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

Exchange only supports (GTT, IOC, FOK)
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK)
post_only
po
boolean False
false
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_only
ro
boolean False
false
If True, Order must reduce the position size, or be cancelled
legs
l
[OrderLeg] True The legs present in this order
The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice
signature
s
Signature True The signature approving this order
metadata
m
OrderMetadata True Order Metadata, ignored by the smart contract, and unsigned by the client
state
s1
OrderState False
''
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client
builder
b
string True The main account ID of the builder
builder_fee
bf
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
Name
Lite
Type Required
Default
Description
instrument
i
string True The instrument to trade in this leg
size
s
string True The total number of assets to trade in this leg, expressed in base asset decimal units.
limit_price
lp
string False
0
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_asset
ib
boolean True Specifies if the order leg is a buy or sell
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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.

Name
Lite
Type Required
Default
Description
client_order_id
co
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_time
ct
string False
0
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds
trigger
t
TriggerOrderMetadata False
``
Trigger fields are used to support any type of trigger order such as TP/SL
broker
b
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.


Name
Lite
Type Required
Default
Description
trigger_type
tt
TriggerType True Type of the trigger order. eg: Take Profit, Stop Loss, etc
tpsl
t
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.

Name
Lite
Type Required
Default
Description
trigger_by
tb
TriggerBy True Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order
trigger_price
tp
string True The Trigger Price of the order, expressed in 9 decimals.
close_position
cp
boolean True If True, the order will close the position when the trigger price is reached
is_split_position
is
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
Name
Lite
Type Required
Default
Description
status
s
OrderStatus True The status of the order
reject_reason
rr
OrderRejectReason True The reason for rejection or cancellation
book_size
bs
[string] True The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs
traded_size
ts
[string] True The total number of assets traded. Sorted in same order as Order.Legs
update_time
ut
string True Time at which the order was updated by GRVT, expressed in unix nanoseconds
avg_fill_price
af
[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"
}
Lite Request
{
    "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"
}

ApiBulkOrdersResponse

Name
Lite
Type Required
Default
Description
orders
o
[Order] True The orders in same order as requested
cancel_acks
ca
[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

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

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

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

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

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

Exchange only supports (GTT, IOC, FOK)
RFQ Maker only supports (GTT, AON), RFQ Taker only supports (FOK)
post_only
po
boolean False
false
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_only
ro
boolean False
false
If True, Order must reduce the position size, or be cancelled
legs
l
[OrderLeg] True The legs present in this order
The legs must be sorted by Asset.Instrument/Underlying/Quote/Expiration/StrikePrice
signature
s
Signature True The signature approving this order
metadata
m
OrderMetadata True Order Metadata, ignored by the smart contract, and unsigned by the client
state
s1
OrderState False
''
[Filled by GRVT Backend] The current state of the order, ignored by the smart contract, and unsigned by the client
builder
b
string True The main account ID of the builder
builder_fee
bf
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
Name
Lite
Type Required
Default
Description
instrument
i
string True The instrument to trade in this leg
size
s
string True The total number of assets to trade in this leg, expressed in base asset decimal units.
limit_price
lp
string False
0
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_asset
ib
boolean True Specifies if the order leg is a buy or sell
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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.

Name
Lite
Type Required
Default
Description
client_order_id
co
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_time
ct
string False
0
[Filled by GRVT Backend] Time at which the order was received by GRVT in unix nanoseconds
trigger
t
TriggerOrderMetadata False
``
Trigger fields are used to support any type of trigger order such as TP/SL
broker
b
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.


Name
Lite
Type Required
Default
Description
trigger_type
tt
TriggerType True Type of the trigger order. eg: Take Profit, Stop Loss, etc
tpsl
t
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.

Name
Lite
Type Required
Default
Description
trigger_by
tb
TriggerBy True Defines the price type (e.g., index price) that activates a Take Profit (TP) or Stop Loss (SL) order
trigger_price
tp
string True The Trigger Price of the order, expressed in 9 decimals.
close_position
cp
boolean True If True, the order will close the position when the trigger price is reached
is_split_position
is
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
Name
Lite
Type Required
Default
Description
status
s
OrderStatus True The status of the order
reject_reason
rr
OrderRejectReason True The reason for rejection or cancellation
book_size
bs
[string] True The number of assets available for orderbook/RFQ matching. Sorted in same order as Order.Legs
traded_size
ts
[string] True The total number of assets traded. Sorted in same order as Order.Legs
update_time
ut
string True Time at which the order was updated by GRVT, expressed in unix nanoseconds
avg_fill_price
af
[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
Name
Lite
Type Required
Default
Description
ack
a
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"
    }]
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiFillHistoryRequest

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. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to request for
kind
k
[Kind] False
all
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned
base
b
[string] False
all
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned
quote
q
[string] False
all
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only entries matching the filter will be returned
start_time
st
string False
0
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_time
et
string False
now()
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
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000
cursor
c
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": ""
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "k": ["PERPETUAL"],
    "b": ["BTC", "ETH"],
    "q": ["USDT", "USDC"],
    "st": "1697788800000000000",
    "et": "1697788800000000000",
    "l": 500,
    "c": ""
}

ApiFillHistoryResponse

Name
Lite
Type Required
Default
Description
result
r
[Fill] True The private trades matching the request asset
next
n
string True The cursor to indicate when to start the query from
Fill
Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
sub_account_id
sa
string True The sub account ID that participated in the trade
instrument
i
string True The instrument being represented
is_buyer
ib
boolean True The side that the subaccount took on the trade
is_taker
it
boolean True The role that the subaccount took on the trade
size
s
string True The number of assets being traded, expressed in base asset decimal units
price
p
string True The traded price, expressed in 9 decimals
mark_price
mp
string False
None
The mark price of the instrument at point of trade, expressed in 9 decimals
index_price
ip
string True The index price of the instrument at point of trade, expressed in 9 decimals
interest_rate
ir
string True The interest rate of the underlying at point of trade, expressed in centibeeps (1/100th of a basis point)
forward_price
fp
string False
None
[Options] The forward price of the option at point of trade, expressed in 9 decimals
realized_pnl
rp
string True The realized PnL of the trade, expressed in quote asset decimal units (0 if increasing position size)
fee
f
string True The fees paid on the trade, expressed in quote asset decimal unit (negative if maker rebate applied)
fee_rate
fr
string True The fee rate paid on the trade
trade_id
ti
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_id
oi
string True An order identifier
venue
v
Venue True The venue where the trade occurred
is_liquidation
il
boolean True If the trade was a liquidation
client_order_id
co
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
signer
s1
string True The address (public key) of the wallet signing the payload
broker
b
BrokerTag False
``
Specifies the broker who brokered the order
is_rpi
ir1
boolean True If the trade is a RPI trade
builder
b1
string True The main account ID of the builder. referred to Order.builder
builder_fee_rate
bf
string True Builder fee percentage charged for this order. referred to Order.builder builderFee
builder_fee
bf1
string True The builder fee paid on the trade, expressed in quote asset decimal unit. referred to Trade.builderFee
fee_currency
fc
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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to request for
instrument
i
string False
all
The perpetual instrument to filter for
start_time
st
string False
0
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_time
et
string False
now()
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
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000
cursor
c
string False
''
The cursor to indicate when to start the query from
kind
k
[Kind] False
all
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned
base
b
[string] False
all
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned
quote
q
[string] False
all
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"]
}
Lite Request
{
    "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

Name
Lite
Type Required
Default
Description
result
r
[FundingPayment] True The funding payments matching the request asset
next
n
string True The cursor to indicate when to start the query from
FundingPayment
Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
sub_account_id
sa
string True The sub account ID that made the funding payment
instrument
i
string True The perpetual instrument being funded
currency
c
string True The currency of the funding payment
amount
a
string True The amount of the funding payment. Positive if paid, negative if received
tx_id
ti
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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiPositionsRequest

Query the positions of a sub account

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to request for
kind
k
[Kind] False
all
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only entries matching the filter will be returned
base
b
[string] False
all
The base filter to apply. If nil, this defaults to all bases. Otherwise, only entries matching the filter will be returned
quote
q
[string] False
all
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"]
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "k": ["PERPETUAL"],
    "b": ["BTC", "ETH"],
    "q": ["USDT", "USDC"]
}

ApiPositionsResponse

Name
Lite
Type Required
Default
Description
result
r
[Positions] True The positions matching the request filter
Positions
Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
sub_account_id
sa
string True The sub account ID that participated in the trade
instrument
i
string True The instrument being represented
size
s
string True The size of the position, expressed in base asset decimal units. Negative for short positions
notional
n
string True The notional value of the position, negative for short assets, expressed in quote asset decimal units
entry_price
ep
string True The entry price of the position, expressed in 9 decimals
Whenever 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_price
ep1
string True The exit price of the position, expressed in 9 decimals
Whenever 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_price
mp
string True The mark price of the position, expressed in 9 decimals
unrealized_pnl
up
string True The unrealized PnL of the position, expressed in quote asset decimal units
unrealized_pnl = (mark_price - entry_price) * size
realized_pnl
rp
string True The realized PnL of the position, expressed in quote asset decimal units
realized_pnl = (exit_price - entry_price) * exit_trade_size
total_pnl
tp
string True The total PnL of the position, expressed in quote asset decimal units
total_pnl = realized_pnl + unrealized_pnl
roi
r
string True The ROI of the position, expressed as a percentage
roi = (total_pnl / (entry_price * abs(size))) * 100^
quote_index_price
qi
string True The index price of the quote currency. (reported in USD)
est_liquidation_price
el
string True The estimated liquidation price
leverage
l
string True The current leverage value for this position
cumulative_fee
cf
string True The cumulative fee paid on the position, expressed in quote asset decimal units
cumulative_realized_funding_payment
cr
string True The cumulative realized funding payment of the position, expressed in quote asset decimal units. Positive if paid, negative if received
margin_type
mt
PositionMarginType True The margin type of the position
isolated_balance
ib
string False
None
[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_im
ii
string False
None
[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_mm
im
string False
None
[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"
    }]
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiPositionHistoryRequest

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_time is unset (partially closed positions have no close time)
  • end_time is unset (partially closed positions have no close time)
  • cursor is unset (they are only returned on the initial page)
  • status is nil or includes PARTIALLY_CLOSED
Since these positions have no close time, query-row limits, as well as time-range and cursor-based pagination, do not apply to them.

Pagination works as follows:
  • We perform a reverse chronological lookup by position-close time, starting from end_time. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to request for
start_time
st
string False
0
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_time
et
string False
now()
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)
kind
k
[Kind] False
all
The kind filter to apply. If nil, this defaults to all kinds. Otherwise, only positions matching the filter will be returned
base
b
[string] False
all
The base filter to apply. If nil, this defaults to all bases. Otherwise, only positions matching the filter will be returned
quote
q
[string] False
all
The quote filter to apply. If nil, this defaults to all quotes. Otherwise, only positions matching the filter will be returned
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000. Applies to fully closed positions only; limit excludes any matching partially-closed positions
cursor
c
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)
status
s
[PositionCloseStatus] False
all
The status filter to apply. If nil, this defaults to all statuses. Otherwise, only positions matching the filter will be returned
is_long
il
boolean False
false
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_short
is
boolean False
false
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_type
mt
[PositionMarginType] False
all
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"]
}
Lite Request
{
    "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"]
}

ApiPositionHistoryResponse

Name
Lite
Type Required
Default
Description
result
r
[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)
next
n
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

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True Trading account ID which held this position
instrument
i
string True Asset this position was for
open_time
ot
string True Timestamp of first trade that opened this lifecycle
status
s
PositionCloseStatus True
is_long
il
boolean True True if the closed position was long
margin_type
mt
PositionMarginType True
close_time
ct
string False
None
Timestamp when the position lifecycle ended. Omitted when status is PARTIALLY_CLOSED
entry_price
ep
string True Average entry price at 9 decimals
exit_price
ep1
string True Average exit price at 9 decimals
position_close_mark_price
pc
string False
None
Mark price at close. Omitted when status is PARTIALLY_CLOSED
realized_pnl
rp
string True Cumulative realized PnL in quote currency
cumulative_fee
cf
string True Cumulative fees in quote currency
cumulative_realized_funding_payment
cr
string True Cumulative realized funding payment in quote currency
closed_volume_base
cv
string True Sum of abs(reducingTradeSize) across all reducing trades
closed_volume_quote
cv1
string True Sum of abs(reducingTradeSize) * tradePrice across all reducing trades
max_open_interest_base
mo
string True Max absolute position size reached during lifecycle
max_open_interest_quote
mo1
string True Max abs(size) * entryVWAP reached during lifecycle
cumulative_initial_margin
ci
string True Sum of markPrice * abs(tradeSize) / leverage for position-increasing trades
max_initial_margin
mi
string True High-water mark of cumulativeInitialMargin during lifecycle
leverage
l
string True Leverage at time of close. When status is PARTIALLY_CLOSED, this is the current leverage
unrealized_pnl
up
string False
None
The unrealized PnL of the position, expressed in quote asset decimal units
unrealized_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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to set the margin type and leverage for
instrument
i
string True The instrument of the position to set the margin type and leverage for
margin_type
mt
PositionMarginType True The margin type to set for the position
leverage
l
string True The leverage to set for the position
signature
s
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
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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"
    }
}
Lite Request
{
    "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

Name
Lite
Type Required
Default
Description
ack
a
boolean True Whether the margin type and leverage was acked

Success

Full Response

{
    "ack": "true"
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to add isolated margin in or remove margin from
instrument
i
string True The instrument to add margin into, or remove margin from
amount
a
string True The amount of margin to add to the position, positive to add, negative to remove, expressed in quote asset decimal units
signature
s
Signature True The signature of this operation
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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"
    }
}
Lite Request
{
    "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

Name
Lite
Type Required
Default
Description
success
s
boolean True Whether the margin mode and leverage was set successfully

Success

Full Response

{
    "success": "true"
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to get the margin limits for
instrument
i
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"
}
Lite Request
{
    "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

Name
Lite
Type Required
Default
Description
instrument
i
string True The isolated position asset
max_addable_amount
ma
string True The max addable amount that can be added to the isolated position, expressed in quote asset decimal units
max_removable_amount
mr
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"
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiDepositHistoryRequest

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. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
currency
c
[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_time
st
string False
0
The start time to query for in unix nanoseconds
end_time
et
string False
now()
The end time to query for in unix nanoseconds
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000
cursor
c1
string False
''
The cursor to indicate when to start the next query from
main_account_id
ma
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
}
Lite Request
{
    "c": ["USDT", "USDC"],
    "st": "1697788800000000000",
    "et": "1697788800000000000",
    "l": 500,
    "c1": "",
    "ma": null
}

ApiDepositHistoryResponse

Name
Lite
Type Required
Default
Description
result
r
[DepositHistory] True The deposit history matching the request account
next
n
string False
''
The cursor to indicate when to start the next query from
DepositHistory
Name
Lite
Type Required
Default
Description
l_1_hash
l1
string True The L1 txHash of the deposit
l_2_hash
l2
string True The L2 txHash of the deposit
to_account_id
ta
string True The account to deposit into
currency
c
string True The token currency to deposit
num_tokens
nt
string True The number of tokens to deposit
initiated_time
it
string True The timestamp when the deposit was initiated on L1 in unix nanoseconds
confirmed_time
ct
string True The timestamp when the deposit was confirmed on L2 in unix nanoseconds, empty if the deposit is pending.
from_address
fa
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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiTransferRequest

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

Fast Withdrawal Funding Address
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.

Name
Lite
Type Required
Default
Description
from_account_id
fa
string True The main account to transfer from
from_sub_account_id
fs
string True The subaccount to transfer from (0 if transferring from main account)
to_account_id
ta
string True The main account to deposit into
to_sub_account_id
ts
string True The subaccount to transfer to (0 if transferring to main account)
currency
c
string True The token currency to transfer
num_tokens
nt
string True The number of tokens to transfer, quoted in tokenCurrency decimal units
signature
s
Signature True The signature of the transfer
transfer_type
tt
TransferType True The type of transfer
transfer_metadata
tm
string True The metadata of the transfer
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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\"}"
}
Lite Request
{
    "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\"}"
}

ApiTransferResponse

Used to acknowledge a transfer request outcome

Name
Lite
Type Required
Default
Description
result
r
ApiTransferAck True The Transfer response object
ApiTransferAck
Name
Lite
Type Required
Default
Description
ack
a
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_id
ti
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiTransferHistoryRequest

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. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
currency
c
[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_time
st
string False
0
The start time to query for in unix nanoseconds
end_time
et
string False
now()
The end time to query for in unix nanoseconds
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000
cursor
c1
string False
''
The cursor to indicate when to start the next query from
tx_id
ti
string False
0
The transaction ID to query for
main_account_id
ma
string False
``
Main account ID being queried. By default, applies the requestor's main account ID.
transfer_types
tt
[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"]
}
Lite Request
{
    "c": ["USDT", "USDC"],
    "st": "1697788800000000000",
    "et": "1697788800000000000",
    "l": 500,
    "c1": "",
    "ti": "1028403",
    "ma": null,
    "tt": ["UNSPECIFIED"]
}

ApiTransferHistoryResponse

Name
Lite
Type Required
Default
Description
result
r
[TransferHistory] True The transfer history matching the request account
next
n
string False
''
The cursor to indicate when to start the next query from
TransferHistory
Name
Lite
Type Required
Default
Description
tx_id
ti
string True The transaction ID of the transfer
from_account_id
fa
string True The account to transfer from
from_sub_account_id
fs
string True The subaccount to transfer from (0 if transferring from main account)
to_account_id
ta
string True The account to deposit into
to_sub_account_id
ts
string True The subaccount to transfer to (0 if transferring to main account)
currency
c
string True The token currency to transfer
num_tokens
nt
string True The number of tokens to transfer
signature
s
Signature True The signature of the transfer
event_time
et
string True The timestamp of the transfer in unix nanoseconds
transfer_type
tt
TransferType True The type of transfer
transfer_metadata
tm
string True The metadata of the transfer
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiWithdrawalRequest

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.

Name
Lite
Type Required
Default
Description
from_account_id
fa
string True The main account to withdraw from
to_eth_address
te
string True The Ethereum wallet to withdraw into
currency
c
string True The token currency to withdraw
num_tokens
nt
string True The number of tokens to withdraw, quoted in tokenCurrency decimal units
signature
s
Signature True The signature of the withdrawal
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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"
    }
}
Lite Request
{
    "fa": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
    "te": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
    "c": "USDT",
    "nt": "1500.0",
    "s": {
        "s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
        "r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
        "s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
        "v": 28,
        "e": "1697788800000000000",
        "n": 1234567890,
        "ci": "325"
    }
}

AckResponse

Used to acknowledge a request has been received and will be processed

Name
Lite
Type Required
Default
Description
result
r
Ack True The Ack Object
Ack
Name
Lite
Type Required
Default
Description
ack
a
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiWithdrawalHistoryRequest

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. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
currency
c
[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_time
st
string False
0
The start time to query for in unix nanoseconds
end_time
et
string False
now()
The end time to query for in unix nanoseconds
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000
cursor
c1
string False
''
The cursor to indicate when to start the next query from
main_account_id
ma
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
}
Lite Request
{
    "c": ["USDT", "USDC"],
    "st": "1697788800000000000",
    "et": "1697788800000000000",
    "l": 500,
    "c1": "",
    "ma": null
}

ApiWithdrawalHistoryResponse

Name
Lite
Type Required
Default
Description
result
r
[WithdrawalHistory] True The withdrawals history matching the request account
next
n
string False
''
The cursor to indicate when to start the next query from
WithdrawalHistory
Name
Lite
Type Required
Default
Description
tx_id
ti
string True The transaction ID of the withdrawal
from_account_id
fa
string True The subaccount to withdraw from
to_eth_address
te
string True The ethereum address to withdraw to
currency
c
string True The token currency to withdraw
num_tokens
nt
string True The number of tokens to withdraw
signature
s
Signature True The signature of the withdrawal
event_time
et
string True The timestamp of the withdrawal in unix nanoseconds
l_1_hash
l1
string False
''
The finalized withdrawal transaction hash on L1, empty if the withdrawal is 'pending'.
l_2_hash
l2
string True The transaction hash on L2
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiSubAccountSummaryRequest

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The subaccount ID to filter by

Query

Full Request

{
    "sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'"
}

ApiSubAccountSummaryResponse

Query for sub-account details, including base currency balance, all derivative positions, margin levels, and P&L.

Name
Lite
Type Required
Default
Description
result
r
SubAccount True The sub account matching the request sub account
SubAccount
Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
sub_account_id
sa
string True The sub account ID this entry refers to
margin_type
mt
MarginType True The type of margin algorithm this subaccount uses
settle_currency
sc
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_pnl
up
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_equity
te
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_margin
im
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_margin
mm
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_balance
ab
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_balances
sb
[SpotBalance] True The list of spot assets owned by this sub account, and their balances
positions
p
[Positions] True The list of positions owned by this sub account
settle_index_price
si
string True The index price of the settle currency. (reported in USD)
is_vault
iv
boolean False
None
Whether this sub account is a vault
vault_im_additions
vi
string False
None
Total amount of IM (reported in settle_currency) deducted from the vault due to redemptions nearing the end of their redemption period
derisk_margin
dm
string True The derisk margin of this sub account
derisk_to_maintenance_margin_ratio
dt
string True The derisk margin to maintenance margin ratio of this sub account
total_cross_equity
tc
string True The total equity of this sub account for cross margin
cross_unrealized_pnl
cu
string True The unrealized PnL of this sub account for cross margin
sub_account_mode
sa1
SubAccountMode True The mode of the sub account
margin_balance
mb
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
Name
Lite
Type Required
Default
Description
currency
c
string True The currency you hold a spot balance in
balance
b
string True This currency's balance in this trading account.
index_price
ip
string True The index price of this currency. (reported in USD)
entry_price
ep
string True The entry price of this spot currency. (reported in USD)
realized_pnl
rp
string True The realized PnL of this spot currency. (reported in USD)
unrealized_pnl
up
string True The unrealized PnL of this spot currency. (reported in USD)
available_to_transfer
at
string True The available to transfer amount of this spot currency.
Positions
Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
sub_account_id
sa
string True The sub account ID that participated in the trade
instrument
i
string True The instrument being represented
size
s
string True The size of the position, expressed in base asset decimal units. Negative for short positions
notional
n
string True The notional value of the position, negative for short assets, expressed in quote asset decimal units
entry_price
ep
string True The entry price of the position, expressed in 9 decimals
Whenever 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_price
ep1
string True The exit price of the position, expressed in 9 decimals
Whenever 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_price
mp
string True The mark price of the position, expressed in 9 decimals
unrealized_pnl
up
string True The unrealized PnL of the position, expressed in quote asset decimal units
unrealized_pnl = (mark_price - entry_price) * size
realized_pnl
rp
string True The realized PnL of the position, expressed in quote asset decimal units
realized_pnl = (exit_price - entry_price) * exit_trade_size
total_pnl
tp
string True The total PnL of the position, expressed in quote asset decimal units
total_pnl = realized_pnl + unrealized_pnl
roi
r
string True The ROI of the position, expressed as a percentage
roi = (total_pnl / (entry_price * abs(size))) * 100^
quote_index_price
qi
string True The index price of the quote currency. (reported in USD)
est_liquidation_price
el
string True The estimated liquidation price
leverage
l
string True The current leverage value for this position
cumulative_fee
cf
string True The cumulative fee paid on the position, expressed in quote asset decimal units
cumulative_realized_funding_payment
cr
string True The cumulative realized funding payment of the position, expressed in quote asset decimal units. Positive if paid, negative if received
margin_type
mt
PositionMarginType True The margin type of the position
isolated_balance
ib
string False
None
[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_im
ii
string False
None
[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_mm
im
string False
None
[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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiSubAccountHistoryRequest

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. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to request for
start_time
st
string False
0
Start time of sub account history in unix nanoseconds
end_time
et
string False
now()
End time of sub account history in unix nanoseconds
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000
cursor
c
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": ""
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "st": "1697788800000000000",
    "et": "1697788800000000000",
    "l": 500,
    "c": ""
}

ApiSubAccountHistoryResponse

Name
Lite
Type Required
Default
Description
result
r
[SubAccount] True The sub account history matching the request sub account
next
n
string True The cursor to indicate when to start the next query from
SubAccount
Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
sub_account_id
sa
string True The sub account ID this entry refers to
margin_type
mt
MarginType True The type of margin algorithm this subaccount uses
settle_currency
sc
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_pnl
up
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_equity
te
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_margin
im
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_margin
mm
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_balance
ab
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_balances
sb
[SpotBalance] True The list of spot assets owned by this sub account, and their balances
positions
p
[Positions] True The list of positions owned by this sub account
settle_index_price
si
string True The index price of the settle currency. (reported in USD)
is_vault
iv
boolean False
None
Whether this sub account is a vault
vault_im_additions
vi
string False
None
Total amount of IM (reported in settle_currency) deducted from the vault due to redemptions nearing the end of their redemption period
derisk_margin
dm
string True The derisk margin of this sub account
derisk_to_maintenance_margin_ratio
dt
string True The derisk margin to maintenance margin ratio of this sub account
total_cross_equity
tc
string True The total equity of this sub account for cross margin
cross_unrealized_pnl
cu
string True The unrealized PnL of this sub account for cross margin
sub_account_mode
sa1
SubAccountMode True The mode of the sub account
margin_balance
mb
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
Name
Lite
Type Required
Default
Description
currency
c
string True The currency you hold a spot balance in
balance
b
string True This currency's balance in this trading account.
index_price
ip
string True The index price of this currency. (reported in USD)
entry_price
ep
string True The entry price of this spot currency. (reported in USD)
realized_pnl
rp
string True The realized PnL of this spot currency. (reported in USD)
unrealized_pnl
up
string True The unrealized PnL of this spot currency. (reported in USD)
available_to_transfer
at
string True The available to transfer amount of this spot currency.
Positions
Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
sub_account_id
sa
string True The sub account ID that participated in the trade
instrument
i
string True The instrument being represented
size
s
string True The size of the position, expressed in base asset decimal units. Negative for short positions
notional
n
string True The notional value of the position, negative for short assets, expressed in quote asset decimal units
entry_price
ep
string True The entry price of the position, expressed in 9 decimals
Whenever 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_price
ep1
string True The exit price of the position, expressed in 9 decimals
Whenever 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_price
mp
string True The mark price of the position, expressed in 9 decimals
unrealized_pnl
up
string True The unrealized PnL of the position, expressed in quote asset decimal units
unrealized_pnl = (mark_price - entry_price) * size
realized_pnl
rp
string True The realized PnL of the position, expressed in quote asset decimal units
realized_pnl = (exit_price - entry_price) * exit_trade_size
total_pnl
tp
string True The total PnL of the position, expressed in quote asset decimal units
total_pnl = realized_pnl + unrealized_pnl
roi
r
string True The ROI of the position, expressed as a percentage
roi = (total_pnl / (entry_price * abs(size))) * 100^
quote_index_price
qi
string True The index price of the quote currency. (reported in USD)
est_liquidation_price
el
string True The estimated liquidation price
leverage
l
string True The current leverage value for this position
cumulative_fee
cf
string True The cumulative fee paid on the position, expressed in quote asset decimal units
cumulative_realized_funding_payment
cr
string True The cumulative realized funding payment of the position, expressed in quote asset decimal units. Positive if paid, negative if received
margin_type
mt
PositionMarginType True The margin type of the position
isolated_balance
ib
string False
None
[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_im
ii
string False
None
[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_mm
im
string False
None
[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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

EmptyRequest

Used for requests that do not require any parameters

Name
Lite
Type Required
Default
Description

Query

Full Request

{
}
Lite 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

Name
Lite
Type Required
Default
Description
result
r
AggregatedAccountSummary True The aggregated account summary
AggregatedAccountSummary
Name
Lite
Type Required
Default
Description
main_account_id
ma
string True The main account ID of the account to which the summary belongs
total_equity
te
string True Total equity of the main (+ sub) account, denominated in USD
spot_balances
sb
[SpotBalance] True The list of spot assets owned by this main (+ sub) account, and their balances
vault_investments
vi
[VaultInvestment] True The list of vault investments held by this main account
total_sub_account_balance
ts
string True Deprecated: Use totalSubAccountEquity instead
total_sub_account_equity
ts1
string True Total equity of the sub accounts, denominated in USD
total_vault_investments_balance
tv
string True Total amount of the vault investments, denominated in USD
total_sub_account_available_balance
ts2
string True Total available balance of the main account, denominated in USD
total_usd_notional_invested
tu
string True Total entry (initial investment) amount of the open investments, denominated in USD
SpotBalance
Name
Lite
Type Required
Default
Description
currency
c
string True The currency you hold a spot balance in
balance
b
string True This currency's balance in this trading account.
index_price
ip
string True The index price of this currency. (reported in USD)
entry_price
ep
string True The entry price of this spot currency. (reported in USD)
realized_pnl
rp
string True The realized PnL of this spot currency. (reported in USD)
unrealized_pnl
up
string True The unrealized PnL of this spot currency. (reported in USD)
available_to_transfer
at
string True The available to transfer amount of this spot currency.
VaultInvestment

Summarizes a vault investment held by a funding account

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The trading account ID of the vault invested in.
num_lp_tokens
nl
string True The number of shares held by the investor.
share_price
sp
string True The current share price (in USD) of this vault investment.
usd_notional_invested
un
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

EmptyRequest

Used for requests that do not require any parameters

Name
Lite
Type Required
Default
Description

Query

Full Request

{
}
Lite Request
{
}

ApiFundingAccountSummaryResponse

The funding account summary, that reports the total equity and spot balances of a funding (main) account

Name
Lite
Type Required
Default
Description
result
r
FundingAccountSummary True The funding account summary
tier
t
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

Name
Lite
Type Required
Default
Description
main_account_id
ma
string True The main account ID of the account to which the summary belongs
total_equity
te
string True Total equity of the main account, denominated in USD
spot_balances
sb
[SpotBalance] True The list of spot assets owned by this main account, and their balances
vault_investments
vi
[VaultInvestment] True The list of vault investments held by this main account
total_cash_balance
tc
string True Total balance of cash (stablecoin) currencies, denominated in USD
total_spot_asset_balance
ts
string True Total balance of non-cash spot currencies, denominated in USD
SpotBalance
Name
Lite
Type Required
Default
Description
currency
c
string True The currency you hold a spot balance in
balance
b
string True This currency's balance in this trading account.
index_price
ip
string True The index price of this currency. (reported in USD)
entry_price
ep
string True The entry price of this spot currency. (reported in USD)
realized_pnl
rp
string True The realized PnL of this spot currency. (reported in USD)
unrealized_pnl
up
string True The unrealized PnL of this spot currency. (reported in USD)
available_to_transfer
at
string True The available to transfer amount of this spot currency.
VaultInvestment

Summarizes a vault investment held by a funding account

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The trading account ID of the vault invested in.
num_lp_tokens
nl
string True The number of shares held by the investor.
share_price
sp
string True The current share price (in USD) of this vault investment.
usd_notional_invested
un
string True The USD notional invested in this vault investment.
ClientTier
Name
Lite
Type Required
Default
Description
tier
t
integer True
futures_taker_fee
ft
integer True
futures_maker_fee
fm
integer True
options_taker_fee
ot
integer True
options_maker_fee
om
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
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to set the leverage for
ratio
r
string True The derisk margin to maintenance margin ratio of this sub account
signature
s
Signature True The signature of this operation
Signature
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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"
    }
}
Lite Request
{
    "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

Name
Lite
Type Required
Default
Description
success
s
boolean True Whether the derisk margin to maintenance margin ratio was set successfully

Success

Full Response

{
    "success": "true"
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

EmptyRequest

Used for requests that do not require any parameters

Name
Lite
Type Required
Default
Description

Query

Full Request

{
}
Lite Request
{
}

ApiGetSubAccountsResponse

Response payload containing all sub-accounts accessible within the given auth session

Name
Lite
Type Required
Default
Description
sub_account_ids
sa
[string] True List of sub-account IDs accessible to the session

Success

Full Response

{
    "sub_account_ids": ["4724219064482495","2095919380","1170592370"]
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to get the leverage for

Query

Full Request

{
    "sub_account_id": "'$GRVT_SUB_ACCOUNT_ID'"
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'"
}

ApiGetAllInitialLeverageResponse

The response to get the initial leverage of a sub account

Name
Lite
Type Required
Default
Description
results
r
[InitialLeverageResult] True The initial leverage of the sub account
InitialLeverageResult
Name
Lite
Type Required
Default
Description
instrument
i
string True The instrument to get the leverage for
leverage
l
string True The initial leverage of this instrument
min_leverage
ml
string True The min leverage user can set for this instrument
max_leverage
ml1
string True The max leverage user can set for this instrument
margin_type
mt
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"
    }]
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiSetInitialLeverageRequest

The request to set the initial leverage of a sub account.
DEPRECATED: This API is deprecated, use set_position_config API instead

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The sub account ID to set the leverage for
instrument
i
string True The instrument to set the leverage for
leverage
l
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"
}
Lite Request
{
    "sa": "'$GRVT_SUB_ACCOUNT_ID'",
    "i": "BTC_USDT_Perp",
    "l": "10"
}

ApiSetInitialLeverageResponse

The response to set the initial leverage of a sub account.
DEPRECATED: This API is deprecated, use set_position_config API instead

Name
Lite
Type Required
Default
Description
success
s
boolean True Whether the leverage was set successfully

Success

Full Response

{
    "success": "true"
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiVaultBurnTokensRequest

Request payload for burning tokens in a vault.

This API allows a client to burn a specified amount of tokens in a particular vault.

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The unique identifier of the vault to burn tokens from.
currency
c
string True The currency used for the burn. This should be the vault's quote currency.
num_tokens
nt
string True The number of tokens to burn.
signature
s
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
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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"
    }
}
Lite Request
{
    "vi": "3477045127917224",
    "c": "USDT",
    "nt": 1000000,
    "s": {
        "s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
        "r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
        "s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
        "v": 28,
        "e": "1697788800000000000",
        "n": 1234567890,
        "ci": "325"
    }
}

AckResponse

Used to acknowledge a request has been received and will be processed

Name
Lite
Type Required
Default
Description
result
r
Ack True The Ack Object
Ack
Name
Lite
Type Required
Default
Description
ack
a
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiVaultInvestRequest

Request payload for investing in a vault.

This API allows a client to invest a specified amount of tokens in a particular vault.

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The unique identifier of the vault to invest in.
currency
c
string True The currency used for the investment. This should be the vault's quote currency.
num_tokens
nt
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).
signature
s
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
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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"
    }
}
Lite Request
{
    "vi": "3477045127917224",
    "c": "USDT",
    "nt": 1000000,
    "s": {
        "s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
        "r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
        "s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
        "v": 28,
        "e": "1697788800000000000",
        "n": 1234567890,
        "ci": "325"
    }
}

AckResponse

Used to acknowledge a request has been received and will be processed

Name
Lite
Type Required
Default
Description
result
r
Ack True The Ack Object
Ack
Name
Lite
Type Required
Default
Description
ack
a
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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.

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The unique identifier of the vault to fetch the summary for.

Query

Full Request

{
    "vault_id": "3477045127917224"
}
Lite Request
{
    "vi": "3477045127917224"
}

ApiVaultInvestorSummaryResponse

Response payload for the summary of a vault investor.

This API provides the summary of investments in a specific vault.

Name
Lite
Type Required
Default
Description
vault_investor_summary
vi
[VaultInvestorSummary] True The summary of investments in the vault.
VaultInvestorSummary

Vault investor summary information.

This struct contains the summary of investments in a vault.

Name
Lite
Type Required
Default
Description
sub_account_id
sa
string True The unique identifier of the vault sub account.
num_lp_tokens
nl
string True The number of Vault LP tokens held by the investor.
avg_entry_price
ae
string True The average entry price (in USD) of the vault LP tokens.
current_price
cp
string True The current price (in USD) of the vault LP tokens.
total_equity
te
string True The current valuation (in USD) of all held vault LP tokens.
all_time_realized_pnl
at
string True The all-time realized PnL (in USD) that the investor has received from the vault.
pending_redemption
pr
VaultRedemption False
None
The singleton pending redemption (omitted if none).
can_burn
cb
boolean False
true
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.

Name
Lite
Type Required
Default
Description
num_lp_tokens
nl
string True The number of LP Tokens requested for redemption.
request_valuation
rv
string True The valuation (in USD) of the redemption request.
request_time
rt
string True [Filled by GRVT Backend] Time at which the redemption request was received by GRVT in unix nanoseconds
max_redemption_period_timestamp
mr
string True [Filled by GRVT Backend] Time in unix nanoseconds, beyond which the request will be force-redeemed.
cancel_blocked
cb
boolean False
true
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
    }]
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiVaultRedeemRequest

Request payload for redeeming from a vault.

This API allows a client to redeem a specified amount of tokens from a particular vault.

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The unique identifier of the vault to redeem from.
currency
c
string True The currency used for the redemption. This should be the vault's quote currency.
num_tokens
nt
string True The number of shares to redeem.
signature
s
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
Name
Lite
Type Required
Default
Description
signer
s
string True The address (public key) of the wallet signing the payload
r
r
string True Signature R
s
s1
string True Signature S
v
v
integer True Signature V
expiration
e
string True Timestamp after which this signature expires, expressed in unix nanoseconds. Must be capped at 30 days
nonce
n
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_id
ci
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"
    }
}
Lite Request
{
    "vi": "3477045127917224",
    "c": "USDT",
    "nt": 1000000,
    "s": {
        "s": "0xc73c0c2538fd9b833d20933ccc88fdaa74fcb0d0",
        "r": "0xb788d96fee91c7cdc35918e0441b756d4000ec1d07d900c73347d9abbc20acc8",
        "s1": "0x3d786193125f7c29c958647da64d0e2875ece2c3f845a591bdd7dae8c475e26d",
        "v": 28,
        "e": "1697788800000000000",
        "n": 1234567890,
        "ci": "325"
    }
}

AckResponse

Used to acknowledge a request has been received and will be processed

Name
Lite
Type Required
Default
Description
result
r
Ack True The Ack Object
Ack
Name
Lite
Type Required
Default
Description
ack
a
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiVaultRedeemCancelRequest

Request payload for canceling a vault redemption.

This API allows a client to cancel a previously initiated redemption from a vault.

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The unique identifier of the vault to cancel the redemption from.

Query

Full Request

{
    "vault_id": "3477045127917224"
}
Lite Request
{
    "vi": "3477045127917224"
}

AckResponse

Used to acknowledge a request has been received and will be processed

Name
Lite
Type Required
Default
Description
result
r
Ack True The Ack Object
Ack
Name
Lite
Type Required
Default
Description
ack
a
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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.

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The unique identifier of the vault to fetch the redemption queue for.

Query

Full Request

{
    "vault_id": "3477045127917224"
}
Lite Request
{
    "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).


Name
Lite
Type Required
Default
Description
redemption_queue
rq
[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_count
pr
string True Number of shares eligible for automated redemption (held in queue for at least the minimum redemption period).
urgent_redemption_token_count
ur
string True Number of shares nearing the maximum redemption period (>= 90% of maximum redemption period).
auto_redeemable_balance
ar
string True Amount available for automated redemption request servicing (in USD).
share_price
sp
string True Current share price (in USD).
pre_min
pm
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.

Name
Lite
Type Required
Default
Description
request_time
rt
string True [Filled by GRVT Backend] Time at which the redemption request was received by GRVT in unix nanoseconds
num_lp_tokens
nl
string True The number of shares to redeem
max_redemption_period_timestamp
mr
string True [Filled by GRVT Backend] Time in unix nanoseconds, beyond which the request will be force-redeemed.
age_category
ac
VaultRedemptionReqAgeCategory True Age category of this redemption request.
is_manager
im
boolean False
None
true if this request belongs to the vault manager, omitted otherwise.
eligible_for_auto_redemption_timestamp
ef
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.

Name
Lite
Type Required
Default
Description
requests
r
[VaultRedemptionRequest] True Pre-minimum-age redemption requests, ordered by age (first element is the oldest request that is pre-minimum-age).
token_count
tc
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.

Name
Lite
Type Required
Default
Description
request_time
rt
string True [Filled by GRVT Backend] Time at which the redemption request was received by GRVT in unix nanoseconds
num_lp_tokens
nl
string True The number of shares to redeem
max_redemption_period_timestamp
mr
string True [Filled by GRVT Backend] Time in unix nanoseconds, beyond which the request will be force-redeemed.
age_category
ac
VaultRedemptionReqAgeCategory True Age category of this redemption request.
is_manager
im
boolean False
None
true if this request belongs to the vault manager, omitted otherwise.
eligible_for_auto_redemption_timestamp
ef
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"
    }
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

Name
Lite
Type Required
Default
Description
vault_id
vi
string True The unique identifier of the vault to filter by
only_own_investments
oo
boolean True Whether to only return investments made by the manager
start_time
st
string False
0
Optional. Start time in unix nanoseconds
end_time
et
string False
now()
Optional. End time in unix nanoseconds

Query

Full Request

{
    "vault_id": "2312134",
    "only_own_investments": true,
    "start_time": "1697788800000000000",
    "end_time": "1697788800000000000"
}
Lite Request
{
    "vi": "2312134",
    "oo": true,
    "st": "1697788800000000000",
    "et": "1697788800000000000"
}

ApiQueryVaultManagerInvestorHistoryResponse

Response to retrieve the vault summary for a given vault

Name
Lite
Type Required
Default
Description
result
r
[ApiVaultInvestorHistory] True The list of vault investor history belong to the manager
ApiVaultInvestorHistory

The vault investor history returned by the service to client

Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
off_chain_account_id
oc
string True The off chain account id of the investor, only visible to the manager
vault_id
vi
string True The unique identifier of the vault.
type
t
VaultInvestorAction True The type of transaction that occurred. List of types: vaultInvest, vaultBurnLpToken, vaultRedeem
price
p
string True The price of the vault LP tokens at the time of the event.
size
s
string True The amount of Vault LP tokens invested or redeemed.
realized_pnl
rp
string True The realized PnL of the vault.
performance_fee
pf
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"
    }]
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

EmptyRequest

Used for requests that do not require any parameters

Name
Lite
Type Required
Default
Description

Query

Full Request

{
}
Lite Request
{
}

ApiGetAuthorizedBuildersResponse

Returns list of authorized builders and the associated fee

Name
Lite
Type Required
Default
Description
results
r
[ApiAuthorizedBuilder] True The list of authorized builders
ApiAuthorizedBuilder
Name
Lite
Type Required
Default
Description
builder_account_id
ba
string True The main account ID of the builder
max_futures_fee_rate
mf
string True The maximum fee rate for the authorized builder
max_spot_fee_rate
ms
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
    }]
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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

ApiBuilderFillHistoryRequest

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. If end_time is not set, we start from the most recent data.
  • The lookup is limited to limit records. If more data is requested, the response will contain a next cursor for you to query the next page.
  • If a cursor is provided, it will be used to fetch results from that point onwards.
  • Pagination will continue until the start_time is reached. If start_time is not set, pagination will continue as far back as our data retention policy allows.

Name
Lite
Type Required
Default
Description
start_time
st
string False
0
The start time to query for in unix nanoseconds
end_time
et
string False
now()
The end time to query for in unix nanoseconds
limit
l
integer False
500
The limit to query for. Defaults to 500; Max 1000
cursor
c
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": ""
}
Lite Request
{
    "st": "1697788800000000000",
    "et": "1697788800000000000",
    "l": 500,
    "c": ""
}

ApiBuilderFillHistoryResponse

Name
Lite
Type Required
Default
Description
result
r
[BuilderFillHistory] True The builder fill history matching the request builder account
next
n
string False
''
The cursor to indicate when to start the next query from
BuilderFillHistory
Name
Lite
Type Required
Default
Description
event_time
et
string True Time at which the event was emitted in unix nanoseconds
off_chain_account_id
oc
string True The off chain account id
instrument
i
string True The instrument being represented
is_buyer
ib
boolean True The side that the subaccount took on the trade
is_taker
it
boolean True The role that the subaccount took on the trade
size
s
string True The number of assets being traded, expressed in base asset decimal units
price
p
string True The traded price, expressed in 9 decimals
mark_price
mp
string True The mark price of the instrument at point of trade, expressed in 9 decimals
index_price
ip
string True The index price of the instrument at point of trade, expressed in 9 decimals
fee_rate
fr
string True Builder fee percentage charged for this order. referred to Order.builder builderFee
fee
f
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="
}
Lite Response
{
    "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
}
Lite Error Response
{
    "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