Salesly API

Idempotency

Safely retry mutation requests without performing the same operation twice.

The Salesly API supports idempotency for safely retrying mutation requests (POST, PUT, PATCH, DELETE) without performing the same operation twice.

How It Works

  1. Generate a unique key (UUID recommended) for each distinct operation
  2. Include it in the Idempotency-Key header
  3. If the request succeeds, the response is cached for 24 hours
  4. Replaying the same key returns the cached response with Idempotent-Replayed: true

Usage

cURL
curl -X POST "https://rest.salesly.app/api/v1/developers/contacts" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{"name": "ACME Corp", "type": "client"}'

Replay Detection

When a cached response is replayed, the response includes:

Idempotent-Replayed: true

The response body and status code are identical to the original.

Conflict Detection

If you reuse the same Idempotency-Key with a different endpoint or HTTP method, the API returns 422:

422 Idempotency Conflict
{
  "error": {
    "type": "idempotency_conflict",
    "message": "This Idempotency-Key has already been used with a different request."
  }
}

Key Scope

  • Keys are scoped to your API key — different accounts can use the same idempotency key
  • Keys expire after 24 hours
  • Keys match on the combination of HTTP method + URL path

When to Use Idempotency

ScenarioUse Idempotency-Key?
Creating a contactYes — prevents duplicates on retry
Batch creating recordsYes — prevents partial duplicate batches
Updating a recordOptional — PUT is naturally idempotent, but useful for tracking
Network timeout on createYes — safely retry without knowing if the first request succeeded
Reading data (GET)No — GET requests are naturally idempotent

Best Practices

  • Generate a new key for each distinct operation — do not reuse keys across different business operations
  • Use UUIDs for keys to avoid collisions
  • Store the key with your request so you can retry with the same key if needed
  • Do not use idempotency keys for GET requests — they are ignored
  • Failed requests are not cached — only 2xx responses are stored, so you can safely retry after a failure