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.

Prefer to not encode query parameters before computing the signature

In order to be easier to handle, Image-Charts checks the signature for both encoded and decoded query params. You do not need to worry about generating a string of the whole query with the right URL-safe characters anymore, if the basic query string check does not work, Image-Charts will also try to decode every query parameter pairs and then check the resulting query string against your signature (ichm).

It means you don't have to worry about URL-encoding algorithm and you can generate the signature key based on an unencoded URL-unsafe query string and it will work.

Generating a signature based on unencoded URL parameters is the recommended way as it's much more robust and abstract away the encoding the transportation uses (e.g. webmail proxies, web-browsers, enterprise proxies).

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
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',
}, null, null, {
  // no need to encode the query string, Image-Charts will decode every parameters by itself to check the signature
  // learn why in our documentation https://documentation.image-charts.com/enterprise/
  encodeURIComponent: (valueWithoutEncoding) => valueWithoutEncoding
});
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
  # no need to encode the query string, Image-Charts will decode every parameters by itself to check the signature
  # learn why in our documentation https://documentation.image-charts.com/enterprise/
  rawQuerystring = [
      ('cht', 'bvs'),
      ('chd', 's:93zyvneTTO'),
      ('chtt', 'Hello world'),
      ('chs', '400x401'),
      ('icac', ACCOUNT_ID)  # don't forget to add your account id before signing it
  ]

  queryString = "&".join( [ param +'='+ value for (param, value) in rawQuerystring ] )
  signature = sign(queryString, SECRET_KEY)
  publicUrl = "https://image-charts.com/chart?" + queryString + "&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
// no need to encode the query string, Image-Charts will decode every parameters by itself to check the signature
// learn why in our documentation https://documentation.image-charts.com/enterprise/
$rawQuerystring = urldecode(http_build_query(array(
  'cht' => 'bvs',
  'chd' => 's:93zyvneTTO',
  'chs' => '400x401',
  'chtt' => 'Hello world',
  '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.Globalization;
using System.Security.Cryptography;
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();

            // Then generate the watermark-free url
            // no need to encode the query string, Image-Charts will decode every parameters by itself to check the signature
            // learn why in our documentation https://documentation.image-charts.com/enterprise/
            sbchart.AppendFormat("cht={0}", "pd");
            sbchart.AppendFormat("&icac={0}", account_id);
            sbchart.AppendFormat("&chd={0}", "a:124,736,372");
            sbchart.AppendFormat("&chs={0}", "400x400");
            sbchart.AppendFormat("&chdl={0}", "Expansion|Payroll|Equipment");
            sbchart.AppendFormat("&chli={0}", "95K€");
            sbchart.AppendFormat("&chl={0}", "10K€|40K€|45K€");

            string querystring = sbchart.ToString();
            var payload = Encoding.UTF8.GetBytes(querystring);
            var hmacSHA = new HMACSHA256(Encoding.UTF8.GetBytes(secret_key));
            var hash = hmacSHA.ComputeHash(payload, 0, payload.Length);
            string signature = BitConverter.ToString(hash).Replace("-", "").ToLower();

            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"

# Then generate the watermark-free url
# no need to encode the query string, Image-Charts will decode every parameters by itself to check the signature
# learn why in our documentation https://documentation.image-charts.com/enterprise/
rawQuerystring = "cht=bvs&icac=#{ACCOUNT_ID}&chtt=Hello world&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.