Skip to content

Integrating with Stitch

Stitch is Beeline’s cross-channel attribution system. It answers two questions that are usually conflated: who brought this person into our world, and who produced this loan. Those are separate ledgers and they are never summed.

This directory is one page per event the collector accepts, not one per system. Stitch does not know which system will send an event, or when, or through what — a CRM’s webhook, a loan origination system’s, a middleware in front of either, or a replacement for any of them. It sees a key, which names the system the owner issued it to, and a payload. Each page therefore describes the event: its payload, its idempotency, what Stitch does with it, and a smoke test; and names, as a guess, who most likely owns it today. New here? Start with the developer guide: what gets built, in the order it pays off, with the link to each contract.

New to the terminology? ../glossary.md explains every term this system uses in plain English — the two ledgers, the confidence ratings, and why “brand search” is treated differently from everything else.

These pages are also published at https://stitchdocs.beeline.team, with an API reference for every collector endpoint.

https://stitch-collector-dev.magic-blocks.workers.dev

Development only. Production hostnames will be t.makeabeeline.com and t.beelineequitynow.com — one first-party collector per registrable domain, which matters more than it looks (see web-sdk.md).

Every server-to-server call (/v1/identify, /v1/conversion, /v1/session, /v1/score, and /v1/declared from a system) sends Authorization: Bearer <your key>. The owner issues one key per emitting system and names it after whatever actually sends. The browser’s endpoints (/v1/collect, /v1/consent, /v1/decorate, /sdk.js) need none.

Ordered by leverage, not by size. The first two are worth more than everything below them combined. “Emitted by” is our best guess at who owns the event today; the contract does not change if it is someone else.

#EventPageEmitted by (today, our guess)What it unlocksWhat breaks without it
1A person becomes knownidentity.mdthe form handler or CRM at contact creation; the portal at sign-in; an agentBind-at-birth. Anonymous browsing history attaches to a real person deterministicallyThe last probabilistic step in the whole conversion path stays probabilistic. Anonymous history and the contact remain two islands
2A lead is created or changes statuslead-events.mdwhatever is the system of record for leads (today, probably the CRM)The lead grain, its attribution anchor, the lead conversion to the ad platforms, the submission id that makes the pixel’s event and ours oneNo leads to attribute; the platforms learn from form fills instead of leads
3A loan starts, moves, fundsloan-stages.mdthe loan origination systemLoan creation, stage transitions and realised revenue. This is the conversion objectThere is nothing to attribute. Every report is empty
3bAn application’s value is wanted nowapplication-value.mdthe application’s backendThe application’s value, from the borrower’s own entry, reported to Google and restated as the loan’s truth arrivesGoogle bids on form fills; the application conversion carries no value
4A page is viewed, a form is submittedweb-sdk.md, tracking-templates.mdthe websites; media buying for the templatesSessions, sources, click IDs, campaign and ad ids, the vendor pixels’ cookies, the submission idNothing upstream of the lead is known
5A session happens outside the browsersessions.mdthe portal’s backend; the agent platformPortal and agent sessions, goal events, the agent’s measurable liftAgent contribution is invisible, and sessions the agent identifies are never bound
6Someone says how they heard about usdeclared-source.mdwhoever asks the questionThe one answer instrumentation cannot give, cross-tabbed against what was trackedPhone, podcast and word of mouth look like “direct”
7Someone refuses or consentsconsent.mdthe CMP, the SDK, a “Do Not Sell” linkA refusal that actually changes what is sentOpt-outs are recorded nowhere that matters
8A call comes intwilio-dni.mdops / TwilioCall attribution, upgrading source certainty from tier E to tier CPhone-in leads stay unattributed
9A conversion goes back outoutbound.mdStitch itselfLead, application and funded value fed to ad platform bidding, restated as the truth arrivesThe platforms optimise on leads instead of funded loans
10Money is spentspend.mdmedia buying / ad opsCost beside value: CAC, cost per funded loan, ROAS, and the spend that reached nothingEvery screen says what a channel produced and none can say what it cost

Idempotency is your safety net, so use it. /v1/conversion takes an idempotency_key and /v1/session an external_session_ref; /v1/identify is idempotent by nature. Re-sending the same key is a no-op that returns 200 instead of 202. Fire the same message a hundred times if your retry logic wants to — it costs nothing and it is far safer than trying to send exactly once.

Send what you have, send more later. No endpoint requires a complete payload. Loan attributes in particular are versioned with validity windows, so a property_status of tbd that later becomes identified is recorded as both, with the transition measurable. Do not wait for complete data.

Two rules Stitch applies that you should know about

Section titled “Two rules Stitch applies that you should know about”

AI and portal sessions convert; they do not acquire. Both are hard-classed as nurture and can never take acquisition credit, whatever you send. The agent harvests demand a channel already produced — if it could take credit it would progressively cannibalise credit from every real channel, and the better it performed the more it would distort the picture.

URL events are behavioural; the system of record is transactional. A /thank-you page hit is evidence someone probably submitted a form. The lead is whatever the system of record says it is. Stitch counts leads from the lead event and uses page events only for funnel shape. The two are never summed and never substituted, which is what stops the classic failure where the site reports 400 conversions, the CRM’s own count is 340, and nobody can explain the gap.

Every page ends with a curl you can paste. These are the same commands scripts/smoke-*.sh runs in CI, so the guide cannot drift from what is actually tested.

Endpoint behaviour is defined by the tests in workers/collector/test/. If this guide and those tests disagree, the tests are right and the guide is a bug — please say so.

Every URL and the sign-in steps: the where-everything-is runbook (internal).