Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.vendaze.com/llms.txt

Use this file to discover all available pages before exploring further.

Write operations in the Vendaze API support idempotency via the Idempotency-Key header. This allows you to safely retry a request if you did not receive a response, without the risk of creating duplicate records.

What idempotency means

An operation is idempotent when executing it multiple times produces the same result as executing it once. In practice, if your network drops during a deal creation, you can repeat the same request and be guaranteed that only one deal will be created.

How to use it

Include the Idempotency-Key header with a unique string you generate:
curl -X POST https://api.vendaze.com/v1/deals \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7f8a9b2c-3d4e-5f60-a1b2-c3d4e5f60718" \
  -d '{
    "name": "Annual Acme Contract",
    "pipeline_id": "pipeline-uuid",
    "stage_id": "stage-uuid",
    "currency_id": "USD",
    "price_cts": 1200000
  }'
If you send the same request again with the same Idempotency-Key, the API returns the original response without processing it again.

Key format

The key must be:
  • A string of up to 255 characters
  • Unique per operation (recommended: UUID v4)
  • Generated by your system, not reused across different operations
import { randomUUID } from 'crypto';

// Generate a unique key per operation attempt
const idempotencyKey = randomUUID();

Behavior by scenario

ScenarioBehavior
First requestProcesses normally and stores the response.
Repeated request with same key and same bodyReturns the original response without reprocessing.
Repeated request with same key and different bodyReturns 422 with code idempotency_conflict.
Repeated request after 24 hoursKey expired. Processes as a new request.

Endpoints that support idempotency

The Idempotency-Key header is accepted on all write endpoints:
  • POST /v1/people
  • POST /v1/companies
  • POST /v1/deals
  • POST /v1/tasks
  • POST /v1/activities
  • POST /v1/products
  • POST /v1/tags
  • POST /v1/lists
  • POST /v1/custom-fields
PATCH and DELETE endpoints are naturally idempotent by the HTTP protocol itself and do not require the header.
async function createDeal(payload, accessToken) {
  const idempotencyKey = randomUUID();

  for (let attempt = 0; attempt < 3; attempt++) {
    try {
      const res = await fetch('https://api.vendaze.com/v1/deals', {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${accessToken}`,
          'Content-Type': 'application/json',
          'Idempotency-Key': idempotencyKey,
        },
        body: JSON.stringify(payload),
      });

      if (res.ok) return res.json();

      // Do not retry on validation errors
      if (res.status === 422) throw new Error('Validation failed');

      // Retry on network failures or 5xx
      if (res.status >= 500 || !res.status) {
        await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
        continue;
      }

      throw new Error(`Unexpected status: ${res.status}`);
    } catch (err) {
      if (attempt === 2) throw err;
    }
  }
}
Idempotency keys persist for 24 hours. Always use a UUID v4 generated at the time of the operation. Never reuse keys across different operations.

Key conflict

If you send a previously used key with a different body, the API returns:
{
  "error": {
    "code": "idempotency_conflict",
    "message": "An idempotency key was reused with a different request body.",
    "request_id": "uuid"
  }
}
This protects against bugs where the same key is accidentally reused for two distinct operations.