Skip to content
API v1.1.0

API reference

Everything you can read or create from your own systems, with a working sample for each call. Base URL: https://customer360.eleservsoft.com

Quick start

  1. In the dashboard open Workspace → API keys and create a key. Pick the permissions and sites it may use and an expiry. The key starts with exk_ and is shown once.
  2. Call List sites to get your site ids (your organization id is in the dashboard URL and on Organization → Settings).
  3. Read a report with a date range. Every list and report call works the same way.
curl "https://customer360.eleservsoft.com/api/v1/orgs/{orgId}/sites" \
  -H "Authorization: Bearer exk_YOUR_KEY"

curl "https://customer360.eleservsoft.com/api/v1/orgs/{orgId}/sites/{siteId}/analytics/overview?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"

Authentication & permissions

Send the key as a bearer token: Authorization: Bearer exk_…. A key acts with its creator's access, narrowed to the permissions and sites chosen when it was created. Anything outside that scope answers 404 (never revealing whether it exists); a permission the key lacks answers 403. Keys never satisfy the interactive two-factor check, so exports of personal data and destructive actions stay in the dashboard. Rotate or revoke keys any time under Workspace → API keys; every use is recorded with its IP.

PermissionAllows
sites.readList sites
analytics.readRead analytics reports
analytics.realtimeRead realtime
analytics.pii.readInclude contact details (PII)
reports.readRun library reports
leads.readRead leads
recommendations.readRead recommendations
popups.readRead popups
spinwheel.readRead spin wheels
shortlinks.readRead short links
shortlinks.manageCreate & edit short links
consent.readRead consent settings
integrations.readRead integrations

Conventions & limits

  • Ids are 24-character hex strings. Visitor ids are UUIDs.
  • Dates: from and to are YYYY-MM-DD in the site's timezone, inclusive, at most 400 days apart. Omitting both gives the last 28 days. Timestamps in responses are ISO 8601 in UTC.
  • Pagination: lists take page (1-based) and return total and pages. The activity log also takes size (max 100).
  • Rate limits: 300 requests per minute per key and 600 per minute per IP address. Over the limit you get 429 with a Retry-After header (seconds).
  • Request ids: every response carries x-request-id. Quote it when you contact support.
  • Bodies are JSON (Content-Type: application/json), at most 256 KB. Responses are JSON unless you ask for format=csv or xlsx on a report.
  • Versioning: paths start with /api/v1. Fields are only added, never renamed, within a version.

Errors

Every error has the same shape. Validation errors list the offending fields in details. The same codes are explained for non-developers in the guide: API and app error codes.

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Enter a full http(s):// URL.",
    "details": [
      {
        "path": "destinationUrl",
        "message": "Enter a full http(s):// URL."
      }
    ],
    "requestId": "1d929651-566f-41e8-9b61-763956dc5065"
  }
}
CodeHTTPMeaningWhat to do
BAD_REQUEST400Malformed JSON or a body larger than 256 KB.Send valid JSON with Content-Type: application/json.
UNAUTHENTICATED401Missing, invalid, expired or revoked API key (or no session).Send Authorization: Bearer exk_… with a live key, or sign in again.
TWO_FACTOR_REQUIRED401Session call: the sign-in has not completed its 2FA step yet.Finish the 2FA challenge at /two-factor.
SESSION_EXPIRED401Session call: the session passed its idle or absolute limit, or was revoked.Sign in again.
FORBIDDEN403The key or user lacks the permission for this action, or the Origin check failed on a browser call.Use a key with the right permission; browser calls must come from the app's own origin.
EMAIL_NOT_VERIFIED403Session call: the account's email is not verified yet.Open the verification email or request a new code.
STEP_UP_REQUIRED403Session call: a sensitive change needs a 2FA confirmation from the last 15 minutes.Confirm the code at /two-factor?stepup=1 and retry.
FEATURE_UNAVAILABLE403The feature isn't included in the organization's plan, or is switched off platform-wide. details[0].message holds the feature key.Upgrade the plan, or ask Product Admin to enable the feature.
LICENCE_INACTIVE403The organization's licence is suspended or cancelled.Settle the open invoice or contact support; tracking keeps accepting hits meanwhile.
NOT_FOUND404Unknown id, or a resource outside the key's organization or sites (never revealed as 403).Check the id and that the key may see that site.
CONFLICT409The change clashes with the current state (duplicate slug, role in use, already paid).Reload the resource and apply the change to the current state.
DOMAIN_ALREADY_CLAIMED409Another organization has verified this hostname.Use a different hostname or ask support to resolve the ownership.
VALIDATION_FAILED422A field is invalid; details lists path and message per field.Fix the listed fields.
LIMIT_EXCEEDED422A plan limit was reached (sites, seats, funnels, uploads). details[0] carries limit, max and current.Remove something or move to a bigger plan.
ACCOUNT_LOCKED423Too many failed sign-ins; the account is locked for a while.Wait for the lock to lift (the email says how long) or reset the password.
RATE_LIMITED429Too many requests; wait for the seconds in Retry-After. X-RateLimit-Limit shows the window's allowance.Back off for Retry-After seconds, then retry with lower concurrency.
UPSTREAM_UNAVAILABLE503The database is temporarily unreachable; retry after Retry-After.Retry with backoff; nothing was changed.
BYO_DB_UNREACHABLE503The organization's own MongoDB is down; analytics reads fail until it is back.Check the database under Workspace → Data storage.
MAINTENANCE503The platform is in a planned maintenance window.Retry after the window announced on /status.
INTERNAL500Unexpected error. The requestId is in the server log; quote it to support.Retry once; if it repeats, send the requestId to support.

Organization

get/api/v1/orgs/{orgId}/sites

List sites

Every site the key can access, with its tracking status (not_installed, receiving, stale, paused). Permission: sites.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "data": [
    {
      "id": "64f1c0ffee0000000000b002",
      "name": "Eleserv website",
      "siteKey": "EX-7K2M9QX4PZ",
      "domain": "eleservsoft.com",
      "timezone": "Asia/Kolkata",
      "currency": "INR",
      "status": "receiving",
      "firstHitAt": "2026-09-01T06:12:40.000Z",
      "lastHitAt": "2026-10-02T11:58:03.000Z",
      "createdAt": "2026-09-01T05:40:12.000Z"
    }
  ]
}
get/api/v1/orgs/{orgId}/audit

Activity log

Who did what in the organization: sign-ins, exports, role changes, settings, licence changes. Newest first. Permission: audit.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
pagequeryinteger (default 1)
1-based page number.
sizequeryinteger (default 25)
qquerystring
Matches the person, action or target.
actionquerystring
Exact action, e.g. member.invited.
daysqueryinteger (default 0)
Only the last N days (0 = all).
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/audit" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "rows": [
    {
      "id": "64f1c0ffee0000000000c003",
      "at": "2026-10-02T09:14:02.000Z",
      "actor": {
        "id": "64f1c0ffee0000000000d004",
        "name": "Asha Rao",
        "email": "asha@example.com"
      },
      "action": "member.invited",
      "label": "Member invited",
      "target": {
        "type": "email",
        "id": "dev@example.com"
      },
      "meta": {
        "role": "manager",
        "sites": "all"
      },
      "orgId": "64f1c0ffee0000000000a001"
    }
  ],
  "total": 148,
  "actions": [
    "member.invited",
    "user.login",
    "report.exported"
  ]
}

Sites

get/api/v1/orgs/{orgId}/sites/{siteId}/status

Installation & data status

Whether the tag is installed and sending, hits in the last 30 minutes, and every domain with its verification state. Permission: sites.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/status" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "status": "receiving",
  "firstHitAt": "2026-09-01T06:12:40.000Z",
  "lastHitAt": "2026-10-02T11:58:03.000Z",
  "hitsLast30Min": 42,
  "rejectedHosts": [],
  "domains": [
    {
      "id": "64f1c0ffee0000000000e005",
      "hostname": "eleservsoft.com",
      "isPrimary": true,
      "includeSubdomains": true,
      "status": "verified",
      "method": "dns",
      "strong": true,
      "token": "elexy-verify-9f2a…",
      "verifiedAt": "2026-09-01T06:20:00.000Z"
    }
  ]
}
get/api/v1/orgs/{orgId}/sites/{siteId}/cookies

Cookie & tag inventory

Cookies, storage keys and third-party hosts found by the scanner and the tag, with category and violation (seen before consent). Permission: consent.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/cookies" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "items": [
    {
      "id": "64f1c0ffee0000000005000b",
      "name": "_ga",
      "kind": "cookie",
      "host": "eleservsoft.com",
      "category": "analytics",
      "vendor": "Google Analytics",
      "purpose": "Distinguishes users.",
      "violation": false,
      "lastSeenAt": "2026-10-01T04:00:00.000Z"
    }
  ],
  "summary": {
    "total": 12,
    "unknown": 1,
    "violations": 0,
    "byCategory": {
      "necessary": 4,
      "analytics": 5,
      "marketing": 2,
      "personalization": 0,
      "unknown": 1
    }
  },
  "scan": {
    "status": "done",
    "startedAt": "2026-10-01T03:58:00.000Z",
    "finishedAt": "2026-10-01T04:01:30.000Z",
    "pages": 25,
    "found": 12,
    "error": null
  },
  "canManage": true,
  "defaultUrl": "https://eleservsoft.com/"
}
get/api/v1/orgs/{orgId}/sites/{siteId}/integrations

Connected marketing integrations

Every integration with connection state, last sync, and (for inbound connectors) the webhook URL the key may read. Permission: integrations.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/integrations" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200

JSON object: the same fields the dashboard screen shows for this feature. See openapi.json for the schema.

Analytics

get/api/v1/orgs/{orgId}/sites/{siteId}/analytics/{report}

Analytics report

GA4-style aggregated reports. overview returns KPIs for the period and the previous one, a daily series and top channels, pages, countries and devices. realtime needs analytics.realtime and ignores the date range. Permission: analytics.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
report*pathoverview | acquisition | pages | events | audience | locations | campaigns | behaviour | attribution | conversions | realtime
fromquerydate
Start date (site timezone), YYYY-MM-DD. Default: 27 days before to.
toquerydate
End date (inclusive), YYYY-MM-DD. Default: today. Max range 400 days.
countryquerystring
locations only: drill into a country (ISO alpha-2) → states/regions.
regionquerystring
locations only (with country): drill into a region → cities.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/analytics/overview?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "from": "2026-09-01",
  "to": "2026-09-30",
  "tz": "Asia/Kolkata",
  "currency": "INR",
  "current": {
    "sessions": 12840,
    "users": 9120,
    "newUsers": 5654,
    "pageviews": 38520,
    "engagementRate": 0.57,
    "avgEngagedSeconds": 48.2,
    "pagesPerSession": 3,
    "conversions": 214,
    "revenue": 318500
  },
  "previous": {
    "sessions": 11210,
    "users": 8035,
    "newUsers": 4982,
    "pageviews": 33630,
    "engagementRate": 0.57,
    "avgEngagedSeconds": 48.2,
    "pagesPerSession": 3,
    "conversions": 180,
    "revenue": 266900
  },
  "series": [
    {
      "date": "2026-09-01",
      "sessions": 410,
      "users": 302,
      "pageviews": 1250,
      "conversions": 7
    },
    {
      "date": "2026-09-02",
      "sessions": 438,
      "users": 311,
      "pageviews": 1301,
      "conversions": 9
    }
  ],
  "channels": [
    {
      "key": "Organic Search",
      "sessions": 5390,
      "users": 4012,
      "engagementRate": 0.61,
      "conversions": 96,
      "revenue": 142000,
      "pageviews": 16170
    },
    {
      "key": "Direct",
      "sessions": 2310,
      "users": 1840,
      "engagementRate": 0.52,
      "conversions": 40,
      "revenue": 61000,
      "pageviews": 6930
    }
  ],
  "pages": [
    {
      "path": "/",
      "title": "Home",
      "views": 9800,
      "users": 6100
    },
    {
      "path": "/pricing",
      "title": "Pricing",
      "views": 3120,
      "users": 2440
    }
  ],
  "countries": [
    {
      "key": "IN",
      "sessions": 10920,
      "users": 7800
    },
    {
      "key": "US",
      "sessions": 640,
      "users": 512
    }
  ],
  "devices": [
    {
      "key": "mobile",
      "sessions": 8220,
      "users": 5900
    },
    {
      "key": "desktop",
      "sessions": 4310,
      "users": 3100
    }
  ]
}
get/api/v1/orgs/{orgId}/sites/{siteId}/funnels

List saved funnels

Permission: analytics.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/funnels" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "data": [
    {
      "id": "64f1c0ffee0000000000f006",
      "name": "Pricing to sign-up",
      "steps": [
        {
          "kind": "page",
          "label": "",
          "match": "starts_with",
          "value": "/pricing"
        },
        {
          "kind": "page",
          "label": "",
          "match": "starts_with",
          "value": "/signup"
        },
        {
          "kind": "event",
          "label": "",
          "eventType": "conversion",
          "name": "signup"
        }
      ],
      "mode": "closed",
      "scope": "session",
      "createdAt": "2026-09-10T08:00:00.000Z"
    }
  ],
  "canSave": true
}
get/api/v1/orgs/{orgId}/sites/{siteId}/funnels/{id}

Run a saved funnel

Ordered step completion with drop-off and median time between steps. Add breakdown to split by channel, device, country or landing page. Permission: analytics.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
id*pathstring
fromquerydate
Start date (site timezone), YYYY-MM-DD. Default: 27 days before to.
toquerydate
End date (inclusive), YYYY-MM-DD. Default: today. Max range 400 days.
breakdownquerynone | channel | device | country | source | campaign
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/funnels/64f1c0ffee0000000000f006?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "units": "sessions",
  "range": {
    "from": "2026-09-01",
    "to": "2026-09-30",
    "tz": "Asia/Kolkata"
  },
  "steps": [
    {
      "label": "/pricing",
      "entered": 3120,
      "count": 3120,
      "pctOfStart": 1,
      "dropOff": 0,
      "dropOffPct": 0,
      "medianSeconds": null
    },
    {
      "label": "/signup",
      "entered": 3120,
      "count": 806,
      "pctOfStart": 0.258,
      "dropOff": 2314,
      "dropOffPct": 0.742,
      "medianSeconds": 41
    },
    {
      "label": "signup",
      "entered": 806,
      "count": 214,
      "pctOfStart": 0.069,
      "dropOff": 592,
      "dropOffPct": 0.734,
      "medianSeconds": 95
    }
  ],
  "started": 3120,
  "completed": 214,
  "conversionRate": 0.069,
  "breakdown": null,
  "sampled": false
}
post/api/v1/orgs/{orgId}/sites/{siteId}/funnels/preview

Run an ad-hoc funnel

Same result as running a saved funnel, for an unsaved definition (2 to 10 steps). Permission: analytics.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl -X POST "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/funnels/preview" \
  -H "Authorization: Bearer exk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "def": {
    "name": "Pricing to sign-up",
    "steps": [
      {
        "kind": "page",
        "label": "",
        "match": "starts_with",
        "value": "/pricing"
      },
      {
        "kind": "page",
        "label": "",
        "match": "starts_with",
        "value": "/signup"
      }
    ],
    "mode": "closed",
    "scope": "session"
  },
  "from": "2026-09-01",
  "to": "2026-09-30"
}'
Response 200
{
  "units": "sessions",
  "range": {
    "from": "2026-09-01",
    "to": "2026-09-30",
    "tz": "Asia/Kolkata"
  },
  "steps": [
    {
      "label": "/pricing",
      "entered": 3120,
      "count": 3120,
      "pctOfStart": 1,
      "dropOff": 0,
      "dropOffPct": 0,
      "medianSeconds": null
    },
    {
      "label": "/signup",
      "entered": 3120,
      "count": 806,
      "pctOfStart": 0.258,
      "dropOff": 2314,
      "dropOffPct": 0.742,
      "medianSeconds": 41
    }
  ],
  "started": 3120,
  "completed": 806,
  "conversionRate": 0.258,
  "breakdown": null,
  "sampled": false
}
post/api/v1/orgs/{orgId}/sites/{siteId}/explore

Explore (ad-hoc query)

Read-only exploration. kind picks the shape: query (metrics by one dimension with filters), segments (compare up to 4 segments on chosen metrics), retention (weekly or monthly cohorts), paths (what visitors do after a page). Dimensions: channel, source, medium, campaign, landing, country, region, device, browser, os, visitor, date. Metrics: users, newUsers, sessions, pageviews, engagementRate, bounceRate, avgEngagedSeconds, pagesPerSession, conversions, conversionRate, revenue. Permission: analytics.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl -X POST "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/explore" \
  -H "Authorization: Bearer exk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "kind": "query",
  "from": "2026-09-01",
  "to": "2026-09-30",
  "query": {
    "metrics": [
      "sessions",
      "conversions",
      "revenue"
    ],
    "dimension": "campaign",
    "filters": [
      {
        "dim": "channel",
        "op": "is",
        "value": "Paid Search"
      }
    ],
    "limit": 10
  }
}'
Response 200
{
  "from": "2026-09-01",
  "to": "2026-09-30",
  "tz": "Asia/Kolkata",
  "rows": [
    {
      "key": "diwali_sale",
      "sessions": 1840,
      "conversions": 62,
      "revenue": 98400
    },
    {
      "key": "brand",
      "sessions": 920,
      "conversions": 31,
      "revenue": 40100
    }
  ],
  "totals": {
    "sessions": 2760,
    "conversions": 93,
    "revenue": 138500
  }
}

Reports

get/api/v1/orgs/{orgId}/sites/{siteId}/reports

List library reports and schedules

Permission: reports.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/reports" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "reports": [
    {
      "key": "kpi_daily",
      "category": "Overview",
      "title": "Daily KPIs",
      "description": "Users, sessions, page views and conversions per day.",
      "pii": false
    },
    {
      "key": "campaign_performance",
      "category": "Acquisition",
      "title": "Campaign performance",
      "description": "Sessions, leads, conversions and revenue per campaign.",
      "pii": false
    }
  ],
  "schedules": [
    {
      "id": "64f1c0ffee00000000010007",
      "reportKey": "kpi_daily",
      "title": "Daily KPIs",
      "frequency": "weekly",
      "recipients": [
        "asha@example.com"
      ],
      "active": true,
      "nextRunAt": "2026-10-06T03:30:00.000Z",
      "lastRunAt": "2026-09-29T03:30:00.000Z",
      "lastStatus": "ok",
      "lastError": null
    }
  ]
}
get/api/v1/orgs/{orgId}/sites/{siteId}/reports/{key}

Run a library report

Returns { columns, rows } (first 200 rows, total is the full count). format=csv or format=xlsx returns the whole report as a file and needs reports.export. Reports marked PII also need analytics.pii.read. Permission: reports.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
key*pathkpi_daily | channel_performance | campaign_performance | source_medium | utm_audit | referrers | page_performance | events | conversions_by_channel | leads | hot_leads | popup_performance | spin_performance | short_links | geo | tech | consent_log | web_vitals | experience
fromquerydate
Start date (site timezone), YYYY-MM-DD. Default: 27 days before to.
toquerydate
End date (inclusive), YYYY-MM-DD. Default: today. Max range 400 days.
formatqueryjson | csv | xlsx (default json)
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/reports/kpi_daily?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "key": "kpi_daily",
  "title": "Daily KPIs",
  "currency": "INR",
  "columns": [
    {
      "key": "date",
      "label": "Date"
    },
    {
      "key": "users",
      "label": "Users"
    },
    {
      "key": "sessions",
      "label": "Sessions"
    },
    {
      "key": "pageviews",
      "label": "Page views"
    },
    {
      "key": "conversions",
      "label": "Conversions"
    }
  ],
  "rows": [
    {
      "date": "2026-09-01",
      "users": 302,
      "sessions": 410,
      "pageviews": 1250,
      "conversions": 7
    },
    {
      "date": "2026-09-02",
      "users": 311,
      "sessions": 438,
      "pageviews": 1301,
      "conversions": 9
    }
  ],
  "total": 30,
  "range": {
    "from": "2026-09-01",
    "to": "2026-09-30"
  }
}

People

get/api/v1/orgs/{orgId}/sites/{siteId}/visitors

List visitors

Visitors active in the period with lead score, tier and lifecycle stage. Contact details are masked unless the key has analytics.pii.read. Permission: analytics.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
viewqueryrecent | hot | identified | customers
tierquerycold | warm | hot | very_hot
stagequeryanonymous | engaged | lead | customer
channelquerystring
campaignquerystring
minScorequeryinteger
qquerystring
Name, email or visitor id prefix.
fromquerydate
Start date (site timezone), YYYY-MM-DD. Default: 27 days before to.
toquerydate
End date (inclusive), YYYY-MM-DD. Default: today. Max range 400 days.
pagequeryinteger (default 1)
1-based page number.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/visitors?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "items": [
    {
      "visitorId": "9b2f6d4e-3c1a-4e0f-9b7d-2a6c8e1f0d11",
      "name": "Rohan Mehta",
      "email": "r***@example.com",
      "leadScore": 82,
      "tier": "hot",
      "stage": "lead",
      "sessions": 6,
      "pageviews": 23,
      "conversions": 1,
      "revenue": 4999,
      "country": "IN",
      "device": "mobile",
      "firstSeenAt": "2026-09-12T10:02:11.000Z",
      "lastSeenAt": "2026-09-30T16:44:09.000Z",
      "firstTouch": {
        "channel": "Paid Social",
        "source": "facebook",
        "campaign": "diwali_sale"
      },
      "lastTouch": {
        "channel": "Direct",
        "source": "(direct)",
        "campaign": "(not set)"
      }
    }
  ],
  "total": 1284,
  "page": 1,
  "pages": 26,
  "tiers": {
    "cold": 900,
    "warm": 260,
    "hot": 98,
    "very_hot": 26
  },
  "stages": {
    "anonymous": 1010,
    "engaged": 190,
    "lead": 70,
    "customer": 14
  },
  "currency": "INR",
  "canExport": true
}
get/api/v1/orgs/{orgId}/sites/{siteId}/visitors/{visitorId}

Visitor / person 360 profile

Sessions, pages, campaigns, leads and scores for one visitor (and the other visitor ids linked to the same person). Contact details are masked unless the key has analytics.pii.read. Permission: analytics.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
visitorId*pathstring
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/visitors/9b2f6d4e-3c1a-4e0f-9b7d-2a6c8e1f0d11" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200

JSON object: the same fields the dashboard screen shows for this feature. See openapi.json for the schema.

get/api/v1/orgs/{orgId}/sites/{siteId}/leads

List leads

Leads from popups, spin wheels, website forms, Google One Tap, the API and connectors, with the campaign that brought them. CSV export (format=csv) requires an interactive 2FA check and is not available to API keys. Permission: leads.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
sourcequerypopup | spin | form | newsletter | onetap | api | connector
campaignquerystring
fromquerydate
Start date (site timezone), YYYY-MM-DD. Default: 27 days before to.
toquerydate
End date (inclusive), YYYY-MM-DD. Default: today. Max range 400 days.
pagequeryinteger (default 1)
1-based page number.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/leads?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "items": [
    {
      "id": "64f1c0ffee00000000020008",
      "createdAt": "2026-09-30T16:44:09.000Z",
      "source": "popup",
      "sourceName": "Diwali offer popup",
      "name": "Rohan Mehta",
      "email": "r***@example.com",
      "phone": "+91 9****1234",
      "company": "",
      "message": "(hidden)",
      "path": "/pricing",
      "country": "IN",
      "channel": "Paid Social",
      "campaign": "diwali_sale",
      "sourceMedium": "facebook / paid"
    }
  ],
  "total": 318,
  "page": 1,
  "pages": 7,
  "bySource": {
    "popup": 190,
    "form": 88,
    "connector": 40
  },
  "pii": false,
  "canExport": false
}

Insights

get/api/v1/orgs/{orgId}/sites/{siteId}/recommendations

Industry recommendations

Suggestions computed nightly against your industry's benchmarks (slow pages, campaigns without UTMs, hot leads nobody has contacted) with their status. Permission: recommendations.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/recommendations" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "industry": "SaaS / B2B Software",
  "computedAt": "2026-10-02T02:10:00.000Z",
  "benchmarks": {
    "orgs": 46,
    "eligible": true,
    "minSessions": 500,
    "rows": [
      {
        "metric": "engagementRate",
        "label": "Engagement rate",
        "value": 0.57,
        "p25": 0.41,
        "p50": 0.52,
        "p75": 0.63,
        "source": "industry"
      }
    ]
  },
  "canManage": true,
  "items": [
    {
      "ruleKey": "utm_missing",
      "status": "open",
      "score": 0.8,
      "severity": "high",
      "title": "Paid traffic without UTM tags",
      "body": "31% of paid-social sessions arrive without a campaign tag, so they show as Direct.",
      "action": "Add utm_source, utm_medium and utm_campaign to every ad link."
    }
  ]
}
get/api/v1/orgs/{orgId}/sites/{siteId}/insights/marketing

Marketing insights

Connected ad and search accounts (Google Ads, Meta Ads, Search Console, GA4 and others) with spend, clicks and conversions next to your own sessions, leads and revenue per channel. Permission: analytics.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
fromquerydate
Start date (site timezone), YYYY-MM-DD. Default: 27 days before to.
toquerydate
End date (inclusive), YYYY-MM-DD. Default: today. Max range 400 days.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/insights/marketing?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200

JSON object: the same fields the dashboard screen shows for this feature. See openapi.json for the schema.

Engagement

get/api/v1/orgs/{orgId}/sites/{siteId}/popups

List popups

Permission: popups.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/popups" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200
{
  "canManage": true,
  "items": [
    {
      "id": "64f1c0ffee00000000030009",
      "name": "Diwali offer",
      "status": "active",
      "layout": "modal",
      "trigger": "exit_intent",
      "leadForm": true,
      "updatedAt": "2026-09-20T07:00:00.000Z",
      "views": 8120,
      "leads": 190
    }
  ]
}
get/api/v1/orgs/{orgId}/sites/{siteId}/popups/{id}

Popup with insights

The popup definition, views / leads / conversion for the period, and A/B test results when a test is running. Permission: popups.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
id*pathstring
fromquerydate
Start date (site timezone), YYYY-MM-DD. Default: 27 days before to.
toquerydate
End date (inclusive), YYYY-MM-DD. Default: today. Max range 400 days.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/popups/64f1c0ffee0000000000f006?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200

JSON object: the same fields the dashboard screen shows for this feature. See openapi.json for the schema.

get/api/v1/orgs/{orgId}/sites/{siteId}/spins

List spin wheels

Permission: spinwheel.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/spins" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200

JSON object: the same fields the dashboard screen shows for this feature. See openapi.json for the schema.

get/api/v1/orgs/{orgId}/sites/{siteId}/spins/{id}

Spin wheel with insights

Permission: spinwheel.read

ParameterInType
orgId*pathstring
Organization id (24 hex characters), shown under Organization → Settings and in the dashboard URL.
siteId*pathstring
Site id, from List sites or the dashboard URL.
id*pathstring
fromquerydate
Start date (site timezone), YYYY-MM-DD. Default: 27 days before to.
toquerydate
End date (inclusive), YYYY-MM-DD. Default: today. Max range 400 days.
Request
curl "https://customer360.eleservsoft.com/api/v1/orgs/64f1c0ffee0000000000a001/sites/64f1c0ffee0000000000b002/spins/64f1c0ffee0000000000f006?from=2026-09-01&to=2026-09-30" \
  -H "Authorization: Bearer exk_YOUR_KEY"
Response 200

JSON object: the same fields the dashboard screen shows for this feature. See openapi.json for the schema.

Tracking

post/v1/collectno key

Send events

Public ingest endpoint used by ex.js. Cookieless and CORS-open; requests must come from a verified domain of the site (Origin header). Returns 202. Most integrations should use the elexy() commands in the Tracking guide instead of calling this directly.

Request
curl -X POST "https://customer360.eleservsoft.com/v1/collect" \
  -H "Content-Type: application/json" \
  -d '{
  "v": 1,
  "s": "EX-7K2M9QX4PZ",
  "vid": "9b2f6d4e-3c1a-4e0f-9b7d-2a6c8e1f0d11",
  "sid": "3f8c1a2b-5d6e-4f70-8a9b-0c1d2e3f4a5b",
  "nv": false,
  "c": {
    "analytics": true,
    "marketing": false
  },
  "ctx": {
    "ref": "https://www.google.com/",
    "lang": "en-IN",
    "tz": "Asia/Kolkata",
    "sw": 390,
    "sh": 844,
    "utm": {
      "utm_source": "google",
      "utm_medium": "cpc",
      "utm_campaign": "brand"
    }
  },
  "e": [
    {
      "id": "c0a8012e-7b4d-4f3a-9d2e-5b6c7d8e9f01",
      "t": "pageview",
      "ts": 1759400000000,
      "u": "https://eleservsoft.com/pricing",
      "ti": "Pricing"
    }
  ]
}'
Response 202
{
  "ok": true
}

Tracking commands (elexy)

Once ex.js is installed, the global elexy() function queues commands even before the script has loaded. Page views, scroll depth, outbound clicks, downloads, form submits and Web Vitals are tracked automatically; single-page apps are handled too. Everything respects the visitor's consent choice.

// Custom event with properties (shows under Events and in funnels)
elexy('event', 'plan_selected', { plan: 'pro', seats: 5 });

// Conversion with value (deduplicated by orderId)
elexy('conversion', { name: 'purchase', value: 4999, currency: 'INR', orderId: 'ORD-123' });

// Link the visitor to your own customer id (never an email or phone)
elexy('identify', { userId: 'CRM-12345' });

// Consent: react to the choice, or reopen the preferences dialog
elexy('onConsent', (choice) => console.log(choice));
elexy('showPreferences');

For strict security policies, Setup → Install & domains also offers a pinned snippet with a Subresource Integrity hash (guide).

Webhooks

Outbound: every new lead to your server

Add an Outbound webhook integration (Setup → Integrations) with a public HTTPS URL. Customer360 POSTs each new lead as JSON with two headers: X-Elexy-Timestamp (Unix seconds) and X-Elexy-Signature (sha256= + HMAC-SHA256 of timestamp + "." + rawBody using your signing secret). Retries happen for 5xx responses.

{
  "event": "lead.created",
  "id": "64f1c0ffee00000000020008",
  "createdAt": "2026-09-30T16:44:09.000Z",
  "site": {
    "id": "64f1c0ffee0000000000b002",
    "name": "Eleserv website",
    "domain": "eleservsoft.com"
  },
  "source": "popup",
  "sourceName": "Diwali offer popup",
  "lead": {
    "name": "Rohan Mehta",
    "email": "rohan@example.com",
    "phone": "+919876501234",
    "company": null,
    "message": null,
    "extra": {}
  },
  "attribution": {
    "channel": "Paid Social",
    "source": "facebook",
    "medium": "paid",
    "campaign": "diwali_sale"
  },
  "page": "/pricing"
}

Inbound: send leads to Customer360

Add the Webhook (inbound) integration to get a URL and secret. POST a JSON lead with the secret in the X-Elexy-Secret header (or as a bearer token). Leads are deduplicated by externalId and merged into the visitor's profile when a visitor id is known. Google Ads lead forms, Google Forms and Tally use the same endpoint with their own formats.

curl -X POST "https://customer360.eleservsoft.com/v1/hooks/webhook_in/EX-XXXXXXXXXX" \
  -H "X-Elexy-Secret: YOUR_INBOUND_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
  "externalId": "CRM-9981",
  "name": "Rohan Mehta",
  "email": "rohan@example.com",
  "phone": "+919876501234",
  "company": "Mehta Traders",
  "message": "Interested in the Growth plan",
  "campaign": "trade_show"
}'