askbowtie

Server-side sessions

The advanced setup. Post page views and conversions from your backend, under one id you own. Attribution becomes exact, nothing can block it, and no JavaScript is required.

Most sites install the tracker and are done. Reach for this when your conversions happen somewhere a browser cannot reliably report: a checkout that completes server-side, a redirect gateway, a payment webhook, a native app.

The problem it solves

Your session id is minted in the browser and kept in localStorage. Your backend cannot read it. So when your server posts a conversion, it sends an id the browser never used, and we cannot connect it to a visit.

Your conversion count stays correct. What breaks is everything around it: the visit that produced the sale is missing from the denominator, so your conversion rate can read above 100%, and your per-source, per-page and per-device breakdowns cover only the fraction we could join.

The fix: one id, two events

You own the identity. Mint it yourself, a UUID in your own first-party cookie set at your edge on the first request. Do not call askbowtie to generate it: that puts our latency and our uptime in front of your page load, and you already have a cookie.

Then post both events under it.

On landing

POST https://askbowtie.com/api/ingest
{
  "domain": "example.com",
  "session_id": "<your visitor id>",
  "events": [{
    "event_type": "page_load",
    "source": "server",
    "page": "/pricing",
    "referrer": "https://www.google.com/",
    "ts": 1735000000
  }]
}

On conversion, later, same id

POST https://askbowtie.com/api/ingest
{
  "domain": "example.com",
  "session_id": "<the same id>",
  "events": [{
    "event_type": "conversion",
    "source": "server",
    "goal": "purchase",
    "value": 49,
    "currency": "USD",
    "page": "/checkout",
    "ts": 1735000600
  }]
}

That is the whole integration. No SDK, no cookie from us, no JavaScript.

What it changes

Conversions onlyServer-side sessions
Conversion countcorrectcorrect
Conversion ratecan exceed 100%correct by construction
Joinprobabilistic, or noneexact, every time
Source / page / device breakdownsattributed slice onlycomplete
Blocked by ad-blockerspage views areno

Rules that bite

Check it worked

Ask for get_traffic over MCP and look at attribution. You want unattributed_rate near zero and by_reason.attributed_session carrying the count. by_goal ranks your goals worst-wired first, so it names which integration to fix instead of making you guess.

One caveat worth knowing: attribution is window-bounded. A conversion resolves only when its page view falls inside the window you queried, so a one-hour view understates a perfectly wired site. Check at 24 hours or wider.

Using it alongside the tracker

Common, and fine. Keep the tracker for engagement, errors and performance; add server-side page views for the flows a browser cannot see. Pick one owner of the identity per flow: if both fire for the same visit under different ids, you will double-count sessions.

For AI agents

Wiring this with a coding agent? Hand it this:

Post BOTH the page view and the conversion to https://askbowtie.com/api/ingest
under ONE session_id that our backend owns (a UUID in our own first-party cookie,
set at the edge on first request). Every event must include "source": "server".
The page_load must carry "page" and "referrer"; the conversion must carry "goal".
Do not call askbowtie to mint the id. Verify by checking that the ingest response
contains {"stored":{"server":N}} with the N you sent, then that get_traffic's
attribution.by_reason.attributed_session covers your conversions.

New here? Install the tracker first. Most sites need nothing more than that.