Skip to content

Stitch developer guide

For: the engineers wiring Beeline’s systems to Stitch. One page that says what gets built, by event, in the order it pays off, with a link to the full contract for each piece. The per-event pages are the contracts; this page is the map.

Stitch is built around events, not systems. It does not know which system will send a given event, when it fires, or whether a middleware sits in between — it sees a key, which names the system the owner issued it to, and a payload. So this guide is organised by event, and the table at the end says who we think owns each one today. If that is you, build it; if it turns out to be a middleware or another team, the contract is the same.

Environment, today: dev only. This guide and the contracts are published at https://stitchdocs.beeline.team; the API reference there covers every endpoint named below.

URL
Collector (every integration endpoint, the SDK)https://stitch-collector-dev.magic-blocks.workers.dev
App (the screens, the exports)https://stitch-app-dev.magic-blocks.workers.dev

Production will put the collector on a first-party host per brand (t.makeabeeline.com, t.beelineequitynow.com); nothing in the contracts changes, only the hostname.

Every server-to-server call carries Authorization: Bearer <key>. There is one key per emitting system, issued by the owner and named after whatever actually sends — ask MagicBlocks; keys are never sent over chat. The system a key belongs to is recorded on every row it creates, so a key for a middleware says “middleware”, not the name of the system behind it. A missing or wrong key is a 401 with no detail. Three names are Stitch’s own and cannot be a key: stitch, manual, manual_spread. The browser’s endpoints (/v1/collect, /v1/consent, /v1/decorate, /sdk.js) need none. Full detail: the provisioning runbook (internal).

Two rules apply everywhere: the lifecycle endpoints take an idempotency key and re-sending it is a harmless 200; send what you have now and more later — no payload needs to be complete. See README.md.

In the order it pays off.

1. A person becomes known → POST /v1/identify

Section titled “1. A person becomes known → POST /v1/identify”

The moment a contact is created from a web form, chat or call, send the visitor’s anon_id (read server-side from the _bid cookie) with the contact’s id. That binds the entire prior browsing history to the person in one deterministic call — the single highest-leverage integration. Send it again on every authenticated sign-in; it is idempotent and repairs drift. → identity.md

2. A lead is created or changes status → POST /v1/conversion with event

Section titled “2. A lead is created or changes status → POST /v1/conversion with event”

The lead’s created event with the real creation time (it becomes the attribution anchor), the contact id, vendor_source, cost_cents, and attrs.submission_id from the form’s hidden field so the pixel’s event and Stitch’s are one event to the platform. Later status events as they happen. → lead-events.md

3. A loan starts, moves and funds → POST /v1/conversion with stage

Section titled “3. A loan starts, moves and funds → POST /v1/conversion with stage”

Every stage you have, when you have it, with the loan’s attributes as they stand: loan_amount, property_value, the stated credit_range/credit_band, fico once pulled, app_type, product, occupancy; lead_external_id on the first event; realised gross_revenue at funding; the current amount on later events when the file changes it. Stitch scores the application on ingest, sends the conversions, and exports the final figures for the model’s refit. → loan-stages.md

Section titled “4. The website → the SDK, the submission id, consent, tracking templates”
  • Load the SDK from the collector: one script tag, no configuration beyond the host. It records page views, sessions, click ids, the ad ids from the tracking templates and the vendor pixels’ cookies, and honours Global Privacy Control on its own. → web-sdk.md
  • On the lead form, write window.stitch.submission() into a hidden field stitch_submission_id and fire the Meta/TikTok pixels with the same id — guarded, as the page shows. → web-sdk.md §3a
  • Call window.stitch.consent({...}) from the CMP’s change callback. → consent.md
  • Media buying: set the tracking templates per platform so every paid click lands with its click id, the ad ids, and the campaign name in utm_campaign. → tracking-templates.md

5. An application’s value is wanted now → POST /v1/score

Section titled “5. An application’s value is wanted now → POST /v1/score”

When the application sections are complete, post the five fields the borrower entered and report conversion_value as the value of the application conversion you report to Google. Same body and answer as the EV Worker’s /score. Do not call it again with updated figures: the value is computed from what the borrower entered and corrected afterwards only by Stitch’s own restatements (the pulled score, the realised revenue, a dead end). → application-value.md, outbound.md

6. A session happens outside the browser → POST /v1/session

Section titled “6. A session happens outside the browser → POST /v1/session”

Portal sessions and agent sessions, with the page’s anon_id when the session began on one of our pages, and goal events through /v1/collect. These convert; they never acquire. → sessions.md

7. Someone says how they heard about us → POST /v1/declared

Section titled “7. Someone says how they heard about us → POST /v1/declared”

On the lead’s attrs, or directly from a form handler, a loan officer’s tool, or a voice agent. → declared-source.md

  • Call attribution through Twilio. → twilio-dni.md
  • Ad spend beside value. → spend.md
  • Conversions back to the platforms — Google, Meta, TikTok, LinkedIn, Microsoft, Taboola, Outbrain, a signed webhook (Zapier) — each a row to enable and credentials to set; what is sent, matched on, excluded and restated. → outbound.md

Our best guess, written down so it can be corrected. Nothing in a contract depends on it being right.

EventToday, probablyCould equally be
A person becomes knownthe form handler or CRM at contact creation; the portal at sign-in; the agent when it learns an identitya middleware that fronts any of them
Lead eventsthe CRM (Relcu)a middleware in front of it, or whatever replaces it
Loan stages and valuethe loan origination system (Vesta)a middleware, an export job, a data platform that already mirrors it
Application valuethe application’s backend (makeabeeline.com’s app)a middleware that fronts the application
Sessions outside the browserthe portal’s backend; the agent platform (MagicBlocks)a middleware
Declared sourcewhoever asks: the lead form, the loan officers, the agent—
Spendmedia buying / ad opsan agency’s reporting
  • The screens: sign in at the app URL with your work email; a code is emailed. Access levels and how people are added: the access runbook (internal).
  • The predictions export for the value model’s refit: GET /api/export/predictions?since=YYYY-MM-DD on the app, with the export token. → application-value.md

Every page ends with a curl you can paste against dev; the same commands run in scripts/smoke-*.sh. Test rows are real rows — use an obvious prefix on ids so they can be excluded later.