NAV
python shell

OAuth 2.0

In addition to the API key methods described in private APIs, Gemini supports OAuth 2.0 flows and adheres to the OAuth 2.0 Standards. Both authorization code and implicit OAuth flows are supported, however use of authorization code flows is strongly recommended for most use cases because of enhanced security and the ability to support features such as refresh tokens.

The first step in using Gemini OAuth is to create a new OAuth application which you can do via API Settings. You will be asked for some basic information including a name, description, background information, logo, and the scopes that you are requesting access to. We will provide you a client_id and a client_secret which are used to identify and secure your app.

Once your app is registered it will be reviewed by Gemini, and then set live for use. You may also follow the same process in our Sandbox Environment to build a test integration.

Please email trading@gemini.com with any questions. We will provide you a client_id and a client_secret. Your client_id will be used in all your requests to identify your app, and client_secret must be sent in all POST requests

Instead of API Keys OAuth 2.0 uses access tokens and, if using the authorization code grant flow, refresh tokens. Access tokens are short-lived (24 hour expiration) and are used in Gemini API calls while refresh tokens don't expire and are used solely to generate new access tokens.

Authorization Code Grant Flow

The OAuth 2.0 authorization code grant flow involves the user being directed to an authorization server which returns an authorization code that may then be exchanged for access and refresh tokens. Access tokens are short-lived (24 hour expiration) and are used as authentication against Gemini APIs, while refresh tokens never expire and are used to regenerate access tokens.

Authorization Request

Users should first be redirected to Gemini to authorize access to your application. The user will be prompted to login using a Gemini OAuth window.

GET https://exchange.gemini.com/auth

Example authorization request:

GET https://exchange.gemini.com/auth?client_id=my_id&response_type=code&redirect_uri=www.example.com/redirect&state=82350325&scope=balances:read,orders:create

URL Parameters

Parameter Type Description
client_id string Unique id of your application. This is provided in your API settings
response_type string The literal string "code"
redirect_uri string The URL users should be returned to when they authorize. Note, this URL must be included in your list of approved redirect_uris in your app registration
state string A random string that will be returned to you in the response.
scope string A comma separated list of scopes corresponding to the access you're requesting for your application. Note, these scopes must be included in your list of scopes in your app registration

Authorization Response

Example redirect_uri response after user login

https://www.example.com/redirect?code=90123465-86ee-44ef-b4e3-835cc89bc8a3&state=82350325

On successful authorization Gemini will redirect your user to the redirect_uri you supplied with additional parameters code and state. The parameter state should match the state you provided, otherwise you should not trust the response. code is a temporary code which you will then use to obtain access and refresh tokens.

Token Request

Once you have received a code you can exchange it for access and refresh tokens.

POST https://exchange.gemini.com/auth/token

Parameter Type Description
client_id string Unique id of your application. This is provided in your API settings
client_secret string Secret of your application. This is provided when you first register an app in API settings
code string The code you received from the authorization request
redirect_uri string This must match the redirect_uri provided in the authorization request
grant_type string The literal string "authorization_code"

Example Token Request

{
    "client_id": "my_id",
    "client_secret": "my_secret",
    "code": "90123465-86ee-44ef-b4e3-835cc89bc8a3",
    "redirect_uri": "www.example.com/redirect",
    "grant_type": "authorization_code"
}

Token Response

Field Type Description
access_token string A short-lived token to use in API call authentication. Is valid until the expires_in time reaches 0
refresh_token string A refresh token to be used to generate new access tokens
token_type string The literal string "bearer"
scope string The scopes the access token will have access to
expires_in integer The lifetime in seconds of the access token, as measured in seconds from the current time

Example Token Response

{
    "access_token": "d9af2411-3e85-41bb-89f4-cf53750f04df",
    "refresh_token": "215c5a89-6df7-457b-ba0b-70695da8c91f",
    "token_type": "Bearer",
    "scope": "balances:read,orders:create",
    "expires_in": 86399
}

Using Refresh Tokens

The access token you receive will be relatively short-lived (default 24 hours). Once an access token has expired you can use your refresh token to generate a new access token. Refresh tokens never expire, however they are one-time use only as your request for a new access token will also return a new refresh token.

Getting a new access token is similar to getting the initial access and refresh tokens with slightly different parameters

Token Request

POST https://exchange.gemini.com/auth/token

Example Token Request

{
    "client_id": "my_id",
    "client_secret": "my_secret",
    "refresh_token": "215c5a89-6df7-457b-ba0b-70695da8c91f",
    "grant_type":"refresh_token"
}
Parameter Type Description
client_id string Unique id of your application
client_secret string Secret of your application. This is provided when you first register an app in [API settings][API Settings]
refresh_token string Your refresh token
grant_type string The literal string "refresh_token"

Token Response

The response is the same as the initial token response – it will contain a new access token to query APIs and a new refresh token for when the access token expires.

Parameter Type Description
access_token string A short-lived token to use in API call authentication
refresh_token string A refresh token to be used to generate new access tokens
token_type string The literal string "bearer"
scope string The scopes the access token will have access to
expires_in integer The lifetime in seconds of the access token, as measured in seconds from the current time

Example Token Response

{
  "access_token": "c5e9459d-dc6f-4567-bce4-050ec965f22e",
  "expires_in": 86399,
  "scope": "balances:read,orders:create",
  "refresh_token": "ce0f14af-74dd-4767-a4e7-286e98b944c1",
  "token_type": "Bearer"
}

Implicit Grant Flow

In addition to the authorization code flow, Gemini also supports the OAuth 2.0 implicit grant flow. This is a simplified version of the authorization code flow and is not recommended for most applications. This OAuth flow is not available by default, please reach out to trading@gemini.com to request access to the implicit grant flow.

When the access_token expires you must request a new one using either the implicit flow or authorization code flow.

Send request to following URL with URL parameters

GET https://exchange.gemini.com/auth

First direct users to Gemini like the example below

GET https://exchange.gemini.com/auth?response_type=token&client_id=my_id&redirect_uri=https://example.com/redirect?scope=Trader&state=7j87

URL Parameters

Parameter Type Description
response_type string The literal string "token"
client_id string Unique id of your application. This is provided in your API settings
redirect_uri string The URL users should be returned to when they authorize. Note, this URL must be included in your list of approved redirect_uris in your app registration
state string A random string that will be returned to you in the response.
scope string A comma separated list of scopes corresponding to the access you're requesting for your application. Note, these scopes must be included in your list of scopes in your app registration

Users will then be sent to Gemini login with their credentials. Once they do they will be sent to the redirect_uri provided.

Authorization Response (URL Parameters)

Example redirect_uri response after user login

https://example.com/redirect#access_token=3b7661f0-f156-498a-ad17-0fa4025ec907&state=7j87&token_type=bearer&scope=Trader&expires_in=83534

On successful authorization Gemini will redirect your user to the redirect_uri you supplied with additional parameters code and state. The parameter state should match the state you provided, otherwise you should not trust the response. access_token is the access token which you will use to make API calls on behalf of the user.

Field Type Description
access_token string A short-lived token to use in API call authentication. Is valid until the expires_in time reaches 0
token_type string The literal string "bearer"
scope string The scopes the access token will have access to
expires_in integer The lifetime in seconds of the access token, as measured in seconds from the current time

Using Access Tokens

Once you have an access token you can use it to call any Gemini API.

Most of the examples for the private APIs in these docs make use of API keys and corresponding headers, to use an access token simply update your header:

Header Description
Authorization The literal string "Bearer " concatenated to your temporary access_token
X-GEMINI-PAYLOAD The base64-encoded JSON payload (the payloads on OAuth do not require a nonce)
import requests
import json
import base64

url = "https://api.gemini.com/v1/mytrades"
access_token = "Bearer d9af2411-3e85-41bb-89f4-cf53750f04df"

payload = {
    "request": "/v1/mytrades",
    "symbol": "btcusd"
}
encoded_payload = json.dumps(payload).encode()
b64 = base64.b64encode(encoded_payload)

request_headers = { 
    "Authorization": access_token,
    "X-GEMINI-PAYLOAD": b64
}

response = requests.post(url,
                        data=None,
                        headers=request_headers,
                        verify=False)

my_trades = response.json()
$ curl -X POST https://api.gemini.com/v1/mytrades \ 
-H 'Authorization: Bearer d9af2411-3e85-41bb-89f4-cf53750f04df' \
-H 'X-GEMINI-PAYLOAD: eyJyZXF1ZXN0IjogIi92MS9teXRyYWRlcyIsICJzeW1ib2wiOiAiYnRjdXNkIn0='
import requests
import json
import base64

url = "https://api.gemini.com/v1/orders/history"
access_token = "Bearer d9af2411-3e85-41bb-89f4-cf53750f04df"

payload = {
    "request": "/v1/orders/history",
    "symbol": "btcusd"
}
encoded_payload = json.dumps(payload).encode()
b64 = base64.b64encode(encoded_payload)

request_headers = { 
    "Authorization": access_token,
    "X-GEMINI-PAYLOAD": b64
}

response = requests.post(url,
                        data=None,
                        headers=request_headers,
                        verify=False)

my_orders = response.json()
$ curl -X POST https://api.gemini.com/v1/orders/history \ 
-H 'Authorization: Bearer d9af2411-3e85-41bb-89f4-cf53750f04df' \
-H 'X-GEMINI-PAYLOAD: eyJyZXF1ZXN0IjogIi92MS9teXRyYWRlcyIsICJzeW1ib2wiOiAiYnRjdXNkIn0='

OAuth Scopes

Gemini uses a role-based system for its API. All OAuth applications are limited to the scopes in the following chart:

Endpoint URI Scope
Get Deposit Addresses /v1/addresses/:network addresses:read, addresses:create
New Deposit Address /v1/deposit/:network/newAddress addresses:create
Create Approved Address /v1/approvedAddresses/:network/request addresses:create
View Approved Address List /v1/approvedAddresses/account/:network addresses:read
Remove Address from Approved Address List /v1/approvedAddresses/:network/remove addresses:create
Get Available Balances /v1/balances balances:read
Get Notional Balances v1/notionalbalances/:currency balances:read
Add A Bank /v1/payments/addbank banks:create
Add A Bank CAD /v1/payments/addbank/cad banks:create
View Payment Methods /v1/payments/methods banks:read, banks:create
New Clearing Order /v1/clearing/new clearing:create
Cancel Clearing Order /v1/clearing/cancel clearing:create
Confirm Clearing Order /v1/clearing/confirm clearing:create
Clearing Order Status /v1/clearing/status clearing:read
Clearing Order List /v1/clearing/list clearing:read
Clearing Broker List /v1/clearing/broker/list clearing:read
Clearing Trades /v1/clearing/trades clearing:read
Withdraw Crypto Funds /v1/withdraw/:currency crypto:send
Get Past Trades /v1/mytrades history:read
Get Orders History /v1/orders/history history:read
Get Notional Volume /v1/notionalvolume history:read
Get Trade Volume /v1/tradevolume history:read
Transfers /v1/transfers history:read
Custody Account Fees /v1/custodyaccountfees history:read
New Order /v1/order/new orders:create
Cancel Order /v1/order/cancel orders:create
Cancel All Session Orders /v1/order/cancel/session orders:create
Cancel All Active Orders /v1/order/cancel/all orders:create
Wrap Order /v1/wrap/:symbol orders:create
Get Instant Quote /v1/instant/quote/:side/:symbol orders:create
Execute Instant Order /v1/instant/execute orders:create
Order Status /v1/order/status orders:read
Get Active Orders /v1/orders orders:read
Account Detail /v1/account account:read

API keys use different roles for to access Gemini APIs. Please see roles for descriptions of each role and scope for API keys.

Revoke OAuth Token

The access_token may be revoked at any time by using v1/oauth/revokeByToken. Once a token is revoked or expires, it can no longer be used to make requests.

This endpoint is only available using an access_token and will revoke the token used to make the request.

HTTP Request

POST https://api.gemini.com/v1/oauth/revokeByToken

Parameters

No fields are expected in this request, other than the request name.

Parameter Type Description
request string The literal string "/v1/oauth/revokeByToken"

Sample payload json { "request": "/v1/oauth/revokeByToken" }

$ curl -X POST https://api.gemini.com/v1/oauth/revokeByToken \ 
-H 'Authorization: Bearer d9af2411-3e85-41bb-89f4-cf53750f04df' \
-H 'X-GEMINI-PAYLOAD: eyJyZXF1ZXN0IjogIi92MS9vYXV0aC9yZXZva2VCeVRva2VuIn0='

Response

An array that indicates the access_token has been revoked.

Field Type Description
message string A message that indicates the token has been revoked for the account
{
    "message": "OAuth tokens and codes have been revoked for 00000000-0000-0000-0000-000000000000 on your account."
}

Revision History

Date Notes
2020/08/20 Initial OAuth documentation