Documentation

Everything you need: from pasting one line to the full API.

Popular guides

Choose a focused guide for the task you want to complete.

Documentation includes widget 1.2.0, CMS plugins 1.1.0 and API version 1.2.0. Last updated: July 2026.

Quick start

CallFlow is a free callback widget with automatic call queue. A visitor to your website leaves a phone number, and the request immediately goes to the CallFlow application on your phone. Start-up takes a few minutes and consists of three steps:

  1. Create an account - in the CallFlow app for Android or later web panel. The account is free.
  2. Add a page - In the 'Packages and Pages' section, add your website address and copy the short key starting with CF-. To publiczny klucz strony (PUBLIC_SITE_KEY) — pozwala wyłącznie wysyłać nowe zgłoszenia, nie daje dostępu do Twojego konta.
  3. Paste the script - Place the following code immediately before the tag </body> swojej strony i podmień klucz oraz adres polityki prywatności.
<script

  src="https://callflowdesk.com/widget/widget.js"

  data-site-key="CF-TWOJ-KLUCZ"

  data-variant="floating"

  data-privacy-url="https://twoja-strona.pl/polityka-prywatnosci/">

</script>

That's enough. A floating button will appear on the website, and each report will trigger a push notification in the app.

Pre-Publication Checklist: add the correct privacy policy address, check the site key, send one test report, confirm the report and push in the application, and finally delete the test report.
The widget sends reports only from websites with a real domain (address with TLD, e.g. .pl, .com). Na localhost formularz się wyświetli, ale wysyłka nie przejdzie walidacji — testuj na domenie docelowej lub stagingowej.

HTML/JS widget

CallFlow 1.2.0 widget is a production script for regular HTML pages. It does not require a framework or external libraries. The form runs in an isolated Shadow DOM - it doesn't interfere with your site's CSS - and can only send new requests via the public CallFlow API.

Basic Installation (Floating Widget)

Paste script before </body> — dokładnie tak jak w Quick start. Default variant floating wyświetla pływający przycisk w rogu ekranu, który otwiera formularz.

Embedded variant in content

If you want to place the form in a specific place on the page (e.g. on the contact subpage), add an empty container and indicate it with the attribute data-target:

<div id="callback"></div>

<script

  src="https://callflowdesk.com/widget/widget.js"

  data-site-key="CF-TWOJ-KLUCZ"

  data-target="#callback"

  data-variant="box">

</script>

Available variants

  • floating — pływający przycisk otwierający formularz (domyślny);
  • box — pełny formularz w miejscu osadzenia;
  • compact — mniejszy formularz do stopki lub sidebara;
  • sticky — pasek przy dolnej krawędzi ekranu;
  • ecommerce — pływający formularz przeznaczony dla karty produktu.

You can watch all variants live on the website Widget demo.

Full configuration attribute table

AttributeDescriptionDefault value
data-site-keySite key from application, required
data-variantfloating, box, compact, sticky, ecommercefloating
data-targetContainer selector for embedded form
data-positionleft albo rightright
data-languagepl albo endocument language
data-titleForm headerlanguage text
data-subtitleDescription under the headinglanguage text
data-button-textButton textlanguage text
data-success-textCustom success messagelanguage text
data-privacy-urlAddress of the site owner's privacy policypage configuration
data-primary-colorSpot color in format #RRGGBB#08D6C3
data-button-colorButton color in format #RRGGBB#0D6EFD
data-text-colorThe color of the formatted text #RRGGBB#061B3A
data-background-colorFormat background color #RRGGBB#FFFFFF
data-allow-urgentfalse ukrywa opcję pilnościpage setup
data-opentrue otwiera formularz po załadowaniufalse

Urgency and privacy policy settings are additionally retrieved from CallFlow. The website user cannot enable a feature that has been disabled by the account owner.

Security and privacy

  • script does not read account data or ticket list;
  • site key only allows you to create a ticket;
  • transmission takes place via HTTPS;
  • the form contains a honeypot and requires explicit consent to contact;
  • the widget does not save cookies and does not use local storage;
  • number is normalized and re-validated by API;
  • request has a timeout of 15 seconds and an idempotence key to protect against duplicates.

Appearance personalization

From version 1.2.0, the widget inherits the font from the website by default (inherit, awaryjnie system-ui), a wygląd można dopasować na dwóch poziomach: Easy (simple attributes) i Advanced (full spectrum CSS). Personalization attributes can be placed on the tag <script> or on the target specified by data-target (atrybut na elemencie docelowym ma pierwszeństwo). Bez tych atrybutów widget wygląda tak jak dotychczas.

Don't want to design from scratch? See the gallery of ready-made styles in the demo - Each example has code to copy.

Easy level - colors, dimensions, font

Each attribute is optional and maps to a CSS variable set on the widget host element (.callflow-widget-host):

AttributeCSS variableDescriptionDefault value
data-accent--callflow-accentMain color: button, focus fields, links#0D6EFD
data-accent-text--callflow-accent-textThe color of the text on the button#fff
data-bg--callflow-bgPanel background#FFFFFF
data-text--callflow-textPanel text color#061B3A
data-muted--callflow-mutedSecondary text (description, consents)#52627a
data-border-color--callflow-border-colorPanel and field bordersrgba(82,98,122,.18) / #ccd7e4
data-radius--callflow-radiusRounding (panel; proportional fields)22px
data-font--callflow-fontFont familyinherited from the page
data-max-width--callflow-max-widthMaximum panel width390px
data-input-bg--callflow-input-bgBackground of the form fields#fff
data-input-text--callflow-input-textText of form fields#061b3a
data-shadow--callflow-shadowPanel Shadow: none, soft, strongsoft

Example of matching the widget to the dark side with gold accents:

<div id="callback"

  data-accent="#c8953f"

  data-accent-text="#0b0b09"

  data-bg="#11181d"

  data-text="#f4f4f1"

  data-muted="#a9b0b4"

  data-border-color="rgba(255,255,255,.14)"

  data-radius="0px"

  data-shadow="none"></div>

<script

  src="https://callflowdesk.com/widget/widget.js"

  data-site-key="CF-TWOJ-KLUCZ"

  data-target="#callback"

  data-variant="box">

</script>

The same variables permeate the Shadow DOM via CSS inheritance, so instead of attributes you can use pure page CSS (sheet or <style>):

#moj-kontener {

  --callflow-accent: #b8860b;

  --callflow-radius: 4px;

  --callflow-max-width: 460px;

}

Precedence order: attribute data-* na elemencie docelowym → atrybut data-* na tagu <script> → zmienna CSS strony → starsze atrybuty data-*-color → wartości domyślne.

Advanced level - full spectrum of CSS

::part() - Important form elements have attributes part, więc strona może je stylować dowolnym CSS bez ograniczeń Shadow DOM. Dostępne nazwy części:

container, title, subtitle, form, field, label, phone-label, input, phone-input, urgent-field, urgent-checkbox, urgent-reason-label, urgent-reason-input, checkbox, checkbox-input, consent, consent-input, link, privacy-link, button, submit-button, status, close-button, floating-trigger, launch-button, sticky-bar, sticky-copy, action-button, config-error.

.callflow-widget-host::part(submit-button) {

  background: linear-gradient(135deg, #e0b96f, #c8953f);

  text-transform: uppercase;

  letter-spacing: .06em;

}

.callflow-widget-host::part(title) {

  font-weight: 500;

}

data-custom-css - raw CSS injected into the Shadow DOM after base styles (cascade wins, affects internal widget selectors):

<div id="callback"

  data-custom-css=".cf-panel{border:0;padding:14px} .cf-submit{letter-spacing:.06em}"></div>

data-css-href - Address of the external sheet loaded into the Shadow DOM. For security reasons, only addresses are accepted https:// oraz ścieżki względne; http://, javascript: i inne schematy są odrzucane.

<script

  src="https://callflowdesk.com/widget/widget.js"

  data-site-key="CF-TWOJ-KLUCZ"

  data-css-href="https://twoja-strona.pl/assets/callflow-theme.css">

</script>

Shadow DOM style order: base styles → z sheet data-css-hrefdata-custom-css. Personalizacja jest w pełni opcjonalna i wstecznie kompatybilna — istniejące osadzenia działają bez zmian.

JavaScript events

The widget emits events on the host element and propagates them to the document, so you can, for example, send a conversion to the analytics system after a successful report:

document.addEventListener('callflow:submitted', (event) => {

  console.log(event.detail.receiptId);

});



document.addEventListener('callflow:error', (event) => {

  console.warn(event.detail.code);

});

Available events:

  • callflow:open — formularz został otwarty;
  • callflow:close — formularz został zamknięty;
  • callflow:submitted — zgłoszenie zostało przyjęte (w event.detail.receiptId znajdziesz identyfikator potwierdzenia);
  • callflow:error — wysyłka się nie powiodła (w event.detail.code znajdziesz kod błędu).

WordPress plugin

CallFlow 1.1.0 plugin adds a widget to your entire WordPress site without editing the template. Supports variants floating, box, sticky i compact oraz osadzanie formularza w treści przez shortcode.

Requirements

  • WordPress 6.0 or later;
  • PHP 7.4 or later (tested on PHP 7.4 and 8.3);
  • site key CF-… utworzony w aplikacji CallFlow.

Step by step installation

  1. Download the plugin - file callflow-wordpress-1.1.0.zip znajdziesz w sekcji Download.
  2. Install in WordPress dashboard - go to Plugins → Add new plugin → Upload plugin to server, point to the downloaded ZIP file, click Install, and after installation Enable.
  3. Configure - go to Settings → CallFlow and:
    • paste the key into the box PUBLIC_SITE_KEY (format CF-XXXX-XXXX);
    • select Variant (default floating);
    • enter the address Privacy Policy of your site;
    • mark Enable the widget globally and click Save changes.

Embedding in content (shortcode)

To display a form inside a post or page, use the shortcode:

[callflow variant="box"]

Using the shortcode automatically disables the second, global widget on this subpage - the form will never be duplicated.

Common problems

  • Key not saving - plugin validates format: key must start with CF- i zawierać wyłącznie wielkie litery, cyfry i myślniki. Skopiuj go ponownie z aplikacji, bez spacji.
  • The widget does not appear on the page - check field Enable the widget globally is checked and the key is not empty. If you use a cache plugin (e.g. LiteSpeed, WP Super Cache), clear the cache after saving your settings.
  • The widget appears twice - you also have the CallFlow for WooCommerce plugin active; see section WooCommerce.

WooCommerce plugin

CallFlow for WooCommerce 1.1.0 is a plugin tailored for stores - it uses the variant ecommerce z nagłówkiem zachęcającym do pytania o produkt. Wersja 1.1.0 jest publiczną betą przeznaczoną do testów na sklepie stagingowym.

Requirements

  • WordPress 6.0 or later, PHP 7.4 or later (tested on PHP 7.4 and 8.3);
  • active plugin WooCommerce (required - without it the widget will not be displayed);
  • site key CF-… z aplikacji CallFlow.

Step by step installation

  1. Download the plugin - file callflow-woocommerce-1.1.0.zip z sekcji Download.
  2. InstallPlugins → Add new plugin → Upload plugin to server, select ZIP, Install, Enable.
  3. Configure - go to Settings → CallFlow WooCommerce and:
    • paste PUBLIC_SITE_KEY;
    • select Variant: ecommerce (domyślny), floating lub sticky;
    • set your own Header form (default "Do you have a question about the product?");
    • mark Enable the store widget and save.

Works with the basic CallFlow plugin

Both plugins can be active at the same time. When the WooCommerce widget is enabled, it automatically disables the global widget of the underlying plugin, so the form will never display twice. If you leave the key field in WooCommerce settings blank, the plugin will use the key from the base CallFlow plugin.

Common problems

  • The widget does not appear - make sure WooCommerce is installed and active; the plugin displays the widget only when WooCommerce is running.
  • Two widgets at once - update both plugins to version 1.1.0; older versions did not coordinate visibility. Alternatively, uncheck "Enable widget globally" in the underlying plugin.
  • This is beta - Test the plugin first on a staging copy of the store before enabling it in production.

PrestaShop 8 Module

The CallFlow 1.1.0 beta module embeds a production widget in the footer of the PrestaShop store (hook displayFooter). Obsługuje warianty ecommerce, floating i sticky.

Requirements

  • PrestaShop 8.0 or later;
  • site key CF-… z aplikacji CallFlow;
  • install the beta version first on the staging store.

Step by step installation

  1. Download module - file callflow-prestashop8-1.1.0.zip z sekcji Download.
  2. Install to panel - go to Modules → Module Manager → Load Module and point to the downloaded ZIP. You will find the module in the "Advertising and marketing" category.
  3. Configure - click Configure for the CallFlow module and:
    • paste PUBLIC_SITE_KEY;
    • select Variant: E-commerce (default), Floating or Sticky;
    • set Widget header (default "Have a question about this product?" - enter your own in Polish);
    • please specify privacy policy address store;
    • set switch Enabled to "Yes" and click Save.

Common problems

  • Error "The CallFlow key must start with CF-" - module validates key format; copy it from the application without spaces.
  • Widget does not appear after saving - clear store cache (Advanced → Performance → Clear cache) and check that the Enabled switch is set to "Yes".
  • Theme does not invoke the footer - the widget is connected to the hook displayFooter; jeśli Twój motyw go nie renderuje, podepnij moduł do innego hooka w Appearance → Items.

Other platforms

The following integrations are technical beta versions of 1.1.0 - please install them in your staging environment first. You will find all packages in the section Download.

Drupal 10/11

After installing the module, go to Configuration → Network Services → CallFlow, paste the site's public key and select a variant.

Joomla 4/5

After installation, enable the plugin System - CallFlow (v System → Plugins), paste PUBLIC_SITE_KEY, wybierz wariant i podaj adres polityki prywatności.

Magento 2 / Adobe Commerce

Copy module to app/code/CallFlow/Callback, uruchom bin/magento setup:upgrade i skonfiguruj go w Stores → Configuration → General → CallFlow. The module contains a CSP whitelist for the script and API samael.pl, więc nie musisz ręcznie modyfikować polityki bezpieczeństwa treści.

e107 2.3

After installation, open CallFlow configuration, paste the key CF-…, wybierz wariant i włącz widget.

Strapi 4/5

Plugin provides public pod configuration /api/callflow/config (endpoint nie ujawnia żadnych danych konta ani zgłoszeń). Ustaw zmienne środowiskowe CALLFLOW_SITE_KEY oraz opcjonalnie CALLFLOW_VARIANT, a we frontendzie użyj:

import {mountCallFlow} from 'strapi-plugin-callflow/client';

await mountCallFlow();

Shopify

Package includes source code Theme App Extension (app embed for a floating widget and app block with a form embedded in the section) - this is not a store installer. Deployment requires the Shopify Partner app and developer store:

shopify app dev

shopify app deploy

After installation, the seller activates CallFlow in Theme settings → App embeds or adds a form block to a theme section.

API for developers

CallFlow provides REST API version 1.2.0 - the same contract powers the mobile app and public widgets.

Basics

  • Base URL: https://callflowdesk.com/api/v1
  • Authentication: header Authorization: Bearer <access_token> (JWT). Token uzyskasz przez POST /auth/login, a odświeżysz przez POST /auth/refresh z refresh_token.
  • No token only works: /auth/register, /auth/login, /auth/refresh oraz /public/leads.
  • Errors: format responses application/problem+json z polami type, title, status, code, detail, trace_id i (dla walidacji) errors.
  • Pagination: lists return next_cursor; kolejną stronę pobierzesz parametrem zapytania cursor.

Auth - Registration and session lifecycle

MethodPathDescription
POST/auth/registerCreates a Main account and returns an active session (requires e-mail, password and version of accepted terms and conditions and privacy policy).
POST/auth/loginLogs the user in with email and password, returning access_token, refresh_token i expires_in.
POST/auth/refreshLists refresh_token na nową parę tokenów sesji.
POST/auth/logoutInvalidates the current session of the logged in user.

Account - Main account, Subaccounts and statistics

MethodPathDescription
GET/accountReturns the active account with the role (main/sub), strefą czasową i uprawnieniami użytkownika.
DELETE/accountPermanently deletes the account with all data (main role only; requires password, and Google account only - confirmation phrase "DELETE ACCOUNT").
GET/account/exportReturns an export of account data in JSON format, limited to the scope visible to the logged in user.
GET/account/consentsReturns the history of acceptance of legal documents (regulations, privacy, marketing).
POST/account/purge-completedHard deletes tickets in final statuses along with notes, queue entries and notifications (main role only).
POST/account/sub-users/invitationsSends an invitation to the Sub user with assignment to selected sources.
GET/dashboardReturns active account statistics: today's calls, scheduled and completed calls, and source load.

Sources - Websites and Contact Packs

MethodPathDescription
GET/sourcesReturns pages and packages available to the user (filter kind, paginacja kursorem).
POST/sourcesCreates a new page or contact package with working hours and expected call time.
GET/sources/{sourceId}Returns details of a single page or package.
PATCH/sources/{sourceId}Updates selected source fields (merge-patch: name, address, business hours, status, etc.).
DELETE/sources/{sourceId}Archive the source while maintaining the request history.
POST/sources/{sourceId}/rotate-keyGenerates a new public site key; the old one stops being active immediately.
GET/sources/{sourceId}/install-codeReturns the ready widget installation code along with the key and data for the QR code.
POST/sources/{sourceId}/send-instructionsSends installation instructions by e-mail (default to the address of the logged in user).

Leads - callback requests and their statuses

MethodPathDescription
GET/leadsReturns tickets available to the user (filters source_id i status, paginacja kursorem).
GET/leads/{leadId}Returns the details of a single ticket.
PATCH/leads/{leadId}/statusChanges the status of a ticket (e.g. handled, no_answer, spam) z opcjonalnym uzasadnieniem.

Schedule - call scheduling

MethodPathDescription
POST/leads/{leadId}/schedule-nextI am planning an interview at the next available date; returns 409, gdy w dozwolonym horyzoncie nie ma terminu.
GET/scheduleReturns the call calendar for a given period (required parameters from i to, opcjonalny filtr source_id).

Devices - push devices

MethodPathDescription
GET/devicesReturns the list of the user's active mobile devices registered for push notifications.
DELETE/devices/{deviceId}Revokes the device - it stops receiving notifications.

Public - endpoints for widgets

MethodPathDescription
POST/public/leadsAccepts request from widget without authentication - requires header Idempotency-Key i publicznego klucza strony; zwraca 202 z potwierdzeniem, nie ujawniając danych konta.

Example: login

curl -X POST https://callflowdesk.com/api/v1/auth/login \

  -H "Content-Type: application/json" \

  -d '{"email":"jan@firma.pl","password":"TwojeBezpieczneHaslo"}'

Reply 200 zawiera access_token (przekazuj go w nagłówku Authorization: Bearer …), refresh_token, czas życia expires_in (w sekundach) oraz obiekt user. Przykład żądania uwierzytelnionego:

curl https://callflowdesk.com/api/v1/leads?status=new \

  -H "Authorization: Bearer ACCESS_TOKEN"

Example: sending a lead publicly

Endpoint POST /public/leads nie wymaga tokenu — identyfikuje stronę po publicznym kluczu CF-…. Nagłówek Idempotency-Key jest required (16-128 characters, e.g. UUID): Retrying the request with the same key will not create a duplicate request.

curl -X POST https://callflowdesk.com/api/v1/public/leads \

  -H "Content-Type: application/json" \

  -H "Idempotency-Key: 4b1f2c62-9e0a-4d7c-8f5e-6a3d2b1c0e9f" \

  -d '{

    "site_public_key": "CF-TWOJ-KLUCZ",

    "phone": "+48601234567",

    "consent": true,

    "language": "pl",

    "widget_variant": "box",

    "source_url": "https://twoja-strona.pl/kontakt",

    "urgent": false,

    "website": ""

  }'

Required fields: site_public_key, phone, consent (musi być true), language i widget_variant. Pole website to honeypot antyspamowy — musi pozostać puste. Odpowiedź 202 zawiera receipt_id, accepted, message_key oraz opcjonalnie queue_position i estimated_callback_at.

When the request limit is exceeded, the API responds with a code 429 z nagłówkiem Retry-After — odczekaj wskazany czas przed ponowieniem. Błędne dane wejściowe zwracają 422 z listą błędów per pole w errors.

Android application

The CallFlow application is the command center for your calls: all reports from widgets go here, you manage pages, keys and the callback calendar. The application will appear on Google Play soon - until then, you will find the installation package in the section Download.

Key Features

  • Call queue - new requests are automatically sent to the appropriate project and queued according to working hours and expected conversation time; statuses (new, in progress, handled, missed, spam) organize the work.
  • Schedule - callback calendar with automatic scheduling of the next available appointment with one touch.
  • Push notifications - each new report immediately triggers a notification; You manage the list of registered devices in the settings and you can revoke access for a lost phone.
  • Subaccounts - as the account owner (main role), you invite colleagues (sub role) by e-mail and assign them selected pages; they only see sources and reports assigned to them.
  • Data export - full export of account data (pages, reports, schedule, consents) to a JSON file, in accordance with GDPR.
  • Account deletion - permanent deletion of the account with all data directly from the application (requires password confirmation, and for Google accounts - the phrase "DELETE ACCOUNT"); details in section Delete your account.

Troubleshooting

The widget does not show up at all

The most common cause is an invalid key. Check the attribute data-site-key: klucz musi zaczynać się od CF- i składać się wyłącznie z wielkich liter, cyfr i myślników (bez spacji na początku i końcu). Otwórz konsolę przeglądarki (F12) — widget zgłasza tam problemy z konfiguracją. Upewnij się też, że skrypt jest wklejony przed </body> i że adres src nie został zmieniony.

Widget displays "Invalid configuration" message

The key is in the correct format but is not active. This happens when a new key has been generated (rotation invalidates the old one immediately) or the page has been archived. Go to the website details in the application and copy current key and replace it in your code or plugin settings.

The form works, but the applications do not reach the application

Check the site status in the application: only active sites accept submissions. A paused or archived page does not accept new leads. Also check that you are not viewing reports with a status filter or on a subaccount without access to this page.

The widget appears twice on WordPress with WooCommerce

You have both plugins active: the base CallFlow and CallFlow for WooCommerce. As of version 1.1.0, the WooCommerce plugin automatically disables the global base widget - update both to 1.1.0. If the problem persists, uncheck "Enable widget globally" in Settings → CallFlow. Also remember that shortcode [callflow] sam wyłącza widget globalny na danej podstronie.

A store with a restrictive CSP blocks the widget

If your site sends a Content-Security-Policy header, add a domain https://samael.pl do dyrektyw script-src (skrypt widgetu) i connect-src (wysyłka zgłoszeń do API). W Magento 2 nie musisz nic robić — nasz moduł zawiera gotową whitelistę CSP.

The widget does not send reports on localhost

This is intentional: field source_url zgłoszenia wymaga prawdziwej domeny z TLD (np. .pl, .com). Adresy typu localhost czy 127.0.0.1 nie przechodzą walidacji. Testuj widget na domenie stagingowej lub tymczasowej subdomenie — formularz i wygląd możesz oczywiście podejrzeć lokalnie.

How to change widget colors without editing the page's CSS?

Use Easy level attributes directly on the tag <script> (lub kontenerze data-target): data-accent zmienia kolor przewodni, data-bg tło, data-text kolor tekstu, data-radius zaokrąglenia. Pełna lista w sekcji Personalization, and ready-made sets in demo gallery.

Where can I find my site's CF key?

In the CallFlow application, open "Packages and Pages", select page - key CF-… jest w jej szczegółach razem z gotowym kodem instalacyjnym do skopiowania. Możesz też wysłać sobie instrukcję instalacji e-mailem prosto z aplikacji.

I don't receive push notifications about new reports

Check that the app has permission for notifications in Android settings and that your device is in the list of devices in the app and has not been revoked. Disable battery optimization for CallFlow if the system puts the application to sleep in the background.

I generated a new key and the widget stopped working

Key rotation immediately invalidates the previous one - this is a security feature. After generating a new key, update it in all places where the widget is embedded: in the website code and in the settings of each CMS plugin.