Idempotent Requests

The Developer API supports idempotent requests to safely retry operations without creating duplicate resources or side effects.

What is Idempotency?

An idempotent request is one that can be safely retried multiple times with the same result. If you make the same request twice with the same idempotency key, the second request returns the cached response from the first request instead of executing the operation again.

Why Use Idempotency?

  • Network retries: Safely retry requests that fail due to network issues
  • Prevent duplicates: Avoid creating duplicate resources if a request is sent multiple times
  • Idempotent operations: Ensure operations like updates or deletions are safe to retry

How It Works

  1. Include an Idempotency-Key header in your request with a unique value (recommend UUID)
  2. The API stores the response for that key
  3. If you retry the same request with the same key within 24 hours, you get the cached response
  4. After 24 hours, the key expires and a new request is processed

Using Idempotency Keys

Header Format

Include the Idempotency-Key header in your request:

curl https://customtradescrm.com/api/v1/companies/me \
  -H "Authorization: Bearer ctc_live_..." \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000"

Key Requirements

  • Format: Any string up to 255 characters (UUID recommended)
  • Uniqueness: Must be unique per company per endpoint
  • Scope: Keys are company-scoped (same key can be used by different companies)
  • Retention: Keys are stored for 24 hours

Best Practices

  1. Use UUIDs: Generate a UUID for each unique operation
  2. Include in retries: Always include the same key when retrying a request
  3. One key per operation: Use a new key for each distinct operation
  4. Store keys: Keep track of idempotency keys for operations you might need to retry

Response Headers

When you include an Idempotency-Key header, the response includes:

  • X-Idempotency-Key: Echo of the idempotency key you provided
  • X-Idempotency-Cached: "true" if a cached response was returned, "false" if the request was processed

Example: First Request

$ curl https://customtradescrm.com/api/v1/companies/me \
  -H "Authorization: Bearer ctc_live_..." \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000"

HTTP/1.1 200 OK
X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
X-Idempotency-Cached: false
{
  "success": true,
  "data": { ... }
}

Example: Retry Request (Same Key)

$ curl https://customtradescrm.com/api/v1/companies/me \
  -H "Authorization: Bearer ctc_live_..." \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000"

HTTP/1.1 200 OK
X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
X-Idempotency-Cached: true
{
  "success": true,
  "data": { ... }
}

Notice X-Idempotency-Cached: true indicates this is the cached response from the first request.

Key Scope

  • Company-scoped: Idempotency keys are unique per company. Different companies can use the same key value
  • Method and path: Keys are scoped to the HTTP method and path. Same key with different method/path is treated as different
  • 24-hour window: Keys expire 24 hours after creation

When to Use Idempotency

Recommended for:

  • POST requests (creating resources)
  • PUT/PATCH requests (updating resources)
  • DELETE requests (deleting resources)
  • Any operation with side effects

Optional for:

  • GET requests (naturally idempotent, but caching can be useful)

Error Responses

Idempotency keys work with error responses too. If a request fails (4xx or 5xx), the error response is cached. Retrying with the same key returns the same error response, preventing repeated failed operations.

Limitations

  • 24-hour retention: Keys expire after 24 hours
  • Company scope: Keys are scoped to your company
  • Method/path scope: Same key with different method or path is treated as a new request
  • Request body: Currently, request body differences are not validated (future enhancement)