FunnelMob

REST API

REST API Reference

FunnelMob SDK-to-Backend REST API reference.

The FunnelMob REST API is used by SDKs to submit events and register sessions. All endpoints require API key authentication.

Base URL

All requests go to https://api.funnelmob.com/v1.

Authentication

All requests must include the X-FM-API-Key header:

X-FM-API-Key: fm_live_abc123

Endpoints

POST /events

Submit a batch of events for processing.

Request Body

{
  "device_id": "550e8400-e29b-41d4-a716-446655440000",
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "platform": "ios",
  "events": [
    {
      "event_id": "unique-event-uuid",
      "event_name": "purchase_complete",
      "timestamp": "2025-12-21T10:30:00.000Z",
      "revenue": {
        "amount": "29.99",
        "currency": "USD"
      },
      "parameters": {
        "item_id": "sku_123",
        "quantity": 2
      }
    }
  ]
}
FieldTypeRequiredDescription
device_idstringNoDevice identifier (IDFV, GAID, or generated UUID)
session_idstring (uuid)NoCurrent session identifier
platformstringNoios, android, or web
eventsarrayYesArray of events (1-100 items)

Event Object

FieldTypeRequiredDescription
event_idstring (uuid)YesUnique identifier for this event
event_namestringYesEvent name (1-100 chars, pattern: ^[a-zA-Z][a-zA-Z0-9_]*$)
timestampstring (date-time)YesISO 8601 timestamp with milliseconds
revenueobjectNoRevenue information
parametersobjectNoCustom key-value parameters

Revenue Object

FieldTypeRequiredDescription
amountstringYesDecimal string (e.g., "29.99")
currencystringYesISO 4217 currency code, uppercase (e.g., "USD")

Responses

  • 202 Accepted — Events accepted for processing
{
  "accepted": 5,
  "rejected": 0,
  "errors": []
}
  • 400 Bad Request — Validation error
  • 401 Unauthorized — Invalid API key
  • 429 Too Many Requests — Rate limit exceeded

Error Response Format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": [
      {
        "field": "events[0].event_name",
        "message": "Must start with a letter"
      }
    ]
  }
}

POST /session

Register a new session when the app opens or comes to foreground.

Request Body

{
  "device_id": "550e8400-e29b-41d4-a716-446655440000",
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "platform": "ios",
  "timestamp": "2025-12-21T10:30:00.000Z",
  "is_first_session": false,
  "context": {
    "app_version": "1.2.3",
    "os_name": "iOS",
    "os_version": "17.2",
    "device_model": "iPhone 15 Pro",
    "locale": "en_US",
    "timezone": "America/New_York",
    "screen_width": 1179,
    "screen_height": 2556
  },
  "consent": {
    "is_user_subject_to_gdpr": true,
    "has_consent_for_data_usage": true,
    "has_consent_for_ads_personalization": false,
    "has_consent_for_ad_storage": true
  }
}
FieldTypeRequiredDescription
device_idstringYesDevice identifier
session_idstring (uuid)YesNew session identifier
platformstringNoios, android, or web
timestampstring (date-time)YesISO 8601 timestamp
is_first_sessionbooleanNoWhether this is the first session (default: false)
contextobjectNoDevice context information
consentobjectNoGDPR / DMA consent state — see below

Device Context

FieldTypeDescription
app_versionstringApp version string
os_namestringiOS, Android, or Web
os_versionstringOS version
device_modelstringDevice model name
localestringDevice locale
timezonestringIANA timezone
screen_widthintegerScreen width in pixels
screen_heightintegerScreen height in pixels

Consent Object

Optional. Mirrors FunnelMobConsent in the SDKs and Google Consent Mode v2 dimensions. When omitted, the host has not configured consent and the backend treats the session as non-EEA / no-restriction.

Consent is sent on session payloads only — not on event batches. The SDK enforces consent locally (it stops dispatching events when consent is revoked), and a session re-fire is scheduled whenever setConsent(...) is called so the backend learns the new state without waiting for the next launch.

FieldTypeRequiredDescription
is_user_subject_to_gdprbooleanYesWhether the user is subject to GDPR. When false, the per-dimension flags below are advisory only.
has_consent_for_data_usagebooleanNoUser granted consent for data usage. When false and is_user_subject_to_gdpr is true, the SDK has stopped dispatching — this field is a record of the decision.
has_consent_for_ads_personalizationbooleanNoGoogle Consent Mode v2 ad_personalization. Forwarded to ad networks.
has_consent_for_ad_storagebooleanNoGoogle Consent Mode v2 ad_storage. Forwarded to ad networks.

Responses

  • 200 OK — Session registered
{
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "server_timestamp": "2025-12-21T10:30:00.123Z"
}
  • 400 Bad Request — Validation error

GET /health

Health check endpoint (no authentication required).

Response: 200 OK