NAV
python shell

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 USD, BTC, ETH, ZEC, BCH, LTC, OXT, LINK, BAT and DAI. 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 trading@gemini.com.

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

Two Factor Authentication

Two factor authentication ("2FA") is enabled by default for all sandbox accounts. To disable 2FA for automated testing, please do the following:

  1. At the Authy 2FA entry screen, set a cookie or an HTTP header with the name GEMINI-SANDBOX-2FA. The value doesn’t matter.
  2. Enter 9999999 as your 2FA code

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

Payload creation

{
    "request": "/v1/order/status",
    "nonce": <nonce>,
    "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=
encoded_payload = json.dumps(payload)
b64 = base64.b64encode(encoded_payload)

In this example, the api_secret is 1234abcd

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

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 json
import base64
import hmac
import hashlib
import datetime, time

url = "https://api.gemini.com/v1/mytrades"
gemini_api_key = "mykey"
gemini_api_secret = "1234abcd".encode()

t = datetime.datetime.now()
payload_nonce =  str(int(time.mktime(t.timetuple())*1000))
payload =  {"request": "/v1/mytrades", "nonce": payload_nonce}
encoded_payload = json.dumps(payload).encode()
b64 = base64.b64encode(encoded_payload)
signature = hmac.new(gemini_api_secret, b64, hashlib.sha384).hexdigest()

request_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.post(url, headers=request_headers)

my_trades = response.json()
print(my_trades)

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, even 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))
Cache-Control no-cache

Master API

A group that contains multiple accounts can provision a Master API key. Master API keys offer the convenience of invoking any account API on behalf of an account within that group. To invoke an API on behalf of an account add that accounts nickname as an account parameter to your request payload.

Master API keys are formatted with a prepending master-, while account level API keys are formatted with a prepending account-.

The account parameter may be used on any API that performs an action for or against a single account.

Example of adding the account parameter to an API call, in this case New Order

{
    "request": "/v1/order/new",
    "account": "my-trading-account",
    "nonce": <nonce>,
    "client_order_id": <client_order_id>,
    "symbol": "btcusd",
    "amount": "5",
    "price": "3633.00",
    "side": "buy",
    "type": "exchange limit"
}

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 digital assets, or
  3. an API key to have access to read-only endpoints

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.

Administrator

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

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:

Auditor

Assigning the Auditor 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:

Account Scoped API

Endpoint URI Trader can access? Fund Manager can access? Auditor 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
Get Notional Volume /v1/notionalvolume
Heartbeat /v1/heartbeat
Get Available Balances /v1/balances
Get Notional Balances v1/notionalbalances/usd
Get Deposit Addresses /v1/addresses/:network
New Deposit Address /v1/deposit/:currency/newAddress
Transfers /v1/transfers
Withdraw Crypto Funds /v1/withdraw/:currency
New Clearing Order /v1/clearing/new
Clearing Order Status /v1/clearing/status 𧅳
Cancel Clearing Order /v1/clearing/cancel
Confirm Clearing Order /v1/clearing/confirm
Get Instant Quote /v1/instant/quote/:side/:symbol
Execute Instant Order /v1/instant/execute
Add A Bank /v1/payments/addbank
View Payment Methods /v1/payments/methods
Account Detail /v1/account
Create Approved Address /v1/approvedAddresses/:network/request
View Approved Address List /v1/approvedAddresses/account/:network
Remove Address from Approved Address List /v1/approvedAddresses/:network/remove

Master Scoped API

Endpoint URI Administrator can access? Trader can access? Fund Manager can access? Auditor can access?
Create Account /v1/account/create
Get Accounts /v1/account/list
Internal Transfer /v1/transfer/:currency

Roles API

HTTP Request

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

The v1/roles endpoint will return a string of the role of the current API key. The response fields will be different for account-level and master-level API keys.

Sample payload

{
    "nonce": <nonce>,
    "request": "/v1/roles"
}

Successful response for account-scoped key

{
    "counterparty_id": EMONNYXJ,
    "isAuditor": False,
    "isFundManager": True,
    "isTrader": True
}

Successful response for master-scoped key

{
    "isAuditor": False,
    "isFundManager": True,
    "isTrader": True,
    "isAccountAdmin": True
}

Parameters

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

Response

The response will be a JSON object indicating the assigned roles to the set of API keys used to call /v1/roles. The Auditor role cannot be combined with other roles. Fund Manager and Trader can be combined.

Field Type Description
counterparty_id string Only returned for master-level API keys. The Gemini clearing counterparty ID associated with the API key making the request.
isAuditor boolean True if the Auditor role is assigned to the API keys. False otherwise.
isFundManager boolean True if the Fund Manager role is assigned to the API keys. False otherwise.
isTrader boolean True if the Trader role is assigned to the API keys. False otherwise.
isAccountAdmin boolean Only returned for master-level API keys. True if the Administrator role is assigned to the API keys. False otherwise.

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 trading@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.

Basis Point

We calculate fees as a fraction of the notional value of each trade (i.e., price × amount). We use units of basis points (“bps”), which represent 1/100th of a percent of notional value. For example, a fee of 25 bps means that 0.25% of the denominated value of the trade will be kept by our exchange, either deducted from the gross proceeds of a trade or charged to the account at the time a trade is executed. Any fees will be applied at the time an order is placed. For partially filled orders, only the executed portion is subject to trading fees.

For more information see Fee Calculation.

Symbols and minimums

Symbols are formatted as CCY1CCY2 where prices are in CCY2 and quantities are in CCY1. CCY1 is in the Currency column and CCY2 is in the respective CCY2 Price Increment column:

Currency Minimum Order Size Tick Size USD Price Increment BTC Price Increment ETH Price Increment BCH Price Increment LTC Price Increment DAI Price Increment
BTC 0.00001 BTC (1e-5) 0.00000001 BTC (1e-8) 0.01 USD N/A 0.0001 ETH (1e-4) 0.0001 BCH (1e-4) 0.001 LTC (1e-3) 0.01 DAI
ETH 0.001 ETH (1e-3) 0.000001 ETH (1e-6) 0.01 USD 0.00001 BTC (1e-5) N/A 0.0001 BCH (1e-4) 0.001 LTC (1e-3) 0.01 DAI
ZEC 0.001 ZEC (1e-3) 0.000001 ZEC (1e-6) 0.01 USD 0.00001 BTC (1e-5) 0.0001 ETH (1e-4) 0.0001 BCH (1e-4) 0.001 LTC (1e-3) N/A
BCH 0.001 BCH (1e-3) 0.000001 BCH (1e-6) 0.01 USD 0.00001 BTC (1e-5) 0.0001 ETH (1e-4) N/A 0.001 LTC (1e-3) N/A
LTC 0.01 LTC (1e-2) 0.00001 LTC (1e-5) 0.01 USD 0.00001 BTC (1e-5) 0.0001 ETH (1e-4) 0.0001 BCH (1e-4) N/A N/A
BAT 1.0 BAT (1e0) 0.000001 BAT (1e-6) 0.00001 USD (1e-5) 0.00000001 BTC (1e-8) 0.0000001 ETH (1e-7) N/A N/A N/A
DAI 0.1 DAI (1e-1) 0.000001 DAI (1e-6) 0.00001 USD (1e-5) N/A N/A N/A N/A N/A
LINK 0.1 LINK (1e-1) 0.000001 LINK (1e-6) 0.00001 USD (1e-5) 0.00000001 BTC (1e-8) 0.0000001 ETH (1e-7) N/A N/A N/A
OXT 1.0 OXT (1e0) 0.000001 OXT (1e-6) 0.00001 USD (1e-5) 0.00000001 BTC (1e-8) 0.0000001 ETH (1e-7) N/A N/A N/A
AMP 10.0 AMP (1e1) 0.000001 AMP (1e-6) 0.00001 USD (1e-5) N/A N/A N/A N/A N/A
COMP 0.001 COMP (1e-3) 0.000001 COMP (1e-6) 0.01 USD N/A N/A N/A N/A N/A
PAXG 0.0001 PAXG (1e-4) 0.00000001 PAXG (1e-8) 0.01 USD N/A N/A N/A N/A N/A
MKR 0.001 MKR (1e-3) 0.000001 MKR (1e-6) 0.01 USD N/A N/A N/A N/A N/A
ZRX 0.1 ZRX (1e-1) 0.000001 ZRX (1e-6) 0.00001 USD (1e-5) N/A N/A N/A N/A N/A
KNC 0.1 KNC (1e-1) 0.000001 KNC (1e-6) 0.00001 USD (1e-5) N/A N/A N/A N/A N/A
MANA 1.0 MANA (1e0) 0.000001 MANA (1e-6) 0.00001 USD (1e-5) N/A N/A N/A N/A N/A
STORJ 0.1 STORJ (1e-1) 0.000001 STORJ (1e-6) 0.00001 USD (1e-5) N/A N/A N/A N/A N/A
SNX 0.01 SNX (1e-2) 0.000001 SNX (1e-6) 0.0001 USD (1e-4) N/A N/A N/A N/A N/A
CRV 0.1 CRV (1e-1) 0.000001 CRV (1e-6) 0.0001 USD (1e-4) N/A N/A N/A N/A N/A
BAL 0.01 BAL (1e-2) 0.000001 BAL (1e-6) 0.0001 USD (1e-4) N/A N/A N/A N/A N/A
UNI 0.01 UNI (1e-2) 0.000001 UNI (1e-6) 0.0001 USD (1e-4) N/A N/A N/A N/A N/A
REN 0.01 REN (1e-2) 0.000001 REN (1e-6) 0.00001 USD (1e-5) N/A N/A N/A N/A N/A
UMA 0.01 UMA (1e-2) 0.000001 UMA (1e-6) 0.0001 USD (1e-4) N/A N/A N/A N/A N/A
YFI 0.00001 YFI (1e-5) 0.00000001 YFI (1e-8) 0.01 USD N/A N/A N/A N/A N/A
AAVE 0.001 AAVE (1e-3) 0.000001 AAVE (1e-6) 0.0001 USD (1e-4) N/A N/A N/A N/A N/A
FIL 0.1 FIL (1e-1) 0.000001 FIL (1e-6) 0.0001 USD (1e-4) N/A N/A N/A N/A N/A

All Supported Symbols

btcusd ethbtc ethusd zecusd zecbtc zeceth zecbch zecltc bchusd bchbtc bcheth ltcusd ltcbtc ltceth ltcbch batusd daiusd linkusd oxtusd batbtc linkbtc oxtbtc bateth linketh oxteth ampusd compusd paxgusd mkrusd zrxusd kncusd manausd storjusd snxusd crvusd balusd uniusd renusd umausd yfiusd btcdai ethdai aaveusd filusd

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

$ curl "https://api.gemini.com/v1/symbols"
import requests, json

base_url = "https://api.gemini.com/v1"
response = requests.get(base_url + "/symbols")
symbols = response.json()

print(symbols)

This endpoint retrieves all available symbols for trading

HTTP Request

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

Sandbox

Base URL can be changed to api.sandbox.gemini.com/v1 for test purposes.

URL Parameters

None

Response

An array of supported symbols. The full list of supported symbols:

Symbols

btcusd ethbtc ethusd zecusd zecbtc zeceth zecbch zecltc bchusd bchbtc bcheth ltcusd ltcbtc ltceth ltcbch batusd daiusd linkusd oxtusd batbtc linkbtc oxtbtc bateth linketh oxteth ampusd compusd paxgusd mkrusd zrxusd kncusd manausd storjusd snxusd crvusd balusd uniusd renusd umausd yfiusd btcdai ethdai aaveusd filusd

JSON response


["btcusd","ethbtc","ethusd","zecusd","zecbtc","zeceth", "zecbch", "zecltc", "bchusd", "bchbtc", "bcheth", "ltcusd", "ltcbtc", "ltceth", "ltcbch", "batusd", "daiusd", "linkusd", "oxtusd", "batbtc", "linkbtc", "oxtbtc", "bateth", "linketh", "oxteth", "ampusd", "compusd", "paxgusd", "mkrusd", "zrxusd", "kncusd", "manausd", "storjusd", "snxusd", "crvusd", "balusd", "uniusd", "renusd", "umausd", "yfiusd", "btcdai", "ethdai", "aaveusd", "filusd"]

Ticker

import requests, json

base_url = "https://api.gemini.com/v1"
response = requests.get(base_url + "/pubticker/btcusd")
btc_data = response.json()

print(btc_data)
$ curl "https://api.gemini.com/v1/pubticker/btcusd"

JSON response

{
    "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

Sandbox

Base URL can be changed to api.sandbox.gemini.com/v1 for test purposes.

Response

The response will be an object

Field Type Description
bid decimal The highest bid currently available
ask decimal The lowest ask currently available
last decimal The price of the last executed trade
volume node (nested) 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

Ticker V2

import requests, json

base_url = "https://api.gemini.com/v2"
response = requests.get(base_url + "/ticker/btcusd")
btc_data = response.json()

print(btc_data)
$ curl "https://api.gemini.com/v2/ticker/btcusd"

JSON response

{
  "symbol": "BTCUSD",
  "open": "9121.76",
  "high": "9440.66",
  "low": "9106.51",
  "close": "9347.66",
  "changes": [
    "9365.1",
    "9386.16",
    "9373.41",
    "9322.56",
    "9268.89",
    "9265.38",
    "9245",
    "9231.43",
    "9235.88",
    "9265.8",
    "9295.18",
    "9295.47",
    "9310.82",
    "9335.38",
    "9344.03",
    "9261.09",
    "9265.18",
    "9282.65",
    "9260.01",
    "9225",
    "9159.5",
    "9150.81",
    "9118.6",
    "9148.01"
  ],
  "bid": "9345.70",
  "ask": "9347.67"
}

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

HTTP Request

GET https://api.gemini.com/v2/ticker/:symbol

URL Parameters

None

Sandbox

Base url can be changed to api.sandbox.gemini.com/v2 for test purposes.

Response

The response will be an object

Field Type Description
symbol string BTCUSD etc.
open decimal Open price from 24 hours ago
high decimal High price from 24 hours ago
low decimal Low price from 24 hours ago
close decimal Close price (most recent trade)
changes array of decimals Hourly prices descending for past 24 hours
-- decimal Close price for each hour
bid decimal Current best bid
ask decimal Current best offer

Candles

import requests, json

base_url = "https://api.gemini.com/v2"
response = requests.get(base_url + "/candles/btcusd/15m")
btc_candle_data = response.json()

print(btc_candle_data)
$ curl "https://api.gemini.com/v2/candles/btcusd/15m"

JSON response

[
    [
     1559755800000,
     7781.6,
     7820.23,
     7776.56,
     7819.39,
     34.7624802159
    ],
    [1559755800000,
    7781.6,
    7829.46,
    7776.56,
    7817.28,
    43.4228281059],
    ...
]

This endpoint retrieves time-intervaled data for the provided symbol.

HTTP Request

GET https://api.gemini.com/v2/candles/:symbol/:time_frame

URL Parameters

None

Parameter Type Description Values
:symbol String Trading pair symbol BTCUSD, etc. See symbols and minimums
:time_frame String Time range for each candle 1m: 1 minute
5m: 5 minutes
15m: 15 minutes
30m: 30 minutes
1hr: 1 hour
6hr: 6 hours
1day: 1 day

Sandbox

Base URL can be changed to api.sandbox.gemini.com/v2 for test purposes.

Response

The response will be an array of arrays

Field Type Description
Array of Arrays Descending order by time
-- -- time long Time in milliseconds
-- -- open decimal Open price
-- -- high decimal High price
-- -- low decimal Low price
-- -- close decimal Close price
-- -- volume decimal Volume

Current Order Book

curl "https://api.gemini.com/v1/book/btcusd"
import requests, json

base_url = "https://api.gemini.com/v1"
response = requests.get(base_url + "/book/btcusd")
btc_book = response.json()

print(btc_book)

JSON response


{
  "bids": [{
            "price": "3607.85",
            "amount": "6.643373",
            "timestamp": "1547147541"
           }
           ...
           ],
  "asks": [{
            "price": "3607.86",
            "amount": "14.68205084",
            "timestamp": "1547147541"
           }
           ...
           ]
}

This will return the current order book as two arrays (bids / asks).

HTTP Request

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

Sandbox

Base URL can be changed to api.sandbox.gemini.com/v1 for test purposes.

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 bid (offers to buy) price levels returned. Default is 50. May be 0 to return the full order book on this side.
limit_asks integer Optional. Limit the number of ask (offers to sell) price levels 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 bid price levels currently on the book. These are offers to buy at a given price
asks array The ask price levels 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 requests, json

base_url = "https://api.gemini.com/v1"
response = requests.get(base_url + "/trades/btcusd")
btcusd_trades = response.json()

print(btcusd_trades)

JSON response

[
  {
    "timestamp": 1547146811,
    "timestampms": 1547146811357,
    "tid": 5335307668,
    "price": "3610.85",
    "amount": "0.27413495",
    "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

Sandbox

Base URL can be changed to api.sandbox.gemini.com/v1 for test purposes.

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
  • block indicates a block trade
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 requests, json

base_url = "https://api.gemini.com/v1"
response = requests.get(base_url + "/auction/btcusd")
btc_auction = response.json()

print(btc_auction)
$ 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",
    "last_collar_price": "631.27",
    "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",
    "last_collar_price": "631.27",
    "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",
    "most_recent_collar_price": "633.545",
    "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",
    "most_recent_collar_price": "633.39",
    "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",
    "last_collar_price": "632.335",
    "next_auction_ms": 1474568008771
}

HTTP Request

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

Sanbox

Base URL can be changed to api.sandbox.gemini.com/v1 for test purposes.

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.
last_collar_price decimal If available, show the collar price 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.
most_recent_collar_price decimal The most recent collar price 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/:symbol/history?since=$(date -d 2016-08-22 +%s)"
import requests, json

base_url = "https://api.gemini.com/v1"
response = requests.get(base_url + "/auction/btcusd/history")
btc_auction_history = response.json()

print(btc_auction_history)

JSON response

[
    {
        "auction_id": 3,
        "auction_price": "628.775",
        "auction_quantity": "66.32225622",
        "eid": 4066,
        "highest_bid_price": "628.82",
        "lowest_ask_price": "629.48",
        "collar_price": "629.15",
        "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",
        "collar_price": "629.68",
        "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.
collar_price decimal The auction_price must be within plus or minus five percent of the collar price for result to be success.

Price feed

import requests, json

base_url = "https://api.gemini.com/v1"
response = requests.get(base_url + "/pricefeed")
prices = response.json()

print(prices)
$ curl "https://api.gemini.com/v1/pricefeed"

JSON Response

[   
    {
        "pair":"BTCUSD",
        "price":"9500.00",
        "percentChange24h": "5.23"
    },
    {
        "pair":"ETHUSD",
        "price":"257.54",
        "percentChange24h": "4.85"
    },
    {
        "pair":"BCHUSD",
        "price":"450.10",
        "percentChange24h": "-2.91"
    },
    {
        "pair":"LTCUSD",
        "price":"79.50",
        "percentChange24h": "7.63"
    },
    {
        "pair":"ZECUSD",
        "price":"72.89",
        "percentChange24h": "-1.90"
    }
]

HTTP Request

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

Sanbox

Base URL can be changed to api.sandbox.gemini.com/v1 for test purposes.

URL Parameters

None

Response

Response is a list of objects, one for each pair,with the following fields:

Field Type Description
pair String Trading pair symbol. See symbols and minimums
price String Current price of the pair on the Gemini order book
percentChange24h String 24 hour change in price of the pair on the Gemini order book

Order Placement APIs

New Order

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.

import requests
import json
import base64
import hmac
import hashlib
import datetime, time

base_url = "https://api.gemini.com"
endpoint = "/v1/order/new"
url = base_url + endpoint

gemini_api_key = "mykey"
gemini_api_secret = "1234abcd".encode()

t = datetime.datetime.now()
payload_nonce =  str(int(time.mktime(t.timetuple())*1000))

payload = {
   "request": "/v1/order/new",
    "nonce": payload_nonce,
    "symbol": "btcusd",
    "amount": "5",
    "price": "3633.00",
    "side": "buy",
    "type": "exchange limit",
    "options": ["maker-or-cancel"] 
}

encoded_payload = json.dumps(payload).encode()
b64 = base64.b64encode(encoded_payload)
signature = hmac.new(gemini_api_secret, b64, hashlib.sha384).hexdigest()

request_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.post(url,
                        data=None,
                        headers=request_headers)

new_order = response.json()
print(new_order)

Sample limit order payload

{
    "request": "/v1/order/new",
    "nonce": <nonce>,
    "client_order_id": <client_order_id>,
    "symbol": "btcusd",
    "amount": "5",
    "price": "3633.00",
    "side": "buy",
    "type": "exchange limit"
}

JSON limit order response

{
    "order_id": "106817811", 
    "id": "106817811", 
    "symbol": "btcusd", 
    "exchange": "gemini", 
    "avg_execution_price": "3632.8508430064554",
    "side": "buy", 
    "type": "exchange limit", 
    "timestamp": "1547220404", 
    "timestampms": 1547220404836, 
    "is_live": True, 
    "is_cancelled": False, 
    "is_hidden": False, 
    "was_forced": False,
    "executed_amount": "3.7567928949",
    "remaining_amount": "1.2432071051",
    "client_order_id": "20190110-4738721",
    "options": [],
    "price": "3633.00", 
    "original_amount": "5"
}

Sample Stop-Limit order payload

{
    "amount": ".1",
    "client_order_id": "470135",
    "price": "10500",
    "nonce": <nonce>,
    "side": "Buy",
    "request": "/v1/order/new",
    "stop_price": "10000",
    "symbol": "btcusd",
    "type": "exchange stop limit"
}

JSON Stop-Limit order response

{
    "order_id": "7419662",
    "id": "7419662",
    "symbol": "btcusd",
    "exchange": "gemini",
    "avg_execution_price": "0.00",
    "side": "buy",
    "type": "stop-limit",
    "timestamp": "1572378649",
    "timestampms": 1572378649018,
    "is_live": True,
    "is_cancelled": False,
    "is_hidden": False,
    "was_forced": False,
    "executed_amount": "0",
    "options": [],
    "stop_price": "10400.00",
    "price": "10500.00",
    "original_amount": "0.01"
}

Roles

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

The OAuth scope must have orders:create assigned to access this endpoint. See OAuth Scopes 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
min_amount string Optional. Minimum decimal amount to purchase, for block trades only
price string Quoted decimal amount to spend per unit
side string "buy" or "sell"
type string The order type. "exchange limit" for all order types except for stop-limit orders. "exchange stop limit" for stop-limit orders.
options array Optional. An optional array containing at most one supported order execution option. See Order execution options for details.
stop_price string Optional. The price to trigger a stop-limit order. Only available for stop-limit orders.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which you intend to place the order. Only available for exchange accounts.

Stop-Limit Orders

A Stop-Limit order is an order type that allows for order placement when a price reaches a specified level. Stop-Limit orders take in both a price and and a stop_price as parameters. The stop_price is the price that triggers the order to be placed on the continous live order book at the price. For buy orders, the stop_price must be below the price while sell orders require the stop_price to be greater than the price.

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.

No options can be applied to stop-limit orders at this time.

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).
"fill-or-kill" This order will only remove liquidity from the order book.

It will fill the entire order immediately or cancel.

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.
"indication-of-interest" An Indication of Interest (IOI) represents a request for liquidity from block trading market-makers for this symbol.

NOTE: An IOI is liquidity-taking by definition.

Response

Response 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.

Sample payload

{
    "nonce": <nonce>,
    "order_id": 106817811,
    "request": "/v1/order/cancel"
}

Upon a successful call, the response will be as follows. Note the *is_cancelled** node will have a value of 'true'

{
    "order_id":"106817811",
    "id":"106817811",
    "symbol":"btcusd",
    "exchange":"gemini",
    "avg_execution_price":"3632.85101103",
    "side":"buy",
    "type":"exchange limit",
    "timestamp":"1547220404",
    "timestampms":1547220404836,
    "is_live":False,
    "is_cancelled":True,
    "is_hidden":False,
    "was_forced":False,
    "executed_amount":"3.7610296649",
    "remaining_amount":"1.2389703351",
    "reason":"Requested",
    "options":[],
    "price":"3633.00",
    "original_amount":"5"
}

Roles

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

The OAuth scope must have orders:create assigned to access this endpoint. See OAuth Scopes 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.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which you intend to cancel the order. Only available for exchange accounts.

Response

Response will be the fields included in Order Status. 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.

Sample payload

{
    "request": "/v1/order/cancel/session",
    "nonce": <nonce>
}

Roles

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

The OAuth scope must have orders:create assigned to access this endpoint. See OAuth Scopes 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
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which you intend to cancel the orders. Only available for exchange accounts.

Response

JSON response

{
    "result":"ok",
    "details":
        {
            "cancelledOrders":[330429345],
            "cancelRejects":[]
        }
}
Field Type Description
result string ok
details node (nested) cancelledOrders/cancelRejects with IDs of both

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.

The OAuth scope must have orders:create assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

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

Sample payload

{
    "nonce": <nonce>,
    "request": "/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
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which you intend to cancel the orders. Only available for exchange accounts.

Response

JSON response

{
    "result": "ok",
    "details": {
        "cancelRejects": [],
        "cancelledOrders": [
            330429106,
            330429079,
            330429082
        ]
    }
}

Field Type Description
result string ok
details node (nested) cancelledOrders/cancelRejects with IDs of both

Order Status APIs

Order Status

Sample payload

{
    "request": "/v1/order/status",
    "nonce": <nonce>,
    "order_id": 44375901
}

Roles

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

The OAuth scope must have orders:read assigned to access this endpoint. See OAuth Scopes 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. order_id cannot be used in combination with client_order_id
client_order_id string Optional. The client_order_id used when placing the order. client_order_id cannot be used in combination with order_id
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which the order was placed. Only available for exchange accounts.

Response

JSON reponse for limit buy

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

JSON response for market buy

{
  "order_id": "107317752",
  "id": "107317752",
  "symbol": "ethusd",
  "exchange": "gemini",
  "avg_execution_price": "126.25",
  "side": "buy",
  "type": "market buy",
  "timestamp": "1547236481",
  "timestampms": 1547236481910,
  "is_live": "False",
  "is_cancelled": "False",
  "is_hidden": "False",
  "was_forced": "False",
  "executed_amount": "0.54517172",
  "remaining_amount": "0",
  "options": []
}
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
  • market sell
  • indication-of-interest
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. 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.
reason string Populated with the reason your order was canceled, if available.
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.
is_hidden boolean Will always return false unless the order was placed with the indication-of-interest execution option.

Get Active Orders

Roles

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

The OAuth scope must have orders:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

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

Sample payload

{
    "nonce": <nonce>,
    "request": "/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
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which the orders were placed. Only available for exchange accounts.

Response

JSON response

[   {
    "order_id": "107421210",
    "id": "107421210",
    "symbol": "ethusd",
    "exchange": "gemini",
    "avg_execution_price": "0.00",
    "side": "sell",
    "type": "exchange limit",
    "timestamp": "1547241628",
    "timestampms": 1547241628042,
    "is_live": True,
    "is_cancelled": False,
    "is_hidden": False,
    "was_forced": False,
    "executed_amount": "0",
    "remaining_amount": "1",
    "options": [],
    "price": "125.51",
    "original_amount": "1"
  },
  {
    "order_id": "107421205",
    "id": "107421205",
    "symbol": "ethusd",
    "exchange": "gemini",
    "avg_execution_price": "125.41",
    "side": "buy",
    "type": "exchange limit",
    "timestamp": "1547241626",
    "timestampms": 1547241626991,
    "is_live": True,
    "is_cancelled": False,
    "is_hidden": False,
    "was_forced": False,
    "executed_amount": "0.029147",
    "remaining_amount": "0.970853",
    "options": [],
    "price": "125.42",
    "original_amount": "1"
  } ]

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

Get Past Trades

Roles

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

The OAuth scope must have history:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

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

Sample payload

{
    "nonce": <nonce>,
    "request": "/v1/mytrades",
    "symbol": "btcusd"
}

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.
account string Optional. Required for Master API keys as described in Private API Invocation. Specifies the account on which the orders were placed. Only available for exchange accounts.

Response

JSON reponse

[ {
    "price": "3648.09",
    "amount": "0.0027343246",
    "timestamp": 1547232911,
    "timestampms": 1547232911021,
    "type": "Buy",
    "aggressor": True,
    "fee_currency": "USD",
    "fee_amount": "0.024937655575035",
    "tid": 107317526,
    "order_id": "107317524",
    "exchange": "gemini",
    "is_auction_fill": False
  }, {
    "price": "3633.00",
    "amount": "0.00423677",
    "timestamp": 1547220640,
    "timestampms": 1547220640195,
    "type": "Buy",
    "aggressor": False,
    "fee_currency": "USD",
    "fee_amount": "0.038480463525",
    "tid": 106921823,
    "order_id": "106817811",
    "exchange": "gemini",
    "is_auction_fill": False
} ]

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
exchange string Will always be "gemini"
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.

Fee and Volume APIs

Get Notional Volume

Roles

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

The OAuth scope must have history:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

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

Sample payload

{
    "nonce": <nonce>,
    "request": "/v1/notionalvolume"
}

Parameters

Parameter Type Description
request string The literal string "/v1/notionalvolume"
nonce integer The nonce, as described in Private API Invocation
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which the trades were placed. Only available for exchange accounts.

Response

JSON response

{
    "web_maker_fee_bps": 25,
    "web_taker_fee_bps": 35,
    "web_auction_fee_bps": 25,
    "api_maker_fee_bps": 10,
    "api_taker_fee_bps": 35,
    "api_auction_fee_bps": 20,
    "fix_maker_fee_bps": 10,
    "fix_taker_fee_bps": 35,
    "fix_auction_fee_bps": 20,
    "block_maker_fee_bps": 0,
    "block_taker_fee_bps": 50,
    "notional_30d_volume": 150.00,
    "last_updated_ms": 1551371446000,
    "date": "2019-02-28",
    "notional_1d_volume": [
        {
            "date": "2019-02-22",
            "notional_volume": 75.00
        },
        {
            "date": "2019-02-14",
            "notional_volume": 75.00
        }
    ]
}

The response will be a JSON object representing the volume in price currency that has been traded across all pairs over a period of 30 days.

Field Type Description
date string UTC date in yyyy-MM-dd format
last_updated_ms timestampms Unix timestamp in millisecond of the last update
web_maker_fee_bps basis point Integer value representing the maker fee for all symbols in basis point for web orders
web_taker_fee_bps basis point Integer value representing the taker fee for all symbols in basis point for web orders
web_auction_fee_bps basis point Integer value representing the auction fee for all symbols in basis point for web orders
api_maker_fee_bps basis point Integer value representing the maker fee for all symbols in basis point for API orders
api_taker_fee_bps basis point Integer value representing the taker fee for all symbols in basis point for API orders
api_auction_fee_bps basis point Integer value representing the auction fee for all symbols in basis point for API orders
fix_maker_fee_bps basis point Integer value representing the maker fee for all symbols in basis point for FIX orders
fix_taker_fee_bps basis point Integer value representing the taker fee for all symbols in basis point for FIX orders
fix_auction_fee_bps basis point Integer value representing the auction fee for all symbols in basis point for FIX orders
block_maker_fee_bps basis point Integer value representing the maker fee for all symbols in basis point for block orders
block_taker_fee_bps basis point Integer value representing the taker fee for all symbols in basis point for block orders
notional_30d_volume decimal Maker plus taker trading volume for the past 30 days, including auction volume
notional_1d_volume array A list of 1 day notional volume for the past 30 days
notional_1d_volume[n].date string UTC date in yyyy-MM-dd format
notional_1d_volume[n].notional_volume decimal Notional volume value in USD for this single day

Get Trade Volume

Roles

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

The OAuth scope must have history:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

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

Sample payload

{
    "nonce": <nonce>,
    "request": "/v1/tradevolume"
}

Parameters

Parameter Type Description
request string The literal string "/v1/tradevolume"
nonce integer The nonce, as described in Private API Invocation
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which the orders were placed. Only available for exchange accounts.

Response

JSON response


[
    [
        {
            "symbol": "btcusd",
            "base_currency": "BTC",
            "notional_currency": "USD",
            "data_date": "2019-01-10",
            "total_volume_base": 8.06021756,
            "maker_buy_sell_ratio": 1,
            "buy_maker_base": 6.06021756,
            "buy_maker_notional": 23461.3515203844,
            "buy_maker_count": 34,
            "sell_maker_base": 0,
            "sell_maker_notional": 0,
            "sell_maker_count": 0,
            "buy_taker_base": 0,
            "buy_taker_notional": 0,
            "buy_taker_count": 0,
            "sell_taker_base": 2,
            "sell_taker_notional": 7935.66,
            "sell_taker_count": 2
        },
        {
            "symbol": "ltcusd",
            "base_currency": "LTC",
            "notional_currency": "USD",
            "data_date": "2019-01-11",
            "total_volume_base": 3,
            "maker_buy_sell_ratio": 0,
            "buy_maker_base": 0,
            "buy_maker_notional": 0,
            "buy_maker_count": 0,
            "sell_maker_base": 0,
            "sell_maker_notional": 0,
            "sell_maker_count": 0,
            "buy_taker_base": 3,
            "buy_taker_notional": 98.22,
            "buy_taker_count": 3,
            "sell_taker_base": 0,
            "sell_taker_notional": 0,
            "sell_taker_count": 0
        }
    ]
]

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

Field Type Description
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.

Gemini Clearing

Gemini Clearing allows two parties to settle a trade off the order book. The initiator enters the trade details for any supported symbol and generates a trade_id. If a counterparty_id is supplied, only the specified counterparty can confirm the order. If a counterparty_id is not supplied, the ticket will generate a trade_id that can filled by any counterparty.

New Clearing Order

Roles

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

The OAuth scope must have clearing:create assigned to access /v1/clearing/new, /v1/clearing/cancel and /v1/clearing/confirm. The OAuth scope must have clearing:read to access /v1/clearing/status. See OAuth Scopes for more information.

HTTP Request

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

Sandbox

Base url can be changed to https://api.sandbox.gemini.com for test purposes. Please reach out to trading@gemini.com to enable Gemini Clearing on your sandbox account and test workflows.

Parameters

Parameter Type Description
request string The literal string "v1/clearing/new"
nonce integer The nonce, as described in Private API Invocation
counterparty_id string An optional symbol that corresponds with a counterparty to which you are directing the trade
expires_in_hrs integer The number of hours before the trade expires. Your counterparty will need to confirm the order before this time expires.
symbol string The symbol of the order
amount string Quoted decimal amount to purchase
price string Quoted decimal amount to spend per unit
side string "buy" or "sell"
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which to place the order. Only available for exchange accounts.

New Clearing Order example

import requests
import json
import base64
import hmac
import hashlib
import datetime, time

base_url = "https://api.gemini.com"
endpoint = "/v1/clearing/new"
url = base_url + endpoint

gemini_api_key = "mykey"
gemini_api_secret = "1234abcd".encode()
counterparty_id = "OM9VNL1G"
t = datetime.datetime.now()
payload_nonce =  str(int(time.mktime(t.timetuple())))

payload = {
    "request": endpoint,
    "nonce": payload_nonce,
    "counterparty_id": counterparty_id,
    "expires_in_hrs": 24,
    "symbol": "btcusd",
    "amount": "100",
    "price": "9500.00",
    "side": "buy"
}

encoded_payload = json.dumps(payload).encode()
b64 = base64.b64encode(encoded_payload)
signature = hmac.new(gemini_api_secret, b64, hashlib.sha384).hexdigest()

request_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.post(url,
                        data=None,
                        headers=request_headers)

new_clearing_order = response.json()
print(new_clearing_order)

Sample payload

{
    "request": "v1/clearing/new",
    "nonce": <nonce>,
    "counterparty_id": "OM9VNL1G",
    "expires_in_hrs": 24,
    "symbol": "btcusd",
    "amount": "100",
    "price": "9500.00",
    "side": "buy"
}

JSON response

{
    "result": "AwaitConfirm",
    "clearing_id": "0OQGOZXW"
}

Response

The response will be an object

Field Type Description
result string A description of the status of the clearing order. Because this is the reponse to an order initiation the response will be AwaitConfirm upon order placement success. Failures will show a brief description of the error in this field or the reason and message fields.
clearing_id string A unique identifier for the clearing order. The clearing_id can be used to check the status of your order or by the counterparty to confirm the order.

New Broker Order

Gemini Clearing also allows for brokers to facilitate trades between two Gemini customers. A broker can submit a new Gemini Clearing order that must then be confirmed by each counterparty before settlement.

Sample payload for broker order initiation

{
    "request": "v1/clearing/broker/new",
    "nonce": <nonce>,
    "source_counterparty_id": "R485E04Q",
    "target_counterparty_id": "Z4929ZDY",
    "symbol": "ethusd",
    "amount": "175.00",
    "expires_in_hrs": 1.0,
    "price": "200",
    "side": "sell"
}

Parameters

Parameter Type Description
request string The literal string "v1/clearing/broker/new"
nonce integer The nonce, as described in Private API Invocation
source_counterparty_id string A symbol that corresponds with the counterparty sourcing the clearing trade
target_counterparty_id string A symbol that corresponds with the counterparty where the clearing trade is targeted
symbol string The symbol of the order
amount string Quoted decimal amount to purchase
expires_in_hrs integer The number of hours before the trade expires. Your counterparty will need to confirm the order before this time expires.
price string Quoted decimal amount to spend per unit
side string "buy" or "sell". This side will be assigned to the source_counterparty_id. The opposite side will be sent to the target_counterparty_id.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the broker account on which to place the order. Only available for exchange accounts.

JSON response to broker clearing order

{
    "result": "AwaitSourceTargetConfirm",
    "clearing_id": "8EM7NVXD"
}

Response

The reponse will be an object

Field Type Description
result string Will return AwaitSourceTargetConfirm, meaning the order is waiting for both the source and the target parties to confirm the order
clearing_id string A unique identifier for the clearing order.

Clearing Order Status

HTTP Request

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

Sample order cancel payload

{
    "request": "v1/clearing/status",
    "nonce": <nonce>,
    "clearing_id": "OM9VNL1G"
}

Parameters

Parameter Type Description
request string The literal string "v1/clearing/status"
nonce integer The nonce, as described in Private API Invocation
clearing_id string A unique identifier for the clearing order. The clearing_id can be used to check the status of, cancel or confirm the order.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which the clearing order was placed. Only available for exchange accounts.

JSON response for confirmed clearing order

{
    "result": "ok",
    "status": "Confirmed"
}

Response

The response will be an object

Field Type Description
result string Will return "ok"
status string A description of the status of the order give in the clearing_id field. See order status descriptions for more information

Order status description

Status Description
AwaitConfirm Indicates that a bilateral trade order has been successfully initiated but has not yet been confirmed by the counterparty
AwaitSourceTargetConfirm Indicates that a broker trade has been successfully initiated but has not yet been confirmed by the target nor source counterparty
AwaitTargetConfirm The source counterparty has confirmed the clearing order but the target counterparty has not yet confirmed
AwaitSourceConfirm The target counterparty has confirmed the clearing order but the source counterparty has not yet confirmed
Confirmed The counterparty has confirmed the clearing order but the trade has not attempted settlement yet.
AttemptSettlement The counterparty has not yet funded their account to the required amount to settle the trade.
Settled The order has been settled and the funds have successfully moved between accounts.
Expired The order expiration time has come before the counterparty confirmed the order or. If the counterparty did confirm the order, then they did not have enough funds to settle the order before the expiration time.
Canceled The order was canceled by the order initiator.
Not Found The clearing_id given in the payload was not successfully matched to a pending clearing order.

Cancel Clearing Order

HTTP Request

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

Sample order cancel payload

{
    "request": "v1/clearing/cancel",
    "nonce": <nonce>,
    "clearing_id": "P0521QDV"
}

Parameters

Parameter Type Description
request string The literal string "v1/clearing/cancel"
nonce integer The nonce, as described in Private API Invocation
clearing_id string A unique identifier for the clearing order. The clearing_id can be used to check the status of, cancel or confirm the order.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which to cancel the clearing order. Only available for exchange accounts.

JSON response - successful cancel

{
    "result": "ok",
    "details": "P0521QDV order canceled"
}

JSON response - failed cancel

{
    "result": "failed",
    "details": "Unable to cancel order P0521QDV"
}

Response

The response will be an object

Field Type Description
result string A description of the status of the clearing order. This reponse will return the string "ok" upon success, or "failed" upon failure.
details string Provides more detailed description on the result. Will either return "P0521QDV order canceled" or "Unable to cancel order P0521QDV".

Confirm Clearing Order

POST https://api.gemini.com/v1/clearing/confirm

Sample order confirmation payload

{
    "request": "v1/clearing/confirm",
    "nonce": <nonce>,
    "clearing_id": "OM9VNL1G",
    "symbol": "btcusd",
    "amount": "100",
    "price": "9500.00",
    "side": "sell"
}

Parameters

Parameter Type Description
request string The literal string "v1/clearing/confirm"
nonce integer The nonce, as described in Private API Invocation
clearing_id string A unique identifier for the clearing order. The clearing_id can be used to check the status of your order or by the counterparty to confirm the order.
symbol string The symbol of the order
amount string Quoted decimal amount to purchase
price string Quoted decimal amount to spend per unit
side string "buy" or "sell". Must be the opposite side of the initiator's side
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account that was sent and is confirming the clearing order. Only available for exchange accounts.

JSON response - clearing order confirmation success

{
    "result": "confirmed"
}

JSON response - clearing order confirmation failure

{
    "result": "error",
    "reason": "InvalidSide",
    "message": "Invalid side for symbol BTCUSD: 'buy'"
}

Response

The reponse will be an object

Field Type Description
result sring A brief description of the result. Will return "confirmed" upon success and "error" upon failure
reason string Will only populate upon failure. Gives the reason for the confirmation error
message string Will only populate upon failure. A more detailed description of the reason for failure

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, Fund Manager or Auditor role assigned. See Roles for more information.

The OAuth scope must have balances:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

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

Sample payload

{
    "nonce": <nonce>,
    "request": "/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
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Master API keys can get all account names using the Get Accounts endpoint.

Response

An array of elements, with one block per currency

JSON response

[
    {
        "type": "exchange",
        "currency": "BTC",
        "amount": "1154.62034001",
        "available": "1129.10517279",
        "availableForWithdrawal": "1129.10517279"
    },
    {
        "type": "exchange",
        "currency": "USD",
        "amount": "18722.79",
        "available": "14481.62",
        "availableForWithdrawal": "14481.62"
    },
    {
        "type": "exchange",
        "currency": "ETH",
        "amount": "20124.50369697",
        "available": "20124.50369697",
        "availableForWithdrawal": "20124.50369697"
    }
]
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
type string "exchange"

Get Notional Balances

This will show the available balances in the supported currencies as well as in notional USD

Roles

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

The OAuth scope must have balances:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

POST https://api.gemini.com/v1/notionalbalances/usd

Sample payload

{
    "nonce": <nonce>,
    "request": "/v1/notionalbalances"
}

Parameters

Parameter Type Description
request string The literal string "/v1/notionalbalances"
nonce integer The nonce, as described in Private API Invocation
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Master API keys can get all account names using the Get Accounts endpoint.

Response

An array of elements, with one block per currency

JSON response

[
    {
        "currency": "BTC",
        "amount": "1154.62034001",
        "amountNotional": "10386000.59",
        "available": "1129.10517279",
        "availableNotional": "10161000.71",
        "availableForWithdrawal": "1129.10517279",
        "availableForWithdrawalNotional": "10161000.71"
    },
    {
        "currency": "USD",
        "amount": "18722.79",
        "amountNotional": "18722.79",
        "available": "14481.62",
        "availableNotional": "14481.62",
        "availableForWithdrawal": "14481.62",
        "availableForWithdrawalNotional": "14481.62"
    },
    {
        "currency": "ETH",
        "amount": "20124.50369697",
        "amountNotional": "100621.31",
        "available": "20124.50369697",
        "availableNotional": "100621.31",
        "availableForWithdrawal": "20124.50369697",
        "availableForWithdrawalNotional": "100621.31"
    }
]
Field Type Description
currency string Currency code, see symbols
amount decimal The current balance
amountNotional decimal Amount, in notional
available decimal The amount that is available to trade
availableNotional decimal Available, in notional
availableForWithdrawal decimal The amount that is available to withdraw
availableForWithdrawalNotional decimal AvailableForWithdrawal, in notional

Transfers

This endpoint shows deposits and withdrawals in the supported currencies. When deposits show as Advanced or Complete they are available for trading.

This endpoint does not currently show cancelled advances, returned outgoing wires or ACH transactions, admin credits and debits, or other exceptional transaction circumstances.

Roles

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

The OAuth scope must have history:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

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

Sample payload

{
    "nonce": <nonce>,
    "request": "/v1/transfers"
}

Parameters

Parameter Type Description
request string The literal string "/v1/transfers"
nonce integer The nonce, as described in Private API Invocation
timestamp timestamp Optional. Only return transfers on or after this timestamp. See Data Types: Timestamps for more information. If not present, will show the most recent transfers.
limit_transfers integer Optional. The maximum number of transfers to return. The default is 10 and the maximum is 50.
account string Optional. Only required when using a master api-key. The name of the account within the subaccount group. Master API keys can get all account names using the Get Accounts endpoint.

Response

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

JSON response

[
   {
      "type":"Deposit",
      "status":"Advanced",
      "timestampms":1507913541275,
      "eid":320013281,
      "currency":"USD",
      "amount":"36.00",
      "method":"ACH"
   },
   {
      "type":"Deposit",
      "status":"Advanced",
      "timestampms":1499990797452,
      "eid":309356152,
      "currency":"ETH",
      "amount":"100",
      "txHash":"605c5fa8bf99458d24d61e09941bc443ddc44839d9aaa508b14b296c0c8269b2"
   },
   {
      "type":"Deposit",
      "status":"Complete",
      "timestampms":1495550176562,
      "eid":298112782,
      "currency":"BTC",
      "amount":"1500",
      "txHash":"163eeee4741f8962b748289832dd7f27f754d892f5d23bf3ea6fba6e350d9ce3",
      "outputIdx":0
   },
   {
      "type":"Deposit",
      "status":"Advanced",
      "timestampms":1458862076082,
      "eid":265799530,
      "currency":"USD",
      "amount":"500.00",
      "method":"ACH"
   },
   {
      "type":"Withdrawal",
      "status":"Complete",
      "timestampms":1450403787001,
      "eid":82897811,
      "currency":"BTC",
      "amount":"5",
      "txHash":"c458b86955b80db0718cfcadbff3df3734a906367982c6eb191e61117b810bbb",
      "outputIdx":0,
      "destination":"mqjvCtt4TJfQaC7nUgLMvHwuDPXMTEUGqx"
   },
   {
      "type": "Withdrawal", 
      "status": "Complete", 
      "timestampms": 1535451930431, 
      "eid": 341167014, 
      "currency": "USD", 
      "amount": "1.00", 
      "txHash": "7bffd85893ee8e72e31061a84d25c45f2c4537c2f765a1e79feb06a7294445c3", 
      "destination": "0xd24400ae8BfEBb18cA49Be86258a3C749cf46853" 
   }
]
Field Type Description
type string Transfer type. Deposit or Withdrawal.
status string Transfer status. Advanced or Complete.
timestampms timestampms The time that the trade was executed in milliseconds
eid integer Transfer event id
currency string Currency code, see symbols
amount decimal The transfer amount
method string Optional. When currency is a fiat currency, the method field will attempt to supply ACH, Wire, or SEN. If the transfer is an internal transfer between subaccounts the method field will return Internal.
txHash string Optional. When currency is a cryptocurrency, supplies the transaction hash when available.
outputIdx integer Optional. When currency is a cryptocurrency, supplies the output index in the transaction when available.
destination string Optional. When currency is a cryptocurrency, supplies the destination address when available.
purpose string Optional. Administrative field used to supply a reason for certain types of advances.

Get Deposit Addresses

Roles

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

The OAuth scope must have addresses:read or addresses:create assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

POST https://api.gemini.com/v1/addresses/:network

Sample payload to return Bitcoin addresses

{
  "request" : "/v1/addresses/bitcoin",
  "nonce" : <nonce>
}

Parameters

Parameter Type Description
request string The string /v1/addresses/:network where :network can be bitcoin, ethereum, bitcoincash, litecoin, zcash, filecoin
nonce integer The nonce, as described in Private API Invocation
timestamp timestampms Optional. Only returns addresses created on or after this timestamp.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account to return deposit addresses for

Response

Get Bitcoin deposit addresses response

[
  {
    "address" : "n2saq73aDTu42bRgEHd8gd4to1gCzHxrdj",
    "timestamp" : 1424285102000,
    "label" : "my bitcoin address"
  },
  {
    "address" : "n2wpl14aJEu10bRgMNd0gdjH8dHJ3h2a3ks",
    "timestamp" : 1824785101000
  }
]

An array of objects with the following fields:

Field Type Description
address string String representation of the new cryptocurrency address.
timestamp timestampms Creation date of the address.
label string Optional. if you provided a label when creating the address, it will be echoed back here.

New Deposit Address

Roles

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

The OAuth scope must have addresses:create assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

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

Sample payload for BTC address generation

{
  "request" : "/v1/deposit/bitcoin/newAddress",
  "nonce" : <nonce>,
  "label" : "optional test label"
}

Sample payload for legacy LTC address generation

{
  "request": "v1/deposit/litecoin/newAddress",
  "nonce" : <nonce>,
  "label" : "LTC legacy deposit address",
  "legacy" : True
}

Parameters

Parameter Type Description
request string The string /v1/deposit/:network/newAddress where :network can be bitcoin, ethereum, bitcoincash, litecoin, zcash, or filecoin.
nonce integer The nonce, as described in Private API Invocation
label string Optional. Label for the deposit address
legacy boolean Optional. Whether to generate a legacy P2SH-P2PKH litecoin address. False by default.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account that will have the new deposit address. Only available for exchange accounts.

Response

New BTC deposit address response

{
  "network" : "bitcoin",
  "address" : "n2saq73aDTu42bRgEHd8gd4to1gCzHxrdj",
  "label" : "optional test label"
}

New LTC deposit address response

{
  "network" : "litecoin",
  "address" : "MJRSgZ3UUFcTBTBAcN38XAXvZLwRe8WVw7",
  "label" : "LTC legacy deposit address"
}

An object with the following fields:

Field Type Description
request string The string /v1/deposit/:network/newAddress where :network can be bitcoin, ethereum, bitcoincash, litecoin, zcash, or filecoin.
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

Before you can withdraw cryptocurrency funds to an approved address, you need three things:

  1. You must have an approved address list for your account
  2. The address you want to withdraw funds to needs to already be on that approved address list
  3. An API key with the Fund Manager role added

If you would like to withdraw via API to addresses that are not on your approved address list, please reach out to trading@gemini.com. We can enable this feature for you provide a set of approved IP addresses. This functionality is only available for exchange accounts. Pre-approved IP addresses and addresses added to your approved address list are required to enable withdrawal APIs for custody accounts.

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.

The OAuth scope must have crypto:send assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

Sample payload for BTC withdrawal

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

Sample payload for ETH withdrawal

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

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 cryptocurrency address.
amount string Quoted decimal amount to withdraw
account string Optional. Only required when using a master api-key. The name of the account within the subaccount group. Master API keys can get all account names using the Get Accounts endpoint.

Response

JSON reponse for BTC withdrawal

{
    "address":"mi98Z9brJ3TgaKsmvXatuRahbFRUFKRUdR",
    "amount":"1",
    "withdrawalId":"02176a83-a6b1-4202-9b85-1c1c92dd25c4",
    "message":"You have requested a transfer of 1 BTC to mi98Z9brJ3TgaKsmvXatuRahbFRUFKRUdR. This withdrawal will be sent to the blockchain within the next 60 seconds."
}

JSON response for ETH withdrawal

{
   "address":"0xA63123350Acc8F5ee1b1fBd1A6717135e82dBd28",
   "amount":"2.34567",
   "txHash":"0x28267179f92926d85c5516bqc063b2631935573d8915258e95d9572eedcc8cc"
}

Upon successful response, the system will return the following:

An object with the following fields:

Field Type Description
address 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. Only shown for ETH and GUSD withdrawals.
withdrawalID string A unique ID for the withdrawal. Only shown for BTC, ZEC, LTC and BCH withdrawals.
message string A human-readable English string describing the withdrawal. Only shown for BTC, ZEC, LTC and BCH withdrawals.

Errors

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."
}

Upon error, a response will contain details to help resolve the error as follows:

The response will contain the following fields:

Field Type Description
result string "error"
reason string short description
message string detailed error message

Internal Transfers

This API allows you to execute an internal transfer between any two accounts within your Master Group. In the scenario of exchange account to exchange account there will be no activity on a blockchain network. All other combinations will result in a movement of funds on a blockchain network.

Gemini Custody account withdrawals will not occur until the daily custody run occurs. In the case of funds moving from a Gemini Custody account to a Gemini Exchange account, the exchange account will get a precredit for the amount to be received. The exchange account will be able to trade these funds but will be unable to withdraw until the funds are processed on the blockchain and received.

Gemini Custody accounts request withdrawals to approved addresses in all cases and require the request to come from an approved IP address. Please reach out to trading@gemini.com to enable API withdrawals for custody accounts.

Roles

The API key you use to access this endpoint must be a Master level key and have the Administrator role assigned. See Roles for more information.

HTTP Request

Sample payload for BTC transfer

{
   "request":"/v1/account/transfer/btc",
   "nonce": <nonce>,
   "sourceAccount":"my-account",
   "targetAccount":"my-other-account",
   "amount":"1"
}

POST https://api.gemini.com/v1/account/transfer/:currency

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

Parameters

Parameter Type Description
request string The string /v1/account/transfer/:currency where :currency is replaced with the three-letter currency code of a supported crypto-currency, e.g. usd or btc or eth. See Symbols and minimums.
nonce integer The nonce, as described in Private API Invocation
sourceAccount string Nickname of the account you are transferring from. Use the Get Accounts endpoint to get all account names in the group.
targetAccount string Nickname of the account you are transferring to. Use the Get Accounts endpoint to get all account names in the group.
amount string Quoted decimal amount to withdraw

Response

JSON reponse for BTC transfer

{
   "uuid":"9c153d64-83ba-4532-a159-ebe3f6797766"
}

Upon successful response, the system will return the following:

An object with the following fields:

Field Type Description
fromAccount string Source account where funds are sent from
toAccount string Target account to receive funds in the internal transfer
amount string Quantity of assets being transferred
fee string Fee taken for the transfer. Exchange account to exchange account transfers will always be free and will not be deducted from the free monthly transfer amount for that account.
currency string Currency code. See symbols for supported assets.
withdrawalId string Excludes exchange to exchange. Unique ID of the requested withdrawal.
uuid string Only for exchange to exchange. Unique ID of the completed transfer
message string Message describing result of withdrawal. Will inform of success, failure, or pending blockchain transaction.
txHash string Only for Ethereum network transfers. Excludes exchange to exchange transfers. Transaction hash for ethereum network transfer.

Add Bank

The add bank API allows for banking information to be sent in via API. However, for the bank to be verified, you must still send in a wire for any amount from the bank account.

Roles

This API requires the FundManager role. See Roles for more information.

The OAuth scope must have banks:create assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

POST https://api.gemini.com/v1/payments/addbank

Sample Payload

{
  "request": "v1/payments/addbank",
  "nonce": <nonce>,
  "accountnumber": "account-number-string",
  "routing": "routing-number-string",
  "type": "checking",
  "name": "Satoshi Nakamoto Checking"
}

Parameters

Parameter Type Description
request string The literal string "v1/payments/addbank"
nonce integer The nonce, as described in Private API Invocation
accountnumber string Account number of bank account to be added
routing string Routing number of bank account to be added
type string Type of bank account to be added. Accepts checking or savings
name string The name of the bank account as shown on your account statements
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Master API keys can get all account names using the Get Accounts endpoint.

Sample Response

{"referenceId": "BankAccountRefId(18428)"}
Field Type Description
referenceId string Reference ID for the new bank addition request. Once received, send in a wire from the requested bank account to verify it and enable withdrawals to that account.

Payment Methods

The payments methods API will return data on balances in the account and linked banks.

Roles

The API key you use to access this endpoint can be either a Master or Account level key with any role assigned. See Roles for more information.

The OAuth scope must have banks:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

POST https://api.gemini.com/v1/payments/methods

Sample Payload

{
    "request": "v1/payments/methods",
    "account": "primary",
    "nonce": <nonce>
}

Parameters

Parameter Type Description
request string The literal string "/v1/payments/methods"
nonce integer The nonce, as described in Private API Invocation
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Master API keys can get all account names using the Get Accounts endpoint.

JSON Response

{
  "balances": [
    {
      "type": "exchange",
      "currency": "USD",
      "amount": "50893484.26",
      "available": "50889972.01",
      "availableForWithdrawal": "50889972.01"
    }
  ],
  "banks": [
    {
      "bank": "Jpmorgan Chase Bank Checking  - 1111",
      "bankId": "97631a24-ca40-4277-b3d5-38c37673d029"
    }
  ]
}

Response

A JSON object containing balance and banking information.

Field Type Description
balances array Array of JSON objects with available fiat currencies and their balances.
-- type string Account type. Will always be exchange
-- currency string Symbol for fiat balance.
-- amount string Total account balance for currency.
-- available string Total amount available for trading
-- availableForWithdrawal string Total amount available for withdrawal
banks array Array of JSON objects with banking information
-- bank string Name of bank account
-- bankId string Unique identifier for bank account

Approved Address APIs

Gemini offers withdrawal address whitelisting to restrict withdrawals only to addresses on the list. Single-user accounts require a 7 day waiting period for addresses newly added to be approved, while multi-user accounts require dual control from 2 users for approval. The users must have the Fund Manager role to approve dual control address list additions. Please see roles for more information.

Approved address lists can be set at the account or group level.

Create an Address Request

Allows for creation of an approved address addition. Once the request is made, the 7 day waiting period will begin. Please note that all approved address requests are subject to the 7 day waiting period.

If you add an address using an account-scoped API key, then the address will be added to your account specific approved address list. If you use a master-scoped API key, the address will be added to your group-level approved address list unless you specify an account.

Please reach out to trading@gemini.com if you have any questions about approved addresses.

Roles

This API requires the FundManager role. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/approvedAddresses/:network/request

Sample Payload for Address Addition for Account-level approved address list

{
    "request": "/v1/approvedAddresses/ethereum/request",
    "nonce": <nonce>,
    "address": "0x0000000000000000000000000000000000000000",
    "label": "api_added_ETH_address",
    "account": "primary"
}
Parameter Type Description
request string The literal string "v1/approvedAddresses/:network/request" where :network can be bitcoin, ethereum, bitcoincash, litecoin, zcash, or filecoin
nonce integer The nonce, as described in Private API Invocation
address string A string of the address to be added to the approved address list.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which you intend to add the approved address.

Sample Response

{
    "message": "Approved address addition is now waiting a 7-day approval hold before activation."
}
Field Type Description
message string Upon successful request, the endpoint will return a string indicating the 7-day approval hold period has begun.

View Approved Addresses

Allows viewing of Approved Address list.

Roles

This API requires the can accept any role. See Roles for more information.

HTTP Request

GET https://api.gemini.com/v1/approvedAddresses/account/:network

Sample payload to view Approved Address list

{
    "request": "/v1/approvedAddresses/account/ethereum",
    "nonce": <nonce>,
    "account": "primary"
}
Parameter Type Description
request string The literal string "v1/approvedAddresses/account/:network" where :network can be bitcoin, ethereum, bitcoincash, litecoin, zcash, filecoin
nonce integer The nonce, as described in Private API Invocation
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which you intend to view the approved address list.

Sample Response for Ethereum Approved Address

{
  "approvedAddresses": [
    {
      "network": "ethereum",
      "scope": "account",
      "label": "api_added_ETH_address",
      "status": "pending-time",
      "createdAt": "1602692572349",
      "address": "0x0000000000000000000000000000000000000000"
    },
    {
      "network": "ethereum",
      "scope": "group",
      "label": "api_added_ETH_address",
      "status": "pending-time",
      "createdAt": "1602692542296",
      "address": "0x0000000000000000000000000000000000000000"
    },
    {
      "network": "ethereum",
      "scope": "group",
      "label": "hardware_wallet",
      "status": "active",
      "createdAt": "1602087433270",
      "address": "0xA63123350Acc8F5ee1b1fBd1A6717135e82dBd28"
    },
    {
      "network": "ethereum",
      "scope": "account",
      "label": "hardware_wallet",
      "status": "active",
      "createdAt": "1602086832986",
      "address": "0xA63123350Acc8F5ee1b1fBd1A6717135e82dBd28"
    }
  ]
}
Field Type Description
approvedAddresses array Array of approved addresses on both the account and group level.
-- network string The network of the approved address. Network can be bitcoin, ethereum, bitcoincash, litecoin, zcash, or filecoin
-- scope string Will return the scope of the address as either "account" or "group"
-- label string The label assigned to the address
-- status string The status of the address that will return as "active", "pending-time" or "pending-mua". The remaining time is exactly 7 days after the initial request. "pending-mua" is for multi-user accounts and will require another administator or fund manager on the account to approve the address.
-- createdAt string UTC timestamp in millisecond of when the address was created.
-- address string The address on the approved address list.

Remove Addresses From Approved Address List

Allows for removal of active or time-pending addresses from the Approved Address list. Addresses that are pending approval from another user on the account cannot be removed via API.

Roles

This API requires the FundManager role. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/approvedAddresses/:network/remove

Sample Payload for Address Removal

{
    "request": "/v1/approvedAddresses/ethereum/remove",
    "nonce": <nonce>,
    "address": "0x0000000000000000000000000000000000000000"
}
Parameter Type Description
request string The literal string "v1/approvedAddresses/:network/remove" where :network can be bitcoin, ethereum, bitcoincash, litecoin, zcash, or filecoin
nonce integer The nonce, as described in Private API Invocation
address string A string of the address to be removed from the approved address list.
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account on which you intend to remove the approved address.

Sample Response for removal of address from group approved address list

{
    "message": "0x0000000000000000000000000000000000000000 removed from group pending-time approved addresses."
}
Field Type Description
message string Upon successful request, the endpoint will return a string indicating the address and whether it was removed from the group-level or account-level approved address list.

Account Administration APIs

Account Detail

The account API will return detail about the specific account requested such as users, country codes, etc.

Roles

The API key you use to access this endpoint can be either a Master or Account level key with any role assigned. See Roles for more information.

HTTP Request

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

Sample Payload

{
    "request": "v1/account",
    "account": "primary",
    "nonce": <nonce>
}

Sample Response

{
  "account": {
    "accountName": "Primary",
    "shortName": "primary",
    "type": "exchange",
    "created": "1498245007981"
  },
  "users": [
    {
      "name": "Satoshi Nakamoto",
      "lastSignIn": "2020-07-21T13:37:39.453Z",
      "status": "Active",
      "countryCode": "US",
      "isVerified": true
    },
    {
      "name": "Gemini Support",
      "lastSignIn": "2018-07-11T20:04:36.073Z",
      "status": "Suspended",
      "countryCode": "US",
      "isVerified": false
    }
  ],
  "memo_reference_code": "GEMPJBRDZ"
}

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/account"
nonce integer The nonce, as described in Private API Invocation
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Master API keys can get all account names using the Get Accounts endpoint.

Response

A JSON object containing basic information about the requested account and its users

Field Type Description
account JSON object Contains information on the requested account
-- accountName string The name of the account provided upon creation. Will default to Primary
-- shortName string Nickname of the specific account (will take the name given, remove all symbols, replace all " " with "-" and make letters lowercase)
-- type string The type of account. Will return either exchange or custody
-- created timestampms The timestamp of account creation, displayed as number of milliseconds since 1970-01-01 UTC. This will be transmitted as a JSON number
users array Contains an array of JSON objects with user information for the requested account
-- -- name string Full legal name of the user
-- -- lastSignIn string Timestamp of the last sign for the user. Formatted as yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
-- -- status string Returns user status. Will inform of active users or otherwise not active
-- -- countryCode string 2 Letter country code indicating residence of user.
-- -- isVerified bool Returns verification status of user.
memo_reference_code string Returns wire memo reference code for linked bank account.

Create Account

A Master API key can create a new exchange account within the group. This API will return the name of your new account for use with the account parameter in when using Master API keys to perform account level functions. Please see the example below

Roles

The API key you use to access this endpoint must be a Master level key and have the Administrator role assigned. See Roles for more information.

HTTP Request

POST https://api.gemini.com/v1/account/create

Sample payload

{
    "request": "/v1/account/create",
    "nonce": <nonce>,
    "name": "My Secondary Account",
    "type": "exchange"
}

Parameters

The request expects a nonce, and an account name

Parameter Type Description
request string The literal string "/v1/account/create"
nonce integer The nonce, as described in Private API Invocation
name string A unique name for the new account
type string optional: Either exchange or custody is accepted. Will generate an exchange account if exchange or parameter is missing. Will generate a custody account if custody

Response

An element containing basic information about the created account

Field Type Description
account string Account reference string for use in APIs based off the provided name field
type string Will return the type of account generated. exchange if an exchange account was created, custody if a custody account was created

JSON response

{
    "account": "my-secondary-account",
    "type": "exchange"
}

Get Accounts in Master Group

A Master API key can be used to get the accounts within the group.

Roles

The API key you use to access this endpoint must be a Master level key. See Roles for more information.

The OAuth scope must have account:read assigned to access this endpoint. See OAuth Scopes for more information.

HTTP Request

POST https://api.gemini.com/v1/account/list

Sample Payload

{
    "request": "/v1/account/list",
    "nonce": <nonce>
}

Parameters

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

Response

The response will be a JSON object containing all accounts within the master group

Field Type Description
name string The name of the account provided upon creation.
account string Nickname of the specific account (will take the name given, remove all symbols, replace all " " with "-" and make letters lowercase)
counterparty_id string The Gemini clearing counterparty ID associated with the API key making the request. Will return None for custody accounts
type string Either "exchange" or "custody" depending on type of account
created timestampms The timestamp of account creation, displayed as number of milliseconds since 1970-01-01 UTC. This will be transmitted as a JSON number

JSON response

[
    {
        "name": "Primary",
        "account": "primary",
        "counterparty_id": "EMONNYXH",
        "type": "exchange",
        "created": 1495127793000
    },
    {
        "name": "My Custody Account",
        "account": "my-custody-account",
        "counterparty_id": None,
        "type": "custody",
        "created": 1565970772000
    },
    {
        "name": "Other exchange account!",
        "account": "other-exchange-account",
        "counterparty_id": "EMONNYXK",
        "type": "exchange",
        "created": 1565970772000
    }
]

Using Master API Keys

Gemini supports sub-account functionality which allows users to create multiple Gemini accounts off of their primary account. Administrators on the primary account can create a master API key via API Settings on the Gemini web UI.

Master API keys can be used for any account level endpoint as well if the proper roles are assigned to it. For example, if a master API key has the Administrator and Fund Manager roles assigned, the key can be used to check balances, create new deposit addresses and withdraw. The master API key will need to pass the account parameter in order to specify the account where the trade is placed.

HTTP Request

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

Sample payload for master API key - /v1/balances

{
    "request": "/v1/balances",
    "nonce": <nonce>,
    "account": "primary"
}

This payload will be the same as the regular balances endpoint but includes the account parameter.

Parameters

Parameter Type Description
request string The literal string "/v1/balances"
nonce integer The nonce, as described in Private API Invocation
account string Only required when using a master api-key. The name of the account within the subaccount group. Master API keys can get all account names using the Get Accounts endpoint.

Response

The response will be the same as using an account API key.

Gemini Dollar

To learn more about GUSD, please visit https://gemini.com/dollar/

Withdraw USD as GUSD

Sample payload

{
    "nonce": <nonce>,
    "request": "/v1/withdraw/usd",
    "address": "0x0F2B20Acb2fD7EEbC0ABc3AEe0b00d57533b6bD1",
    "amount": "500"
}

In order to withdraw USD as Gemini Dollar, you need the following:

  1. At least 1 GUSD address on your approved address list or have withdrawals to non-approved addresses enabled
  2. An API key with the Fund Manager role added
  3. A balance of USD available for withdrawal

Be sure to check the balances endpoint to see how much USD you have in the "availableForWithdrawal" field.

Parameters

Parameter Type Description
request string The string /v1/withdraw/usd. See Symbols and minimums.
nonce integer The nonce, as described in Private API Invocation
address string Standard string format of a GUSD address.
amount string Quoted decimal amount to withdraw
account string Optional. Required for Master API keys as described in Private API Invocation. The name of the account within the subaccount group. Specifies the account that is withdrawing GUSD.

Response

JSON reponse for GUSD withdrawal

{
   "destination":"0x0F2B20Acb2fD7EEbC0ABc3AEe0b00d57533b6bD2",
   "amount":"500",
   "txHash":"6b74434ce7b12360e8c2f0321a9d6302d13beff4d707933a943a6aa267267c93"
}

Upon successful response, the system will return the following:

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

GUSD Redemption

To redeem outstanding GUSD, you must deposit your GUSD to a Gemini dollar deposit address. You can generate a deposit address by visiting https://exchange.gemini.com/deposit/usd/geminidollar or by using the New Deposit Address endpoint.

When deposited to your Gemini account, Gemini dollars are redeemed and your account is credited the equivalent U.S. dollar amount.

GUSD redemptions and creations on your account can be viewed using the Transfers endpoint.

Sample response for GUSD Creation

{
    "type": "Withdrawal", 
    "status": "Complete", 
    "timestampms": 1535451930431, 
    "eid": 341167014, 
    "currency": "USD", 
    "amount": "500.00", 
    "txHash": "7bffd85893ee8e72e31061a84d25c45f2c4537c2f765a1e79feb06a7294445c3", 
    "destination": "0xd24400ae8BfEBb18cA49Be86258a3C749cf46853" 
}

Sample response for GUSD Redemption

{
    "type": "Deposit", 
    "status": "Complete", 
    "timestampms": 155319645931, 
    "eid": 541767026, 
    "currency": "USD", 
    "amount": "100.00", 
    "txHash": "7bffd85893ee8e72e31061a84d25c45f2c4537c2f765a1e79feb06a7294445c3", 
    "destination": "0xd24400ae8BfEBb18cA49Be86258a3C749cf46853" 
}

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

Sample payload

{
    "nonce": <nonce>,
    "request": "/v1/heartbeat"
}

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

JSON response

{
    "result": "ok"
}

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

Field Type Description
result string "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 Auction not open or paused, ineligible timing, market not open, or 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 or Order not found
406 Insufficient Funds
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
ConflictingAccountName The specified name is already in use within the master group
EndpointMismatch The request was submitted to an endpoint different than the one in the payload
EndpointNotFound No endpoint was specified
GTSTradeIDMustBeString The Clearing ID must be a string
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
InvalidStopPrice For new stop limit orders, the price was invalid
InvalidStopPriceSell For new stop limit sell orders, the "stop_price" price was lower than the "sell" price
InvalidStopPriceBuy For new stop limit buy orders, the "stop_price" price was greater than the "buy" price
InvalidStopPriceRatio For new stop limit orders, the "buy" or "sell" price was not within 50% of the "stop_price"
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.
InvalidAccountName The specified name did not match any accounts within the master group
InvalidAccountType The specified type did not match exchange or custody
InvalidFundTransfer The fund transfer was not successful
Maintenance The system is down for maintenance
MarketNotOpen The order was rejected because the market is not accepting new orders
MissingAccountName A required account name was not specified in a field requiring one
MissingAccounts A required account field was not specified
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
MissingPayloadKey The payload is missing a required key
MissingSignatureHeader The X-GEMINI-SIGNATURE header was missing
MissingName A required name field was not specified
MissingNonce A nonce was not provided in the payload. See Private API Invocation for more detail.
MoreThanOneAccount More than one account was specified on an API that only accepts a single account
AccountsOnGroupOnlyApi The account field was specified on a non-master API key
AccountLimitExceeded The account field specified more than the maximum supported accounts for that API
NoAccountOfTypeRequired The account field specified multiple accounts and some were not of the required account type
AccountNotOfTypeRequired The account specified in the account field was not of the required account type
NotGroupApiCompatible A master API key was used to invoke an account only API
ExceededMaxAccountsInGroup An account could not be created as the master group already has the maximum number of allowed accounts in it
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.
HasNotAgreedToCustodyTerms The Group has not yet agreed to the Custody terms and conditions. Please visit https://exchange.gemini.com/custody to read the terms and conditions of custody accounts.
BadAccountType The type parameter must contain a string of either exchange or custody.

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
2017/11/30 API Change clarify that only seven calendar days of data will be available through public API endpoints at Trade History and Auction History. Email support@gemini.com for information about Gemini market data.

Please note this seven day limit on retrieving historical data does not affect your private API endpoints Get Past Trades or Order Status.
2017/12/01 API Change added collar_price to Current Auction and Auction History
2018/02/09 API Change update API Error Codes
2018/04/06 New Feature: Document block trading support.
2018/04/06 New Feature: Document Transfers endpoint.
2018/09/10 Added Gemini dollar example to Transfers.
2018/09/14 Document new fill-or-kill order placement options.
2019/03/01 Document changes to Notional Volume
2019/03/22 Add Gemini Dollar section and detail changes to Withdrawals
2019/05/31 Add legacy parameter for LTC address generation
2019/06/07 Add documentation for ticker v2 and candles endpoints
2019/08/08 New Feature Documentation for Gemini Clearing functionality
2019/08/16 New Feature Documentation for Account Administration APIs and Group Level API keys
2019/11/12 New Feature Documentation for Stop Orders and Group->Master API key reference changes
2019/11/18 New Feature Updating Stop order documentation
2020/03/05 New Feature Documentation for Retrieving deposit addresses, Price Feed, and Notional Balances
2020/04/09 Documentation for new token support: BAT, DAI, LINK, OXT
2020/07/23 New Feature Documentation for Adding a Bank, Viewing Payment Methods and Account Detail
2020/08/28 Removing DAIBTCand DAIETH trading pairs
2020/09/11 Documentation for new token support: AMP, COMP, PAXG
2020/09/24 Documentation for new token support: MKR, ZRX, KNC, MANA, STORJ, SNX, CRV, BAL, UNI, REN, UMA, YFI