Skip to content

Enterprise version

This section is dedicated to the paying enterprise version. This plan use the same API but is watermark free and you can setup your own sub-domain for the perfect integration.

Once subscribed to the enterprise plan you will receive an account id and a secret key. These two keys are mandatory to sign your request and remove the watermark.

Remove Image-Charts watermark by signing URLs

Signing request must be done server-side otherwise anyone will be able to reuse your secret key. Beside signing there are no other computation involved server-side. Image-Charts is still the fastest option compared to server-side charts setup and generation.

You will need to sign the url using HMAC-SHA256 hash algorithm. Before hashing the URL add your account id inside it using the &icac=YOUR_ACCOUNT_ID parameter, then hash it and at the resulting hash in the &ichm=GENERATED_HASH query parameter. Don't forget to convert URL-unsafe characters before generating the signature.

Note that Image-Chart supports ichm parameter both at the end of the query string (e.g. https://image-charts.com/chart?{QUERY_STRING}&ichm=GENERATED_HASH) and at the beginning (e.g https://image-charts.com/chart?ichm=GENERATED_HASH&{QUERY_STRING}).

As an example here is a graph signed, without watermark:

chart

&icac=fgribreau
&ichm=0785cf22a0381c2e0239e27c126de4181f501d117c2c81745611e9db928b0376

Signing your URLs will ensure that no-one beside you created it and Image-Charts will verify the generated hash to be sure you your account created it. Here are some examples in various languages:

// HMAC Helper
const crypto = require('crypto');
const qs = require('querystring');

function sign(secretKey, query) {
  return crypto
    .createHmac('sha256', secretKey)
    .update(query)
    .digest('hex');
}

// Now let's generate a chart url that will be sent inside an email or a bot message

// First setup our account
const ACCOUNT_ID = 'MY_ACCOUNT_ID';
const SECRET_KEY = 'MY_SECRET_KEY';

// Then generate the watermark-free url
// qs.stringify will encode URL-unsafe characters for us
const rawQuerystring = qs.stringify({
  cht: 'bvs',
  icac: ACCOUNT_ID, // don't forget to add your account id before signing it
  chd: 's:93zyvneTTO',
  chs: '400x401',
});
const signature = sign(SECRET_KEY, rawQuerystring);
const publicUrl = `https://image-charts.com/chart?${rawQuerystring}&ichm=${signature}`;

// Finally send it to slack or via email, here we simply use console.log
console.log(publicUrl);
# -*- coding: utf-8 -*-

from urllib.parse import urlencode
import hmac, hashlib, codecs

def sign(query, secretKey):
  return codecs.getencoder('hex')(hmac.new(secretKey.encode('utf-8'), query.encode('utf-8'), hashlib.sha256).digest())[0].decode('utf-8')

if __name__ == '__main__':
  # First setup our account
  ACCOUNT_ID = 'MY_ACCOUNT_ID'
  SECRET_KEY = 'MY_SECRET_KEY'

  # Then generate the watermark-free url
  # urlencode will encode URL-unsafe characters for us
  rawQuerystring = urlencode({
      'cht': 'bvs',
      'chd': 's:93zyvneTTO',
      'chs': '400x401',
      'icac': ACCOUNT_ID  # don't forget to add your account id before signing it
  })
  signature = sign(rawQuerystring, SECRET_KEY)
  publicUrl = "https://image-charts.com/chart?" + rawQuerystring + "&ichm=" + signature

  # Finally send it to slack or via email, here we simply use print
  print(publicUrl)
<?php
function sign($query, $secretKey) {
  return hash_hmac('sha256', $query, $secretKey);
}

// First setup our account
define('ACCOUNT_ID', 'MY_ACCOUNT_ID');
define('SECRET_KEY', 'MY_SECRET_KEY');

// Then generate the watermark-free url
// http_build_query will encode URL-unsafe characters for us

$rawQuerystring = http_build_query(array(
  'cht' => 'bvs',
  'chd' => 's:93zyvneTTO',
  'chs' => '400x401',
  'icac' => ACCOUNT_ID  // don't forget to add your account id before signing it
));

$signature = sign($rawQuerystring, SECRET_KEY);
$publicUrl = 'https://image-charts.com/chart?' . $rawQuerystring . '&ichm=' . $signature;

// Finally send it to slack or via email, here we simply use print
echo $publicUrl;
using System;
using System.Text;

namespace CustomExtensions
{
    public static class StringExtension
    {
        public static string HmacSha256Digest(this string message, string secret)
        {
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] keyBytes = encoding.GetBytes(secret);
            byte[] messageBytes = encoding.GetBytes(message);
            System.Security.Cryptography.HMACSHA256 cryptographer = new System.Security.Cryptography.HMACSHA256(keyBytes);
            byte[] bytes = cryptographer.ComputeHash(messageBytes);
            return BitConverter.ToString(bytes).Replace("-", "").ToLower();
        }
    }
}

namespace App
{
    using CustomExtensions;
    public class Program
    {
        public static void Main(string[] args)
        {
            string account_id = "YOUR_ACCOUNT_ID";
            string secret_key = "YOUR_SECRET_KEY";

            var sbchart = new StringBuilder();

            // specify you querystring
            // Note: we use Uri.EscapeDataString instead of HttpUtility.UrlEncode,
            //       learn why there: https://stackoverflow.com/a/47877559/745121
            sbchart.AppendFormat("cht={0}", Uri.EscapeDataString("pd"));
            sbchart.AppendFormat("&icac={0}", Uri.EscapeDataString(account_id));
            sbchart.AppendFormat("&chd={0}", Uri.EscapeDataString("a:124,736,372"));
            sbchart.AppendFormat("&chs={0}", Uri.EscapeDataString("400x400"));
            sbchart.AppendFormat("&chdl={0}", Uri.EscapeDataString("Expansion|Payroll|Equipment"));
            sbchart.AppendFormat("&chli={0}", Uri.EscapeDataString("95K€"));
            sbchart.AppendFormat("&chl={0}", Uri.EscapeDataString("10K€|40K€|45K€"));

            var querystring = sbchart.ToString();
            string signature = querystring.HmacSha256Digest(secret_key);
            Console.WriteLine("https://image-charts.com/chart?ichm="+signature+"&"+querystring);
        }
    }
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

class Program {
    public static void main(String[] args) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
        // First setup our account
        String ACCOUNT_ID = "ACCOUNT_ID";
        String SECRET_KEY = "SECRET_KEY";

        // specify you querystring
        String querystring = "cht=bvs&icac=" + ACCOUNT_ID + "&chd=s:93zyvneTTO&chs=400x401";

        // don't forget to add your account id before signing it
        String signature = HmacSha256Digest(querystring, SECRET_KEY);

        // Then generate the watermark-free url
        String publicUrl = "https://image-charts.com/chart?" + querystring + "&ichm=" + signature;

        // Finally send it to slack or via email or inside an PDF report, here we print into the console output
        System.out.println(publicUrl);
    }


    public static String HmacSha256Digest(String data, String key) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec signingKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(signingKey);
        byte[] rawHmac = mac.doFinal(data.getBytes("UTF-8"));
        byte[] hexArray = {(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'};
        byte[] hexChars = new byte[rawHmac.length * 2];
        for ( int j = 0; j < rawHmac.length; j++ ) {
            int v = rawHmac[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
}
# tested on ruby 2.3
require 'openssl'
require 'uri'

SECRET_KEY = "MY_ACCOUNT_ID"
ACCOUNT_ID = "MY_SECRET_KEY"

# don't forget to add your account id before signing it
# Then generate the watermark-free url
# CGI::escape will encode URL-unsafe characters for us
rawQuerystring = URI.encode("cht=bvs&icac=#{ACCOUNT_ID}&chd=s:93zyvneTTO&chs=400x401")

signature = OpenSSL::HMAC.hexdigest('SHA256', SECRET_KEY, rawQuerystring)
publicUrl = "https://image-charts.com/chart?#{rawQuerystring}&ichm=#{signature}"

# Finally send it to slack or via email, here we simply use puts
puts publicUrl

Want more?

Don't see your favorite language here? Just ask us 👼 !

Online Url Generator

The easiest way to generate a watermark-free Image-Charts is to use our online url generator.