---
title: "Update Gem Records"
method: PATCH
path: "/api/v1/gems/{gem_id}/records"
tags: ["Gemstones"]
---

# Update Gem Records

`PATCH /api/v1/gems/{gem_id}/records`

## Request

- Base URL: `https://api.gemstoneaiapp.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.gemstoneaiapp.com/api/v1/gems/{gem_id}/records`
- Auth: none declared

PATCH /api/v1/gems/{gem_id}/records (LNK-RECORDS)

Record the owner's own facts about their piece: measurements, carat weight,
lab report, notes. True partial patch — an omitted field is left untouched,
an explicit null clears just that field. Returns the updated block, or null
once the last recorded field is cleared.

Owner-only. Dual-owner resolution follows GET /{gem_id}/details and PUT
/{gem_id} (LNK-DETAILSANON / LNK-GEMRENAME): user_id when authenticated OR
device_id via X-Device-Id, with the owner filter inside the query so a
foreign gem 404s without leaking that it exists. Note the sibling
PATCH /{gem_id}/investment still fetches first and 403s — it leaks
existence; this route deliberately does not copy that.

These values remain owner claims. Weight, quantity and scope changes
recalculate valuation; when evidence pricing is enabled, measurement edits
also trigger a separate evidence valuation. Scan estimates stay separate.

## Path parameters

- `gem_id` integer, required

## Headers

- `X-Device-Id` integer, nullable
- `authorization` string, nullable

## Request body

- RecordsUpdateRequest: Body for PATCH /api/v1/gems/{gem_id}/records. True partial patch: an omitted field is left untouched, an explicit null clears that one field. The route reads ``model_fields_set`` to tell those apart — do not add defaults that would blur the distinction.
  - `length_mm` number, nullable
  - `width_mm` number, nullable
  - `depth_mm` number, nullable
  - `carat` number, nullable
  - `stone_quantity` integer, nullable
  - `carat_scope` 'per_stone' | 'total', nullable
  - `lab_name` string, nullable
  - `certificate_number` string, nullable
  - `notes` string, nullable
  - `reference_number` string, nullable
  - `watch_year` integer, nullable
  - `box_papers` 'full_set' | 'papers' | 'box' | 'none', nullable
  - `watch_condition` 'unworn' | 'excellent' | 'good' | 'worn', nullable

## Response `200`

Successful Response

- GemRecordsBlock: Additive per-gem "records" block — facts the OWNER stated about their own piece. Null block when they have recorded nothing. Deliberately separate from the *_estimate fields: these are never AI output and a rescan never overwrites them. The piece title is not part of this block — PUT /gems/{id} (LNK-GEMRENAME) owns renaming and writes main_heading.
  - `length_mm` number, nullable
  - `width_mm` number, nullable
  - `depth_mm` number, nullable
  - `carat` number, nullable
  - `stone_quantity` integer, nullable
  - `carat_scope` 'per_stone' | 'total', nullable
  - `lab_name` string, nullable
  - `certificate_number` string, nullable
  - `notes` string, nullable
  - `reference_number` string, nullable
  - `watch_year` integer, nullable
  - `box_papers` 'full_set' | 'papers' | 'box' | 'none', nullable
  - `watch_condition` 'unworn' | 'excellent' | 'good' | 'worn', nullable
  - `updated_at` string, date-time, nullable

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/gemstoneaiapp/apis/gemstoneai-api.md) · [All operations](https://skmtc.dev/gemstoneaiapp/apis/gemstoneai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/gemstoneaiapp/apis/gemstoneai-api/revisions/fcb441f55161?raw)
