Carrying your own IDs through: __meta¶
When results come back, you need to know where each translated field goes. The
Eurotext item id doesn't tell you "this is the description of product X in
en_US" — that mapping lives in your system.
__meta is the mechanism. It's a reserved key inside the item body for data
that must not be translated. Whatever you put there rides along untouched and
comes back inside translation.__meta when you fetch the result. The spec's own
example says it out loud:
This is also the answer to "is there an external reference id?" — there's no
dedicated field, __meta is it. Put your primary key here.
The one rule: flat key-value only¶
Every value inside __meta must be a simple key-value value — string, number, or
boolean. Nested arrays, objects, null, and JSON-encoded structures are
rejected. Split routing data into separate flat keys instead.
// rejected — nested array
'__meta' => [ 'attributes' => ['name', 'description'] ]
// rejected — JSON structure hidden in a string
'__meta' => [ 'attributes' => '["name","description"]' ]
// fine — flat key-value pairs
'__meta' => [ 'id_in_your_system' => 132, 'locale' => 'en_US', 'source' => 'akeneo' ]
The client checks this before it sends, so invalid meta throws an
InvalidArgumentException with a clear message instead of an opaque 4xx from the
API.
What an Akeneo item looks like¶
Translating a product's name and description into US English — text under your
own field names, routing info under __meta:
$client->createItem(
projectId: $projectId,
sourceLanguage: LanguageMap::toEurotext('de-DE'),
targetLanguage: LanguageMap::toEurotext('en-US'),
textType: 'product',
body: [
'name' => 'Roter Bürostuhl',
'description' => 'Ergonomischer Stuhl mit verstellbarer Lehne.',
'__meta' => [
'product_uuid' => $product->getUuid(),
'locale' => 'en_US',
'source' => 'akeneo',
],
],
);
Reading it back¶
$item = $client->getItem($projectId, $itemId);
$translation = $item['translation'];
$meta = $translation['__meta'];
$product = $repo->find($meta['product_uuid']);
$locale = $meta['locale'];
foreach ($translation as $field => $value) {
if ($field === '__meta') {
continue;
}
// The body field names double as Akeneo attribute codes here. If yours
// differ, keep that mapping in your own store (see 12-idempotency.md) —
// not in __meta, which is flat scalars only.
$product->setValue($field, $locale, $value);
}
What you put in __meta on the way out is exactly what you read on the way back —
so make it carry everything you need to write the value home, and nothing you'd
mind a translator seeing.
Don't rely on
__metabeing searchable or filterable server-side — treat it as round-trip payload only. If you need to look items up, keep your own index (your id → returned project id + item id); see12-idempotency.md.