---
title: Update one field on a passport
description: Patch one field on a passport with audit trail entry. Defaults to status approved; override to ai_suggested or supplier to route into the review queue.
canonical: "https://www.tracepass.eu/docs/update-field"
locale: en
source: "https://www.tracepass.eu/docs/update-field"
---

# Update one field on a passport

> Patch one field on a passport with audit trail entry. Defaults to status approved; override to ai_suggested or supplier to route into the review queue.

```http
PATCH /api/v1/passports/{id}/fields/{key}
```

Patch a single field on a passport. The value is validated against the field key (must exist on the passport's template) and persisted with an audit trail entry tagged `via API key <prefix>`. Use this in preference to writing the whole `fields` map when you only need to update one number — it's a smaller write and the per-field audit entry is what dashboard reviewers see.

Writes default to `status: "approved"` — API-key-driven integrations are trusted by convention (unlike dashboard editors, where non-admins write `pending_review`). Override with `source: "ai_suggested"` or `source: "supplier"` if you want the value to land in the review queue instead.

An alternate addressing form exists at PATCH /api/v1/passports/by-serial/{serial}/fields/{key} — same body, same response, useful when your ERP only knows the customer-side serial. Counts as one v1 write. Honours `Idempotency-Key`.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Authorization` | header | string | yes | `Bearer <token>` — either a `tp_` API key (Developer → API Keys; simplest, for server-to-server) or an OAuth 2.0 access token (Developer → OAuth Apps; for user-authorized apps, scoped + revocable). The Authentication page has the full OAuth flow and scope list. |
| `Idempotency-Key` | header | string | no | UUID v4 per logical operation. |
| `id` | path | ObjectId | yes | Passport ID. To address by serial instead, use PATCH /api/v1/passports/by-serial/{serial}/fields/{key}. |
| `key` | path | string | yes | Field key (camelCase) as defined on the passport's template — e.g. `nominalVoltage`, `batteryChemistry`, `recycledContentCobalt`. 400 if the key isn't on the template. |
| `value` | body | string \| number \| boolean \| array \| object | yes | New value. The platform doesn't reformat strings into numbers — send the value in the type the template field expects. |
| `source` | body | enum | no | Tag the origin of the value. One of: `manual`, `ai_suggested`, `ai_approved`, `reference_db`, `supplier`, `system`. Default `manual`. `ai_suggested` and `supplier` land in the review queue; everything else writes as approved. |
| `sourceLocale` | body | string (ISO 639-1) | no | Locale of the value (one of the 24 EU locales). Drives translation direction + the public viewer's language resolution. Defaults to the passport's `sourceLocale` when omitted. |

## Examples

```bash
curl -sS -X PATCH \
  https://app.tracepass.eu/api/v1/passports/6650b2c3d4e5f6a7b8c9d0e1/fields/ratedCapacity \
  -H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "value": 5.24 }'
```

```typescript
await fetch(
  `https://app.tracepass.eu/api/v1/passports/${id}/fields/ratedCapacity`,
  {
    method: "PATCH",
    headers: {
      Authorization: `Bearer ${process.env.TRACEPASS_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ value: 5.24 }),
  },
);
```

```python
import os, requests
res = requests.patch(
    f"https://app.tracepass.eu/api/v1/passports/{passport_id}/fields/ratedCapacity",
    headers={"Authorization": f"Bearer {os.environ['TRACEPASS_API_KEY']}"},
    json={"value": 5.24},
)
res.raise_for_status()
```

## Responses

### 200 — Updated

```json
{
  "field": {
    "value": 5.24,
    "source": "manual",
    "status": "approved",
    "accessLevel": "public",
    "sourceLocale": "en",
    "lastUpdatedAt": "2026-05-09T10:30:00.000Z",
    "lastUpdatedBy": "api_key:tp_89b2482d"
  },
  "version": 4
}
```

### 400 — Invalid field key

```json
{ "error": "Invalid field key: notARealField" }
```

### 404 — Not found

```json
{ "error": "Passport not found" }
```

## Related

- [Create a passport](https://www.tracepass.eu/docs/create-passport.md)
- [Attach an economic-operator party](https://www.tracepass.eu/docs/upsert-party.md)
