Skip to main content

API Overview

This article provides an overview of the API and its endpoints.

To see the endpoints list and all information concerning them, click here.

General Information

  • The base endpoint is API_URL.
  • All endpoints return either a JSON object or array.
  • Data is returned in descending order: Newest first, oldest last.
  • Currently, TESTNET is used for all networks:
  • You can insert an internal ID, on the External ID parameter, that you have in your own system to better keep track of certain operations: orders, deposits, exchanges and/or payouts (check the endpoints documentation to see the endpoints where it is applicable).

General information on endpoints and public endpoints:

  • For GET endpoints, parameters must be sent as a query string.
  • For POST, PUT, and DELETE endpoints, the parameters may be sent as a query string or in the request body with content type application/x-www-form-urlencoded.

    You may mix parameters between both the query string and request body, if you wish to do so.

  • Parameters may be sent in any order.
  • If a parameter is sent in both the query string and request body, the query string parameter is used.

Endpoint Security

  • All endpoints are protected by HMAC SHA256 signature. API key/secret pairs are generated at https://my.coinsflow.pl.
  • To sign a request, use the Authorization header containing the following parameters:
    • username
    • algorithm
    • headers
    • signature

Example: Authorization: hmac username="$HMAC_KEY", algorithm="hmac-sha256", headers="date request-line", signature="$SIGNATURE"

Sample bash script demonstrating how to sign a request:

#!/bin/bash

set -e

METHOD=$(echo "$1" | tr a-z A-Z)
ENDPOINT=$2
PAYLOAD=$3
GATEWAY_HOST=api.sandbox.coinsflow.pl
HMAC_KEY=<insert API_KEY here>
HMAC_SECRET=<insert API_SECRET here>

ENDPOINT_URL="https://$GATEWAY_HOST$ENDPOINT"
DATE=$(LC_ALL=en_US.utf8 date -u +"%a, %d %b %Y %H:%M:%S UTC")

if [ -z "$METHOD" ] || [ -z "$ENDPOINT" ]
then
echo -e "Usage `basename "$0"` METHOD ENDPOINT\nExample GET /endpoint"
exit 0
fi

SIGN_STRING="date: $DATE\n$METHOD $ENDPOINT HTTP/1.1"
SIGNATURE=$(echo -en $SIGN_STRING | openssl dgst -sha256 -hmac "$HMAC_SECRET" -binary | base64)

# Helper function to URL-encode the payload
urlencode() {
echo -n "$1" | jq -sRr @uri
}

# URL-encode the payload if provided
if [[ -n "$PAYLOAD" ]]; then
FORM_BODY=""
IFS='&' read -ra PARAMS <<< "$PAYLOAD"
for PARAM in "${PARAMS[@]}"; do
KEY=$(echo "$PARAM" | cut -d'=' -f1)
VALUE=$(echo "$PARAM" | cut -d'=' -f2-)
ENCODED_KEY=$(urlencode "$KEY")
ENCODED_VALUE=$(urlencode "$VALUE")
FORM_BODY+="${ENCODED_KEY}=${ENCODED_VALUE}&"
done
FORM_BODY=${FORM_BODY%&} # Remove trailing '&'
fi

# Calculate SHA-256 digest if payload exists
if [[ -n "$FORM_BODY" ]]; then
DIGEST=$(echo -n "$FORM_BODY" | openssl dgst -sha256 -binary | base64)
else
DIGEST=""
fi

if [[ -n "$FORM_BODY" ]]; then
curl -d "$FORM_BODY" -s -X "$METHOD" "$ENDPOINT_URL" -H "Host: $GATEWAY_HOST" -H "Date: $DATE" -H "Digest: SHA-256=$DIGEST" -H "Authorization: hmac username=\"$HMAC_KEY\", algorithm=\"hmac-sha256\", headers=\"date request-line\", signature=\"$SIGNATURE\"" -H "Content-Type: application/x-www-form-urlencoded" | jq
else
curl -s -X "$METHOD" "$ENDPOINT_URL" -H "Host: $GATEWAY_HOST" -H "Date: $DATE" -H "Authorization: hmac username=\"$HMAC_KEY\", algorithm=\"hmac-sha256\", headers=\"date request-line\", signature=\"$SIGNATURE\"" | jq
fi

Example usage for POST:

./hmac.sh POST /deposits "asset=a1b98c9a-e5d8-4cd2-b1be-37d05276008b&amount=1"

Example usage for GET:

./hmac.sh GET /assets

Integration Examples

If your application is developed in a different language, you may need some help integrating the endpoints in your code. Below you can find examples on how to integrate with some popular languages.

If you need help with a language that is not mentioned, please contact our support team.

Python Example

The code below is an example of how to integrate our endpoints into your own application code written in Python.


import hashlib
import hmac
import requests
import base64
from datetime import datetime, timezone

# GET example - Get inactive assets
# method = 'GET'
# endpoint = '/assets?active=false'

# POST example - Make Payout
method = 'POST'
endpoint = '/payouts?amount=0.1' # query parameters have higher precedence over body parameters and can be mixed
payload = {
'destination': '0x023C3eD42d6F50e8695b9cA422ea98aAA0c3654b',
'asset': 'a7ae72b6-6570-4044-b69f-32b644e49a8a'
}

# POST example - Get temporary deposit address
# method = 'POST'
# endpoint = '/deposits'
# payload = {
# # TRX_TEST
# 'asset': 'df6abe62-04a2-49d5-898e-c0f359f7cd81'
# }

# Absolute endpoint url
endpoint_url = 'https://api.sandbox.coinsflow.pl' + endpoint

# Replace credentials with your actual secret key
public_key = 'gcXZDyKETqJjvnBBFUO4uYq6Vbo9jvmx4N8LexzwyR5CdwkWKNDWMP87FgKokAwR'
secret_key = 'sYZPfoNzA8LNvSV19lPp851byhwqCMWufg6EbHF690ogHsi7ezHPLR0ZqbBRy9eE'


def generate_hmac_sha256_signature(key, message):
return base64.b64encode(hmac.new(key.encode(), message.encode(), hashlib.sha256).digest()).decode('utf-8')


# Press the green button in the gutter to run the script.
if __name__ == '__main__':

# Get the current UTC date and time
gmt_datetime = datetime.now(timezone.utc).strftime("%a, %d %b %Y %H:%M:%S GMT")

# Generate the HMAC SHA-256 signature
signatureStr = "date: " + gmt_datetime + "\n@request-target: " + method.lower() + " " + endpoint
signature = generate_hmac_sha256_signature(secret_key, signatureStr)

headers = {
'date': gmt_datetime,
'content-type': 'application/x-www-form-urlencoded',
'authorization': 'hmac username="' + public_key + '", '
'algorithm="hmac-sha256", headers="date '
'@request-target", signature="' + signature + '"'
}

# Calculate request BODY Digest signature for 'POST', 'PUT' methods only, GET requests does not need this
if method in ['POST', 'PUT']:
# Convert the payload dictionary to URL-encoded string
payload_encoded = '&'.join([f'{key}={payload[key]}' for key in payload])
# Generate the SHA-256 digest
digest = base64.b64encode(bytes.fromhex(hashlib.sha256(payload_encoded.encode()).hexdigest())).decode('utf-8')
headers['digest'] = "SHA-256=" + digest
else:
payload_encoded = None

# Send the request
request = requests.Request(method, endpoint_url, data=payload_encoded, headers=headers)
prepared_request = request.prepare()

# Print the request method and endpoint
print("Endpoint: " + prepared_request.method + " " + prepared_request.url)

# Print the headers that will be sent
print("Request Headers:")
for key, value in prepared_request.headers.items():
print(f"{key}: {value}")

# Send the request
response = requests.Session().send(prepared_request)

# Check the response
if response.status_code in {200, 201}:
print("Request succeeded!")
print(response.text)
else:
print(f"Request failed with status code {response.status_code}: {response.text}")

PHP Example

The code below is an example of how to integrate our endpoints into your own application code written in PHP.

declare(strict_types=1);

$host = 'api.sandbox.coinsflow.pl';
$key = '';
$secret = '';

$endpoint = '/assets';
$method = 'GET';
$payload = [];

// Generate HMAC signature
$date = (new DateTime('now', new DateTimeZone('GMT')))->format('D, d M Y H:i:s e');
$signString = sprintf("date: %s\n@request-target: %s %s", $date, strtolower($method), $endpoint);
$signature = base64_encode(hash_hmac('sha256', $signString, $secret, true));
$digest = sprintf('SHA-256=%s', base64_encode(hash('sha256', http_build_query($payload), true)));

// Add request headers
$headers = [
"date: $date",
"digest: $digest",
"content-type: application/x-www-form-urlencoded",
sprintf('authorization: hmac username="%s", algorithm="hmac-sha256", headers="date @request-target", signature="%s"', $key, $signature)
];

// Initialize cURL session
$curl = curl_init(sprintf('https://%s%s', $host, $endpoint));
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

// POST example
if($method === 'POST') {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($payload));
}

// Execute the cURL request and get the response
$response = curl_exec($curl);

// Check for cURL errors
if (curl_errno($curl)) {
echo 'cURL error: ' . curl_error($curl);
}

// Close cURL session
curl_close($curl);

// Output the response
echo $response;

Node.js Example

The code below is an example of how to integrate our endpoints into your own application code written in Node.js.

#!/usr/bin/env node
const axios = require('axios');
const crypto = require('crypto');
const moment = require('moment');
const querystring = require('querystring');
/**
* Configuration for the API client
* @typedef {Object} Config
* @property {string} url - Base URL of the API
* @property {string} host - API host name
* @property {string} hmac_key - HMAC username/key
* @property {string} hmac_secret - HMAC secret for signing
*/
/**
* API Client with HMAC Authentication
*/
class ApiClient {
/**
* Create a new API client instance
* @param {Config} config - Configuration object
*/
constructor(config) {
this.config = config;
}
/**
* Send a GET request to the API
* @param {string} endpoint - API endpoint
* @returns {Promise<any>} Response data
*/
async get(endpoint) {
try {
const headers = this.generateHeaders('GET', endpoint);
const response = await axios.get(this.config.url + endpoint, { headers });
return response.data;
} catch (error) {
this.handleError(error);
}
}
/**
* Send a POST request to the API
* @param {string} endpoint - API endpoint
* @param {Object} payload - Request payload
* @returns {Promise<any>} Response data
*/
async post(endpoint, payload = {}) {
try {
const encodedPayload = querystring.stringify(payload);
const headers = {
...this.generateHeaders('POST', endpoint, payload),
'Content-Type': 'application/x-www-form-urlencoded'
};
const response = await axios.post(
this.config.url + endpoint,
encodedPayload,
{ headers }
);
return response.data;
} catch (error) {
this.handleError(error);
}
}
/**
* Generate headers for HMAC authentication
* @param {string} method - HTTP method
* @param {string} endpoint - API endpoint
* @returns {Object} Headers object
* @private
*/
generateHeaders(method, endpoint, payload = {}) {
const date = moment().utc().format("ddd, DD MMM YYYY HH:mm:ss") + " GMT";
const signKey = this.sign(date, method, endpoint);
const headers = {
'Host': this.config.host,
'Date': date,
'Authorization': `hmac username="${this.config.hmac_key}", algorithm="hmac-sha256", headers="date @request-target", signature="${signKey}"`
};
// Add digest header for POST requests with payload
if (method === 'POST' && Object.keys(payload).length > 0) {
const encodedPayload = querystring.stringify(payload);
const payloadHash = crypto
.createHash('sha256')
.update(encodedPayload)
.digest('base64');
headers['Digest'] = `SHA-256=${payloadHash}`;
}
return headers;
}
/**
* Generate HMAC signature
* @param {string} date - Formatted date string
* @param {string} method - HTTP method
* @param {string} endpoint - API endpoint
* @returns {string} Base64 encoded signature
* @private
*/
sign(date, method, endpoint) {
const signString = `date: ${date}\n@request-target: ${method.toLowerCase()} ${endpoint}`;
return crypto
.createHmac('sha256', this.config.hmac_secret)
.update(signString)
.digest('base64');
}
/**
* Handle API errors
* @param {Error} error - Error object
* @private
*/
handleError(error) {
if (error.response) {
console.error('Full error response:', {
status: error.response.status,
statusText: error.response.statusText,
data: error.response.data,
headers: error.response.headers
});
throw new Error(`API Error: ${error.response.status} - ${error.response.statusText} - ${JSON.stringify(error.response.data)}`);
}
throw error;
}
}
// Example usage
async function main() {
// Configuration
const config = {
url: 'https://api.sandbox.coinsflow.pl',
host: 'api.sandbox.coinsflow.pl',
hmac_key: '',
hmac_secret: ''
};
// Create client instance
const client = new ApiClient(config);
try {
// GET request example
const getResult = await client.get('/assets?active=true');
console.log('GET Response:', JSON.stringify(getResult, null, 2));
// POST Payout request example
const postPayload = {
amount: '0.1',
destination: 'address-here',
asset: 'df6abe62-04a2-49d5-898e-c0f359f7cd81'
};
const postResult = await client.post('/payouts', postPayload);
console.log('POST Response:', JSON.stringify(postResult, null, 2));
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
}
// Execute if running directly
if (require.main === module) {
main().catch(error => {
console.error('Fatal error:', error);
process.exit(1);
});
}
module.exports = ApiClient;

Go Example

The code below is an example of how to integrate our endpoints into your own application code written in the Go language.

package main

import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"net/http"
"net/url"
"sort"
"strings"
"time"
)

func generateHMACSignature(secretKey, message string) string {
key := []byte(secretKey)
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}

func main() {
var method = "GET"
var endpoint = ""

// Replace 'payload' with the data you want to send in the POST request
payload := url.Values{}
payload.Set("param1", "")
payload.Set("param2", "")
// Add more parameters as needed

// Absolute endpoint URL
endpointURL := "https://api.sandbox.coinsflow.pl" + endpoint

// Replace credentials with your actual secret key
publicKey := ""
secretKey := ""

// Get the current UTC date and time
gmtDatetime := time.Now().UTC().Format(time.RFC1123)
gmtDatetime = strings.ReplaceAll(gmtDatetime, "UTC", "GMT")

// Convert the payload dictionary to URL-encoded string
sortedPayload := url.Values{}
for key := range payload {
sortedPayload[key] = payload[key]
}
sortedPayloadString := sortedPayload.Encode()

// Generate the HMAC SHA-256 signature
signatureStr := fmt.Sprintf("date: %s\n@request-target: %s %s", gmtDatetime, strings.ToLower(method), endpoint)
signature := generateHMACSignature(secretKey, signatureStr)

// Generate the SHA-256 digest
hash := sha256.New()
hash.Write([]byte(sortedPayloadString))
digest := base64.StdEncoding.EncodeToString(hash.Sum(nil))

headers := map[string]string{
"date": gmtDatetime,
"digest": "SHA-256=" + digest,
"content-type": "application/x-www-form-urlencoded",
"authorization": fmt.Sprintf(`hmac username="%s", algorithm="hmac-sha256", headers="date @request-target", signature="%s"`, publicKey, signature),
}

// Create the request
client := &http.Client{}
req, err := http.NewRequest(method, endpointURL, bytes.NewBufferString(sortedPayloadString))
if err != nil {
fmt.Println("Error creating request:", err)
return
}

// Set headers
for key, value := range headers {
req.Header.Set(key, value)
}

// Print the request method and endpoint
fmt.Println("Endpoint:", req.Method, req.URL.String())

// Print the headers that will be sent
fmt.Println("Request Headers:")
for key, value := range req.Header {
fmt.Printf("%s: %s\n", key, strings.Join(value, ","))
}

// Send the request
resp, err := client.Do(req)
if err != nil {
fmt.Println("Request failed:", err)
return
}
defer resp.Body.Close()

// Check the response
if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
fmt.Println("Request succeeded!")
// Handle successful response here
} else {
fmt.Printf("Request failed with status code %d\n", resp.StatusCode)
// Handle error response here
}
}

Need further assistance?

If you didn't find what you were looking for, please contact our support team.