GET, PUT and DELETE are idempotent by HTTP design. For POST and PATCH on sensitive resources (tasks, service orders, tickets) follow the practices below.
- Send a client-generated identifier in
externalId(e.g. ERP ID). Before creating, run the matchingGETfiltered byexternalId. - If it exists, update via
PATCH; otherwise create viaPOST.
- Use the
deliveryIdfrom the payload to deduplicate on your side (write-once into awebhook_deliveriestable).
async function postWithSafety(body) {
const existing = await findByExternalId(body.externalId);
if (existing) return existing;
try {
return await api.post('/tasks', body);
} catch (err) {
if (err.status === 409) {
return findByExternalId(body.externalId);
}
throw err;
}
}- Native
Idempotency-Keysupport (Stripe-like) — watch the changelog.