Knowledge Base
  • 💡Welcome To PointPay
  • 📃WhitePapper v 1.0
    • Disclaimer
    • Market Overview
      • Overview of 2018-2023
      • Evolution and Statement
      • Challenges and Opportunities
    • PointPay 2.0
      • Ecosystem Overview
      • Services Synergy
    • Crypto Exchange
      • Main Benefits
      • Security Measures
      • Customer Support
    • Digital Vault
      • Role in Ecosystem
      • Features and Benefits
      • Integration with other Services
    • PointPay Token
      • Token Info
      • Utility and Benefits
    • Project Future
      • Project Vision
      • Upcoming Features
    • Conclusion
  • 📈Tokenomics
  • ⚖️Token Swap Flow
  • 🔗Network
    • Mainnet&TestNet
    • Smart contracts
      • Contract Deployment
      • Deploy with Remix IDE
      • Deploy with Thirdweb
    • Explorer API
    • RPC API
  • Exchange API Documentation
    • Public endpoints | HTTP
      • Pairs List
      • Pairs Stats
      • Specific Pair Stats
      • Order Book Data
      • Market History
      • Market History Data
      • Products
      • Symbols
      • Depth List
      • Chart Data KLine
    • Private endpoints | HTTP
      • Authentication and API Keys
      • Create Limit Order
      • Cancel Order
      • My Active Orders
      • All My Trade Balances
      • My Specific Trade Balance
      • My Order Info
      • My Trades Info
      • My Order History
      • My Order History List
    • Basic structure | WEBSOKET
    • Public methods | WEBSOKET
      • Ping-Pong
      • System Time
      • KLine methods
      • Market Price methods
      • Market Status methods
      • Deals methods
      • Depth methods
    • Private methods | WEBSOKET
      • Authorization
      • My Assets methods
      • My Orders methods
Powered by GitBook
On this page
  • Get your API keys
  • Requirements
  • Connection Examples
  1. Exchange API Documentation
  2. Private endpoints | HTTP

Authentication and API Keys

Get your API keys to unlock full access to all PointPay API features.

PreviousPrivate endpoints | HTTPNextCreate Limit Order

Last updated 7 months ago

Get your API keys

Follow simple steps to generate API keys for using private endpoints:

  • to the PointPay exchange and navigate to the section in your profile. (Note: You also need to enable two-step authentication if you haven't already)

  • To create API keys, click Add API Key. A package of keys will be generated, including an API Public Key, an API Secret Key, and a WebSocket Token. You can create up to 5 packages of API keys.

  • Before using your API keys, they must be activated. To activate them, use the "Activate API" switch in the created package.

  • Authentication with API keys is required for using

  • WebSocket Token is required for usage of .

  • You can use authentication for retrieving additional data from

Requirements

  • Base URL: https://api.pointpay.io

  • Auth requests should be using POST method and should include:

    • Body data with JSON that contains the following params:

      • "request" - a request endpoint path without the domain name. Example: "/api/v1/account/balance"

        • "nonce" - a 13-character number that must always be greater than the nonce of the previous completed request. For example: "1704070810000". We suggest generating a nonce as the UNIX timestamp in milliseconds. This ensures you always get an incrementing number, but be careful not to send two API calls simultaneously, as their nonces will be identical, causing one of the requests to be rejected.

        • params of request (depending on choosen request)

    • Headers - With every request you need to provide next headers:

      • 'Content-type': 'application/json'

        • 'X-TXC-APIKEY': api_key (it's your public PointPay API key)

        • 'X-TXC-PAYLOAD': payload (it's payload is base64-encoded body data)

        • 'X-TXC-SIGNATURE': signature (it's signature is hex(HMAC_SHA512(payload), key=api_secret))

Connection Examples

To assist you in getting started with our API, we've provided sample code in multiple programming languages.

use GuzzleHttp\Client;

public function callApi()
{
    $apiKey = 'xxxxxxxxx';
    $apiSecret = 'xxxxxxxxxxxx';
    $request = '/api/v1/account/balances';
    $baseUrl = 'https://api.pointpay.io';

    $data = [
        'request' => $request,
        'nonce' => (string)\Carbon\Carbon::now()->getTimestampMs(),
    ];

    $completeUrl = $baseUrl . $request;
    $dataJsonStr = json_encode($data, JSON_UNESCAPED_SLASHES);
    $payload = base64_encode($dataJsonStr);
    $signature = hash_hmac('sha512', $payload, $apiSecret);

    $client = new Client();
    try {
        $res = $client->post($completeUrl, [
            'headers' => [
                'Content-type' => 'application/json',
                'X-TXC-APIKEY' => $apiKey,
                'X-TXC-PAYLOAD' => $payload,
                'X-TXC-SIGNATURE' => $signature
            ],
            'body' => json_encode($data, JSON_UNESCAPED_SLASHES)
        ]);
    } catch (\Exception $e) {
        return response()->json(['error' => $e->getMessage()]);
    }

    return response()->json(['result' => json_decode($res->getBody()->getContents())]);
}

Example 1 - Java native http client

example.java
import com.google.gson.Gson;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.junit.jupiter.api.Test;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;

class TestExample {

    Gson GSON = new Gson();
    String apiBasePath = "https://api.pointpay.io";
    String apiKey = "xxxxxxxxx";
    String apiSecret = "xxxxxxxxx";

    @Test
    void getBalance() throws Exception {
        String methodPath = "/api/v1/account/balance";
        String dataJson = GSON.toJson(new BalancesRequest(
                methodPath, "USDT", System.currentTimeMillis()
        ));
        String payload = Base64.getEncoder().encodeToString(dataJson.getBytes());
        String signature = new HmacUtils(HmacAlgorithms.HMAC_SHA_512, apiSecret).hmacHex(payload);

        try (var client = HttpClient.newHttpClient()) {
            var response = client.send(
                    HttpRequest.newBuilder()
                            .uri(URI.create(apiBasePath + methodPath))
                            .headers("Content-Type", "application/json",
                                    "X-TXC-APIKEY", apiKey,
                                    "X-TXC-PAYLOAD", payload,
                                    "X-TXC-SIGNATURE", signature)
                            .POST(HttpRequest.BodyPublishers.ofString(dataJson))
                            .build(),
                    HttpResponse.BodyHandlers.ofString()
            );
            ApiResponse apiResponse = GSON.fromJson(response.body(), ApiResponse.class);
            System.out.println(apiResponse.result());
        }
    }
}

record BalancesRequest(String request, String currency, Long nonce) {
}

record ApiResponse(Boolean success,
                   String message,
                   Integer code,
                   BalancesResponse result) {
}

record BalancesResponse(String available, String freeze) {
}
build.gradle
dependencies {
    implementation('commons-codec:commons-codec:1.17.0')
    implementation('com.squareup.okhttp3:okhttp:4.12.0')
    implementation('com.squareup.retrofit2:converter-gson:2.11.0')
    testImplementation platform('org.junit:junit-bom:5.10.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
}

Example 2 - Retrofit2 okhttp client

ExampleRetrofit.java
import com.google.gson.Gson;
import okhttp3.OkHttpClient;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;
import org.junit.jupiter.api.Test;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.Body;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;

import java.util.Base64;

interface ApiClient {
    @Headers("Content-Type: application/json")
    @POST("/api/v1/account/balance")
    Call<ApiResponse<BalancesResponse>> balance(
            @Body BalancesRequest balancesRequest,
            @Header("X-TXC-APIKEY") String apiKey,
            @Header("X-TXC-PAYLOAD") String payload,
            @Header("X-TXC-SIGNATURE") String signature
    );
}

class TestExampleRetrofit {

    String apiBasePath = "https://api.pointpay.io";
    String apiKey = "xxxxxxxxx";
    String apiSecret = "xxxxxxxxx";

    ApiClient apiClient = new Retrofit.Builder()
            .baseUrl(apiBasePath)
            .addConverterFactory(GsonConverterFactory.create())
            .client(new OkHttpClient.Builder().build())
            .build()
            .create(ApiClient.class);

    @Test
    void getBalance() throws Exception {
        String methodPath = "/api/v1/account/balance";
        BalancesRequest request = new BalancesRequest(
                methodPath, "USDT", System.currentTimeMillis()
        );
        String dataJson = new Gson().toJson(request);
        String payload = Base64.getEncoder().encodeToString(dataJson.getBytes());
        String signature = new HmacUtils(HmacAlgorithms.HMAC_SHA_512, apiSecret).hmacHex(payload);

        ApiResponse<BalancesResponse> apiResponse = apiClient.balance(request, apiKey, payload, signature)
                .execute().body();
        System.out.println(apiResponse.result());
    }
}

record BalancesRequest(String request, String currency, Long nonce) {
}

record ApiResponse<T>(Boolean success, String message, Integer code, T result) {
}

record BalancesResponse(String available, String freeze) {
}
build.gradle
dependencies {
    implementation('commons-codec:commons-codec:1.17.0')
    implementation('com.squareup.okhttp3:okhttp:4.12.0')
    implementation('com.squareup.retrofit2:retrofit:2.11.0')
    implementation('com.squareup.retrofit2:converter-gson:2.11.0')
    testImplementation platform('org.junit:junit-bom:5.10.0')
    testImplementation 'org.junit.jupiter:junit-jupiter'
}
import { HttpService, Injectable } from '@nestjs/common';
import * as crypto from 'crypto';
import { AxiosResponse } from 'axios';

export interface GetBalanceRequest {
  request: string;
  currency: string;
  nonce: string;
}

export interface GetBalances {
  success: boolean;
  message: string;
  result: {
    available: string;
    freeze: string;
  };
  code: number;
}

@Injectable()
export class PaymentService {
  constructor(private http: HttpService) {
    this.createInvoice().then(console.log);
  }
  createInvoice(): Promise<AxiosResponse<GetBalances>> {
    const now = Date.now();
    const input = {
      request: '/api/v1/account/balance',
      currency: 'ETH',
      nonce: `${now}`,
    } satisfies GetBalanceRequest;

    const secret = 'xxxxxxxx';
    const apiKey = 'xxxxxxxx';
    const baseUrl = 'https://api.pointpay.io';
    const payload = JSON.stringify(input, null, 0);
    console.log(payload);
    const jsonPayload = Buffer.from(payload).toString('base64');
    const encrypted = crypto
      .createHmac('sha512', secret)
      .update(jsonPayload)
      .digest('hex');

    console.log({
      'Content-type': 'application/json',
      'X-TXC-APIKEY': apiKey,
      'X-TXC-PAYLOAD': jsonPayload,
      'X-TXC-SIGNATURE': encrypted,
    });
    return this.http
      .post<GetBalances>(`/api/v1/account/balance`, payload, {
        headers: {
          'Content-type': 'application/json',
          'X-TXC-APIKEY': apiKey,
          'X-TXC-PAYLOAD': jsonPayload,
          'X-TXC-SIGNATURE': encrypted,
        },
        baseURL: baseUrl,
      })
      .toPromise();
  }
}
import json
import time
import base64
import hmac
import hashlib
import requests

# Constants
REQUEST_URL = "https://api.pointpay.io"
API_PATH = "/api/v1/account/balance"
API_KEY = "xxxxxxxxx"
API_SECRET = "xxxxxxxxx"

def calc_signature(payload: str) -> str:
    """
    Calculate the HMAC-SHA512 signature.

    Args:
        payload (str): Base64-encoded data.

    Returns:
        str: Hex-encoded HMAC-SHA512 signature.
    """
    signature = hmac.new(
        API_SECRET.encode(),
        payload.encode(),
        hashlib.sha512
    ).hexdigest()
    return signature

def call_api():
    # Prepare the request data
    data = {
        "request": API_PATH,
        "currency": "ETH",
        "nonce": str(int(time.time() * 1000))  # Current timestamp in milliseconds
    }

    # Convert data to JSON string
    data_json_str = json.dumps(data, separators=(',', ':'))

    # Create payload and signature
    payload = base64.b64encode(data_json_str.encode()).decode()
    signature = calc_signature(payload)

    # Prepare the headers
    headers = {
        "Content-Type": "application/json",
        "X-TXC-APIKEY": API_KEY,
        "X-TXC-PAYLOAD": payload,
        "X-TXC-SIGNATURE": signature
    }

    # Make the POST request
    response = requests.post(
        url=f"{REQUEST_URL}{API_PATH}",
        headers=headers,
        data=data_json_str
    )

    # Log the response
    print(response.status_code)
    print(response.text)

if __name__ == "__main__":
    call_api()/
package main

import (
	"crypto/hmac"
	"crypto/sha512"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

const (
	requestURL = "https://api.pointpay.io"
	apiPath    = "/api/v1/account/balance"
	apiKey     = "xxxxxxxxx"
	apiSecret  = "xxxxxxxxx"
)

func calcSignature(payload string) string {
	h := hmac.New(sha512.New, []byte(apiSecret))
	h.Write([]byte(payload))
	return hex.EncodeToString(h.Sum(nil))
}

func callAPI() {
	data := map[string]string{
		"request": apiPath,
		"currency": "USDT",
		"nonce":    fmt.Sprintf("%d", time.Now().UnixNano()/int64(time.Millisecond)),
	}

	dataJSON, _ := json.Marshal(data)
	dataJSONString := string(dataJSON)

	payload := base64.StdEncoding.EncodeToString([]byte(dataJSONString))
	signature := calcSignature(payload)

	client := &http.Client{}
	req, _ := http.NewRequest("POST", requestURL+apiPath, strings.NewReader(dataJSONString))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-TXC-APIKEY", apiKey)
	req.Header.Set("X-TXC-PAYLOAD", payload)
	req.Header.Set("X-TXC-SIGNATURE", signature)

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)
	
	fmt.Println(string(body))
}

func main() {
	callAPI()
}
Errors

Response example:

{
    "code": 400,
    "success": false,
    "message": "authentication failure",
    "result": []
}

This error occurs in the following cases:

  • The request was signed incorrectly.

  • Some of the provided parameters are incorrect.

  • The base URL or path is incorrect.

Provided is incorrect or less than on the previous completed request

The API keys are not .

Sign In
API Management
private HTTP API endpoints
private WebSocket methods
public HTTP API endpoints
nonce
activated