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
GETendpoints, parameters must be sent as aquerystring. - For
POST,PUT, andDELETEendpoints, the parameters may be sent as aquery stringor in therequestbody with content typeapplication/x-www-form-urlencoded.You may mix parameters between both the
querystring andrequestbody, if you wish to do so. - Parameters may be sent in any order.
- If a parameter is sent in both the
querystring andrequestbody, thequerystring 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
Authorizationheader 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
}
}