Errors
You will branch on whya call failed far more often than you read the message. A revoked key and a dish with no model are both “no 3D appeared”, and they call for opposite responses.
Dish.tsx
const { data, error } = useArmenusItem(itemId);
if (error?.isAuthError) {
// Every dish will fail, not just this one. Log it loudly.
reportToSentry(error);
return <DishPhoto item={fallback} />;
}ArmenusError in JavaScript and ArmenusException in Dart both carry status, code, message, isRetryable and isAuthError.
Status codes
| Status | Code | What it means, and what to do |
|---|---|---|
| 401 | unauthorized | Key missing, revoked, or not a pk_. The account behind it may also have been suspended. Fix the key — retrying will not help. |
| 403 | forbidden | The calling origin is not on this key’s allowlist. Add it, or clear the list entirely for native apps. |
| 404 | not_found | No such dish that this key may read. Deliberately indistinguishable from “belongs to someone else” — confirming that an id exists would let anyone enumerate a competitor’s catalogue. |
| 422 | validation_failed | Malformed parameters. details names the offending path. |
| 429 | rate_limited | Over the key’s quota. Read x-ratelimit-reset. Retryable. |
| 0 | timeout · network_error | Never reached us. Retryable — and the SDK already tried. |
Retries
The SDKs retry retryable failures twice by default, with jittered exponential backoff. The jitter matters: without it, a restaurant full of phones that all failed on the same blip retries in lockstep and reproduces it. Set retries: 1 to disable.
Only idempotent GETs exist on this surface, which is why retrying is safe here by default — a property of the embed API being read-only, not a general licence.