Conversion tracking

Capture post-click outcomes with the Conversion API, including leads, sales, refunds, cancellations, and attribution context.

What conversion tracking does

Conversion tracking lets you measure what happens after someone clicks one of your short links. Instead of only knowing that a click occurred, you can record the business outcomes that followed-a lead form submission, a completed purchase, a subscription signup, a refund.

This gives you a complete picture: not just "how many people clicked?" but "how many people clicked and then became customers?"


How it works (end to end)

Flow diagram: a visitor clicks a tracking-enabled short link; if the destination is safe to modify Nimriz appends nim_ct to the destination URL, otherwise it redirects without the token; the landing page captures nim_ct, the visitor completes an action, the backend sends a signed conversion event, and Nimriz joins the conversion to the original click by click ID or external ID
The nim_ct token bridges the click and the conversion event your backend reports.

The nim_ct parameter is the deterministic bridge between the click and the conversion. It is an opaque token-it does not encode any personal information.


Prerequisites

  • A workspace plan that includes conversion tracking.
  • Conversion tracking explicitly enabled on the links you want to measure.
  • A workspace Conversion API signing secret generated from IntegrationsDeveloperConversion API.
  • A secure server-side environment to receive and store the click ID, and to send signed conversion events.
  • Control over your landing page to capture the nim_ct query parameter.

Step 1-Enable conversion tracking on a link

Conversion tracking is opt-in per link. It is not enabled by default.

  1. Open the link's detail page.
  2. Find the Conversion tracking card. It shows the link's tracking status, whether the workspace Conversion API secret is configured, and the destination token policy.
  3. Click Enable conversion tracking.

When conversion tracking is enabled on a link, Nimriz will append nim_ct=<token> to the destination URL on every redirect where the destination is safe to modify.


Step 2-Generate your signing secret

Your Conversion API signing secret is used to sign requests from your backend to the Nimriz Conversion API. This is a separate credential from your workspace API key.

  1. Go to IntegrationsDeveloperConversion API in the dashboard.
  2. Find the Conversion API secret panel.
  3. Click Generate Conversion API secret.
  4. Copy and store the secret securely in your server-side environment variables. Owners and admins can reveal the current secret later or rotate it with Rotate Conversion API secret; rotating immediately replaces the previous secret.
The Conversion API secret panel before a secret exists, with the Generate Conversion API secret button
The Conversion API secret panel under Integrations → Developer → Conversion API.

Never expose this secret in browser-side code or commit it to version control.


Step 3-Capture nim_ct on your landing page

When a visitor clicks your enabled short link, Nimriz appends nim_ct=<token> to the destination URL before redirecting. Your landing page needs to read and store this token.

// Server-side example (Next.js App Router, Express, etc.)
export async function GET(request: Request) {
  const url = new URL(request.url);
  const clickId = url.searchParams.get('nim_ct');

  if (clickId) {
    // Store on the session, lead record, cart, order, or checkout metadata
    await storeClickIdForSession(sessionId, clickId);
  }

  // Render your landing page normally
}

Where to store nim_ct depends on your funnel:

Funnel stageWhere to store nim_ct
Lead/signup formOn the pending lead or CRM contact record.
E-commerce checkoutOn the cart or order metadata before payment completes.
SaaS trialOn the pending trial or account record.
Long consideration cycleCarry it through your CRM pipeline to the closed event.

Step 4-Send conversion events from your backend

After a business event occurs (a lead is created, an order is paid, a subscription activates), your backend sends a signed POST request to the Nimriz Conversion API.

Endpoint

POST https://api.nimriz.com/api/conversions/callback/:workspace_id

Replace :workspace_id with your workspace's UUID. The easiest source is the Conversion API endpoint panel under IntegrationsDeveloperConversion API, which shows the full callback URL with a copy button; the UUID is also shown as Workspace ID under SettingsWorkspace.

Required headers

Content-Type: application/json
X-Nim-Timestamp: <current unix timestamp in seconds>
X-Nim-Signature: v1=<hex hmac sha256>
Idempotency-Key: <stable key for this conversion event>

Generating the signature

import crypto from 'node:crypto';

function signConversionRequest({ secret, timestamp, rawBody }) {
  return `v1=${crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')}`;
}

// Usage
const timestamp = Math.floor(Date.now() / 1000).toString();
const body = JSON.stringify(payload);
const signature = signConversionRequest({
  secret: process.env.NIM_CONVERSION_SECRET,
  timestamp,
  rawBody: body,
});

Conversion event types

Nimriz supports five immutable conversion outcome types. Each event type is stored permanently-negative follow-on events (refund, cancellation, reversal) do not overwrite the original positive event.

lead

A non-monetary attributable outcome: form submission, trial signup, demo booking, newsletter subscription.

{
  "event_name": "lead",
  "event_time": "2026-04-01T14:30:00.000Z",
  "event_id": "crm-lead-abc123",
  "user_data": {
    "click_id": "nimct_xxxxxxxxxxxxxxxxxxxxxxxx",
    "external_id": "contact_12345"
  },
  "custom_data": {
    "properties": {
      "source_system": "hubspot",
      "form_type": "demo-request"
    }
  }
}

sale

A confirmed purchase, paid invoice, or subscription activation.

{
  "event_name": "sale",
  "event_time": "2026-04-01T15:05:00.000Z",
  "event_id": "order-xyz789",
  "user_data": {
    "click_id": "nimct_xxxxxxxxxxxxxxxxxxxxxxxx",
    "external_id": "customer_67890"
  },
  "custom_data": {
    "order_id": "order-xyz789",
    "value": 149.00,
    "currency": "USD",
    "quantity": 1,
    "properties": {
      "plan": "pro-annual"
    }
  }
}

refund

A confirmed refund on a prior sale. Must reference the original sale.

{
  "event_name": "refund",
  "event_time": "2026-04-10T09:00:00.000Z",
  "event_id": "refund-xyz789-1",
  "custom_data": {
    "order_id": "refund-xyz789",
    "related_order_id": "order-xyz789",
    "value": 149.00,
    "currency": "USD",
    "properties": {
      "reason": "customer_request"
    }
  }
}

cancellation

A cancellation or void of a prior commitment when it is distinct from a refund in your billing system.

{
  "event_name": "cancellation",
  "event_time": "2026-04-12T11:00:00.000Z",
  "event_id": "cancel-sub-67890",
  "custom_data": {
    "related_order_id": "order-xyz789",
    "properties": {
      "reason": "end_of_contract"
    }
  }
}

reversal

A chargeback or negative financial adjustment when it does not fit the refund or cancellation semantics.

{
  "event_name": "reversal",
  "event_time": "2026-04-15T13:00:00.000Z",
  "event_id": "chargeback-xyz789",
  "custom_data": {
    "related_order_id": "order-xyz789",
    "value": 149.00,
    "currency": "USD",
    "properties": {
      "reason": "fraudulent"
    }
  }
}

Complete field reference

FieldRequiredTypeDescription
event_nameYesStringOne of: lead, sale, refund, cancellation, reversal.
event_timeNoISO 8601 stringWhen the event occurred. Defaults to the time Nimriz receives the request.
event_idRecommendedStringYour stable business identifier for this event. Used for business-level deduplication.
user_data.click_idNoStringThe nim_ct value captured from the landing page URL. Enables deterministic click attribution.
user_data.external_idNoStringYour stable customer or lead identifier. Lets Nimriz fall back to the same customer's most recent attributed touch when no click_id is supplied.
custom_data.order_idRecommended for salesStringYour order, invoice, or transaction identifier.
custom_data.related_order_idRequired for refund/cancellation/reversalStringReferences the original sale's order_id.
custom_data.related_event_idAlternative to related_order_idStringReferences the original event's event_id.
custom_data.valueNoNumberMonetary value. Requires currency when provided.
custom_data.currencyConditionalStringISO 4217 currency code (e.g., USD, EUR). Required when value is set.
custom_data.quantityNoIntegerMust be a positive integer.
custom_data.propertiesNoObjectArbitrary key/value metadata for your own reporting context.
Idempotency-Key headerRecommendedStringDeduplication key for the request. When omitted, Nimriz derives one from a hash of the raw request body.

event_id vs Idempotency-Key

These two fields serve distinct purposes and work together:

  • event_id is the stable business identifier for a specific outcome (for example, "this lead was created after clicking the spring campaign link"). Nimriz uses it for business-level deduplication and for negative follow-on events that reference related_event_id.

  • Idempotency-Key protects a request delivery. Requests that arrive with an Idempotency-Key Nimriz has already stored for your workspace are treated as redeliveries of the same request, not new events.

To retry a failed or timed-out request safely, you can resend the identical request bytes with the same Idempotency-Key:

First attempt:   Idempotency-Key: crm-lead-abc123-v1,  event_id: crm-lead-abc123
Retry attempt:   Idempotency-Key: crm-lead-abc123-v1,  event_id: crm-lead-abc123  (same key, same body)

If your delivery system sends a fresh Idempotency-Key for the same business event, keep the same event_id. Nimriz returns the stored conversion event with duplicate: true instead of creating a second conversion.


Query-sensitive destinations

Some destination URLs cannot safely have nim_ct appended because they rely on signed or integrity-protected query strings. Common examples:

  • Pre-signed S3 or GCS URLs (contain X-Amz-Signature, X-Goog-Signature, or policy parameters).
  • Destinations with HMAC-protected parameter sets.
  • Payment confirmation URLs with integrity tokens.

When Nimriz detects a query-sensitive destination, it suppresses nim_ct appending rather than risk breaking the redirect. The short link redirects normally to the destination-but without the nim_ct parameter.

What you can still do:

  • Use user_data.external_id in your conversion events to link conversions to customers identified by your own system.
  • If your system assigns order IDs before the redirect, carry the order ID through your funnel without relying on nim_ct.

Idempotency and retries

Conversion events are designed to be sent at-least-once safely. If your backend fails or times out when sending an event, retry with the same event_id. Nimriz returns the stored event (with duplicate: true) rather than creating a duplicate.

Rules:

  • Same Idempotency-Key + same payload on a retry → returns the stored result, no duplicate.
  • Same Idempotency-Key + different payload → rejected with 409 idempotency_conflict (the key is already associated with a different payload).
  • Same event_id + fresh Idempotency-Key → returns the stored conversion event, no duplicate.
  • If you omit the header entirely, Nimriz falls back to a hash of the raw body, so byte-identical retries still deduplicate. Include event_id for business-level deduplication across different delivery attempts.

Viewing conversions in the dashboard

Attributed conversion events appear in your analytics under AnalyticsConversions (the Conversion reporting view).

The view shows:

  • KPI counts by outcome over your selected date range: attributed outcomes, sales, leads, and negative outcomes.
  • A daily conversion-events chart.
  • An Attribution method split: how attributed conversions divide between click-ID, customer-ID, and negative-follow-on attribution.
  • A table of attributed conversions with click-time UTM, variant, and experiment context, filterable by domain, short URL, and event type.

Conversion data is also available in analytics exports (see Exports).


Troubleshooting

nim_ct is not appearing on my landing page URL

  1. Confirm conversion tracking is enabled on the link (the Conversion tracking card on link detail shows "Enabled for this link").
  2. Check whether the destination URL is classified as query-sensitive. If Nimriz detects a signed URL pattern, it suppresses nim_ct to avoid breaking the redirect.
  3. Confirm you are clicking the actual short link (not navigating directly to the destination).

Conversion API request is rejected with a 401 or signature error

  1. Confirm you are using the Conversion API signing secret, not the workspace API key.
  2. Verify the signature computation: HMAC-SHA256("${timestamp}.${rawBody}", secret).
  3. Confirm X-Nim-Timestamp is a Unix timestamp in seconds (not milliseconds).
  4. Confirm you are signing the raw request body bytes-do not parse and re-serialize the JSON before signing, as this can alter byte order or whitespace.

Refund/cancellation event is rejected

Negative follow-on events must reference an earlier sale. Include custom_data.related_order_id matching the original sale's order_id, or custom_data.related_event_id matching the original sale's event_id. If no matching sale exists in Nimriz yet, the event will be rejected.

Conversions appear but attribution shows 0%

Attribution requires a valid nim_ct click ID in user_data.click_id. If conversions arrive without a click ID, they are stored (for reporting totals) but cannot be attributed to a specific click. Ensure your funnel is capturing and forwarding nim_ct from the landing page URL to your conversion event.


Related guides

Related next steps

Ready to test this setup?

Create an account to try the workflow, or compare plans when the setup needs higher limits, integrations, or team controls.