eurotext / rest-integration
Reference client and developer documentation for the Eurotext v2 REST API
Requires
- php: >=8.1
- guzzlehttp/guzzle: ^7.8
Requires (Dev)
- phpunit/phpunit: ^10.5
This package is auto-updated.
Last update: 2026-08-02 11:05:24 UTC
README
A small, dependency-light reference client and developer documentation for connecting a system to the Eurotext v2 REST API (translation projects).
The client is a straight, synchronous port of production code that has been communicating with the Eurotext API successfully. It is framework-agnostic and drops cleanly into a Symfony/Akeneo connector, a CLI command, or a queue worker.
📖 Live docs: https://eurotext.github.io/rest-integration-docs/
Verified against the live Eurotext stage API — see
VERIFICATION.md.
What's in here
src/
EurotextClient.php # HTTP client — the full project lifecycle
LanguageMap.php # BCP-47 (de-DE) -> Eurotext code (de-de, mlt, gai, ...)
ProjectStatus.php # Collapse the "elements" poll payload into one status
examples/
submit_and_poll.php # Runnable end-to-end round-trip
tests/ # PHPUnit — every method has a test
docs/ # Endpoint reference, workflow, language codes, pitfalls
Requirements
- PHP 8.1+
guzzlehttp/guzzle^7.8
Install
You can use this two ways.
As a Composer package (published on Packagist):
composer require eurotext/rest-integration
Releases are tagged with SemVer; see
CHANGELOG.md. Prefer to grab the source directly? Download a
release ZIP or
clone https://github.com/Eurotext/rest-integration. (composer.lock is
intentionally not committed — library convention; your app's lock file pins the
version.)
Or as a template — the code is small and readable on purpose. Copy src/
(three files) into your project, adjust the namespace, and go. The docs/ are
useful either way.
To work on the kit itself:
composer install composer test # runs PHPUnit
Quickstart
use Eurotext\EurotextClient; use Eurotext\LanguageMap; use Eurotext\ProjectStatus; $client = new EurotextClient($apiKey); // stage by default $project = $client->createProject('My project', type: 'order'); $client->createItem( projectId: (int) $project['id'], sourceLanguage: LanguageMap::toEurotext('de-DE'), // -> de-de targetLanguage: LanguageMap::toEurotext('fr-FR'), // -> fr-fr textType: 'product', body: ['name' => 'Roter Stuhl', '__meta' => ['id_in_your_system' => 42]], ); $client->transitionProject((int) $project['id'], 'new'); // start translation // ...later, from a cron/queue job: $status = ProjectStatus::fromProject($client->getProject((int) $project['id']));
See examples/submit_and_poll.php for the full
round-trip including result fetching and cleanup-on-failure, and
examples/curl/ if you'd rather poke at the API by hand first.
Docs
- 01 — Overview
- 02 — Authentication & environments
- 03 — The workflow, end to end
- 04 — Endpoint reference (request/response bodies)
- 05 — Language codes
- 06 — Text types
- 07 — Carrying your own IDs (
__meta) - 08 — Reading project status
- 09 — Error handling
- 10 — Pitfalls
- 11 — Webhook & polling
- 12 — Idempotency & duplicate protection
Examples
submit_and_poll.php— the flow in one filetranslate_catalogue.php— a worked catalogue translation with push/poll phases and a state storecurl/— the same calls as curl and a REST-client file
The workflow
- Authenticate —
Authorization: Bearer <key>,Content-Type: application/json. - Create a project —
POST /project(type: "order"to commission, or"quote"for a price estimate). - Add items —
POST /project/{id}/item(one item per source unit; fields go intobody). - Start —
PATCH /transition/project/{id}withstatus: "new". - Poll —
GET /project/{id}; read theelementsgroups until everything is infinished(useProjectStatus). Delivery takes hours to days — poll from a cron/queue job, not a request. - Fetch results —
GET /project/{id}/item/{itemId}; the translation is undertranslation, the source stays underbody. - Cleanup —
DELETE /project/{id}to abandon a project, but only before it starts: a draft or freshly-transitioned project can be deleted; once its items arein-progressthe API rejects the delete.
Environments
| Environment | Base URL |
|---|---|
| Stage (default) | https://stage.api.eurotext.de/api/v2 |
| Production | https://api.eurotext.de/api/v2 |
Pitfalls worth knowing up front
These are the non-obvious things that cost real debugging time — full detail in
docs/10-pitfalls.md:
- Language codes are proprietary, not BCP-47.
de-DE->de-de, but alsomt-MT->mlt,ga-IE->gai. UseLanguageMaporGET /info/languages. __metatakes flat key-value pairs only. String, number, or bool values are fine ({"id_in_your_system": 132}); arrays, objects, null, and JSON-encoded structures are rejected.textTypeis a fixed set (specialized-text,product,term,marketing,template,software,ai-01,ai-02,ai-03) — and it grows, so read it fromGET /info/text-typesrather than hardcoding.- Status lives in
elements, grouped by state; each group hasitemsand may havefiles. "Done" means every item sits infinished. - Translation vs. source: the result is under
translation, notbody.
License
MIT.