The one idea
Every link Figlix puts on a post already carries UTM tags it built itself: the channel in utm_source, the campaign in utm_campaign, the exact post in utm_content. Keep those tags when a visitor lands, and send them back with the event when that visitor converts. Figlix matches them to the post that carried the link. An event with no tags still counts — as direct.
The endpoint
On Insights → Conversions in Figlix, someone with the workspace's permission makes a source — one per site or app — and gets a key. The key goes in the path, and it is the whole authentication:
POST https://api.figlix.com/public/conversions/<key>The key names the brand, so keep it on the server where you can. Any origin may call it, so a browser snippet works too. If it leaks, revoke it on the same screen and make another — the events it already sent stay.
The body
POST https://api.figlix.com/public/conversions/<key>
content-type: application/json
{
"events": [
{
"id": "signup-1042",
"type": "SIGNUP_COMPLETED",
"occurredAt": "2026-09-22T04:12:09Z",
"anonymousId": "v_8f2a…",
"url": "https://your-site.example/start?utm_source=facebook&utm_campaign=spring-launch&utm_content=<post id>"
}
]
}Up to 50 events in one call, 32 KB in all. A bigger backlog is more calls.
Every field
id· yes- Your own id for the event, 1–128 characters. The same id on a retry counts once, so retrying is free.
type· yes- What happened. One of the types below, or your own in the same shape.
occurredAt· yes- When it happened, ISO 8601. Inside the last 30 days; a few minutes into the future is allowed for a clock that drifts.
url· one of the two- The landing page's full address, with the utm_ parameters the visitor arrived with. Figlix reads the tags off it.
utm· one of the two- The tags themselves: source, medium, campaign, content, term. Send these when you kept the tags rather than the whole address.
value, currency· together or not at all- The amount in the currency's units (149.5, not 14950) and its ISO 4217 code, such as AUD.
anonymousId, sessionId· no- Opaque ids you choose, up to 128 characters, never an email address. Send an anonymousId per visitor: it is what lets a funnel count people rather than events.
metadata· no- Up to 20 keys of short strings (at most 200 characters each). Never personal data — an email address anywhere in it refuses the event.
The event types
Figlix knows these, and shows them in words on Insights:
LANDING_PAGE_VIEWSIGNUP_STARTEDSIGNUP_COMPLETEDWEDDING_CREATEDVENDOR_SEARCHEDVENDOR_SHORTLISTEDVENDOR_PROFILE_CLAIM_STARTEDVENDOR_PROFILE_CLAIM_COMPLETEDSUBSCRIPTION_STARTEDREVENUE
Your own type is allowed in the same shape: UPPER_CASE, 3–60 characters, such as BOOKING_CONFIRMED.
From the browser
// On every page: keep the tags the visitor landed with, and who they are to you.
const q = new URLSearchParams(location.search);
if (q.has("utm_source")) sessionStorage.setItem("figlix_landing", location.href);
let anonymousId = localStorage.getItem("figlix_visitor");
if (!anonymousId) localStorage.setItem("figlix_visitor", (anonymousId = crypto.randomUUID()));
// When the thing happens: send it once, with an id of your own.
fetch("https://api.figlix.com/public/conversions/<key>", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ events: [{
id: "signup-" + SIGNUP_ID,
type: "SIGNUP_COMPLETED",
occurredAt: new Date().toISOString(),
anonymousId,
url: sessionStorage.getItem("figlix_landing") ?? location.href,
}] }),
});Sending from your server is better where you can: it survives ad blockers, and the key stays out of the page.
What it answers
200- The batch was read. The body says how many were accepted, how many were duplicates of ids already sent, and which were refused and why.
404- source_not_found — the key names no active source. It was revoked, or copied wrongly.
413- body_too_large — over 32 KB. Send fewer events per call.
422- validation_failed — the body is not { "events": [ … ] }, or it is empty, or over 50.
429- rate_limited — too many calls at once. The retry-after header says when to come back.
5xx- Figlix's side. Retry with the same ids; nothing is ever counted twice.
Retries are free: the id you send is yours and unique per brand, so the same event twice counts once and says so.
What never to send
- An email address, a name or a phone number — anywhere, including inside metadata. Figlix refuses the event rather than storing it.
- Anything you would not want in a marketing report. Metadata is for a plan name or a product line, not for a person.
- A key in a public repository. Keep it on the server where you can; revoke and remake it on Insights → Conversions if it leaks.
What Figlix does with it
- Attributes each event as it arrives — last touch — to the channel, campaign and post its tags name. A tag that names nothing Figlix knows is kept as it arrived, and that dimension counts as unattributed.
- Shows the last 30 days on Insights → Conversions: by type, by channel, by campaign, by post, with the recent events.
- Counts them against a funnel you define — landed, signed up, paid — on Insights → Funnels, which says where people stop and which channel's people get furthest. Send an
anonymousIdand it counts people rather than events. - Holds no personal data about your customers. That is a rule at the door, not a promise: an email address in the metadata refuses the event.
- Reads no ad spend yet, so it shows counts and values rather than a cost per conversion. That arrives when spend does.