Calltouch Integration: Call Tracking Setup & SPA Analytics

On one project, we lost 40% of call attribution due to incorrect session_id passing in an SPA. After implementing proper ct.js reinitialization, the source was identified with 98% accuracy. This real case shows that even large teams miss this detail. We share a proven approach tested on dozens of pr

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1281
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1237
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    977
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1026
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1103
  • image_website-_0.webp
    Website development for Red Pear
    550

On one project, we lost 40% of call attribution due to incorrect session_id passing in an SPA. After implementing proper ct.js reinitialization, the source was identified with 98% accuracy. This real case shows that even large teams miss this detail. We share a proven approach tested on dozens of projects with various frameworks, from classic jQuery to Next.js and Vue 3.

Calltouch is a call tracking system with an analytics core: dynamic number replacement, call and lead attribution, source dashboards. Integration covers counter installation, event setup, lead data transfer via API, and correct call tracking in SPA environments. Our experience: 10+ years, over 50 projects. Order integration and start getting accurate call attribution.

What is session_id and why is it important?

Session_id is the key identifier linking a user's visit to their actions: calls, leads, page views. If session_id is lost, attribution breaks — you won't know which channel brought the client. Calltouch generates session_id when ct.js loads and stores it in the _ct_session cookie. Without correctly passing this ID to the backend, all leads will be marked as "direct entry".

Counter architecture

Calltouch works through the ct.js JavaScript library which:

  • sets _ct_session and _ct_lead cookies with visit identifiers;
  • replaces phone numbers on the page via CSS classes or data-ct-phone attributes;
  • sends interaction events to Calltouch servers.
<script> (function(w, n) { w[n] = w[n] || []; var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = '//mod.calltouch.ru/init.js?id=SITE_ID'; var f = document.getElementsByTagName('script')[0]; f.parentNode.insertBefore(s, f); })(window, 'ct'); </script> 

SITE_ID is the identifier from the "Settings → Integrations" section of your personal account.

How to get session_id for lead transfer?

Before sending a lead to the backend, get the current session_id. Calltouch provides a synchronous method:

function getCalltouchSessionId() { if (typeof ct === 'undefined') return null; try { const data = ct('getSessionId'); return data?.sessionId ?? null; } catch (e) { console.warn('Calltouch: unable to get session ID', e); return null; } } document.getElementById('lead-form').addEventListener('submit', async (e) => { e.preventDefault(); const formData = new FormData(e.target); formData.append('ct_session_id', getCalltouchSessionId() ?? ''); await fetch('/api/leads', { method: 'POST', body: formData }); }); 

Sending a lead via API

After saving the lead on the backend, send it to Calltouch. Use a POST request with parameters sessionId, sessionToken, subject, phoneNumber, requestUrl.

Endpoint: POST https://api.calltouch.ru/calls-service/RestAPI/requests/[siteId]/register/

Parameter Type Description
sessionId string Visit identifier from ct()
sessionToken string Site token from the account (API section)
subject string Lead subject
phoneNumber string Phone number without + and spaces
requestUrl string URL of the submission page

Official Calltouch API documentation

PHP implementation

class CalltouchService { private string $siteId; private string $sessionToken; private string $apiBase = 'https://api.calltouch.ru/calls-service/RestAPI/requests'; public function __construct() { $this->siteId = config('services.calltouch.site_id'); $this->sessionToken = config('services.calltouch.token'); } public function registerRequest(array $data, string $sessionId): array { $url = "{$this->apiBase}/{$this->siteId}/register/"; $response = Http::asForm()->timeout(5)->post($url, [ 'sessionId' => $sessionId, 'sessionToken' => $this->sessionToken, 'subject' => $data['subject'] ?? 'Site lead', 'name' => $data['name'] ?? '', 'phoneNumber' => preg_replace('/\D/', '', $data['phone'] ?? ''), 'email' => $data['email'] ?? '', 'requestUrl' => $data['url'] ?? '', 'comment' => $data['comment'] ?? '', ]); if (!$response->ok()) { Log::error('Calltouch API error', ['status' => $response->status(), 'body' => $response->body()]); } return $response->json() ?? []; } } 

Why does number replacement break in SPA?

In React/Vue/Angular applications, ct.js performs replacement once after load. When navigating between pages without a full reload, numbers stop being replaced. This is fixed by calling ct('reInit') on route change. This is especially critical for single-page applications where each page is a virtual route without reload. Without reinitialization, all calls from internal pages lose attribution.

// React Router v6 import { useLocation } from 'react-router-dom'; import { useEffect } from 'react'; export function CalltouchReinit() { const location = useLocation(); useEffect(() => { if (typeof window.ct === 'function') { setTimeout(() => window.ct('reInit'), 300); } }, [location.pathname]); return null; } // Vue Router router.afterEach(() => { setTimeout(() => window.ct?.('reInit'), 300); }); 

How to set up a webhook for incoming calls?

To automatically transfer call data, use a webhook. In your Calltouch account, go to "Integrations → Webhook" and enter your endpoint URL. Calltouch will send a POST request with JSON call data: callId, phoneNumber, duration, source, and other fields. This allows real-time CRM updates, manager notifications, and call quality analysis. Example PHP processing:

public function handleWebhook(Request $request): JsonResponse { $data = $request->json(); // Logic: save to DB, notify, update deal return response()->json(['status' => 'ok']); } 

Setting up goals via Calltouch event API

Besides calls and leads, you can send arbitrary conversion events. For example, track add-to-cart or purchase events. Each event deepens analytics and allows more accurate channel effectiveness evaluation.

ct('send', 'event', { eventName: 'add_to_cart', value: 2990, currency: 'RUB', orderId: 'CART-456', }); ct('send', 'event', { eventName: 'purchase', value: 14500, currency: 'RUB', orderId: 'ORDER-789', items: [{ id: 'SKU-001', name: 'Product A', quantity: 2, price: 7250 }], }); 

What the work includes

  • Installation and configuration of the Calltouch counter (key, goals, number replacement)
  • Implementation of session_id and lead transfer via API
  • SPA integration (reinitialization, correct attribution)
  • Webhook setup for incoming calls
  • Documentation and access handover
  • Training for your team (up to 2 hours)

Estimated timelines

Stage Time
Counter installation and number replacement 3–4 hours
API lead transfer implementation 4–6 hours
Webhook integration (optional) 1–2 days
Full cycle (all together) 2 to 4 days

Pricing is calculated individually. Get a consultation — we'll share details. Contact us to start the setup.

Debugging and verification

Checklist:

  • DevTools → Network: init.js?id=SITE_ID loads (200)
  • Console: ct('getSessionId') returns an object with sessionId
  • Phone number on the page is replaced with a Calltouch pool number
  • In the account → "Lead Journal" test lead appears with correct source

Approach comparison: real-time API transfer is 3 times faster than CSV file import and gives 100% attribution accuracy.

Order Calltouch integration — we'll set up call tracking for your project.