---
title: "Add Place By Id"
method: POST
path: "/saved/add-place"
tags: ["saved"]
---

# Add Place By Id

`POST /saved/add-place`

Save a place by id — optionally to a list. Idempotent per (place, list).

THE contract is a canonical place ULID (`canonical_places.id`) — the
spine identity every surface joins on; saves resolve entirely from the
spine with zero paid fetches, and dedup by canonical place_id.

A Google place_id is also accepted as the LEGACY autocomplete path (the
picker hands us a gpid before any canonical row exists); that path still
ends canonical — the resolver mints/links the row and stamps
`item.place_id` — it just pays the Google fetch to get there.

## Headers

- `x-client-id` string, nullable

## Request body

- AddPlaceByIdRequest
  - `place_id` string, required
  - `list_id` string, uuid, nullable
  - `skip_enrichment` boolean

## Response `200`

Successful Response

- SavedItemOut
  - `id` string, uuid, required
  - `list_id` string, uuid, nullable, required
  - `place_ref` string, required
  - `place_id` string, nullable, required
  - `caption` string, nullable, required
  - `description` string, nullable
  - `name` string, required
  - `category` string, nullable, required
  - `city` string, nullable, required
  - `state` string, nullable, required
  - `country` string, nullable, required
  - `lat` number, nullable, required
  - `lng` number, nullable, required
  - `image_url` string, nullable, required
  - `image_thumbhash` string, nullable
  - `rating` number, nullable, required
  - `num_reviews` integer, nullable, required
  - `tabelog_tier` integer, nullable
  - `michelin` MichelinDistinction — A place's Michelin Guide distinction, structured. Canonical rationale — the TS mirror and the renderers point here rather than restating it. Rides alongside `michelin_award` rather than replacing it: that field is a pre-rendered label ("★★★"), and a label cannot drive iconography. An award string we don't recognise yields NO distinction (we never paint a mark we can't justify) while still surfacing verbatim in `michelin_award`, so a new tier degrades to text rather than disappearing.
    - `tier` 'stars' | 'bib_gourmand' | 'selected', required
    - `stars` integer, nullable
    - `green_star` boolean
    - `url` string, nullable
    - `cuisine` string, nullable
  - `source` string, required
  - `source_url` string, nullable, required
  - `is_shared` boolean, required
  - `review_state` string, nullable, required
  - `created_at` string, required

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.dev/stardrift/apis/fastapi.md) · [All operations](https://skmtc.dev/stardrift/apis/fastapi/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/stardrift/fastapi/revisions/00746572572a/schema)
