Skip to main content

From recording to Clip or Memo

A recording is the common audio input. The app processes it into a Clip or a Memo, using the selected input mapping: Text syncs to the cloud for both. The API does not store audio. Duration is an intended use, not an automatic classification rule. Recording is the shared resource name and the database table remains recordings. Each row has the result type clip or memo; Memo is not renamed to Recording.

The recording object

Create, read, and edit responses use the same recording object:
type is clip or memo. A device capture can include deviceId. An import can include an optional externalId from your own system. Timestamps are Unix milliseconds. status tells you whether text is pending, transcribing, ready, no_speech, or failed. The app reports transcription progress. Saving nonempty transcript text makes the recording ready; this API does not start transcription. A pending app capture cannot be edited until the app saves it.

Create and retry

POST /recordings accepts type plus optional title, transcript, summary, recordedAt, externalId, and audio. Include Idempotency-Key on every create. Retry with the same key and body to recover the saved result without duplicate items or overwritten edits. A conflicting body returns 409; retrying a deleted recording returns 410. If you provide externalId, repeated imports of that ID with the same body also reuse the existing recording. Retry keys and external IDs are scoped to the integration associated with your key. A newly created key has a new integration identity; keep the original key for retries of earlier imports. A key with create or edit permission but no read permission receives only { "recording": { "id": "…", "revision": 1 } }. It cannot retrieve text later added by the account owner.

Edit and delete

Read GET /recordings/{id} and copy its ETag response header into If-Match. Then send only the fields you want to change:
Editable fields are title, transcript, summary, and pinned. A recording’s type and capture identity stay fixed. DELETE /recordings/{id} also requires If-Match. A newer edit returns 412; read again and reconcile before retrying. A missing If-Match returns 428. GET /recordings accepts type, q, deviceId, status, from, and to. Search matches title and transcript. Date bounds are inclusive. Results are newest first by capture time. Set limit up to 100 and pass nextCursor as cursor to continue with the same filters; null means the last page. For the latest clip, use GET /recordings?type=clip&limit=1. Check its status: it may still be processing. Pagination reflects current data, not a frozen snapshot.

Local audio

For type: "memo", creation may include local file references:
These are opaque IDs in your client’s local store. They are optional and do not upload the file. Paths, audio bytes, and download URLs are not accepted. The response includes the last reported available references; it cannot prove an offline client’s file is still present. Italic cannot play or remove that local file through this API. Clips always return audio: [] and cannot be created with audio references. Audio used during capture and transcription is an in-progress recording input, not retained Clip audio. Once converted and saved as a Clip, only text remains. A pending or failed input is not a completed Clip. Client transfer and cleanup reports remain part of the app protocol.

Errors

Errors contain error.code and error.message. The X-Request-Id header identifies a request for support. JSON requests are limited to 1,500,000 bytes.