Idempotency
All mutating endpoints (POST, PATCH, DELETE) accept an Idempotency-Key header to safely retry requests without duplicating side effects.
How It Works
Section titled “How It Works”- Generate a unique key (e.g., a UUID) for each distinct operation
- Include it in the
Idempotency-Keyheader - If you retry the same request with the same key, you get the cached response — the operation is not executed again
curl -X POST https://app.weplaytestgames.com/api/v1/games \ -H "Authorization: Bearer wpg_sk_..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \ -d '{"name": "My Game", "description": "A roguelike adventure"}'Matching Rules
Section titled “Matching Rules”A cached response is returned only when all of the following match:
- API key ID
- Idempotency key value
- HTTP method
- Endpoint path
- Request body (SHA-256 hash)
If you reuse an idempotency key with a different method, endpoint, or body, the server returns 422 Unprocessable Entity:
{ "error": { "code": "IDEMPOTENCY_MISMATCH", "message": "This idempotency key was already used with a different request" }}Key Expiration
Section titled “Key Expiration”Idempotency keys are stored for 24 hours, then automatically cleaned up. After expiration, the same key can be reused for a new operation.
When to Use Idempotency Keys
Section titled “When to Use Idempotency Keys”Use idempotency keys for any operation where a retry could cause unwanted duplicates:
- Creating games or playtests
- Reserving playtest slots
- Submitting videos
- Requesting payouts
- Purchasing credit
- Sending chat messages
Generating Keys
Section titled “Generating Keys”const idempotencyKey = crypto.randomUUID();
const response = await fetch('https://app.weplaytestgames.com/api/v1/games', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', 'Idempotency-Key': idempotencyKey, }, body: JSON.stringify({ name: 'My Game', description: 'A roguelike adventure' }),});import uuidimport requests
idempotency_key = str(uuid.uuid4())
response = requests.post( 'https://app.weplaytestgames.com/api/v1/games', headers={ 'Authorization': f'Bearer {api_key}', 'Idempotency-Key': idempotency_key, }, json={'name': 'My Game', 'description': 'A roguelike adventure'},)- Different API keys can independently use the same idempotency key string without colliding
- GET requests do not need idempotency keys (they are inherently idempotent)
- The
Idempotency-Keyheader is optional — if omitted, every request is treated as unique