REST API

Recording Entry API

Overview

Transcript entry (sentence) editing API. Provides the ability for users to correct STT recognition errors.


PATCH /api/v1/tasks/{taskId}/entries/{sid}

Description

Modifies the original text (original_text) of a single sentence in a historical recording.

Design highlights:

  • Preserves the original STT output: On the first edit, the system automatically backs up the original STT result to original_text_raw, which you can trace back to at any time
  • No automatic retranslation: This endpoint only changes the original text; translation must be triggered by calling GET /api/v1/sse/recordings/{taskId}/entries/{sid}/retranslate
  • Optimistic lock: You can pass expected_revision to prevent concurrent overwrites
  • Automatic TTS cache invalidation: After the original text changes, the TTS cache for that sentence in all languages is cleared

Limitations

  • Only recordings that have finished processing (processing_status === completed) are allowed; in-progress recordings return recording_not_completed
  • You can only edit recordings owned by the API Key holder

Authentication

Header: X-API-Key (see Authentication)

Request Parameters

Path Parameters

ParameterTypeRequiredDescription
taskIdstringYesTask ID (UUID)
sidnumberYesSentence ID (1-based)

Body Parameters (JSON)

ParameterTypeRequiredDescription
original_textstringYesCorrected original text, 1–2000 characters
expected_revisionnumberNoOptimistic lock: the current transcript revision; a mismatch returns transcript_revision_conflict

Request Example

# Direct overwrite (recommended: tasks path)
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/{taskId}/entries/5" \
  -H "X-API-Key: vas_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "original_text": "Corrected text" }'

# With optimistic lock
curl -X PATCH "https://vas-poc.vurbo.ai/api/v1/tasks/{taskId}/entries/5" \
  -H "X-API-Key: vas_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "original_text": "Corrected text", "expected_revision": 3 }'

Success Response

HTTP 200

{
  "data": {
    "sid": 5,
    "original_text": "Corrected text",
    "original_text_raw": "Original STT output",
    "original_text_edited_at": "2026-05-06T10:30:00.000000Z",
    "translated_texts": {
      "en-US": "Stale previous translation; re-run via the retranslate endpoint"
    },
    "revision": 4
  }
}
FieldTypeDescription
sidnumberSentence ID
original_textstringThe corrected original text
original_text_rawstringThe original STT output (backed up on the first edit)
original_text_edited_atstringEdit time (ISO 8601)
translated_textsobjectExisting translations (not updated automatically; you must separately call the SSE retranslate endpoint)
revisionnumberThe new revision after the write, used for the next optimistic lock

Specific Error Codes

Error CodeHTTPDescription
recording_not_found404The recording does not exist or does not belong to this user
recording_not_completed422The recording has not finished processing yet
entry_not_found404The specified sentence could not be found
entry_text_empty422The original text is empty
entry_text_too_long422The original text exceeds the 2000-character limit
transcript_revision_conflict409The revision does not match (it was modified by another request), or another write to the same transcript is in progress
speaker_transcript_not_found404The transcript could not be found
storage_upload_failed500Writing the transcript back to storage failed

Typical Workflow: Edit + Automatic Retranslation

// 1. Get the current revision from historyTranscribe (via init_metadata or by reading it yourself)
const currentRevision = 3;

// 2. Edit the original text
const editResp = await fetch(`/api/v1/tasks/${id}/entries/${sid}`, {
  method: 'PATCH',
  headers: { 'X-API-Key': key, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    original_text: 'Corrected text',
    expected_revision: currentRevision,
  }),
});
const { data } = await editResp.json();
// Use the returned data.revision; do not assume it equals expected_revision + 1

// 3. Trigger single-sentence retranslation (emits progress / translated / done events)
const sse = new EventSource(
  `/api/v1/sse/recordings/${id}/entries/${sid}/retranslate`
    + `?expectedRevision=${data.revision}&api_key=${key}`
);
sse.addEventListener('translated', (e) => {
  const { lang, text } = JSON.parse(e.data);
  console.log(`${lang}: ${text}`);
});
sse.addEventListener('done', (e) => {
  const { revision } = JSON.parse(e.data);
  // Again, use the returned value: if another write happened in between, the number skips
  sse.close();
});

Version: V1.24.1 Last Updated: 2026-09-28

Copyright © 2026