Busy apps, 429s and backfills

Batch your steps, handle a 429 with Retry-After, and send history from before you started.

Batch your steps

One call per step works for a small app. For a busy one, queue steps as they happen and send them in batches of up to 500 per call, every few seconds or when the queue fills:

{"events": [
  {"event": "signed_up", "person": "user-123", "at": "2026-10-17T10:00:00Z"},
  {"event": "created_project", "person": "user-123", "at": "2026-10-17T10:14:00Z"},
  {"event": "signed_up", "person": "user-456", "at": "2026-10-17T10:02:00Z"}
]}

Set at on each step when you batch, so each one keeps the time it actually happened.

When the answer is 429

Each workspace can make 20 calls a second, with bursts of up to 600. Past that, the answer is 429 Too Many Requests with a Retry-After header in seconds.

  1. Wait the seconds in Retry-After.
  2. Send the same batch again.

Nothing is counted twice: each person counts once per step, at the earliest time sent, so resending a batch that partly arrived is harmless. The same goes for any retry after a timeout or a network error.

async function sendBatch(events) {
  for (;;) {
    const res = await fetch('https://api.outcomify.com/api/funnels/track', {
      method: 'POST',
      headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
      body: JSON.stringify({ events }),
    });
    if (res.status !== 429) return res;
    const wait = Number(res.headers.get('Retry-After') ?? 1);
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
}

The monthly allowance

A workspace records up to 250,000 steps a month for free. A record is one person reaching one step for the first time, so repeats don't count. Past it, new steps are answered with 429 and a Retry-After of an hour, and the body's resetsAt says when the month's allowance starts again. What is already recorded keeps counting in your reports. The setup card on the Funnels page shows This month: … of … step records.

Send your history

You can start your funnels with a past. Read when each person reached each step from your own database, and send it with at:

  • at can be up to 400 days back.
  • Send in batches of up to 500, and handle 429s as above.
  • Sending the same history twice is harmless. If you send an earlier time for a step than the one stored, the earlier one wins.

Once history is in, the report's previous period and the step trends' earlier weeks have something to compare against from day one.

Other answers

Status Means
400 A step isn't valid: a name with characters that aren't allowed, a missing person, an at too far back or in the future. The answer says which one.
401 The key is missing, wrong or revoked.
403 The key doesn't have the funnels.write scope — create one on the Funnels page. Or, if the answer says Funnel tracking is paused for this workspace, we've paused your workspace's tracking: contact support. Keep your events and send them again once it's lifted.
422 The call has a new step name, and your workspace already uses 50. See Privacy, limits and retention.

Still stuck? Email info@outcomify.com and a person will answer.