Gemini Crypto Exchange Logo
Requests

Private API Invocation

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.


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.

Authenticated APIs do not submit their payload as POSTed data, but instead put it in the X-GEMINI-PAYLOAD header

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.

Headers

HeaderValue
Content-Length0
Content-Typetext/plain
X-GEMINI-APIKEYYour Gemini API key
X-GEMINI-PAYLOADThe base64-encoded JSON payload
X-GEMINI-SIGNATUREhex(HMAC_SHA384(base64(payload), key=api_secret))
Cache-Controlno-cache

Examples

To use the private WebSocket APIs, you need to properly authenticate your requests. This page explains how to generate the necessary authentication headers.


Request JSON

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

{
    "request": "/v1/order/events",
    "nonce": <nonce>
}
json

Whitespace 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 Encoding

The JSON payload needs to be base64 encoded:

~$ base64 << EOF
> {
>     "request": "/v1/order/events",
>     "nonce": <nonce>
> }
> EOF
ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYs
CgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=
bash

Generating the Signature

In this example, the api_secret is 1234abcd:

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

Complete Python Example

import ssl
import websocket
import json
import base64
import hmac
import hashlib
import time

def on_message(ws, message):
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws):
    print("### closed ###")

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

payload = {"request": "/v1/order/events","nonce": time.time()}
encoded_payload = json.dumps(payload).encode()
b64 = base64.b64encode(encoded_payload)
signature = hmac.new(gemini_api_secret, b64, hashlib.sha384).hexdigest()


ws = websocket.WebSocketApp("wss://api.sandbox.gemini.com/v1/order/events",
                            on_message=on_message,
                            header={
                                'X-GEMINI-PAYLOAD': b64.decode(),
                                'X-GEMINI-APIKEY': gemini_api_key,
                                'X-GEMINI-SIGNATURE': signature
                            })
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
python

Final Request Format

The final request will look like this. The linebreaks are added for clarity, your http library may or may not put them in.

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