Signals Docs
Reference

REST ingest API

The public endpoints the SDK uses - and that your backend can use too.

Base URL: your PixelFox ingest API (e.g. https://api.pixelfox.app). Authenticate with the X-Signals-Key header, or ?key= where headers aren't possible. CORS is open; origin allow-listing is enforced per key (dashboard → Settings).

POST /v1/ingest

Send up to 50 events per request (body cap 256 KiB):

curl -X POST https://api.pixelfox.app/v1/ingest \
  -H "Content-Type: application/json" \
  -H "X-Signals-Key: sig_live_…" \
  -d '{
    "events": [{
      "event": "purchase",
      "uuid": "3f1c…-…",
      "distinct_id": "user-123",
      "timestamp": "2026-08-05T12:00:00Z",
      "properties": {
        "order_id": "1001",
        "total": 129.5,
        "currency": "USD",
        "email": "[email protected]"
      }
    }]
  }'

Response: {"accepted": 1} - returned as soon as the batch is accepted; destination fan-out happens asynchronously. When the account's monthly event allowance (plus a 20% grace margin) is exhausted, the excess is dropped and reported as {"accepted": n, "dropped": m}; bot traffic and events matching the site's block rules answer {"accepted": 0} without an error.

FieldRequiredNotes
eventEvent name (see conventions)
uuidUnique id per event - the browser↔server dedup key. Omit only if no browser pixel will ever fire this event
distinct_id-Visitor/user id; defaults to an anonymous id derived server-side
timestamp-ISO 8601; defaults to arrival time
properties-Event properties. email/phone here trigger identity stitching on identify-type events

Errors: 401 missing key · 403 invalid key or origin not allowed · 413 too many events / body too large · 429 rate limited (200 req/10s per IP, 1000 req/10s per key).

GET /v1/config

What the SDK fetches on load - public per-site config, never secrets:

{
  "mode": "online",
  "business_category": "ecommerce_retail",
  "clarity": { "project_id": "…" } | null,
  "facebook": { "pixel_id": "…", "route_pixels": [{ "pixel_id": "…", "url_pattern": "/eu/*" }] } | null,
  "tiktok": { "pixel_code": "…" } | null,
  "ga4": { "measurement_id": "…" } | null,
  "gtm": { "container_id": "GTM-…" } | null,
  "custom_loader": false,
  "events": [ { "id": "…", "name": "hero_cta_clicked", "trigger": "click",
                "selector": ".hero .btn", "url_pattern": "/", "text_contains": "",
                "properties": {}, "conversion_event": "lead",
                "destinations": { "tiktok": false },
                "value_selector": "", "field_selectors": { "email": "input[name=email]" },
                "enabled": true } ]
}

mode is online or offline (offline sites are anonymous-only and the edge strips identifiers). ga4 is null when the destination routes server-side, so the tag does not load gtag. custom_loader is true when a first-party domain is configured and the tag should source vendor scripts through it. Per-definition destinations flags (absent = send) and the value_selector / field_selectors read at fire time are described under event definitions.

business_category is the site's Meta-style business category (ecommerce_retail, entertainment_media, education, real_estate, technology, financial_services, automotive, travel, other), set in the dashboard's site settings. It is informational - integrations use it to surface the conversion events recommended for that kind of business; capture behaves identically for every category.

POST /v1/inventory

Used by the SDK's auto-discovery; body { page, url, title, elements: [{ type, selector, text, href?, event_hint? }] } with at most 300 elements. Deduplicated server-side per (key, page) content hash. Response: {"accepted": n}.

GET /v1/health

{"ok": true, "ratelimit": "redis" | "memory"} - for uptime checks; the second field says whether rate-limit and quota counters are shared across replicas.

Other public endpoints

RoutePurpose
GET /signals.min.js, /signals.mjs, /signals-engage.min.js (also under /v1/)The tag itself, with ETag and a 5-minute cache
GET /v1/script-statusWhether the tag is built, its size and ETag
GET /v1/tls-check?domain=Certificate gate for first-party domains (used by the edge proxy)
GET/POST /g/collectGA4 wire-format intake for server-side GTM
POST /v1/engage, /v1/surveys/respond, /v1/promos/track, /v1/formSurveys, forms and promos
/sg.js, /sx.js, /sp.js, /tt.js, /a/c, /s/p, /t/eFirst-party custom loader proxies, served only on a claimed domain

On this page