VitrinaAPI

Voice clips

Recorded voice notes the team and the agent reuse, with transcript, expiry and a model filter.

Beta
This may change at any time, with a changelog entry and a notice to recent callers — see versioning.

Download the full API pública projection: openapi.json.

Automate replies and assignment explains this resource in prose, with runnable examples.

MethodPathWhat it does
GET/voice-clipsList voice clips
POST/voice-clipsUpload a voice clip
DELETE/voice-clips/{id}Delete a voice clip
GET/voice-clips/{id}Fetch one voice clip
PATCH/voice-clips/{id}Edit a voice clip
GET/voice-clips/{id}/play-urlGet a play URL for a voice clip

GET /voice-clips

List voice clips

Deprecated — use /media-assets (voice clips are its audio files, same ids).

Every clip in the workspace library, newest first, expired ones included and marked expired: true.

With live=true the answer is only the clips that may be SENT now: not expired, and whose model filter is empty or names model (case- and whitespace-insensitive). Without model, only clips with no model filter qualify. tag (comma-separated) keeps clips carrying any of the tags.

ParameterInTypeRequiredConstraints
livequerytrue \falseno
modelquerystringnomáx. 120
tagquerystringnomáx. 200
curl https://api.vitrinadev.com/api/v1/voice-clips \
  -H "Authorization: Bearer $VITRINA_KEY"

Example response (200)

[
  {
    "id": "6b0f3c1e-2a4d-4f7e-9b1a-0c2d3e4f5a6b",
    "name": "Garantía 6 meses",
    "tags": [
      "garantia",
      "cierre"
    ],
    "when_to_use": "Cuando el cliente pregunta por la garantía de un seminuevo.",
    "expires_at": null,
    "expired": false,
    "models": [
      "iPhone 13",
      "iPhone 13 Pro",
      "iPhone 14"
    ],
    "transcript": "Hola, te cuento que todos nuestros equipos tienen seis meses de garantía.",
    "mime_type": "audio/ogg",
    "byte_size": 48213,
    "duration_ms": 12480,
    "original_filename": "garantia.ogg",
    "created_by": "2f1e0d9c-8b7a-4c6d-9e5f-1a2b3c4d5e6f",
    "created_at": "2026-10-28T15:04:05.000Z",
    "updated_at": "2026-10-28T15:04:05.000Z"
  }
]

Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429

POST /voice-clips

Upload a voice clip

Deprecated — use /media-assets (voice clips are its audio files, same ids).

Uploads the audio (file: OGG/Opus, MP3, M4A/AAC, WAV, WebM or AMR, at most 16 MB; 415 for another type, 413 above the cap) with its details. The clip is transcribed on upload unless transcript is sent; when speech-to-text fails or hears nothing usable, transcript is null and can be filled with PATCH. duration_ms is measured from the audio. name defaults to the file name. Answers 201 with the clip.

Or a JSON body (application/json) — what an MCP connector sends through call_operation, which cannot build multipart: \{ filename, content, content_encoding?, content_type? \} plus the operation's own form fields. content is UTF-8 text by default, or base64 when content_encoding is "base64" (images, PDF, audio, video). The same byte cap applies to the decoded bytes (413 above it); invalid base64 is a 400; the content type defaults from the filename extension.

Body

FieldTypeRequiredConstraints
filenamestringyesmín. 1, máx. 255
contentstringyesmín. 1, máx. 35000000
content_encodingutf8 \base64—
content_typestring—máx. 200
namestring—máx. 120
tagsstring[]—
when_to_usestring—máx. 2000
expires_atstring | null—date-time
modelsstring[]—
transcriptstring—máx. 8000
curl -X POST https://api.vitrinadev.com/api/v1/voice-clips \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file": "(binary audio part)",
    "name": "Garantía 6 meses",
    "tags": "garantia,cierre",
    "when_to_use": "Cuando el cliente pregunta por la garantía."
  }'

Example response (201)

{
  "id": "6b0f3c1e-2a4d-4f7e-9b1a-0c2d3e4f5a6b",
  "name": "Garantía 6 meses",
  "tags": [
    "garantia",
    "cierre"
  ],
  "when_to_use": "Cuando el cliente pregunta por la garantía de un seminuevo.",
  "expires_at": null,
  "expired": false,
  "models": [
    "iPhone 13",
    "iPhone 13 Pro",
    "iPhone 14"
  ],
  "transcript": "Hola, te cuento que todos nuestros equipos tienen seis meses de garantía.",
  "mime_type": "audio/ogg",
  "byte_size": 48213,
  "duration_ms": 12480,
  "original_filename": "garantia.ogg",
  "created_by": "2f1e0d9c-8b7a-4c6d-9e5f-1a2b3c4d5e6f",
  "created_at": "2026-10-28T15:04:05.000Z",
  "updated_at": "2026-10-28T15:04:05.000Z"
}

Answers: 201 · 400 · 401 · 403 · 404 · 409 · 429

DELETE /voice-clips/{id}

Delete a voice clip

Deprecated — use /media-assets (voice clips are its audio files, same ids).

Removes the clip and its audio from the library. Voice notes already sent in conversations stay there. To stop offering a clip without losing it, set expires_at instead.

ParameterInTypeRequiredConstraints
idpathuuidyes
curl -X DELETE https://api.vitrinadev.com/api/v1/voice-clips/<id> \
  -H "Authorization: Bearer $VITRINA_KEY"

Answers: 204 · 400 · 401 · 403 · 404 · 409 · 429

GET /voice-clips/{id}

Fetch one voice clip

Deprecated — use GET /media-assets/\{id\}.

The clip with its details, transcript and expired state.

ParameterInTypeRequiredConstraints
idpathuuidyes
curl https://api.vitrinadev.com/api/v1/voice-clips/<id> \
  -H "Authorization: Bearer $VITRINA_KEY"

Example response (200)

{
  "id": "6b0f3c1e-2a4d-4f7e-9b1a-0c2d3e4f5a6b",
  "name": "Garantía 6 meses",
  "tags": [
    "garantia",
    "cierre"
  ],
  "when_to_use": "Cuando el cliente pregunta por la garantía de un seminuevo.",
  "expires_at": null,
  "expired": false,
  "models": [
    "iPhone 13",
    "iPhone 13 Pro",
    "iPhone 14"
  ],
  "transcript": "Hola, te cuento que todos nuestros equipos tienen seis meses de garantía.",
  "mime_type": "audio/ogg",
  "byte_size": 48213,
  "duration_ms": 12480,
  "original_filename": "garantia.ogg",
  "created_by": "2f1e0d9c-8b7a-4c6d-9e5f-1a2b3c4d5e6f",
  "created_at": "2026-10-28T15:04:05.000Z",
  "updated_at": "2026-10-28T15:04:05.000Z"
}

Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429

PATCH /voice-clips/{id}

Edit a voice clip

Deprecated — use /media-assets (voice clips are its audio files, same ids).

Changes the details and the transcript; the audio itself is replaced by uploading a new clip. tags and models are replaced wholesale. expires_at: null removes the expiry (an expired clip becomes sendable again). At least one field is required.

ParameterInTypeRequiredConstraints
idpathuuidyes

Body

FieldTypeRequiredConstraints
namestring—mín. 1, máx. 120
tagsstring[]—
when_to_usestring—máx. 2000
expires_atstring | null—date-time
modelsstring[]—
transcriptstring | null—máx. 8000
curl -X PATCH https://api.vitrinadev.com/api/v1/voice-clips/<id> \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transcript": "Hola, te cuento que todos nuestros equipos tienen seis meses de garantía.",
    "expires_at": "2026-11-30T23:59:59-03:00"
  }'

Example response (200)

{
  "id": "6b0f3c1e-2a4d-4f7e-9b1a-0c2d3e4f5a6b",
  "name": "Garantía 6 meses",
  "tags": [
    "garantia",
    "cierre"
  ],
  "when_to_use": "Cuando el cliente pregunta por la garantía de un seminuevo.",
  "expires_at": null,
  "expired": false,
  "models": [
    "iPhone 13",
    "iPhone 13 Pro",
    "iPhone 14"
  ],
  "transcript": "Hola, te cuento que todos nuestros equipos tienen seis meses de garantía.",
  "mime_type": "audio/ogg",
  "byte_size": 48213,
  "duration_ms": 12480,
  "original_filename": "garantia.ogg",
  "created_by": "2f1e0d9c-8b7a-4c6d-9e5f-1a2b3c4d5e6f",
  "created_at": "2026-10-28T15:04:05.000Z",
  "updated_at": "2026-10-28T15:04:05.000Z"
}

Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429

GET /voice-clips/{id}/play-url

Get a play URL for a voice clip

Deprecated — use /media-assets (voice clips are its audio files, same ids).

A short-lived signed URL (15 minutes) to stream or download the audio. Ask for a new one when it expires; do not store it.

ParameterInTypeRequiredConstraints
idpathuuidyes
curl https://api.vitrinadev.com/api/v1/voice-clips/<id>/play-url \
  -H "Authorization: Bearer $VITRINA_KEY"

Example response (200)

{
  "url": "https://storage.example.com/tenants/…/voice-clips/6b0f….ogg?X-Amz-Signature=…",
  "expires_at": "2026-10-28T15:19:05.000Z",
  "mime_type": "audio/ogg"
}

Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429

On this page