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 aninsert. 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:
- Create the project first, persist its id, then add items. Keep the project-creation step small so there's less to retry.
- On a create timeout, don't blindly retry. The project may exist. Either
look for it (
GET /projectis 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. - 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.