Implementation guide

Idempotency

Safely retry POST /research without creating duplicate work. Replay semantics, body matching, TTL, and 409 conflict codes.

Browse developer docs

Current: Idempotency

The Idempotency-Key header

POST /api/v2/research accepts an optional Idempotency-Key header. Send a fresh UUID per logical request when you need retry safety — the server dedupes retries and returns the same job_id.

bash

curl -X POST "https://api.grep.ai/api/v2/research" \
  -H "Authorization: Bearer $GREP_API_KEY" \
  -H "Idempotency-Key: 8b9c1f24-3c1e-4a8d-9f7b-2a6e1c4d5b8e" \
  -H "Content-Type: application/json" \
  -d '{"question":"Due diligence on Stripe","effort":"medium"}'

Replay semantics

If a request fails partway (timeout, connection drop), retry with the same key. The server returns the original committed response — same job_id, same body. No duplicate jobs are created.

bash

# Same key + same body → same job_id, no new work scheduled.
curl -X POST "https://api.grep.ai/api/v2/research" \
  -H "Authorization: Bearer $GREP_API_KEY" \
  -H "Idempotency-Key: 8b9c1f24-3c1e-4a8d-9f7b-2a6e1c4d5b8e" \
  -H "Content-Type: application/json" \
  -d '{"question":"Due diligence on Stripe","effort":"medium"}'

# Returns identical envelope as the original call:
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed"
}

Body-hash matching

Replay only succeeds if the request body matches the original. The server hashes the JSON body and compares — if you change the body but reuse the key, the request is rejected with 409 idempotency_key_reuse_mismatch. This protects against accidental key reuse across different operations.

TTL windows

After the window expires, the same key can be reused for a fresh job. In practice, generate a new UUID per request and you'll never hit the boundary.

StateReplay window
Committed24 hours after the job terminates
Pending1 hour while the job is in flight

409 conflict codes

Three distinct 409 codes you might see when reusing a key: Same key, different request body. The server rejects rather than silently overwrite — you almost certainly meant to use a fresh key. Same key while the original job is still in progress. Retry the GET on the original job_id instead of POSTing again. Key was valid but the TTL elapsed. Generate a new key and try again.