NAV
shell python

Introduction

Gemini offers both public and private REST APIs.

Public REST APIs provide market data such as:

Private REST APIs allow you to manage both orders and funds:

Survey

Please complete our API Use Survey to help us improve your experience using the Gemini APIs.

Sandbox

Gemini's sandbox site is an instance of the Gemini Exchange that offers full exchange functionality using test funds.

Sandbox URLs

Website
https://exchange.sandbox.gemini.com

REST API
https://api.sandbox.gemini.com

WebSocket Feed
wss://api.sandbox.gemini.com

Documentation
https://docs.sandbox.gemini.com

Create your account

Go to the sandbox site to register for a test account to begin trading.

Your account will automatically be credited with test BTC, USD, and ETH. You may use these funds to trade, both through the web site and through the API.

Gemini's sandbox site does not support either depositing or withdrawing your test funds, which can only be used to trade on the sandbox exchange.

Sandbox does not support email notifications. If you need this as part of your testing plan, please contact institutional@gemini.com.

If you have any issues, or if you need to adjust your balances (to test insufficient funds handling, for example), contact institutional@gemini.com.

Rate Limits

To prevent abuse, Gemini imposes rate limits on incoming requests as described in the Gemini API Agreement.

For public API entry points, we limit requests to 120 requests per minute, and recommend that you do not exceed 1 request per second.

For private API entry points, we limit requests to 600 requests per minute, and recommend that you not exceed 5 requests per second.

How are rate limits applied?

When requests are received at a rate exceeding X requests per minute, we offer a "burst" rate of five additional requests that are queued but their processing is delayed until the request rate falls below the defined rate.

When you exceed the rate limit for a group of endpoints, you will receive a 429 Too Many Requests HTTP status response until your request rate drops back under the required limit.

Example: 600 requests per minute is ten requests per second, meaning one request every 0.1 second.

If you send 20 requests in close succession over two seconds, then you could expect:

Use WebSocket APIs

Polling Order Status API endpoints may be subject to rate limiting: Gemini recommends using WebSocket API to get market data and realtime information about your orders and trades.

Information you want How to get it through the WebSocket API
Your trade notifictions Order Events: Filled
All trade notifcations Market Data: Trade event
Your active orders
  1. Populate local state using Order Events: Active Orders
  2. then update local state by processing individual order event types as received:
The status of an active order A subscription to Order Events will provide you will all your active orders followed by realtime updates to order status. Maintain local state and look up the status of your order there.
All active orders Market Data: Change Event

Batch cancels

If you want to cancel a group of orders, instead of making multiple Cancel Order requests, use one of Gemini's batch cancel endpoints:

Then use your Order Events WebSocket subscription to watch for notifications of:

Requests

There are two types of APIs below, the public ones and the private ones, which are subdivided into order placement, order status, and account status.

Public API invocation

Public APIs are accessible via GET, and the parameters for the request are included in the query string.

Private API invocation

To walk through the process of generating a private API invocation, we start with the request json itself

// The comments are for documentation purposes only as the JSON
// spec does not permit comments.
{
    // The generic elements, required for all POSTS
    "request": "/v1/order/status",
    "nonce": 123456,

    // Request-specific data
    "order_id": 18834
}

Whitespace is valid JSON, so it is ignored by the server, and may be included if desired. The hashes are always taken on the base64 string directly, with no normalization, so whatever is sent in the payload is what should be hashed, and what the server will verify.

~$ base64 << EOF
> {
>     "request": "/v1/order/status",
>     "nonce": 123456,
>
>     "order_id": 18834
> }
> EOF
ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYs
CgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=
b64 = base64.b64encode("""{
    "request": "/v1/order/status",
    "nonce": 123456,

    "order_id": 18834
}
""")
b64 = 'ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo='

In this example, the api_secret is 1234abcd

echo -n 'ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=' | openssl sha384 -hmac "1234abcd"
(stdin)= 337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f
signature = hmac.new("1234abcd", b64, hashlib.sha384).hexdigest()
'337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f'

The final request will look like this:

curl --request POST \
  --url https://api.gemini.com/v1/order/status \
  --header 'Cache-Control: no-cache' \
  --header 'Content-Length: 0' \
  --header 'Content-Type: text/plain' \
  --header 'X-GEMINI-APIKEY: mykey' \
  --header 'X-GEMINI-PAYLOAD: ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=' \
  --header 'X-GEMINI-SIGNATURE: 337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f'
import requests
import base64
import hmac
from hashlib import sha384

url = "https://api.gemini.com/v1/order/status"

gemini_api_key = "mykey"
gemini_api_secret = "1234abcd"

# for the purposes of this example, we've shown hand-rolled JSON - please import json and use json.dumps in your real code!
b64 = base64.b64encode("""{
    "request": "/v1/order/status",
    "nonce": 123456,

    "order_id": 18834
}
""")

signature = hmac.new("1234abcd", b64, hashlib.sha384).hexdigest()

headers = {
    'Content-Type': "text/plain",
    'Content-Length': "0",
    'X-GEMINI-APIKEY': gemini_api_key,
    'X-GEMINI-PAYLOAD': b64,
    'X-GEMINI-SIGNATURE': signature,
    'Cache-Control': "no-cache"
    }

response = requests.request("POST", url, headers=headers)

print(response.text)

Which produces these HTTP headers

POST /v1/order/status
Content-Type: text/plain
Content-Length: 0
X-GEMINI-APIKEY: mykey
X-GEMINI-PAYLOAD:ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N
    0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGV
    yX2lkIjogMTg4MzQKfQo=
X-GEMINI-SIGNATURE: 337cc8b4ea692cfe65b4a85fcc9f042b2e3f
    702ac956fd098d600ab15705775017beae402be773ceee10719f
    f70d710f

Authentication

Gemini uses API keys to allow access to private APIs. You can obtain these by logging on and creating a key in Settings/API. This will give you both an "API Key" that will serve as your user name, and an "API Secret" that you will use to sign messages.

All requests must contain a nonce, a number that will never be repeated and must increase between requests. This is to prevent an attacker who has captured a previous request from simply replaying that request. We recommend using a timestamp at millisecond or higher precision. The nonce need only be increasing with respect to the session that the message is on.

Sessions

A single account may have multiple API keys provisioned. In this document, we'll refer to these as "sessions". All orders will be recorded with the session that created them. The nonce associated with a request needs to be increasing with respect to the session that the nonce is used on.

This allows multithreaded or distributed trading systems to place orders independently of each other, without needing to synchronize clocks to avoid race conditions.

In addition, some operations (such as Cancel All Session Orders) act on the orders associated with a specific session.

Require Heartbeat

When provisioning a session key you have the option of marking the session as "Requires Heartbeat". The intention here is to specify that if connectivity to the exchange is lost for any reason, then all outstanding orders on this session should be canceled.

If this option is selected for a session, then if the exchange does not receive a message for 30 seconds, then it will assume there has been an interruption in service, and cancel all outstanding orders. To maintain the session, the trading system should send a heartbeat message at a more frequent interval. We suggest at most 15 seconds between heartbeats.

The heartbeat message is provided for convenience when there is no trading activity. Any authenticated API call will reset the 30 second clock, event if explicit heartbeats are not sent.

This feature is often referred to as "Cancel on Disconnect" on connection-oriented exchange protocols.

Payload

The payload of the requests will be a JSON object, which will be described in the documentation below. Rather than being sent as the body of the POST request, it will be base-64 encoded and stored as a header in the request.

All of them will include the request name and the nonce associated with the request. The nonce must be increasing with each request to prevent replay attacks.

Header Value
Content-Length 0
Content-Type text/plain
X-GEMINI-APIKEY Your Gemini API key
X-GEMINI-PAYLOAD The base64-encoded JSON payload
X-GEMINI-SIGNATURE hex(HMAC_SHA384(base64(payload), key=api_secret))

Roles

Example of error response due to API key missing a role

{  
   "result":"error",
   "reason":"MissingRole",
   "message":"To access this endpoint, you need to log in to the website and go to the settings page to assign one of these roles [FundManager] to API key wujB3szN54gtJ4QDhqRJ which currently has roles [Trader]"
}

Gemini uses a role-based system for private API endpoints so that you can separate privileges for your API keys.

By assigning different roles to different API keys, you can create

  1. one API key that can trade, and
  2. another API key that can withdraw BTC to a whitelisted address

You can configure which roles are assigned to your API keys by logging in to the Gemini Exchange website and going to API Settings to configure your API keys.

If you try to access an endpoint that requires a role you did not assign to your API key, you will get back a response with:

See Error Codes for more information about API error responses.

Trader

Assigning the Trader role to an API key allows this API key to:

Fund Manager

Assigning the Fund Manager role to an API key allows this API key to

Endpoint summary

Here's a summary of which role you need to assign to your API key to use each endpoint in the API:

Endpoint URI Trader can access? Fund Manager can access?
New Order /v1/order/new
Cancel Order /v1/order/cancel
Cancel All Session Orders /v1/order/cancel/session
Cancel All Active Orders /v1/order/cancel/all
Order Status /v1/order/status
Get Active Orders /v1/orders
Get Past Trades /v1/mytrades
Get Trade Volume /v1/tradevolume
Heartbeat /v1/heartbeat
Get Available Balances /v1/balances
New Deposit Address /v1/deposit/:currency/newAddress
Withdraw Crypto Funds To Whitelisted Address /v1/withdraw/:currency

Troubleshooting

Please use our Sandbox environment to develop and test your code.

If your private API request is failing, turn on debug logging so you can print out:

Make sure that you are not sending the JSON as the POST body.

If you receive a 400 error that you are missing required data, then copy the base64 encoded string in X-GEMINI-PAYLOAD to a base64 decoder such as https://www.base64decode.org/ and decode it. Compare the decoded JSON to the documentation for the endpoint you are trying to access.

If you are receiving a 429 response, then see Rate Limits.

Support

If you still have a problem then contact institutional@gemini.com with the following information:

  1. Which environment did you try to make the request in, production or sandbox?
  2. What is your API key?
  3. What URL were you trying to hit?
  4. What IP address did you make the request from?
  5. What date and time (including time zone) did you try to make the request?

Please make sure to include:

If you leave any of this information out, the response to your support request may be delayed.

Client Order ID

Order Event subscription Accepted event showing client_order_id

[ {
  "type" : "accepted",
  "order_id" : "372456298",
  "event_id" : "372456299",
  "client_order_id": "20170208_example", 
  "api_session" : "AeRLptFXoYEqLaNiRwv8",
  "symbol" : "btcusd",
  "side" : "buy",
  "order_type" : "exchange limit",
  "timestamp" : "1478203017",
  "timestampms" : 1478203017455,
  "is_live" : true,
  "is_cancelled" : false,
  "is_hidden" : false,
  "avg_execution_price" : "0", 
  "original_amount" : "14.0296",
  "price" : "1059.54"
} ]

Order Status endpoint for the same order, showing client_order_id

{
    "avg_execution_price": "0.00",
    "client_order_id": "20170208_example",
    "exchange": "gemini",
    "executed_amount": "0",
    "id": "372456298",
    "is_cancelled": false,
    "is_hidden": false,
    "is_live": true,
    "order_id": "372456298",
    "original_amount": "14.0296",
    "price": "1059.54",
    "remaining_amount": "14.0296",
    "side": "buy",
    "symbol": "btcusd",
    "timestamp": "1478203017",
    "timestampms": 1478203017455,
    "type": "exchange limit",
    "was_forced": false
}

Client order ID is a client-supplied order identifier that Gemini will echo back to you in all subsequent messages about that order.

Although this identifier is optional, Gemini strongly recommends supplying client_order_id when placing orders using the New Order endpoint.

This makes it easy to track the Order Events: Accepted and Order Events: Booked responses in your Order Events WebSocket subscription.

Visibility

Your client order ids are only visible to the Gemini exchange and you. They are never visible on any public API endpoints.

Uniqueness

Gemini recommends that your client order IDs should be unique per trading session.

Allowed characters

Your client order ids should match against this PCRE regular expression: [:\-_\.#a-zA-Z0-9]{1,100}.

Characters Description ASCII Codes (Dec)
A-Z Uppercase A-Z 65 - 90
a-z Lowercase a-z 97 - 122
0-9 Digits 48 - 57
# Hash, octothorpe, number sign 35
- Hyphen 45
. Period 46
: Colon 58
_ Underscore 95

Data Types

The protocol description below will contain references to various types, which are collected here for reference

Type Description
string A simple quoted string, following standard JSON rules; see the JSON spec for details.
decimal A decimal value, encoded in a JSON string. The contents will be a series of digits, followed by an optional decimal point and additional digits.
timestamp The number of seconds since 1970-01-01 UTC. This is usually provided for compatibility; implementors should use the more precise timestampms when available. When used as an input, either the millisecond or second precision is usable; this is unambiguous for dates past 1/29/1970
timestampms The number of milliseconds since 1970-01-01 UTC. The begin date is the standard UNIX epoch, so this will be 1000 times the UNIX timestamp in seconds. This will be transmitted as a JSON number, not a string.
integer An whole number, transmitted as a JSON number.
boolean A JSON boolean, the literal string true or false
array a JSON array. Each element contains a payload that will be described.

Timestamps

The timestamp data type describes a date and time as a whole number in Unix Time format, as the number of seconds or milliseconds since 1970-01-01 UTC.

Requests

When timestamp is supplied as a request parameter, the following two values are supported in order of preference:

  1. The number of milliseconds since 1970-01-01 UTC
  2. The number of seconds since 1970-01-01 UTC (unix epoch)

For your convenience, a POST request may supply the timestamp parameter in a JSON payload as a string instead of a number.

Timestamp format example Supported request type
whole number (seconds) 1495127793 GET, POST
string (seconds) "1495127793" POST only
whole number (milliseconds) 1495127793000 GET, POST
string (milliseconds) "1495127793000" POST only

Behavior

If the timestamp parameter is not present, the default behavior is to return the most recent items in the list. For example, the public Trade History endpoint will return the most recent trades without a timestamp parameter.

The first trade on Gemini occurred at 1444311607801 milliseconds. Any request for a timestamp value before this is the same as requesting the very first item in the list.

You may choose to supply a timestamp of 0 to get the first trade in the list when retrieving trades historically.

If unable to parse your timestamp value, the exchange will return an InvalidTimestampInPayload error.

Responses

In a JSON response, the key

For backwards compatibility, some but not all timestamp values will be supplied in seconds.

Symbols and minimums

Symbols are formatted as CCY1CCY2 where prices are in CCY2 and quantities are in CCY1, as this table makes explicit:

Symbol Price currency Quantity currency Minimum order size Minimum order increment Minimum price increment
btcusd USD BTC 0.00001 BTC (1e-5) 0.00000001 BTC (1e-8) 0.01 USD
ethusd USD ETH 0.001 ETH (1e-3) 0.000001 ETH (1e-6) 0.01 USD
ethbtc BTC ETH 0.001 ETH (1e-3) 0.000001 ETH (1e-6) 0.00001 BTC (1e-5)

Precision on the exchange

Quantity and price on incoming orders are strictly held to the minimums and increments on the table shown above.

However, once on the exchange, quantities and notional values may exhibit additional precision down to two decimal places past the "minimum order increment" listed above. For instance, it is possible that a btcusd trade could execute for a quantity of 0.0000000001 (1e-10) BTC. This is due to:

This additional precision is marketable once on the exchange.

Your account balances are maintained to full fractional precision in each currency.

Public APIs

Symbols

import urllib2
base_url = "https://api.gemini.com/v1"
# or, for sandbox
# base_url = "https://api.sandbox.gemini.com/v1"
response = urllib2.urlopen(base_url + "/symbols")
print(response.read())
$ curl "https://api.gemini.com/v1/symbols"
[ "btcusd", "ethusd", "ethbtc" ]

This endpoint retrieves all available symbols for trading

HTTP Request

GET https://api.gemini.com/v1/symbols

URL Parameters

None

Response

An array of supported symbols

Ticker

import urllib2
base_url = "https://api.gemini.com/v1"
# or, for sandbox
# base_url = "https://api.sandbox.gemini.com/v1"
response = urllib2.urlopen(base_url + "/pubticker/btcusd")
print(response.read())
$ curl "https://api.gemini.com/v1/pubticker/btcusd"
{
    "ask": "977.59",
    "bid": "977.35",
    "last": "977.65",
    "volume": {
        "BTC": "2210.505328803",
        "USD": "2135477.463379586263",
        "timestamp": 1483018200000
    }
}

This endpoint retrieves information about recent trading activity for the symbol.

HTTP Request

GET https://api.gemini.com/v1/pubticker/:symbol

URL Parameters

None

Response

The response will be an object

Field Type Description
bid decimal The highest bid currently available
asks decimal The lowest ask currently available
last decimal The price of the last executed trade
volume Information about the 24 hour volume on the exchange. See below

The volume field will contain information about the 24 hour volume on the exchange. The volume is updated every five minutes based on a trailing 24-hour window of volume. It will have three fields

Field Type Description
timestamp timestampms The end of the 24-hour period over which volume was measured
(price symbol, e.g. "USD") decimal The volume denominated in the price currency
(quantity symbol, e.g. "BTC") decimal The volume denominated in the quantity currency

Current Order Book

curl "https://api.gemini.com/v1/book/btcusd"
import urllib2
base_url = "https://api.gemini.com/v1"
# or, for sandbox
# base_url = "https://api.sandbox.gemini.com/v1"
response = urllib2.urlopen(base_url + "/book/btcusd")
print(response.read())

The above command returns JSON structured like this:


{
  "bids": [ /* bids look like asks */ ],
  "asks": [
    {
      "price": "822.12",  // Note these are sent as strings
      "amount": "12.1"  // Ditto
    },
    ...
  ]
}

This will return the current order book, as two arrays, one of bids, and one of asks

HTTP Request

GET https://api.gemini.com/v1/book/:symbol

URL Parameters

If a limit is specified on a side, then the orders closest to the midpoint of the book will be the ones returned.

Parameter Type Description
limit_bids integer Optional. Limit the number of bids (offers to buy) returned. Default is 50. May be 0 to return the full order book on this side.
limit_asks integer Optional. Limit the number of asks (offers to sell) returned. Default is 50. May be 0 to return the full order book on this side.

Response

The response will be two arrays

Field Type Description
bids array The bids currently on the book. These are offers to buy at a given price
asks array The asks currently on the book. These are offers to sell at a given price

The bids and the asks are grouped by price, so each entry may represent multiple orders at that price. Each element of the array will be a JSON object

Field Type Description
price decimal The price
amount decimal The total quantity remaining at the price
timestamp timestamp DO NOT USE - this field is included for compatibility reasons only and is just populated with a dummy value.

Trade History

curl "https://api.gemini.com/v1/trades/btcusd?since=$(date -d 2014-01-01 +%s)"
import urllib2
import datetime
date = datetime.date(2015,1,1).strftime("%s")
base_url = "https://api.gemini.com/v1"
# or, for sandbox
# base_url = "https://api.sandbox.gemini.com/v1"
response = urllib2.urlopen(base_url + "/trades/btcusd?since=%s" % date)
print(response.read())

The above command returns JSON structured like this:

[
  {
    "timestamp": 1420088400,
    "timestampms": 1420088400122,
    "tid": 155814,
    "price": "822.12",
    "amount": "12.10",
    "exchange": "gemini",
    "type": "buy"
  },
  ...
]

This will return the trades that have executed since the specified timestamp. Timestamps are either seconds or milliseconds since the epoch (1970-01-01). See the Data Types section about timestamp for information on this.

Each request will show at most 500 records.

If no since or timestamp is specified, then it will show the most recent trades; otherwise, it will show the most recent trades that occurred after that timestamp.

HTTP Request

GET https://api.gemini.com/v1/trades/:symbol

URL Parameters

Parameter Type Description
timestamp timestamp Optional. Only return trades after this timestamp. See Data Types: Timestamps for more information. If not present, will show the most recent trades. For backwards compatibility, you may also use the alias 'since'.
limit_trades integer Optional. The maximum number of trades to return. The default is 50.
include_breaks boolean Optional. Whether to display broken trades. False by default. Can be '1' or 'true' to activate

Response

The response will be an array of JSON objects, sorted by timestamp, with the newest trade shown first.

Field Type Description
timestamp timestamp The time that the trade was executed
timestampms timestampms The time that the trade was executed in milliseconds
tid integer The trade ID number
price decimal The price the trade was executed at
amount decimal The amount that was traded
exchange string Will always be "gemini"
type string
  • buy means that an ask was removed from the book by an incoming buy order
  • sell means that a bid was removed from the book by an incoming sell order
  • auction indicates a bulk trade from an auction
broken boolean Whether the trade was broken or not. Broken trades will not be displayed by default; use the include_breaks to display them.

Current auction

import urllib2
base_url = "https://api.gemini.com/v1"
# or, for sandbox
# base_url = "https://api.sandbox.gemini.com/v1"
response = urllib2.urlopen(base_url + "/auction/btcusd")
print(response.read())
$ curl "https://api.gemini.com/v1/auction/btcusd"

Before an auction opens

{
    "closed_until_ms": 1474567602895,
    "last_auction_price": "629.92",
    "last_auction_quantity": "430.12917506",
    "last_highest_bid_price": "630.10",
    "last_lowest_ask_price": "632.44",
    "next_auction_ms": 1474567782895
}

After an auction opens

{
    "last_auction_eid": 109929,
    "last_auction_price": "629.92",
    "last_auction_quantity": "430.12917506",
    "last_highest_bid_price": "630.10",
    "last_lowest_ask_price": "632.44",
    "next_auction_ms": 1474567782895,
    "next_update_ms": 1474567662895
}

After an indicative price has been published

{
    "last_auction_eid": 110085,
    "most_recent_indicative_price": "632.33",
    "most_recent_indicative_quantity": "151.93847124",
    "most_recent_highest_bid_price": "633.26",
    "most_recent_lowest_ask_price": "633.83",
    "next_auction_ms": 1474567782895,
    "next_update_ms": 1474567722895
}

After the last indicative price has been published

{
    "last_auction_eid": 110239,
    "most_recent_indicative_price": "632.305",
    "most_recent_indicative_quantity": "151.93847124",
    "most_recent_highest_bid_price": "633.24",
    "most_recent_lowest_ask_price": "633.54",
    "next_auction_ms": 1474567782895,
    "next_update_ms": 1474567782895
}

After the auction runs

{
    "closed_until_ms": 1474567828771,
    "last_auction_price": "632.375",
    "last_auction_quantity": "243.21166049",
    "last_highest_bid_price": "633.13",
    "last_lowest_ask_price": "633.54",
    "next_auction_ms": 1474568008771
}

HTTP Request

GET https://api.gemini.com/v1/auction/:symbol

URL Parameters

None

Response

Response in an object with the following fields:

Field Type Description
closed_until_ms timestampms If the auction is not currently open, show the time at which the next auction opens. Not present if the auction has already opened.
last_auction_eid integer After an auction opens, the unique event ID for last specific auction event. Changes when an auction event occurs: the auction opens, an indicative price is published, and the auction itself runs. Not present before the auction opens.
last_auction_price decimal If available, show the auction price from the last successful auction for this trading pair. Not present after current auction begins publishing indicative prices.
last_auction_quantity decimal If available, show the auction quantity from the last successful auction for this trading pair. Not present after current auction begins publishing indicative prices.
last_highest_bid_price decimal If available, show the highest bid price from the continuous trading order book at the time of the last successful auction for this trading pair. Not present after current auction begins publishing indicative prices.
last_lowest_ask_price decimal If available, show the lowest ask price from the continuous trading order book at the time of the last successful auction for this trading pair. Not present after current auction begins publishing indicative prices.
most_recent_indicative_price decimal The most recently published indicative price for the auction. Not present before the current auction begins publishing indicatives.
most_recent_indicative_quantity decimal The most recently published indicative quantity for the auction. Not present before the current auction begins publishing indicatives.
most_recent_highest_bid_price decimal The most recent highest bid at the time of the indicative price for the auction. Not present before the current auction begins publishing indicatives.
most_recent_lowest_ask_price decimal The most recent lowest ask at the time of the indicative price for the auction. Not present before the current auction begins publishing indicatives.
next_update_ms timestampms Timestamp of the next event in this auction, either the publication of an indicative price/quantity or the auction itself.
next_auction_ms timestampms Timestamp of when the next auction will run.

Auction history

curl "https://api.gemini.com/v1/auction/btcusd?since=$(date -d 2016-08-22 +%s)"
import urllib2
import datetime
date = datetime.date(2015,1,1).strftime("%s")
base_url = "https://api.gemini.com/v1"
# or, for sandbox
# base_url = "https://api.sandbox.gemini.com/v1"
response = urllib2.urlopen(base_url + "/trades/auction?since=%s" % date)
print(response.read())

The above command returns JSON structured like this:

[
    {
        "auction_id": 3,
        "auction_price": "628.775",
        "auction_quantity": "66.32225622",
        "eid": 4066,
        "highest_bid_price": "628.82",
        "lowest_ask_price": "629.48",
        "auction_result": "success",
        "timestamp": 1471902531,
        "timestampms": 1471902531225,
        "event_type": "auction"
    },
    {
        "auction_id": 3,
        "auction_price": "628.865",
        "auction_quantity": "89.22776435",
        "eid": 3920,
        "highest_bid_price": "629.59",
        "lowest_ask_price": "629.77",
        "auction_result": "success",
        "timestamp": 1471902471,
        "timestampms": 1471902471225,
        "event_type": "indicative"
    },
  ...
]

This will return the auction events, optionally including publications of indicative prices, since the specific timestamp.

Timestamps are either seconds or milliseconds since the epoch (1970-01-01). See the Data Types section about timestamp for information on this.

Each request will show at most 500 records.

If no since or timestamp is specified, then it will show the most recent events. Otherwise, it will show the oldest auctions that occurred after that timestamp.

HTTP Request

GET https://api.gemini.com/v1/auction/:symbol/history

URL Parameters

Parameter Type Description
since timestamp Optional. Only returns auction events after the specified timestamp. If not present or empty, will show the most recent auction events. You can also use the alias 'timestamp'.
limit_auction_results integer Optional. The maximum number of auction events to return. The default is 50.
include_indicative boolean Optional. Whether to include publication of indicative prices and quantities. True by default, true to explicitly enable, and false to disable.

Response

The response will be an array of JSON objects, sorted by timestamp, with the newest event shown first.

Field Type Description
timestamp timestamp The time that the auction event ran
timestampms timestampms The time that the auction event ran in milliseconds
auction_id integer The auction ID number
eid integer Unique event ID for this specific auction event.
event_type string indicative for the publication of an indicative price or auction for the auction result
auction_result string success or failure, indicating whether the auction has found a price.
auction_price decimal If auction_result is success, the price at which orders were filled. Zero if result is failure.
auction_quantity decimal If auction_result is success, the quantity that was filled. Zero if result is failure.
highest_bid_price decimal Highest bid price from the continuous trading order book at the time of the auction event, if available.
lowest_ask_price decimal Lowest ask price from the continuous trading order book at the time of the auction event, if available.

Order Placement APIs

New Order

Only limit orders are supported through the API at present.

If you wish orders to be automatically cancelled when your session ends, see the require heartbeat section, or manually send the cancel all session orders message.

// As before, the comments here are for documentation only; you may not put
// any comments in the submitted JSON as per the JSON spec
{
    // Standard headers`
    "request": "/v1/order/new",
    "nonce": <nonce>,

    // Request-specific items
    "client_order_id": "20150102-4738721", // A client-specified order token
    "symbol": "btcusd",       // Or any symbol from the /symbols api
    "amount": "34.12",        // Once again, a quoted number
    "price": "622.13",
    "side": "buy",            // must be "buy" or "sell"
    "type": "exchange limit",  // the order type; only "exchange limit" supported
    "options": ["maker-or-cancel"] // execution options; may be omitted for a standard limit order
}

On success, this will return a JSON response that looks like


{
    // These are the same fields returned by order/status
    "order_id": "22333",
    "client_order_id": "20150102-4738721",
    "symbol": "btcusd",
    "price": "34.23",
    "avg_execution_price": "34.24",
    "side": "buy",
    "type": "exchange limit",
    "timestamp": "128938491",
    "timestampms": 128938491234,
    "is_live": true,
    "is_cancelled": false,
    "options": ["maker-or-cancel"], 
    "executed_amount": "12.11",
    "remaining_amount": "16.22",
    "original_amount": "28.33"
}

Roles

The API key you use to access this endpoint must have the Trader role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/order/new

Parameters

Parameter Type Description
request string The literal string "/v1/order/new"
nonce integer The nonce, as described in Private API Invocation
client_order_id string Recommended. A client-specified order id
symbol string The symbol for the new order
amount string Quoted decimal amount to purchase
price string Quoted decimal amount to spend per unit
side string "buy" or "sell"
type string The order type. Only "exchange limit" supported through this API
options array Optional. An optional array containing at most one supported order execution option. See Order execution options for details.

What about market orders?

The API doesn't directly support market orders because they provide you with no price protection.

Instead, use the “immediate-or-cancel” order execution option, coupled with an aggressive limit price (i.e. very high for a buy order or very low for a sell order), to achieve the same result.

Order execution options

Note that options is an array. If you omit options or provide an empty array, your order will be a standard limit order - it will immediately fill against any open orders at an equal or better price, then the remainder of the order will be posted to the order book.

If you specify more than one option (or an unsupported option) in the options array, the exchange will reject your order.

The available limit order options are:

Option Description
"maker-or-cancel" This order will only add liquidity to the order book.

If any part of the order could be filled immediately, the whole order will instead be canceled before any execution occurs.

If that happens, the response back from the API will indicate that the order has already been canceled ("is_cancelled": true in JSON).

Note: some other exchanges call this option "post-only".
"immediate-or-cancel" This order will only remove liquidity from the order book.

It will fill whatever part of the order it can immediately, then cancel any remaining amount so that no part of the order is added to the order book.

If the order doesn't fully fill immediately, the response back from the API will indicate that the order has already been canceled ("is_cancelled": true in JSON).
"auction-only" This order will be added to the auction-only book for the next auction for this symbol.



The order may be cancelled up until the the auction locks, after which cancel requests will be rejected.

Result

Result will be the fields included in Order Status

Cancel Order

This will cancel an order. If the order is already canceled, the message will succeed but have no effect.


{
    // Standard headers
    "request": "/v1/order/order/cancel",
    "nonce": <nonce>,

    // Request-specific items
    "order_id": 12345
}

Roles

The API key you use to access this endpoint must have the Trader role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/order/cancel

Parameters

Parameter Type Description
request string The literal string "/v1/order/cancel"
nonce integer The nonce, as described in Private API Invocation
order_id integer The order ID given by /order/new.

Response

Result of /order/status for the canceled order. If the order was already canceled, then the request will have no effect and the status will be returned.

Cancel All Session Orders

This will cancel all orders opened by this session.

This will have the same effect as heartbeat expiration if "Require Heartbeat" is selected for the session.

Roles

The API key you use to access this endpoint must have the Trader role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/order/cancel/session

Parameters

Parameter Type Description
request string The literal string "/v1/order/cancel/session"
nonce integer The nonce, as described in Private API Invocation

Response

The response will be a JSON object with the single field "result" with value "true"

Field Type Description
result boolean will always be true if the response is 200 OK

Cancel All Active Orders

This will cancel all outstanding orders created by all sessions owned by this account, including interactive orders placed through the UI.

Typically Cancel All Session Orders is preferable, so that only orders related to the current connected session are cancelled.

Roles

The API key you use to access this endpoint must have the Trader role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/order/cancel/all

Parameters

Parameter Type Description
request string The literal string "/v1/order/cancel/all"
nonce integer The nonce, as described in Private API Invocation

Response

The response will be a JSON object with the single field "result" with value "true"

Field Type Description
result boolean will always be true if the response is 200 OK

Order Status APIs

Order Status

Gets the status for an order


{
    // Standard headers
    "request": "/v1/order/status",
    "nonce": 123,  // a number representing your nonce

    // Request-specific items
    "order_id": 1234  // The order id from the response to the order/new request
}

On success, this will return a JSON response that looks like

{
  "order_id" : "44375901",
  "id" : "44375901",
  "symbol" : "btcusd",
  "exchange" : "gemini",
  "avg_execution_price" : "400.00",
  "side" : "buy",
  "type" : "exchange limit",
  "timestamp" : "1494870642",
  "timestampms" : 1494870642156,
  "is_live" : false,
  "is_cancelled" : false,
  "is_hidden" : false,
  "was_forced" : false,
  "executed_amount" : "3",
  "remaining_amount" : "0",
  "options" : [ ],
  "price" : "400.00",
  "original_amount" : "3"
}

Roles

The API key you use to access this endpoint must have the Trader role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/order/status

Parameters

Parameter Type Description
request string The literal string "/v1/order/status"
nonce integer The nonce, as described in Private API Invocation
order_id integer The order id to get information on

Response

Field Type Description
order_id string The order id
client_order_id string An optional client-specified order id
symbol string The symbol of the order
exchange string Will always be "gemini"
price decimal The price the order was issued at
avg_execution_price decimal The average price at which this order as been executed so far. 0 if the order has not been executed at all.
side string Either "buy" or "sell".
type string Description of the order:
  • exchange limit
  • auction-only exchange limit
  • market buy
  • auction-only market buy
  • market sell
  • auction-only market sell
options string An array containing at most one supported order execution option. See Order execution options for details.
timestamp timestamp The timestamp the order was submitted. Note that for compatibility reasons, this is returned as a string. See the Difference From Bitfinex section below. We recommend using the timestampms field instead.
timestampms timestampms The timestamp the order was submitted in milliseconds.
is_live boolean true if the order is active on the book (has remaining quantity and has not been canceled)
is_cancelled boolean true if the order has been canceled. Note the spelling, "cancelled" instead of "canceled". This is for compatibility reasons.
was_forced boolean Will always be false.
executed_amount decimal The amount of the order that has been filled.
remaining_amount decimal The amount of the order that has not been filled.
original_amount decimal The originally submitted amount of the order.

Get Active Orders

[ {
  "order_id" : "44375938",
  "id" : "44375938",
  "symbol" : "ethusd",
  "exchange" : "gemini",
  "avg_execution_price" : "0.00",
  "side" : "buy",
  "type" : "exchange limit",
  "timestamp" : "1494871426",
  "timestampms" : 1494871426935,
  "is_live" : true,
  "is_cancelled" : false,
  "is_hidden" : false,
  "was_forced" : false,
  "executed_amount" : "0",
  "remaining_amount" : "500",
  "options" : [ "maker-or-cancel" ],
  "price" : "30.50",
  "original_amount" : "500"
}, {
  "order_id" : "44375906",
  "id" : "44375906",
  "symbol" : "ethusd",
  "exchange" : "gemini",
  "avg_execution_price" : "31.72",
  "side" : "sell",
  "type" : "exchange limit",
  "timestamp" : "1494871242",
  "timestampms" : 1494871242386,
  "is_live" : true,
  "is_cancelled" : false,
  "is_hidden" : false,
  "was_forced" : false,
  "executed_amount" : "3.152585",
  "remaining_amount" : "3.422815",
  "options" : [ "maker-or-cancel" ],
  "price" : "30.12",
  "original_amount" : "6.5754"
} ]

Roles

The API key you use to access this endpoint must have the Trader role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/orders

Parameters

This takes no parameters other than the general ones

Parameter Type Description
request string The literal string "/v1/orders"
nonce integer The nonce, as described in Private API Invocation

Reponse

An array of the results of /order/status for all your live orders.

Get Past Trades

[ {
  "price" : "30.00",
  "amount" : "1000",
  "timestamp" : 1494871386,
  "timestampms" : 1494871386089,
  "type" : "Sell",
  "aggressor" : true,
  "fee_currency" : "USD",
  "fee_amount" : "75.00",
  "tid" : 44375933,
  "order_id" : "44375931",
  "exchange" : "gemini",
  "is_auction_fill" : false
}, {
  "price" : "31.72",
  "amount" : "3.152585",
  "timestamp" : 1494871242,
  "timestampms" : 1494871242391,
  "type" : "Sell",
  "aggressor" : true,
  "fee_currency" : "USD",
  "fee_amount" : "0.2499999905",
  "tid" : 44375908,
  "order_id" : "44375906",
  "exchange" : "gemini",
  "is_auction_fill" : false
} ]

Roles

The API key you use to access this endpoint must have the Trader role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/mytrades

Parameters

Parameter Type Description
request string The literal string "/v1/mytrades"
nonce integer The nonce, as described in Private API Invocation
symbol string The symbol to retrieve trades for
limit_trades integer Optional. The maximum number of trades to return. Default is 50, max is 500.
timestamp timestamp Optional. Only return trades on or after this timestamp. See Data Types: Timestamps for more information. If not present, will show the most recent orders.

Reponse

The response will be an array of trade information items.

Field Type Description
price decimal The price that the execution happened at
amount decimal The quantity that was executed
timestamp timestamp The time that the trade happened in epoch seconds
timestampms timestampms The time that the trade happened in milliseconds
type string Will be either "Buy" or "Sell", indicating the side of the original order
aggressor boolean If true, this order was the taker in the trade
fee_currency string Currency that the fee was paid in
fee_amount decimal The amount charged
tid integer Unique identifier for the trade
order_id string The order that this trade executed against
client_order_id string The optional client-specified order id that this trade is associated with
is_auction_fill boolean True if the trade was filled at an auction
break string Optional Will only be present if the trade is broken. See Break Types below for more information.

How to retrieve your trade history

To retrieve your full trade history walking backwards,

  1. Initial request: POST to https://api.gemini.com/v1/mytrades with a JSON payload including a timestamp key with value 0 and a limit_trades key with value 500
  2. When you receive the list of trades, it will be sorted by timestamp descending - so the first element in the list will have the highest timestamp value. For this example, say that value is X.
  3. Create a second POST request with a JSON payload including a timestamp key with value X+1 and a limit_trades key with value 500.
  4. Take the first element of the list returned with highest timestamp value Y and create a third POST request with a JSON payload including a timestamp key with value Y+1 and a limit_trades key with value 500.
  5. Continue creating POST requests and retrieving trades until an empty list is returned.

Break Types

In the rare event that a trade has been reversed (broken), the trade that is broken will have this flag set. The field will contain one of these values

Value Description
manual The trade was reversed manually. This means that all fees, proceeds, and debits associated with the trade have been credited or debited to the account seperately. That means that this reported trade must be included for order for the account balance to be correct.
full The trade was fully broken. The reported trade should not be accounted for. It will be as though the transfer of fund associated with the trade had simply not happened.

Get Trade Volume

Roles

The API key you use to access this endpoint must have the Trader role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/tradevolume

Parameters

Parameter Type Description
request string The literal string "/v1/tradevolume"
nonce integer The nonce, as described in Private API Invocation

Reponse

The response will be an array of up to 30 days of trade volume for each symbol.

Field Type Description
account_id string client account id
symbol string The symbol
base_currency decimal quantity is denominated in this currency
notional_currency decimal price is denominated as the amount of notional currency per one unit of base currency. Notional values are denominated in this currency
data_date string UTC date in yyyy-MM-dd format
total_volume_base decimal Total trade volume for this day
maker_buy_sell_ratio decimal Maker buy/sell ratio is the proportion of maker base volume on trades where the account was on the buy side versus all maker trades. If there is no maker base volume on the buy side, then this value is 0.
buy_maker_base decimal Quantity for this day where the account was a maker on the buy side of the trade.
buy_maker_notional decimal Notional value for this day where the account was a maker on the buy side of the trade.
buy_maker_count decimal Number of trades for this day where the account was a maker on the buy side of the trade.
sell_maker_base decimal Quantity for this day where the account was a maker on the sell side of the trade.
sell_maker_notional decimal Notional value for this day where the account was a maker on the sell side of the trade.
sell_maker_count decimal Number of trades for this day where the account was a maker on the sell side of the trade.
buy_taker_base decimal Quantity for this day where the account was a taker on the buy side of the trade.
buy_taker_notional decimal Notional value for this day where the account was a taker on the buy side of the trade.
buy_taker_count decimal Number of trades for this day where the account was a taker on the buy side of the trade.
sell_taker_base decimal Quantity for this day where the account was a taker on the sell side of the trade.
sell_taker_notional decimal Notional value for this day where the account was a taker on the sell side of the trade.
sell_taker_count decimal Number of trades for this day where the account was a taker on the sell side of the trade.

Fund Management APIs

Get Available Balances

This will show the available balances in the supported currencies

Roles

The API key you use to access this endpoint must have the Trader or Fund Manager role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/balances

Parameters

No fields are expected in the request, other than the request name and the nonce

Parameter Type Description
request string The literal string "/v1/balances"
nonce integer The nonce, as described in Private API Invocation

Response

An array of elements, with one block per currency

Field Type Description
currency string Currency code, see symbols
amount decimal The current balance
available decimal The amount that is available to trade
availableForWithdrawal decimal The amount that is available to withdraw

New Deposit Address

Sample payload

{
  "request" : "/v1/deposit/btc/newAddress",
  "nonce" : "12345",
  "label" : "optional test label"
}

New BTC deposit address

{
  "currency" : "BTC",
  "address" : "n2saq73aDTu42bRgEHd8gd4to1gCzHxrdj",
  "label" : "optional test label"
}

New ETH deposit address

{
  "currency" : "ETH",
  "address" : "0xA63123350Acc8F5ee1b1fBd1A6717135e82dBd28",
  "label" : "optional test label"
}

This will create a new cryptocurrency deposit address with an optional label.

Roles

The API key you use to access this endpoint must have the Fund Manager role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/deposit/:currency/newAddress

where :currency is a supported cryptocurrency, e.g. btc or eth.

Parameters

Parameter Type Description
request string The string /v1/deposit/:currency/newAddress where :currency is replaced with the three-letter currency code of a supported crypto-currency, e.g. btc or eth. See Symbols and minimums.
nonce integer The nonce, as described in Private API Invocation
label string Optional label for the deposit address

Response

An object with the following fields:

Field Type Description
currency string Currency code, see symbols
address string String representation of the new cryptocurrency address.
label string Optional: if you provided a label when requesting the address, it will be echoed back here.

Withdraw Crypto Funds To Whitelisted Address

Sample payload for BTC withdrawal

{  
   "request":"/v1/withdraw/btc",
   "nonce":"12345",
   "address":"mi98Z9brJ3TgaKsmvXatuRahbFRUFKRUdR",
   "amount":"1"
}

Sample successful BTC withdrawal response

{  
   "destination":"mi98Z9brJ3TgaKsmvXatuRahbFRUFKRUdR",
   "amount":"1",
   "txHash":"6ca7340d4dd0af1892f11d88d2b40d4846332d36b91ef60bbb844904de250941"
}

Sample payload for ETH withdrawal

{  
   "request":"/v1/withdraw/eth",
   "nonce":"12345",
   "address":"0xA63123350Acc8F5ee1b1fBd1A6717135e82dBd28",
   "amount":"2.34567"
}

Sample successful ETH withdrawal response

{  
   "address":"0xA63123350Acc8F5ee1b1fBd1A6717135e82dBd28",
   "amount":"2.34567",
   "txHash":"123abc1234"
}

Error when account does not have whitelists enabled

{  
   "result":"error",
   "reason":"CryptoAddressWhitelistsNotEnabled",
   "message":"Cryptocurrency withdrawal address whitelists are not enabled for account 24.  Please contact support@gemini.com for information on setting up a withdrawal address whitelist."
}

Error when account has whitelists enabled but this specific address is not whitelisted

{  
   "result":"error",
   "reason":"CryptoAddressNotWhitelisted",
   "message":"'moXiuoPh6oe2edoFQvxbyxQZgiYkNzjXZ9' is not a whitelisted BTC address.  Please contact support@gemini.com for information on adding addresses to your withdrawal whitelist."
}

Before you can withdraw cryptocurrency funds to a whitelisted address, you need three things:

  1. cryptocurrency address whitelists needs to be enabled for your account
  2. the address you want to withdraw funds to needs to already be on that whitelist
  3. an API key with the Fund Manager role added

Contact institutional@gemini.com for information on setting up whitelists and adding addresses. See Roles for more information on how to add the Fund Manager role to the API key you want to use.

Roles

The API key you use to access this endpoint must have the Fund Manager role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/withdraw/:currency

where :currency is a supported cryptocurrency, e.g. btc or eth.

Parameters

Parameter Type Description
request string The string /v1/withdraw/:currency where :currency is replaced with the three-letter currency code of a supported crypto-currency, e.g. btc or eth. See Symbols and minimums.
nonce integer The nonce, as described in Private API Invocation
address string Standard string format of a whitelisted cryptocurrency address.
amount string Quoted decimal amount to withdraw

Response

An object with the following fields:

Field Type Description
destination string Standard string format of the withdrawal destination address
amount string The withdrawal amount
txHash string Standard string format of the transaction hash of the withdrawal transaction

Session APIs

Heartbeat

This will prevent a session from timing out and canceling orders if the require heartbeat flag has been set. Note that this is only required if no other private API requests have been made. The arrival of any message resets the heartbeat timer.

HTTP Request

POST https://api.gemini.com/v1/heartbeat

Parameters

No fields are expected in this request other than the request name and the nonce

Parameter Type Description
request string The literal string "/v1/heartbeat"
nonce integer The nonce, as described in Private API Invocation

Response

The response will be a JSON object with a single field "result" with value "true"

Field Type Description
result boolean will always be true if the response is 200 OK

Error Codes

If a response is in error, then the HTTP response code will be set to reflect this, and a JSON body will be returned that will contain information about the failure.

HTTP Error Codes

HTTP Status Meaning
200 Request was successful
30x API entry point has moved, see Location: header. Most likely an http: to https: redirect.
400 The request was malformed; in the case of a private API request, missing or malformed Gemini private API authentication headers
403 The API key is missing the role necessary to access this private API endpoint
404 Unknown API entry point
429 Rate Limiting was applied
500 The server encountered an error
502 Technical issues are preventing the request from being satisfied
503 The exchange is down for maintenance

Error payload


{
    "result": "error",
    "reason": "BadNonce",
    "message": "Out-of-sequence nonce <1234> precedes previously used nonce <2345>"
}

In the event of an error, a non-200 error code will be returned, and the response body will be a json object with three fields:

  1. result, which will always be "error"
  2. reason, which will be one of the strings listed in the table below
  3. message, a human-readable English string indicating additional error information.
Reason Meaning
AuctionNotOpen Failed to place an auction-only order because there is no current auction open for this symbol
ClientOrderIdTooLong The Client Order ID must be under 100 characters
ClientOrderIdMustBeString The Client Order ID must be a string
ConflictingOptions New orders using a combination of order execution options are not supported
EndpointMismatch The request was submitted to an endpoint different than the one in the payload
EndpointNotFound No endpoint was specified
IneligibleTiming Failed to place an auction order for the current auction on this symbol because the timing is not eligible: new orders may only be placed before the auction begins.
InsufficientFunds The order was rejected because of insufficient funds
InvalidJson The JSON provided is invalid
InvalidNonce The nonce was not greater than the previously used nonce, or was not present
InvalidOrderType An unknown order type was provided
InvalidPrice For new orders, the price was invalid
InvalidQuantity A negative or otherwise invalid quantity was specified
InvalidSide For new orders, and invalid side was specified
InvalidSignature The signature did not match the expected signature
InvalidSymbol An invalid symbol was specified
InvalidTimestampInPayload The JSON payload contained a timestamp parameter with an unsupported value.
Maintenance The system is down for maintenance
MarketNotOpen The order was rejected because the market is not accepting new orders
MissingApikeyHeader The X-GEMINI-APIKEY header was missing
MissingOrderField A required order_id field was not specified
MissingRole The API key used to access this endpoint does not have the required role assigned to it
MissingPayloadHeader The X-GEMINI-PAYLOAD header was missing
MissingSignatureHeader The X-GEMINI-SIGNATURE header was missing
NoSSL You must use HTTPS to access the API
OptionsMustBeArray The options parameter must be an array.
OrderNotFound The order specified was not found
RateLimit Requests were made too frequently. See Rate Limits below.
System We are experiencing technical issues
UnsupportedOption This order execution option is not supported.

Difference from Bitfinex

In order to make it easy for existing market participants to use Gemini, we have attempted to be compatible with Bitfinex.com where possible. Differences are highlighted below. If you encounter other compatibility-breaking differences, please contact us at institutional@gemini.com.

Stats API

This has been removed.

Authentication

The headers have been renamed to X-GEMINI-APIKEY, X-GEMINI-PAYLOAD, and X-GEMINI-SIGNATURE

Lends and Margin Trading

The APIs relating to offers, lends, and margin orders have been removed.

Order Types

The only order type supported through the order/new API are limit orders.

Hidden Orders

Auction-only orders are the only type of undisplayed liquidity.

Replace Order Removed

There is no "Replace Order" API. Instead, cancel and place a new order. There is no way to maintain time priority across an operation like this.

Sessions and Require Heartbeats

These are features specific to Gemini. See sessions for more information.

Timestamp

We recommend that you use the timestampms field if you are implementing against our API. The timestamp field is included for compatibility with Bitfinex, but the behavior is inconsistent; sometimes it's an integer, sometimes it has a decimal point, and other times it is returned as a string.

Revision History

Date Notes
2015/10/05 Initial REST API documentation
2015/12/22 Document sandbox usage
2016/04/27 Document marker-or-cancel and immediate-or-cancel order placement options.
2016/05/31 Add ETH to supported symbols
2016/08/23 New feature: auction documentation added to new order placement, public APIs, and streaming market data.
2016/12/14 New feature: API key roles, crypto deposit and withdrawal endpoints
2017/02/08 Better explanation of how Gemini rate limits public and private API requests; better client order id documentation
2017/02/22 Added recipe for retrieving full trade history from Get Past Trades endpoint
2017/03/30 Improved documentation for Get Past Trades and Get Available Balances
2017/05/02 Clarify how rate limits are applied.
2017/05/15 Better JSON examples for all the Order Status API endpoints
2017/05/19 API Change order status JSON changed to always include an options array with order execution options. If no order execution options were submitted with the original order, the array will be empty.

Affected endpoints:
2017/05/22 API Change bugfix to timestamp handing in POST requests. Previously a timestamp submitted as a string was silently ignored; timestamps submitted as strings will now be parsed. No timestamp request parameter will be silently discarded. Updated documentation at Data Types: Timestamps to reflect timestamp behavior in requests and responses.

Affected endpoints:
2017/05/31 Added explanation about using limit orders with the immediate-or-cancel execution option instead of market orders to New Order endpoint
2017/07/27

© Copyright 2017 Gemini Trust Company, LLC.