docs

Bulk revocation

Revoking many subscribers at once.

There is no bulk revocation endpoint today. To revoke many subscribers, loop over the single-subscriber DELETE call:

for (const id of subscriberIds) {
  const res = await fetch(
    `${BASE}/partners/${PARTNER_ID}/users/${id}/`,
    { method: 'DELETE', headers: { 'X-Helium-P-API-Key': KEY } },
  );
  // 404 = already gone, treat as success
  if (!res.ok && res.status !== 404) {
    queueRetry(id);
  }
}

For sane bulk behavior:

  • Sequence, don't fan out. The gateway rate-limits per key.
  • Honor 429s. On 429, sleep for Retry-After seconds and resume.
  • Retry idempotently. Treat 404 as success.
  • Audit-log on your side before each call. If something falls over, you still have the list of subscribers you intended to revoke.
  • Throttle to about 5 requests per second as a starting point. Raise it if you have headroom and Helium approves.
async function revokeAll(ids: string[]) {
  const results: { id: string; status: number; ok: boolean }[] = [];
  for (const id of ids) {
    let attempt = 0;
    while (true) {
      const res = await fetch(
        `${BASE}/partners/${PARTNER_ID}/users/${id}/`,
        { method: 'DELETE', headers: { 'X-Helium-P-API-Key': KEY } },
      );

      if (res.status === 429 && attempt < 4) {
        const wait = Number(res.headers.get('retry-after') ?? 1) * 1_000;
        await new Promise((r) => setTimeout(r, wait));
        attempt++;
        continue;
      }

      results.push({ id, status: res.status, ok: res.ok || res.status === 404 });
      break;
    }
    await new Promise((r) => setTimeout(r, 200)); // ~5 rps
  }
  return results;
}

If you regularly need to revoke thousands of subscribers at once, for mass churn or breach response, tell your account owner. A bulk endpoint is on the roadmap and your use-case helps prioritize it.

TODO: confirm with @Oleksandr whether a bulk endpoint is in scope for the next release. If it ships, this page becomes a POST /partners/{id}/users/revoke-batch/ reference.