The Profiles API exposes the profiles UMAP360 resolves from your events — list and search them, read a profile's events and identity signals, and merge two profiles. All routes are served under /v1-profiles and require a read key (uk_read_); the merge route requires an admin key.

GET https://YOUR_PROJECT_REF.supabase.co/functions/v1/v1-profiles
Authorization: Bearer uk_read_YOUR_READ_KEY

Read & admin keys are server-side only

Unlike the write key, read and admin keys can access your data — keep them on your server, never in a browser. See Authentication.

Reads are rate-limited to 60 requests per minute and the merge to 10 per minute, per (organization, client IP) — see Errors & rate limits. An invalid limit / offset returns 400; an unmatched route returns 404 Not found.

List profiles — GET /v1-profiles

ParameterDefaultNotes
limit50Max 100 (larger values are clamped to 100).
offset0For pagination.
identifiedtrue / false to filter by whether the profile has a known userId.
sort_bylast_seen_atOne of last_seen_at, first_seen_at, event_count, session_count, engagement_score, created_at.
sort_orderdescasc or desc.
{ "success": true, "profiles": [ /* … */ ], "total": 1234, "limit": 50, "offset": 0 }

Get a profile — GET /v1-profiles/:id

:id is either the profile's UUID or its canonical_id. Returns the profile plus its active identity signals and 30-day stats — 404 Profile not found if it doesn't exist in your org.

{
  "success": true,
  "profile": {
    "id": "…",
    "canonical_id": "…",
    "identities": [ /* signal_type, signal_value, confidence, first_seen_at, last_seen_at, occurrence_count */ ],
    "stats": { "total_sessions": 12, "events_last_30_days": 340 }
  }
}

Get a profile's events — GET /v1-profiles/:id/events

ParameterDefaultNotes
limit50Max 200.
offset0Legacy offset pagination (returns an exact total).
cursorOpaque keyset cursor — recommended for deep pages. Takes precedence over offset. A malformed value → 400 Invalid cursor.
event_nameFilter to a single event name.
precise_total1 to get an exact total on the cursor path (otherwise it's estimated).

The offset path returns an exact total; the cursor path returns next_cursor

  • has_more and (by default) an estimated total:
{
  "success": true,
  "events": [
    { "id": "…", "event_name": "Purchase Completed", "event_timestamp": "…", "properties": {}, "context": {}, "resolution_method": "…" }
  ],
  "total": 340,
  "limit": 50,
  "next_cursor": "eyJ0cyI6…",
  "has_more": true
}

Page forward by passing the returned next_cursor as ?cursor= on the next request; stop when has_more is false.

Read a profile's identities — GET /v1-profiles/:id/identities

Returns the identity signals, browser fingerprints, and click IDs tied to the profile — useful for confirming identity stitching worked.

{
  "success": true,
  "identities": {
    "signals": [ /* … */ ],
    "fingerprints": [ /* fingerprint_hash, stability_score, first_seen_at, last_seen_at, occurrence_count */ ],
    "click_ids": [ /* click_type, click_id, campaign_source, campaign_medium, first_seen_at, is_exhausted */ ]
  }
}

Search profiles — GET /v1-profiles/search

Provide one of:

ParameterNotes
emailMatch by email signal (lower-cased).
user_idMatch by known user ID.
anonymous_idMatch by anonymous ID.
q (or query)Free-text search (max 200 characters).

Add ?partial=true for substring matching (the default is exact match). limit defaults to 20 (max 50). With no search parameter you get 400 Search parameter required: q, email, user_id, or anonymous_id.

{ "success": true, "profiles": [ /* … */ ], "count": 3 }

Merge two profiles — POST /v1-profiles/merge

Requires an admin key

Merging is destructive and needs an admin key (uk_admin_).

curl -X POST https://YOUR_PROJECT_REF.supabase.co/functions/v1/v1-profiles/merge \
  -H "Authorization: Bearer uk_admin_YOUR_ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source_profile_id": "…",
    "target_profile_id": "…",
    "reason": "manual review"
  }'

source_profile_id and target_profile_id are required and must both exist in your org. Merging a profile into itself returns 400; a missing or cross-org profile returns 404 One or both profiles not found. reason is optional.

Next

Last updated 2026-06-10

We use cookies for analytics — to understand how visitors use UMAP360 and improve the product. Essential cookies (session, forms) always run; analytics cookies wait for your call. See cookie policy.