Idempotent Requests
Retry API requests fearlessly, ensuring the operation performs just once!
Our platform has a seamless integration of optional idempotent requests for POST
and PATCH
operations.
This integration closely adheres to the Idempotency-key ietf draft.
These idempotent operations deliver the same result regardless of the number of requests made, using an idempotent key.
Leveraging this feature guarantees the safety and reliability of your requests, especially in cases where network or communication issues might inject uncertainty into request outcomes. Idempotent requests are critical for workflows that require the insurance of only one successful delivery request.
This feature was introduced in version 0.22.0 and is fully operable from 0.24.0 and beyond. Currently, the Idempotency headers are not enabled on the cloud platform but are available for self-hosting.
Please be aware that idempotency might not be supported in all community SDKs.
How to Perform an Idempotent Request with SDKs
Supporting SDKS will implement Idempotency for you as long as you have retries turned on. Not only is this seamless but it also ensures that no event request is dropped provided that your system stays up.
Idempotent request with api
To make an idempotent request, simply include the Idempotency-Key: <key>
in your request header.
This key should be a unique client-generated value, boasting enough entropy to prevent collisions;
we recommend a collision-resistant Unique Identifier, such as UUIDv7, CUID, or ULID, as your idempotency keys.
Understanding Response Replay
Our API stores the status code and response body from your initial idempotent request. This way if an identical idempotency key appears in a later request, the API will replay the saved response from the original request - even if it involves client or server error responses.
In the event of a response replay, the response will carry an Idempotency-Replay: true
header.
Idempotent Request Responces
Here are some unique pieces constraints you should be aware of especially if you are not using the sdk:
- A
<key>
exceeding 255 characters will trigger a400 Bad Request
error. - An inconsistent request body compared to the initial request will return a
422 Unprocessable Entity
error. - A ongoing processing of the initial request that hasn’t yet responded will result in a
409 Conflict
error. This will include aRetry-After
header.
Results will not saved if an API request is invalid.
Expiring Keys
All idempotency keys are ensured to be automatically removed once they are 24 hours and 1 minute old. After this period, the reused key will be treated as a new request and response.
Practical Examples
Example 1 - No idempotency
import { Novu } from '@novu/node';
const novu = new Novu("<NOVU_SECRET_KEY>");
await novu.trigger("<WORKFLOW_TRIGGER_IDENTIFIER>", {
to: {
subscriberId: "<UNIQUE_SUBSCRIBER_IDENTIFIER>",
},
payload: {
name: "Hello World",
},
actor: "actorId",
tenant: "tenantIdentifier",
});
Example 2 - Idempotency Active
import { Novu } from '@novu/node';
const novu = new Novu("<NOVU_SECRET_KEY>", {
retryConfig: {
retryMax: 5
}
});
// This request is now idempotent
await novu.trigger("<WORKFLOW_TRIGGER_IDENTIFIER>", {
to: {
subscriberId: "<UNIQUE_SUBSCRIBER_IDENTIFIER>",
},
payload: {
name: "Hello World",
},
actor: "actorId",
tenant: "tenantIdentifier",
});
References
Was this page helpful?