idempotency_key_in_use

The first request with this `Idempotency-Key` is still running. Wait, then retry with the same key.

HTTP 409The resource is not in a state that allows this operation.

When it fires

A request with this Idempotency-Key is still running, and its outcome is not known yet. It happens when a client times out and retries while the first attempt is still being processed, or when two workers pick up the same job at once. The second request was not run.

Response shape

Every Repull error follows the same envelope. The code is stable and safe to switch on.

{
  "error": {
    "code": "idempotency_key_in_use",
    "message": "A request with this `Idempotency-Key` is still in flight. Its outcome is not known yet.",
    "fix": "Wait for the original request to return, then retry with the SAME key to receive its stored response. Do not switch keys — that would send a second request.",
    "field": "Idempotency-Key",
    "value_received": "msg-164743-checkin",
    "docs_url": "https://repull.dev/docs/errors/idempotency_key_in_use",
    "request_id": "req_01J5X7Y8Z9ABCDEF12345678"
  }
}

How to fix

  1. Wait a few seconds, then retry with the same key. Once the first request finishes you get its stored response, marked `Idempotency-Status: cached`.
  2. Do not switch to a new key to get past this. That would run the action a second time, which is exactly what the key prevents.

Common gotchas

  • Set your client timeout longer than the slowest action you call. Sending a message with attachments or sending a special offer can take several seconds.
  • If the first request ends in a server error or a 429, nothing is stored, and your retry with the same key runs for real.

Examples

curl

# Same key, a few seconds later
curl -X POST https://api.repull.dev/v1/conversations/164743/messages \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Idempotency-Key: msg-164743-checkin" \
  -H "Content-Type: application/json" \
  -d '{"message": "Your check-in details are ready."}'

TypeScript

async function postIdempotent(url: string, body: unknown, key: string) {
  for (let i = 0; i < 5; i++) {
    const res = await fetch(url, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.REPULL_API_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': key, // never changes between attempts
      },
      body: JSON.stringify(body),
    })
    if (res.status !== 409) return res
    const { error } = await res.clone().json()
    if (error.code !== 'idempotency_key_in_use') return res
    await new Promise((r) => setTimeout(r, 2000 * (i + 1)))
  }
  throw new Error('first request still running')
}

If you're an AI agent

The first request with this Idempotency-Key is still running. Wait, then retry with the SAME key to get its stored response. Never switch keys to get past it.

Hit an error that isn't covered? Email hello@repull.dev with the request id from the response headers.

AI