LearnMobile Setup

Mobile Setup

Send events from your iOS or Android app to Hardal with an HTTP POST to the /collect endpoint.

How mobile tracking works

Mobile apps send each event to /collect on your first-party URL with an HTTP POST request. You don't need to install an SDK.

Privacy by default

You can send mobile events without attaching a known user identity. After a user grants consent, include only the identifiers allowed by your consent rules.

Consent Signals

When to send consent and what each signal changes.

Mobile collection endpoint

POST https://analytics.yourdomain.com/collect

Use your first-party URL. This is the same data-host-url value shown in the Dashboard.

HeaderRequiredValue
Content-TypeYesapplication/json
tenant-idYesTenant ID from Setup
x-virgo-session-idNoStable UUID for the current app session
x-virgo-consentNogranted or denied

Create one UUID when an app session starts and reuse it in x-virgo-session-id for that session. If you omit it, Hardal creates a session ID for the request. Send x-virgo-consent: granted when identity processing is allowed and denied when it is not. If the header is omitted, Hardal reuses a valid first-party identity cache for the same Tenant ID and Source ID; without that cache, it removes userId and visitorId before processing.

Mobile event payload

{
  "type": "event",
  "eventName": "app_open",
  "payload": {
    "sourceId": "your-source-id",
    "title": "Home Screen",
    "hostname": "com.yourcompany.app",
    "url": "app://home",
    "referrer": "",
    "timestamp": 1773914400000,
    "timezone": "Europe/Istanbul",
    "data": {
      "screen_name": "HomeScreen",
      "app_version": "3.2.1"
    }
  }
}

One event cannot contain both a non-empty items array and a non-empty leads array.

Mobile request examples

curl -X POST https://analytics.yourdomain.com/collect \
  -H "Content-Type: application/json" \
  -H "tenant-id: your-tenant-id" \
  -H "x-virgo-session-id: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{
    "type": "event",
    "eventName": "purchase",
    "payload": {
      "sourceId": "your-source-id",
      "title": "Order Confirmed",
      "hostname": "com.yourcompany.app",
      "url": "app://order/confirmation",
      "timestamp": 1773914400000,
      "data": {
        "transaction_id": "ORD-20260615-7891",
        "value": 214.98,
        "currency": "USD",
        "items": [
          { "item_id": "SKU-1", "item_name": "Running Shoes", "price": 134.99, "quantity": 1 }
        ]
      }
    }
  }'

The endpoint and payload match the API & Server-side setup. Only the sender changes: here, the request comes from your app instead of your backend.

A valid request returns 202 Accepted. Use the response Event ID and Request ID when troubleshooting.

Pick your events