Settings
Account-level settings shared by every device: read with defaults, deep-merge updates, optimistic versioning.
One settings object per account (per user, not per key): what you change on the phone is what the watch, the desktop and the hub read. GET /v1/settings always answers the full object with defaults applied; version is 0 and updatedAt is null until the first write.
PATCH /v1/settings deep-merges a partial object into what is stored and validates the result strictly — an unknown key or a bad value is a 400. Send the version you last read to make the write conditional: when someone else changed the settings meanwhile you get 409 version_conflict with current (the GET shape) and nothing is written. A database outage is a 503 settings_unavailable, never defaults presented as your settings.
| Key | Values | Default |
|---|---|---|
transcripts.waveform | ring, bars, blob, dot, off | ring |
transcripts.haptics | true / false | true |
transcripts.liveText | true / false | true |
transcripts.target | auto, phone, watch | auto |
transcripts.language | BCP-47 tag (at most 16 characters) or null for auto-detect | null |
The same operations are in the SDKs (client.settings.get() / client.settings.update(partial, { version }) in TypeScript, client.settings.update(partial, version=…) in Python), the CLI (codaid settings get, codaid settings set transcripts.waveform=bars) and the MCP server (settings_get, settings_update).
bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128The settings with defaults applied.
application/json- response
settings*version*integerOptimistic-concurrency counter; 0 = never written.
0 <= valueupdatedAt*|Time of the last write; null when never written.
date-timecurl -X GET 'https://ai.codai.ro/v1/settings'{ "settings": { "transcripts": { "waveform": "ring", "haptics": true, "liveText": true, "target": "auto", "language": null } }, "version": 0, "updatedAt": "2019-08-24T14:15:22Z"}bearerAuthAuthorizationBearer <codai_…>A codai API key (codai_ prefix). Ephemeral tokens from POST /v1/tokens are accepted only by the media surfaces matching their scope (/v1/realtime, /v1/audio/*, /v1/embeddings).
x-request-id?stringClient correlation id; echoed back as x-codai-trace-id and persisted on the usage row.
length <= 128A deep partial of the settings plus an optional expected version.
application/json- body
settings*Deep partial of UserSettings; unknown keys are rejected.
version?integerExpected current version; a mismatch is a 409.
0 <= valueThe stored settings with defaults applied (same shape as GET).
application/json- response
settings*version*integerOptimistic-concurrency counter; 0 = never written.
0 <= valueupdatedAt*|Time of the last write; null when never written.
date-timecurl -X PATCH 'https://ai.codai.ro/v1/settings' \ -H 'Content-Type: application/json' \ -d '{ "settings": {}}'{ "settings": { "transcripts": { "waveform": "ring", "haptics": true, "liveText": true, "target": "auto", "language": null } }, "version": 0, "updatedAt": "2019-08-24T14:15:22Z"}