Upload call transcripts or recordings

Upload the dealer's sample call transcripts or recordings to file storage. This is the first step of the "Upload Call Transcripts / Recordings" task.

POSThttps://api.spyne.ai/console/v1/product-onboarding/vini/call-transcripts-recordings/files
AuthBearer token (console user)Rate limitNot documentedProcessingSynchronous; waits until every file is stored

The call returns each file's storage key and URL. It does not record the URLs against the agent: the console UI does that next with Save readiness answers in Go-Live. Nothing in the code reads these files to train the agent today.

Auth: Bearer token of a signed-in console user, checked with the identity service. Rate limit: not documented. Processing: synchronous. The call waits until every file is stored.

Before you call it

  • Send one or more files in the multipart field files. All files in one request must be the same uploadType:
    • transcript: .txt, .pdf or .docx, up to 25 MB.
    • recording: .mp3, .wav or .m4a, up to 200 MB.
  • The extension check is not case-sensitive. If any file has another extension, the whole request is rejected.
  • Send transcripts and recordings in separate requests.
  • product and segmentName are free text that only shape the storage folder. The console UI sends the two halves of the tab key: product is sales, service, acquisition or receptionist, and segmentName is inbound or outbound.
  • Each file is stored under vini-call-transcripts-recordings/<enterpriseId>/<teamId>/<product>/<segmentName>/<uploadType>/, with a timestamp and random prefix on the file name.
  • Send Authorization: Bearer YOUR_TOKEN. Use multipart/form-data; the client sets the boundary.

Request body

Multipart form fields.

Requiredalways send
Request checklist
  1. Text fields first: add enterpriseId, teamId, product, segmentName and uploadType. The console UI adds these before the files.
  2. Files: add each file under the field name files.
ParameterTypeRequiredDescription
enterpriseIdstringRequiredDealer group. Cannot be blank.
teamIdstringRequiredRooftop. Cannot be blank.
productstringRequiredFolder name, for example sales. Cannot be blank.
segmentNamestringRequiredFolder name, for example inbound. Cannot be blank.
uploadTypestringRequiredtranscript or recording.
filesfile (repeatable)RequiredOne or more files of the allowed types.

Sample request

curl -X POST "https://api.spyne.ai/console/v1/product-onboarding/vini/call-transcripts-recordings/files" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "enterpriseId=<enterpriseId>" \
  -F "teamId=<teamId>" \
  -F "product=sales" \
  -F "segmentName=inbound" \
  -F "uploadType=transcript" \
  -F "[email protected]" \
  -F "[email protected]"
import requests

data = {
    "enterpriseId": "<enterpriseId>",
    "teamId": "<teamId>",
    "product": "sales",
    "segmentName": "inbound",
    "uploadType": "recording",
}
files = [("files", ("call-1.mp3", open("call-1.mp3", "rb"), "audio/mpeg"))]
res = requests.post(
    "https://api.spyne.ai/console/v1/product-onboarding/vini/call-transcripts-recordings/files",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    data=data,
    files=files,
)
print(res.status_code, res.json())
import { readFile } from 'node:fs/promises';

const form = new FormData();
form.append('enterpriseId', '<enterpriseId>');
form.append('teamId', '<teamId>');
form.append('product', 'sales');
form.append('segmentName', 'inbound');
form.append('uploadType', 'transcript');
form.append('files', new Blob([await readFile('call-1.txt')], { type: 'text/plain' }), 'call-1.txt');

const res = await fetch('https://api.spyne.ai/console/v1/product-onboarding/vini/call-transcripts-recordings/files', {
  method: 'POST',
  headers: { Authorization: 'Bearer YOUR_TOKEN' },
  body: form,
});
console.log(res.status, await res.json());

Sample response

{
  "success": true,
  "error": false,
  "message": "Files uploaded successfully.",
  "data": [
    {
      "fileName": "call-1.txt",
      "key": "vini-call-transcripts-recordings/<enterpriseId>/<teamId>/sales/inbound/transcript/1760263200000-ab12cd-call-1.txt",
      "url": "https://example-bucket.s3.amazonaws.com/vini-call-transcripts-recordings/<enterpriseId>/<teamId>/sales/inbound/transcript/1760263200000-ab12cd-call-1.txt"
    }
  ]
}
{
  "error": true,
  "message": "Invalid file format for transcript. Allowed formats: .txt, .pdf, .docx",
  "invalidFiles": ["call-1.mp3"]
}
{ "error": true, "message": "No file uploaded. Provide one or more files in the `files` field." }
{ "message": "Invalid Token", "error": true, "code": "ERROR_AUTH_401", "details": "", "data": null }
{ "error": true, "message": "<upload error message>" }

Response parameters (200)

ParameterTypeDescription
successbooleantrue on success.
errorbooleanfalse on success.
messagestringFiles uploaded successfully.
data[].fileNamestringOriginal file name.
data[].keystringStorage key.
data[].urlstringStorage URL. The console UI saves these as go-live readiness answers.

Errors

StatusReasonWhen it happens
400<fields> cannot be blank.enterpriseId, teamId, product or segmentName is blank.
400Missing or invalid inputA required field is missing, or uploadType is not transcript or recording. The framework rejects the call; the body is not documented.
400No file uploaded ...No file in files.
400Invalid file format for ...At least one file has an extension that is not allowed. invalidFiles lists them.
401Invalid tokenMissing or rejected token.
408Request timeoutThe console could not reach the identity service to check the token.
500Upload error messageThe upload went over the size limit, or a storage write failed.

What happens next

  • The console UI posts the returned url values to Save readiness answers in Go-Live. It uses step viniCallTranscriptsRecordings and question transcript or recordings, merged with answers saved earlier.
  • Then it calls Mark a task done with taskName: "Upload Call Transcripts / Recordings" and the tab's segmentName.
  • The task is marked done even if the go-live readiness save fails, because the console UI ignores the result of both follow-up calls.

Did this page help you?