Unimode Catalog Enrichment

API reference

Base URL: https://pyfyjiaqw2.execute-api.us-east-1.amazonaws.com/api. Every path below is under it, over HTTPS only.

Authentication: every request carries your workspace's API key:

Authorization: Bearer um_live_...

Keys are stored by Unimode only as hashes. A missing, unknown or revoked key gets 401. Requests are rate limited; sustained bursts get 429 or 403.

Endpoints

Method and path Purpose
GET /v1/me Your workspace: status, profiles, spend limit per run, next setup step
GET /v1/integration External ID, registered role and folders
GET /v1/integration/template CloudFormation template that creates the access role
PUT /v1/integration Register (and verify) the role and its folders
POST /v1/integration/rotate-external-id Issue a new external ID
POST /v1/runs Start a run on a feed
GET /v1/runs Your recent runs
GET /v1/runs/{run_id} One run's status, counts and cost

Starting a run

POST /v1/runs
{"input": "s3://acme-feeds/unimode/2026-10/feed.jsonl",
 "output": "s3://acme-results/unimode-results/",
 "profile": "acme.apparel",
 "max_usd": 20}

Any other field is rejected. Before starting, Unimode checks that the feed is readable and the output writable.

Runs

GET /v1/runs/{run_id} and GET /v1/runs return:

{"run_id": "20261022-...", "status": "running", "profile": "acme.apparel",
 "input": "s3://acme-feeds/unimode/2026-10/feed.jsonl",
 "output": "s3://acme-results/unimode-results/20261022-.../",
 "created_at": "...", "started_at": "...", "finished_at": null,
 "cost_usd": 0.12, "accepted": 950, "rejected": 50, "delivered": null, "error": null}

status is queued, running, succeeded, failed, cancelled, budget_exceeded, or expired (30 days after the run finished, when Unimode has deleted its copies; only run_id, created_at and expired_at remain). cost_usd is the spend so far and updates while the run is in progress.

What a run delivers

Under <output>/<run_id>/:

File Contents
items.jsonl One record per enriched product: id, publishable, needs_review_reasons, subcategory, attributes (each with its value and where it came from), extra_details, qa (buyer questions and answers).
errors.jsonl Feed lines that were rejected: line (1-based; empty for a repeated id), id, message; then products that failed enrichment: line empty, id, message, stage.
run.json Status, counts (accepted, rejected, delivered, failed), cost_usd, timestamps. Written last: when it exists, the delivery is complete.

A feed with no valid products fails the run; errors.jsonl and run.json are still delivered. If the output stops being writable mid-run (for example, the role was deleted), the run fails, and Unimode keeps the results so they can be delivered again. You are charged only for listings delivered in items.jsonl.

Errors

Status When
400 Input or output outside your registered folders; unknown profile; max_usd above your workspace's limit (detail.code = max_usd_above_limit); a role in another account or not named UnimodeEnrichmentAccess*.
401 Missing, unknown or revoked API key.
403 Workspace not active (setup not finished, or suspended).
404 Run not found.
413 Feed larger than the limit (detail.code = input_too_large).
422 Malformed request, including fields that are not allowed.
424 Access to your account failed: detail.code is role_assume_failed, input_unreadable or output_unwritable.