Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.whitebit.com/llms.txt

Use this file to discover all available pages before exploring further.

Introduction

WhiteBIT OAuth 2.0 implementation uses the standard Authorization Code Grant flow. This flow is suitable for server-side applications where the client secret can be securely stored. The OAuth 2.0 endpoints documented on this page cover the Authorization Code Grant flow for read access to account data. For partner-issued API keys, a separate OAuth API key flow uses Authorization Code with PKCE (S256), a 4-hour access token, and no refresh token. See the Fast API Key integration guide for the full integration.
package main

import (
	"bytes"
	"context"
	"crypto/rand"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"time"
)

// TokenResponse represents the OAuth token response
type TokenResponse struct {
	Data struct {
		AccessToken  string `json:"access_token"`
		ExpiresIn    int    `json:"expires_in"`
		RefreshToken string `json:"refresh_token"`
		Scope        string `json:"scope"`
		TokenType    string `json:"token_type"`
	} `json:"data"`
}

const BASE_URL = "https://whitebit.com"
const CLIENT_ID = "YOUR_CLIENT_ID"
const CLIENT_SECRET = "YOUR_CLIENT_SECRET"

// Initiate OAuth flow
func initiateOAuthFlowHandler(w http.ResponseWriter, r *http.Request) {
	b := make([]byte, 32)
	rand.Read(b)
	state := base64.RawURLEncoding.EncodeToString(b)

	// In production, store state in session

	authURL, _ := url.Parse(BASE_URL + "/auth/login")
	q := authURL.Query()
	q.Set("clientId", CLIENT_ID)
	q.Set("state", state)
	authURL.RawQuery = q.Encode()

	http.Redirect(w, r, authURL.String(), http.StatusFound)
}

// Handle OAuth callback
func oauthCallbackHandler(w http.ResponseWriter, r *http.Request) {
	code := r.URL.Query().Get("code")
	state := r.URL.Query().Get("state")

	// Verify state here...

	token, err := exchangeCodeForToken(r.Context(), code)
	if err != nil {
		http.Error(w, "Authentication failed", http.StatusInternalServerError)
		return
	}

	fmt.Fprintf(w, "Token received: %s", token.Data.AccessToken)
}

func exchangeCodeForToken(ctx context.Context, code string) (*TokenResponse, error) {
	data := url.Values{}
	data.Set("client_id", CLIENT_ID)
	data.Set("client_secret", CLIENT_SECRET)
	data.Set("code", code)

	resp, err := http.PostForm(BASE_URL+"/oauth2/token", data)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var tokenResponse TokenResponse
	json.NewDecoder(resp.Body).Decode(&tokenResponse)
	return &tokenResponse, nil
}

Scopes

Available Scopes (requested during client setup):
  • general: General API access
  • show.userinfo: Access to basic user information
  • users.read: Read user data
  • users.email.read: Read user email information
  • users.kyc.read: Information about whether a user has passed KYC verification
  • orders.read: Read trading orders
  • orders.create: Create trading orders
  • orders.delete: Delete trading orders
  • balances.read: Read account balances
  • markets.read: Read market information
  • deals.read: Read trading deals
  • orders_history.read: Read order history
  • users.transactions.read: Read user transactions
  • users.converts.read: Read currency conversion history
  • users.balances.read: Read user account balances
  • users.orders.read: Read user orders
  • users.deals.read: Read user deals
  • apikeys.create: Issue an OAuth-bound API key during the consent flow
  • apikeys.read: Read OAuth-issued API key state and retrieve its secret once
  • apikeys.delete: Delete an OAuth-issued API key owned by the OAuth2 client