---
title: "Capture Attribution"
method: POST
path: "/api/auth/capture-attribution"
tags: ["auth"]
---

# Capture Attribution

`POST /api/auth/capture-attribution`

## Request

- Base URL: `https://api.equity-rank.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.equity-rank.com/api/auth/capture-attribution`
- Auth: HTTP bearer

Persist the visitor's first-touch acquisition source at sign-in so signups
can be attributed to a channel (paid ad, programmatic SEO, referral, organic
search, or direct). Without this, ad/SEO links carry utm_source / er_src but
nothing records them, making paid spend impossible to measure.

When the client has no stored attribution (cleared storage, second device),
the source is derived server-side from the X-ER-Src header / er_src cookie /
Referer, so the row always gets at least 'direct' — never NULL.

Writes use DB-level first-touch semantics (see _write_attribution): a real
channel label is never overwritten by a later 'direct', fixing the
second-device downgrade path. Idempotent per user via the service-role key
(bypasses RLS). Best-effort — attribution never blocks the user.

## Request body

- CaptureAttributionRequest
  - `source` string, nullable
  - `utm_source` string, nullable
  - `utm_medium` string, nullable
  - `utm_campaign` string, nullable
  - `utm_content` string, nullable
  - `referrer` string, nullable

## Response `200`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/equity-rank/apis/equity-rank-api.md) · [All operations](https://skmtc.dev/equity-rank/apis/equity-rank-api/llms.txt) · [OpenAPI document](https://skmtc.dev/equity-rank/apis/equity-rank-api/revisions/c2f2463fee33?raw)
