Idempotency & retries

Every write endpoint requires an Idempotency-Key so network retries never double-send a DM, double-follow, or double-charge you.

How it works

  • Send a unique Idempotency-Key header with each write (/dm/send, /actions/*, POST /tweets).
  • The first request with a given key executes and its result is stored.
  • Any repeat with the same key returns the stored result — no second send, no second charge. The response carries an X-Idempotent-Replay: true header.
Omitting the header returns 400 invalid_request. Always send one.

Choosing a key

Use a value that's stable for the logical operation you're performing:

  • One-off action — a random UUID (uuidgen / crypto.randomUUID()).
  • Batch / campaign — a deterministic key like campaign42:acc_1a2b3c:user_44196397. Re-running your job then safely skips anyone already messaged.

Safe retry pattern

JavaScript
async function sendOnce(body, key) {
  for (let attempt = 0; attempt < 3; attempt++) {
    const res = await fetch("https://api.xautodm.com/v1/dm/send", {
      method: "POST",
      headers: {
        Authorization: "Bearer " + process.env.XAUTODM_API_KEY,
        "Idempotency-Key": key,          // same key across retries
        "Content-Type": "application/json",
      },
      body: JSON.stringify(body),
    });
    if (res.status !== 502) return res.json();  // retry only on upstream errors
    await new Promise(r => setTimeout(r, 1000 * (attempt + 1)));
  }
}

Because the key is constant across attempts, a request that actually succeeded upstream but failed to return won't be sent again — the retry just returns the stored result.

Errors & rate limitsEndpoint reference