phase 2 single provider

Optional Idempotency-Key header with Redis dedupe so client retries after proxy-forwarded timeouts do not double-bill upstream completions.

Milestone 2.1.6 — Idempotency-Key for Provider Retries

Status: Complete
Goal: 2.1 — OpenAI-compatible proxy path
Phase: 2 — Single Provider End-to-End
Estimated effort: 2 days
Depends on: 2.1.5
ADR: ADR-0035


Why This Milestone Exists

Milestone 2.1.5 names double-retry storms (proxy + client) as a Medium risk and mitigates it only with documentation. If a client times out after the proxy has already started an upstream completion, a naive retry creates a second billed request. Stripe and OpenAI solve this with Idempotency-Key.


Deliverables

  • Optional request header Idempotency-Key (opaque string, max length documented).
  • Redis key: idempotency:{org_id}:{key} (org from verified token — never from body).
  • TTL window (e.g. 24h) storing first response fingerprint / status for replay or in-flight lock.
  • Streaming: document that idempotency applies to non-streaming first; streaming follow-up if needed.
  • API docs + OpenAPI note.

Acceptance Criteria

  • Duplicate Idempotency-Key within TTL does not create a second upstream completion when the first request successfully claimed and committed (integration test)
  • Missing header preserves current behavior
  • Cross-org key collision impossible (org_id in Redis key)
  • Metrics: hit / miss / conflict counters with bounded labels
  • Documented in API docs and .env.example (TTL env if configurable)

Branch

feature/m2-1-6-idempotency-key

PR Title

feat(proxy): Idempotency-Key Redis dedupe for provider retries (m2.1.6)

Edit on GitHub

Last updated on

On this page

0%