Ambit Signal

api | install-astro | install-caddy | install-cloudflare | install-express | install-js-tag | install-netlify | install-nginx | install-shopify | install-squarespace | install-sveltekit | install-vercel-next | install-webflow | install-wix | install-wordpress | mcp | outcomes | privacy | quickstart | troubleshooting

Outcomes: leads, bookings, sales

Outcomes connect AI attribution to business results. Each outcome is stored against the site with its first-touch source, so reports show "ChatGPT: 3 inquiries, 1 booked, $850".

Server-side (trusted): POST /v1/outcomes

Use this from your backend, CRM, or automation (Zapier, Make, n8n). Value and status are accepted only with an API key.

curl -s -X POST https://signal.ambit.agency/v1/outcomes \
  -H "Authorization: Bearer $AMBIT_SIGNAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "site_id": "st_YOURSITEID",
    "type": "booking",
    "id": "INV-1042",
    "status": "confirmed",
    "value": 850,
    "src": {"provider": "openai", "via": "utm:chatgpt.com", "landing": "/private-dining"}
  }'
Field Required Notes
site_id yes Must belong to the key's account.
type yes lead, booking, sale or signup.
id yes Your id for this outcome (max 100 chars). Re-sending the same type + id updates it (for example when a lead becomes a booking).
status no Counted as converted: booked, won, closed_won, confirmed, deposit_received, menu_planning, prep, in_progress, completed, invoiced, paid, active, paused. Counted as lost: cancelled, inactive. Anything else (for example new, open, proposal_sent) is open pipeline.
value no Number, in the site's currency. Converted outcomes report as booked value; open ones as open quotes.
src no The first-touch record. Take it from the form's hidden ambit_src field (JSON string, parse it) or from window.ambitSrc(). Keys: provider, via, landing, ts, tz, screen, lang. provider is one of openai, perplexity, google, microsoft, anthropic, meta, xai, or empty.

Once an outcome has a known source it keeps it: a later update without src does not erase it.

Browser (untrusted): window.ambitSignal.outcome

With the JS tag on the page:

window.ambitSignal.outcome("lead", "form-" + Date.now());

Browser calls are accepted only from the site's own domain (Origin check) and are rate limited. They cannot set value or status and cannot overwrite an outcome your server already reported. Use them to count leads on sites with no backend; report value from the server.

Form recipes

The JS tag adds a hidden input ambit_src to every form on the page. Its value is a JSON string such as {"provider":"openai","via":"utm:chatgpt.com","landing":"/","ts":1790170000000}. Make sure your form handler keeps that field, then forward it as src.

Webflow forms

  1. Install the JS tag.
  2. Webflow stores the extra ambit_src field with each submission automatically (Forms tab shows it).
  3. To send outcomes: Site settings > Forms > add a webhook to Zapier or Make, then a step that POSTs to /v1/outcomes with type: "lead", id = the submission id, src = the parsed ambit_src field.

HubSpot forms

  1. Create a single-line text contact property with internal name ambit_src.
  2. Add it to the form as a hidden field.
  3. The JS tag fills it on submit for embedded HubSpot forms rendered as regular <form> elements. For the iframe embed, add in the form embed options: onFormReady: function(f){ var i=f.querySelector('input[name="ambit_src"]'); if(i) i.value=JSON.stringify(window.ambitSrc()); }.
  4. Report outcomes from a HubSpot workflow webhook (deal stage changes), mapping ambit_src to src.

Gravity Forms (WordPress)

Gravity Forms saves only its own fields, so use a Hidden field rather than the auto-added input. 1. Add a Hidden field labelled ambit_src. Under Appearance, set Custom CSS Class to ambit-src. 2. Install the JS tag, and in the theme footer add: ```html

`` 3. In agform_after_submissionhook,wp_remote_postto/v1/outcomeswithtype: "lead",id= the entry id, andsrc= the decoded hidden field. Keep the API key inwp-config.phpas a constant (AMBIT_SIGNAL_API_KEY`), never in the database or theme.

Formspree

  1. Install the JS tag. Formspree keeps unknown fields, so ambit_src arrives with each submission.
  2. Formspree > Plugins > Webhook to your automation, then POST to /v1/outcomes as above.

Checking it

curl -s -H "Authorization: Bearer $AMBIT_SIGNAL_API_KEY" \
  "https://signal.ambit.agency/v1/sites/st_YOURSITEID/report?days=30" | python3 -c "import sys,json; print(json.load(sys.stdin)['report']['inquiries'])"