Skip to main content
Idempotency makes it safe to retry requests without accidentally performing the same operation twice. Nova Embed supports idempotency in 2 ways:
  1. Scoring submissions are idempotent by default.
  2. Criteria and library mutations support an optional Idempotency-Key header.

Scoring submissions (default)

For POST /v1/jobs/{jobId}/applications/{applicationId}/scoring-jobs, Nova deduplicates requests using:
  • Your tenant (from X-Tenant-Id and your API key)
  • jobId
  • applicationId
If you submit the same jobId and applicationId again, Nova returns the existing scoring job. This behavior exists even if you do not send an Idempotency-Key.
Scoring submission routes do not use the generic HTTP Idempotency-Key replay layer. If you send the header there, Nova ignores it and uses scoring’s built-in identity rules instead.
Batch scoring works the same way. POST /v1/jobs/{jobId}/scoring-batches ignores Idempotency-Key and deduplicates by the batch’s scoring identity.

Re-scoring

To create a new scoring job for an application, pass rescore: { enabled: true }. Re-scoring is idempotent per criteria version. Submitting rescore.enabled: true multiple times without changing criteria returns the same re-score job. To pin a specific criteria version:
{
  "resume": { "type": "url", "url": "https://storage.example.com/resumes/abc123.pdf" },
  "jobDescription": "We are looking for a Senior Backend Engineer with 5+ years experience...",
  "rescore": {
    "enabled": true,
    "criteriaVersionId": "cmlz26ck2000awp61q9qcjcne"
  }
}

What creates a new scoring job

ChangeNew job?
jobId changesYes
applicationId changesYes
rescore.enabled set to trueYes
rescore.criteriaVersionId changes while rescoringYes
resume changesNo
applicationData changesNo

Retry strategy

  1. Retry network failures and 5xx errors with exponential backoff.
  2. For 429, wait for Retry-After before retrying.
  3. For scoring retries, re-submit the same jobId and applicationId. Use rescore only when you intentionally want a new scoring job.

Idempotency-Key header (criteria and library mutations)

For criteria and library write requests, you can send an Idempotency-Key header to safely retry without duplicating side effects. Supported methods: POST, PUT, PATCH, DELETE.

How it works

When you send Idempotency-Key: <key>:
  • The first request runs normally.
  • A retry with the same key and the same request parameters returns the original response and includes Idempotent-Replayed: true.
  • Reusing the same key with different request parameters returns 422 IDEMPOTENCY_KEY_ALREADY_USED.
  • If another request with the same key is still running, the API returns 409 IDEMPOTENCY_REQUEST_IN_PROGRESS.
Use a UUID v4 for Idempotency-Key. Keys must be 1 to 255 characters.
Idempotency keys stay valid for 24 hours. After that, you can reuse the same key and Nova treats it as a new request.
Idempotency-Key replay and mismatch behavior does not apply to scoring submissions or scoring batches. Those endpoints already deduplicate by scoring identity.
Idempotency keys are scoped to your partner account and environment. All active API keys under the same partner share the same idempotency namespace for that environment. Reusing the same key across different X-Tenant-Id values is treated as a parameter mismatch and returns 422 IDEMPOTENCY_KEY_ALREADY_USED.

Which responses are replayed

  • Successful 2xx responses are replayed with the same key.
  • Endpoint-generated 4xx responses are replayed with the same key, including business-rule failures and handler-thrown validation errors.
  • 409 IDEMPOTENCY_REQUEST_IN_PROGRESS and 429 RATE_LIMITED are not cached. Retry the same request with the same key after the condition clears.
  • Request-shape failures are not cached. That includes missing required headers, invalid Content-Type, malformed JSON, and schema or path validation errors. After you fix the request, you can retry with the same key.

Rate limiting and retries

Rate limiting (including in-flight concurrency limits) runs before the HTTP idempotency replay layer.
This means a retry can return 429 RATE_LIMITED before the API has a chance to replay a cached response. If you get a 429, wait for Retry-After and retry again using the same Idempotency-Key.

Example

curl -X POST https://embed.nova.dweet.com/v1/jobs/job-123/criteria/items \
  -H "Authorization: Bearer sk_live_..." \
  -H "X-Tenant-Id: acme-corp" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 2d6d8d5a-6c4f-4c2f-8c6e-5b6f0d51a1b2" \
  -d '{"text":"5+ years backend experience","importance":"required"}'
SDK
await nova.jobs.criteria.items.add(
  {
    jobId: 'job-123',
    body: {
      text: '5+ years backend experience',
      importance: 'required',
    },
  },
  {
    idempotencyKey: '2d6d8d5a-6c4f-4c2f-8c6e-5b6f0d51a1b2',
  },
);
If a scoring request fails because the resume URL is inaccessible, generate a new URL and retry the same scoring submission. Since the job wasn’t created, the retry is safe.