REST API
Entries
Overview
Transcript entry (sentence) editing API. Provides the ability for users to correct STT recognition errors.
PATCH /api/v1/tasks/{taskId}/entries/{sid}
V1.4.1 Naming Unification: This endpoint provides the following two equivalent paths, with identical behavior (same Controller, same UUID):
- Recommended
PATCH /api/v1/tasks/{taskId}/entries/{sid}(added in V1.4.1)- Deprecated
PATCH /api/v1/recordings/{recordingId}/entries/{sid}(the legacy path prior to V1.4.1, to be removed in V1.6.0)Use the
taskspath for new integrations; existing integrations may continue using therecordingspath until V1.6.0.For compatibility with legacy data such as the
expectedRevisionoptimistic lock, the examples below still retain both path forms.
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_revisionto 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 returnrecording_not_completed - You can only edit recordings owned by the API Key holder
Authentication
Header: X-API-Key (see Authentication)
Request Parameters
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
taskId | string | Yes | Task ID (UUID, the same value as the legacy name recordingId) |
sid | number | Yes | Sentence ID (1-based) |
Body Parameters (JSON)
| Parameter | Type | Required | Description |
|---|---|---|---|
original_text | string | Yes | Corrected original text, 1–2000 characters |
expected_revision | number | No | Optimistic 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
}
}
| Field | Type | Description |
|---|---|---|
sid | number | Sentence ID |
original_text | string | The corrected original text |
original_text_raw | string | The original STT output (backed up on the first edit) |
original_text_edited_at | string | Edit time (ISO 8601) |
translated_texts | object | Existing translations (not updated automatically; you must separately call the SSE retranslate endpoint) |
revision | number | The new revision after the write, used for the next optimistic lock |
Specific Error Codes
| Error Code | HTTP | Description |
|---|---|---|
recording_not_found | 404 | The recording does not exist or does not belong to this user |
recording_not_completed | 422 | The recording has not finished processing yet |
entry_not_found | 404 | The specified sentence could not be found |
entry_text_empty | 422 | The original text is empty |
entry_text_too_long | 422 | The original text exceeds the 2000-character limit |
transcript_revision_conflict | 409 | The revision does not match (it was modified by another request) |
speaker_transcript_not_found | 404 | The transcript blob could not be found |
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/recordings/${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();
// data.revision will be 4; subsequent operations use this as the baseline
// 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);
// revision will be 5
sse.close();
});
Version: V1.5.7 Last Updated: 2026-05-20