Skip to main content
Filip Nohe

Signature counter for a European Citizens' Initiative

What is a European Citizens' Initiative?

A European Citizens' Initiative (ECI) is an official EU petition. It is the only element of direct democracy at the European level. Citizens can ask the European Commission to propose a new law. If one million citizens across the EU (as well as a certain minimum in at least 7 member states) sign the initiative, the European Commission must consider taking action on the issue.

Why build your own landing page?

The European Commission provides a so-called Central Online Collection System to collect online signatures for European Citizens' Initiatives.

However, the Central Online Collection System's landing page for an ECI doesn't exactly follow best practices for campaigning landing pages, which is one reason it is unappealing to many campaigning organisations.

Among the various confusing things about the official ECI pages is that there are 2 separate pages for every ECI during signature collection:

Central Online Collection System European Commission's register page
Counts online signatures only Counts online and offline signatures
updates instantly updates once per day
URL uses initiative ID URL uses registration number

That's why campaigners might want to build their own landing page on a website they control:

Build a signature counter using the European Commission's API

For social proof, you usually want to prominently show a signature counter on your landing page. Thankfully, the European Commision has a public (though not publicly documented) API that allows you to get the number of online signatures. Here's how I built a signature counter. I originally built it for the Tax the Rich ECI, but I'm using the excellent My Voice, My Choice (which you should sign if you haven't already) as an example here:

More than 900.000 people have signed. Help us reach 1 million!

HTML

Set up a text and a progress bar. Provide a fallback in case Javascript is disabled or something doesn't load properly. You can update this manually from time to time.

<span class="signature-number">More than 900.000</span> people have signed. Help us reach 1 million! 
<progress class="signature-progress" value="900000" max="1000000"></progress>

CSS

Some styles, you can tweak this according to your tastes or brand.

:root {
    --progress-color: #090;
    --progress-bg-color: #eee;
}
.signature-progress[value] {
    width: 100%;
    height: 40px;
    appearance: none;
    border: 3px solid var(--progress-color);
    border-radius: 5px;
    color: var(--progress-color);
    background-color: var(--progress-bg-color);
}
.signature-progress[value]::-webkit-progress-bar {
    background-color: var(--progress-bg-color);
    border-radius: 5px;
}
.signature-progress[value]::-webkit-progress-value {
    background-color: var(--progress-color);
    border-radius: 0px;
}
.signature-progress[value]::-moz-progress-bar {
    background-color: var(--progress-color);
    border-radius: 0px;
}

Javascript

We load the live signature count from the API, add offline signatures and update the counter and progress bar with the total number.

async function eciProgress() {
    const offlineSignatureCount = 28261; // number of offline signatures
    const locale = "de-DE"; // the locale according to which you want your numbers formatted
    const eciID = "044"; // ID of your ECI. It's the number in the URL of the Central Online Collection System page such as https://eci.ec.europa.eu/044/public/
    const signatureProgress = document.querySelector(".signature-progress");
    const url = "https://eci.ec.europa.eu/" + eciID + "/public/api/report/progression"
    const response = await fetch(url);
    const progress = await response.json();
    const signatureCount = progress.signatureCount + offlineSignatureCount;
    if (typeof signatureCount === "number" && signatureCount > 0) {
        signatureProgress.setAttribute("value", signatureCount);
        let localizedSignatureCount = new Intl.NumberFormat(locale).format(signatureCount);
        document.querySelectorAll(".signature-number").forEach((el) => {
            el.textContent = localizedSignatureCount;
        });
    }
}
eciProgress();

Caveats and limitations

  1. If you want to count offline signatures, you have to add them manually. The current number of submitted offline signatures is not officially published anywhere and cannot be automatically retrieved, so you have to update it manually in the script. Officially registered organizers of the ECI can see the number of paper signatures they have reported in their account. Otherwise you can only estimate the number by closely monitoring the daily total numbers at the European Commission's register page and comparing them with the online numbers of the Central Online Collection System.
  2. The Commission's API can presumably handle a lot of hits, but be considerate – you don't really need to refresh the counter every second while the user is reading the page. Checking the API once on page load as in the example should be sufficient. We don't want the Central Online Collection System to go down or the API to get restricted.