Skip to content

Idempotency & duplicate protection

Short version: the API does not dedupe for you, and there's no idempotency key. If you POST the same product twice, you get two projects (or two items), both real, both billable. Duplicate protection is your responsibility. Here's how to hold it.

There's no external reference field — use __meta

There is no dedicated "your id" field on a project or item. The intended place for your own identifier is body["__meta"] — the spec example is literally {"id_in_your_system": 132}. Put your primary key there so a fetched result can be traced back to your record.

But __meta comes back only when you read an item you already know about. Don't assume you can search or filter by it server-side. So __meta answers "where does this result belong?", not "have I already sent this?". For the second question you need your own bookkeeping.

Keep your own mapping

Store the link between your records and Eurotext's ids as soon as you create them:

your product / field eurotext_project_id eurotext_item_id status submitted_at
product 512 / en_US 42 132 in-progress 2021-08-14

This table is what makes everything else idempotent:

  • Don't resend what's in flight. Before creating a project/item for a record, check whether it already has an open (in-progress/unfinished) row. If it does, skip — don't create a second one.
  • Write-back is keyed, not appended. When results arrive, update the target field by (product, locale) — a set, not an insert. Re-importing the same finished item then just re-writes the same value, which is harmless.
  • Track imported items. Record which eurotext_item_ids you've already written back, so partial-delivery polling doesn't import the same item twice.

The retry-after-timeout trap

The classic duplicate source: createProject times out, you retry, and now there are two projects — the first one did get created, you just never saw the response.

Guard against it:

  1. Create the project first, persist its id, then add items. Keep the project-creation step small so there's less to retry.
  2. On a create timeout, don't blindly retry. The project may exist. Either look for it (GET /project is paginated and lists your projects) before creating another, or accept the create only once you've stored the returned id and made the rest of the push resumable from there.
  3. Make the push resumable. If adding items fails halfway, you either delete the project and start clean (09-error-handling.md) or resume by adding only the items that aren't there yet — decide which, and be consistent.

Rule of thumb

Treat Eurotext as a system that faithfully does exactly what you ask, every time you ask — including asking twice. All the "have I done this already?" logic lives on your side, anchored on your own id in __meta and your own mapping table.