---
title: "Get a menu item's photo"
method: POST
path: "/images/items"
tags: ["Images"]
---

# Get a menu item's photo

`POST /images/items`

## Request

- Base URL: `https://api.layout.link/v1`
- URL: `https://api.layout.link/v1/images/items`
- Auth: HTTP bearer

The photo a restaurant published of one menu item. The same lookup the MCP `item_photo` tool runs. A photo Layout already holds answers at once and draws no allowance. Otherwise Layout reads the restaurant's own site, answering 200 when the photo turns up within about 12 seconds and 202 `finding` with an `imageId` when it does not; poll GET /images/items/{imageId}. Layout stops looking 35 seconds after the request. Read-only: nothing is built or charged to the person.

## Headers

- `Layout-Version` '2026-10-01'
- `Idempotency-Key` string

## Request body

- ItemImageRequest
  - `item` string, required: The menu item, in the person's words. Spelling and phrasing need not match the menu.
  - `placeId` string
  - `query` string: A restaurant name.
  - `near` string: Where, in the person's words. Not needed for a chain: its photos are the same at every branch.
  - `lat` number
  - `lng` number

## Response `200`

An answer: the photo, or why there is none.

- union
  - object
    - `status` 'photo', required
    - `restaurant` ImageRestaurant, required
      - `name` string, required
      - `address` string, nullable, required
    - `item` string, required: The item as the restaurant names it.
    - `priceMinor` integer: Their listed price in minor units when last read. Not a quote.
    - `image` ItemImage, required
      - `url` string, required: A JPEG, up to 1000px on its long side, served from Layout's CDN. Show this URL; do not copy the file.
      - `webpUrl` string, required: The same photo as WebP, smaller.
      - `width` integer, nullable, required
      - `height` integer, nullable, required
      - `source` 'menu' | 'product_page', required: `menu`: from the restaurant's own menu. `product_page`: from its own page for the item.
      - `checkedAt` string, nullable, required: When Layout last checked the photo against the restaurant's site (ISO 8601).
  - object
    - `status` 'finding', required
    - `imageId` string, required
    - `restaurant` ImageRestaurant, required
      - `name` string, required
      - `address` string, nullable, required
    - `retryAfterSec` integer, required: When to poll GET /images/items/{imageId}.
    - `giveUpAt` string, required: When the search stops (ISO 8601), 35 seconds after the request. A poll after it answers `no_photo`.
  - object
    - `status` 'no_photo', required
    - `restaurant` ImageRestaurant
      - `name` string, required
      - `address` string, nullable, required
    - `item` string
    - `reason` 'not_published' | 'not_found_in_time', required: `not_published`: the item is on the menu with no photo. `not_found_in_time`: no photo Layout could trust turned up within 35 seconds. Asking again later may find one.
  - object
    - `status` 'not_on_menu', required
    - `restaurant` ImageRestaurant, required
      - `name` string, required
      - `address` string, nullable, required
    - `checkedItems` integer: How many menu items were checked.
  - object: `item` named no dish (only the restaurant, or a word like `food`). Ask the person which item.
    - `status` 'needs_item', required
  - object
    - `status` 'needs_location', required
    - `candidates` object[], required: Send one back as `placeId`. Empty: send `near` or coordinates.
      - `placeId` string, required
      - `name` string, required
      - `address` string, required
      - `distanceMi` number, nullable, required
  - object
    - `status` 'not_found', required
  - object: The restaurant asked Layout not to show its photos.
    - `status` 'removed', required
    - `restaurant` ImageRestaurant
      - `name` string, required
      - `address` string, nullable, required

## Other responses

- `202`: Still finding it. Poll GET /images/items/{imageId}.
- `400`: The body is invalid. The message names the field. `unsupported_version`: the Layout-Version header names no version this API answers.
- `401`: The token is missing, expired, revoked, issued for another audience, or the person disconnected. Every 401 reads the same.
- `403`: The credential is real and may not do this: an application or account that is suspended, a live person on an unapproved application, a scope the token was not granted, or a person whose Layout account cannot order yet.
- `404`: No place with that placeId.
- `409`: `idempotency_conflict`: the Idempotency-Key was already used with a different request. `in_progress`: the first request with that key is still running; retry after `Retry-After`.
- `429`: A per-minute brake, or a daily allowance of image searches (the person's, Layout's, or your application's). The message names which. Photos Layout already holds never count.
- `500`: Layout failed to answer. Retry with backoff.
- `503`: Credentials or a dependency could not be checked right now. Retry with backoff.

---

[API](https://skmtc.dev/layout/apis/layout-partner-api.md) · [All operations](https://skmtc.dev/layout/apis/layout-partner-api/llms.txt) · [OpenAPI document](https://skmtc.dev/layout/apis/layout-partner-api/revisions/7ff4ba01bf56?raw)
