TrackSERPs
Log in

Idempotency

Safely retry write operations without risk of duplicate keyword creation or accidental duplicate credit charges.

Why Use Idempotency Keys?

If an HTTP connection drops before you receive a response, you cannot know whether the server executed your request or failed before starting.

To prevent duplicate manual runs or duplicate keyword additions when retrying network requests, pass an Idempotency-Key header containing a unique identifier (such as a UUID).

cURL with Idempotency-Key
curl -X POST "https://api.trackserps.com/v1/projects/proj_abc123/runs" \
  -H "Authorization: Bearer ts_live_..." \
  -H "Idempotency-Key: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" \
  -H "Content-Type: application/json"

How the Server Handles Idempotent Requests

  1. First Request: The server saves your Idempotency-Key and a hash of the request payload, executes the operation, and caches the response for 24 hours.
  2. Retries with Identical Payload: If the server receives another request with the same Idempotency-Key and identical request body, it immediately returns the cached response with the original status code and headers without re-executing or re-charging credits.
  3. Mismatched Payload Conflict (409): If the same key is reused with a different request body, the API refuses execution and returns HTTP 409 Conflict with error code idempotency_mismatch.
409 Idempotency Mismatch Response
HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "error": {
    "code": "idempotency_mismatch",
    "message": "Idempotency-Key was already used with a different request payload.",
    "request_id": "req_conflict_123"
  }
}

SDK Automatic Idempotency

The official @trackserps/sdk generates a cryptographically random UUID for every POST write request automatically, ensuring zero duplicates during connection blips or automatic retries:

SDK Idempotency Handling
import { TrackSERPs } from "@trackserps/sdk";

const client = new TrackSERPs({ apiKey: "ts_live_..." });

// 1. By default, the SDK automatically generates a unique UUID idempotency key for every POST:
const run = await client.runs.create("proj_abc123");

// 2. You can also supply a custom idempotency key to tie retries to an internal task ID:
await client.keywords.create(
  "proj_abc123",
  { keywords: [{ phrase: "seo rank tracker" }] },
  { idempotencyKey: "job_batch_order_84920" }
);
Idempotency · TrackSERPs API Docs