Skip to content

The workflow, end to end

Six calls, in order. The first four are the push; the last two are the poll and fetch you run later.

sequenceDiagram
    participant You
    participant ET as Eurotext API

    You->>ET: POST /project  (type: order)
    ET-->>You: 201 { id: 4711 }

    loop per source unit (all items BEFORE the transition)
        You->>ET: POST /project/4711/item
        ET-->>You: 201 { id: 99 }
    end

    You->>ET: PATCH /transition/project/4711  (status: new)
    ET-->>You: 204  (project now locked — no more items)

    Note over You,ET: hours to days pass

    loop until finished (cron / worker)
        You->>ET: GET /project/4711
        ET-->>You: { elements: { finished: {...}, ... } }
    end

    loop per finished item
        You->>ET: GET /project/4711/item/99
        ET-->>You: { translation: {...} }
    end

This order is mandatory — the API enforces it, it is not a suggestion:

  • Add every item before the transition. A new project is a draft (status: default); items can only be created and edited in that state.
  • After the transition the project is locked (status: locked). You cannot add further items, and existing items can no longer be changed — forgot one, start a new project for it.
  • While items are in-progress you still cannot add items, and the project can no longer be deleted. The delete/cleanup window closes the moment work starts.

Invalid sequences: transitioning before adding items leaves an empty project; adding or editing items after the transition is rejected; deleting a project whose items are in-progress is rejected.

1. Create the project

POST /project with type: "order" (or "quote" for an estimate first). You get back an id — keep it, everything else hangs off it.

2. Add items

POST /project/{id}/item, one call per source unit. Each item declares its source and target language and carries the actual text in body. This is also where you attach your own identifiers (see 07-metadata-roundtrip.md) so you can find your way back later.

Add every item you need before moving on.

3. Start translation

PATCH /transition/project/{id} with status: "new". Until you do this the project just sits there as a draft. After it, the project is locked: translation begins, no more items can be added, existing items can't be changed, and you only read the project from here on. This step is the point of no return — make sure every item is in place first.

4. Store the project id

Not an API call — just don't lose the id. Write it next to your records (product, batch, whatever). The poll step needs it, and it's your only handle on the work in flight.

5. Poll for delivery

GET /project/{id} on a schedule. The response groups items by state under elements; you're waiting for all of them to land in finished. See 08-status-model.md for how to read it, or just use ProjectStatus::fromProject().

Do this from a cron job or a queue worker. A web request that waits for a human translation is a web request that times out. Thirty minutes between polls is plenty. If you can receive an inbound HTTP call, register a webhook url at project creation instead and skip polling — 11-webhook-and-polling.md covers both.

6. Fetch results

For each finished item, GET /project/{id}/item/{itemId}. The translated fields are under translation; the untouched source is still under body. Pull your identifiers back out of translation.__meta, and write each value home.

Cleanup

If step 2 or 3 blows up halfway, DELETE /project/{id} so you don't leave a half-built project behind. This works only while the project is still a draft or freshly transitioned — once its items are in-progress, the project can no longer be deleted. The example wraps the push in a try/catch that deletes on failure, before any work has started.