Call Tracking API
Replace the phone numbers on your site with tracking numbers for generating extra income and tracking purposes. Record full attribution on source, campaign and keywords to measure your ROI on every call.
Introduction #
The Optico Call Tracking API lets you replace the phone numbers on your site with tracking numbers for generating extra income and tracking purposes. You make calls to the API with your visitor information and phone numbers, and the API responds with the tracking numbers to display. Throughout this documentation the API is referred to as OSP.
How It Works
Your system transfers visit information to OSP with each page load: page URL, referer URL, IP address. OSP uses these to group calls into page views and visits, and monitor traffic sources, keywords and mobile traffic. A visit represents a user session and can contain one or more page views. Each page view can generate one or more calls.
OSP tracks how views convert to calls and exposes the stats in the client interface. For visitors coming from a search engine or Google Ads campaign, the originating keyword is recorded against the call, so you can see which keywords lead to the most profitable conversations.
https://www.optico.fr
Transport & Conventions
| Method | All endpoints use POST |
| Content-Type | application/x-www-form-urlencoded |
| Response format | application/json |
| Parameter names | snake_case in requests, camelCase in responses |
| Timeout | 5 seconds recommended |
Getting Started #
- Create an account on www.optico.fr: you will receive a username, password, API key, and access to the backend platform for management.
- Integrate the API to get tracking numbers associated with your phones. Call
/ospViewon every page and use the tracking numbers returned.
- The common parameters (
api_key,visit_id,ip,url, etc.) are required on every request. - Call
/ospViewon every page (even pages without phone numbers) to capture the full visitor journey and keyword sources. - Always send
user_agentso OSP can filter bot traffic. Skip the request when the visitor is clearly a robot.
Authentication #
Every request must include your api_key as a POST field.
api_key=osp_3a8f1c5d7b2e4906a8c1f5d3b9e7042c
The API key is issued when you register at www.optico.fr. Each registered domain has its own unique key.
AUTHENTICATION_ERROR. See Errors.Errors #
All error responses share the same structure regardless of endpoint:
{ "status": "AUTHENTICATION_ERROR", "errorMessage": "Invalid API key" }
| Status | Meaning |
|---|---|
MISSING_PARAMETER | A required parameter was not included in the request. |
INVALID_PARAMETER | A parameter was sent with an invalid value or wrong type. |
AUTHENTICATION_ERROR | The api_key is incorrect, or no domain matched the key. |
SYSTEM_ERROR | An internal server error occurred on Optico's side. |
WARNING | Request was valid, but no tracking number could be assigned (e.g. pool exhausted). Returns HTTP 200: always check the status field. |
Endpoints #
| Endpoint | Method | Purpose |
|---|---|---|
/ospView | POST | Track a page view. Returns tracking phone number(s) for Direct display, or viewId for Click display. |
/ospClick | POST | Get a tracking number on demand when a visitor clicks a phone link (Click display). |
/ospExpiration | POST | Update the expiration time of an already-assigned tracking number. |
Concepts #
| Concept | Description |
|---|---|
| Visit | A single user session. One visitor = one visit. |
| View | A single page load within a visit. One visit → many views. |
| Tracking number | A temporary phone number assigned to a visitor. Calls are forwarded to the real number. |
The visitId Cookie
Store the visitId returned by ospView in a cookie and send it on every subsequent request for the same session.
| Cookie name | optico_visit_id |
| Value | Integer visitId from ospView response |
| Expiry | 30 minutes |
visit_id=0. On subsequent views, read the cookie and send its value as visit_id.Display modes #
There are two strategies for showing tracking numbers to visitors. Both can coexist on the same website, but keep the same mode for a given page. The mode is controlled by the direct_display parameter of /ospView.
direct_display=true): tracking numbers replace all phone numbers on the page at load time; no click required.direct_display=false): a tracking number is assigned on demand when a visitor clicks to reveal it, conserving number inventory.POST /ospView #
Direct Display
All phone numbers on the page are replaced with tracking numbers at page-load time. Set direct_display=true and pass the original phones in the phones parameter. OSP responds with a map of original phones to tracking numbers in surtaxPhones. This requires enough available tracking numbers to assign a unique one per visitor per phone number.
Flow
Click Display
With click display (direct_display=false), by default no phone number is shown on the page: instead a text such as "Click to show number" appears in place of each number. When a visitor clicks that link, an AJAX call is made to your server, which requests a tracking number from /ospClick and returns it to the browser for display.
You can use click display with or without tracking visit information. If you want only a tracking number for a phone without visit statistics, call /ospClick directly (omitting view_id). If you want full visit tracking, call /ospView first to record the page view and get a viewId, then pass that viewId to /ospClick.
view_id to /ospClick to link the click to the page view for full attribution. Without it, only the click is recorded.Flow
Required Parameters
| Parameter | Type | Description |
|---|---|---|
api_key | string | Your API key. |
visit_id | integer | 0 on first page view. The visitId from the previous response on subsequent views. |
ip | string | Visitor IPv4 address. Example: 84.72.113.98 |
url | string | Full URL of the current page. |
page_title | string | Title of the current page. |
is_mobile | boolean | true if mobile, false otherwise. |
referer_url | string | Referrer URL. Send empty string if none. |
nr_phones | integer | Total number of valid phone numbers on the page. Send 0 if none. |
direct_display | boolean | true for Direct display, false for Click display. |
Direct Display: Additional Parameters
| Parameter | Type | Description |
|---|---|---|
phones required |
string | Comma-separated original phones to replace. Simple: 0490260716,0450982756Multiple private pools: append :typeId per number: 0490260716:5,0450982756:6 |
client_data optional |
array | Arbitrary data keyed by phone number. Max 500 characters per entry. |
Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
type | integer | - | Tracking number type ID. Only when domain uses multiple pools. See Tracking Type Prefix Table. |
expiration | integer | -1 | -1 = domain default. 0 = expire immediately. Positive = seconds. |
user_agent | string | - | Visitor's HTTP User-Agent. Used for bot filtering. Strongly recommended. |
unique_visitor_id | string | - | Unique visitor identifier for cross-session deduplication. |
unique_view_id | string | - | Unique view identifier for deduplication. |
Success Response
| Field | Type | Description |
|---|---|---|
status | string | OK |
visitId | integer | Store in optico_visit_id cookie (30 min). Send as visit_id on next view. |
viewId | integer | Pass as view_id to ospClick calls on this page. |
surtaxPhones | object | Direct display only. Map of originalPhone → { surtaxPhoneNumber, surtaxPhoneCode }. |
clientData | mixed | Echo of the client_data sent in the request. |
Examples
Direct Display
curl -X POST https://www.optico.fr/ospView -d "api_key=osp_3a8f1c5d7b2e4906a8c1f5d3b9e7042c" -d "visit_id=0" -d "ip=84.72.113.98" -d "url=http://www.mysite.com/contact" -d "page_title=Contact Us" -d "is_mobile=false" -d "referer_url=http://www.google.com/" -d "nr_phones=2" -d "direct_display=true" -d "phones=0490260716,0450982756" -d "user_agent=Mozilla/5.0 ..." # → { "status": "OK", "visitId": 42, "surtaxPhones": { "0490260716": { "surtaxPhoneNumber": "01.02.03.04.05" } } }
surtaxPhoneCode is not null, display it alongside the tracking number: the caller must enter this code after the call connects.Click Display
# Step 1: page load curl -X POST https://www.optico.fr/ospView \ -d "api_key=osp_..." \ -d "direct_display=false" \ -d "visit_id=0" \ -d "ip=84.72.113.98" \ -d "url=http://www.mysite.com/contact" \ -d "page_title=Contact Us" \ -d "is_mobile=false" \ -d "referer_url=http://www.google.com/" \ -d "nr_phones=1" \ -d "user_agent=Mozilla/5.0 ..." # → { "status": "OK", "visitId": 42, "viewId": 101 } # Step 2: on click curl -X POST https://www.optico.fr/ospClick \ -d "api_key=osp_..." \ -d "view_id=101" \ -d "phone=0490260716" # → { "status": "OK", "surtaxPhone": { "surtaxPhoneNumber": "01.02.03.04.05" } }
POST /ospClick #
Called server-side when a visitor clicks to reveal a tracking number. Returns a tracking number assigned on demand for the given phone. For the full two-step integration pattern, see Click Display.
Required Parameters
| Parameter | Type | Description |
|---|---|---|
api_key | string | Your API key. |
phone | string | The original phone number to obtain a tracking number for. |
Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
view_id | integer | - | The viewId from ospView. Links the click to the page view for analytics. |
type | integer | - | Tracking number type ID. See Tracking Type Prefix Table. |
expiration | integer | -1 | -1 = domain default. 0 = expire immediately. Positive = seconds. |
user_agent | string | - | For bot detection. |
client_data | array | - | Data to associate with the phone. Max 500 chars per entry. |
Success Response
| Field | Type | Description |
|---|---|---|
status | string | OK |
visitId | integer | Optico visit ID. |
viewId | integer | Optico page view ID. |
surtaxPhone | object | { surtaxPhoneNumber, surtaxPhoneCode }: the assigned tracking number. |
clientData | mixed | Echo of client_data. |
POST /ospExpiration #
Use ospExpiration to extend or immediately release a tracking number that is currently assigned.
expiration=0 to return the number to the pool immediately.Required Parameters
| Parameter | Type | Description |
|---|---|---|
api_key | string | Your API key. |
surtax_phone | string | The tracking phone number whose expiration to update. Example: 08.90.12.34.56 |
Optional Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
expiration | integer | -1 | -1 = domain default. 0 = expire now. Positive = seconds. |
user_agent | string | - | For bot detection. |
Success Response
| Field | Type | Description |
|---|---|---|
status | string | OK |
surtaxPhone | string | Same tracking phone as sent in the request. |
expiresAt | string | New expiration datetime. Format: YYYY-MM-DD HH:MM:SS (UTC). |
WARNING status from this endpoint means the tracking number was already expired and the update could not be applied.Example
# Extend by 10 minutes curl -X POST https://www.optico.fr/ospExpiration \ -d "api_key=osp_..." \ -d "surtax_phone=08.90.12.34.56" \ -d "expiration=600" # → { "status": "OK", "surtaxPhone": "08.90.12.34.56", "expiresAt": "2026-03-13 14:30:00" } # Release immediately curl -X POST https://www.optico.fr/ospExpiration \ -d "api_key=osp_..." \ -d "surtax_phone=08.90.12.34.56" \ -d "expiration=0" # → { "status": "OK", "surtaxPhone": "08.90.12.34.56", "expiresAt": "2026-03-13 13:47:02" }
Appendix: Tracking Type Prefix Table #
The type parameter selects which phone number pool to draw from. Only needed when your domain is configured with multiple pools.
| Type ID | Prefix | Type ID | Prefix |
|---|---|---|---|
| 1 | 0800 | 22 | 0825 |
| 2 | 0810 | 23 | 004420 |
| 3 | 09 | 24 | 0049 |
| 4 | 0820 | 25 | 004990 |
| 5 | 0899 | 26 | 0034900 |
| 6 | 01 | 27 | 004491 |
| 7 | 02 | 28 | 00349 |
| 8 | 03 | 29 | 0044800 |
| 9 | 04 | 30 | 0032 |
| 10 | 05 | 31 | 0891 |
| 11 | 0892 | 32 | 0890 |
| 12 | 0897 | 33 | 0895 |
| 17 | 0826 | 34 | 0806 |
| 18 | 0805 | 35 | 0809 |
| 20 | 0811 | 36 | 06 |
| 21 | 0821 |