---
title: "Upload Audio"
method: POST
path: "/v2/audios"
tags: ["Audio Emotion API"]
---

# Upload Audio

`POST /v2/audios`

## Request

- Base URL: `https://api.imentiv.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.imentiv.ai/v2/audios`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer
  - OAuth 2
    - Authorization code: `https://api.imentiv.ai/oauth/authorize`
    - Token URL: `https://api.imentiv.ai/oauth/token` scopes: `media.write`

Analyze emotions and speech patterns from audio content.

Submit audio from multiple sources and receive detailed emotion analysis,
speaker identification, and transcription with emotional insights.

**Input Sources:**
- **YouTube**: Provide any YouTube video URL (audio will be extracted)
- **Instagram**: Instagram Reels and video posts (public content)
- **Twitter/X**: Twitter video posts and media content
- **Facebook**: Facebook video posts (public content)
- **Cloud Storage**: Dropbox, Google Drive, or other cloud service links
- **Direct URL**: Any publicly accessible audio or video link
- **File Upload**: Upload audio files directly from your device

**Audio Extraction:**
Video files are supported for URLs only (YouTube, Instagram, Twitter, Facebook,
Dropbox, direct links) - the audio track will be automatically extracted and analyzed.
For file uploads, use audio formats only (MP3, WAV, AAC, M4A).

**Analyze Specific Segments:**
Focus on specific portions using `start_millis` and `end_millis` parameters.
This helps target key moments and optimize credit usage.

**How It Works:**
1. Submit your audio and receive an immediate response with an audio ID
2. Audio is queued for processing (typically completes within minutes)
3. Optionally receive a webhook notification via `callback_url` when complete
4. Retrieve results using the audio ID

**Supported Formats:**
- File Upload: MP3, WAV, AAC, M4A
- Media URLs: MP3, WAV, AAC, M4A, MP4, AVI, MOV (audio extracted from video URLs)

**Credit Usage:**
Billed on success; the amount is recorded after the run and is not quoted
on this request. Each audio is billed at least 5 credits. A 402 is
returned before processing starts when admission is refused.

**Extra Parameters:**
- **diarization** (bool): Enable or disable speaker diarization for identifying different speakers in the audio. Default is True. Disabling it reduces the per-second credit cost.
- **text_emotion** (bool): Enable or disable transcript emotion analysis for the transcribed text. Default is True. Requires `transcription=True`; if `transcription` is False this is forced off. Disabling it reduces the per-second credit cost. Supplying a `transcript` is the exception: the words already exist, so `text_emotion` is honoured as you sent it.
- **transcription** (bool): Enable or disable transcript / ASR generation. Default is True. When False, no transcript is produced and `text_emotion` is forced off. Disabling it reduces the per-second credit cost.
- **language** (str, optional): Language code for the audio (e.g., 'en'). If not provided, language will be auto-detected.
- **multilingual** (bool): Opt-in mixed-language transcription. Default is False. Once the audio completes, the lines that are not in its main language are also translated into the main language and billed as a translation, on top of transcription; `auto_translation` on the audio reports it.
- **expected_languages** (str, optional): Comma-separated codes of the languages the audio may contain, the main one included (e.g., 'en,ja'), up to 5. Detection is restricted to them. If `language` is also sent it must be one of them. An invalid code is refused with 422 `invalid_language` before anything is charged.

**Bringing your own transcript:**
Pass `transcript` (and optionally `transcript_format`) to skip our speech-to-text
entirely. Your speaker turns become the diarization and your speaker names are used
verbatim, so the analysis comes back attributed to real participants rather than
"Speaker 1" / "Speaker 2" — and you are not billed for the transcription stage.
A `start_millis`/`end_millis` trim is rejected: we would not have media your
timestamps line up with. A `media_url` source is accepted — the download runs
first and your transcript is applied once processing completes; that
response's `status` is `queue`. After that apply we deliver `callback_url`
(success or failure). A file or presigned upload applies in the same
request and reports `processing`. The response reports `speaker_count` so you
can see how many speakers we read out of what you sent.

**Recording type:**
Pass `audio_type=contact_center_call` to tag a support/sales call at upload.
`POST /v1/audios` does not accept `audio_type` — tag afterwards with
`PUT /v1/audios/{id}/audio-type`. A call uploaded as video starts generic;
PUT the companion audio id after processing completes (`POST /v2/videos`
does not take `audio_type` either).

## Request body `multipart/form-data`

- BodyUploadAudioV2AudiosPost
  - `title` string, required: A descriptive title for your audio (e.g., 'Customer Call' or 'Team Meeting').
  - `description` string: Optional notes about the audio content or context.
  - `media_url` string: URL to your audio/video source (YouTube, Instagram, Twitter, Facebook, Dropbox, or any direct media link). Audio will be extracted if source is video. Leave empty if uploading a file instead.
  - `start_millis` number: Start point in milliseconds to begin analysis. Use 0 to start from the beginning. If provided (>0), end_millis is required with minimum 1-second (1000ms) gap.
  - `end_millis` number: End point in milliseconds to stop analysis. Use 0 only when analyzing the full audio (start_millis must also be 0). If start_millis is provided, end_millis is required and must be at least 1000ms greater than start_millis.
  - `callback_url` string: Your webhook URL to receive a notification when analysis completes. Must be an https URL on a publicly reachable host.
  - `audio_file` string, binary: Upload an audio file directly (mp3, wav, aac, m4a). File upload takes priority over media_url.
  - `diarization` boolean: Speaker diarization. Enabled by default. Disabling this stage reduces the per-second credit cost.
  - `text_emotion` boolean: Text emotion analysis. Enabled by default. Requires a transcript: ignored (forced off) when transcription is disabled and you supply no `transcript`. Supplying a `transcript` is the exception — the words already exist, so this is honoured as you sent it. Disabling this stage reduces the per-second credit cost.
  - `transcription` boolean: Transcript / ASR generation. Enabled by default. When disabled, no transcript is produced and text_emotion is forced off. Supplying a `transcript` overrides this field entirely: our ASR is skipped either way, but your transcript is used and text_emotion still applies. Disabling this stage reduces the per-second credit cost.
  - `language` string, nullable: Language code for analysis. Auto-detected if not provided. With `expected_languages` it must be one of them.
  - `multilingual` boolean: Opt in to mixed-language transcription: the speech may switch language, and each stretch is transcribed in the language it is spoken in. Once the audio completes, the lines that are not in its main language are also translated into the main language and billed as a translation, on top of transcription (`auto_translation` reports it). This is input only; the languages actually detected are reported separately.
  - `expected_languages` string, nullable: Comma-separated codes of the languages the audio may contain, the main one included (e.g. `en,ja`), 1 to 5 after duplicates are removed. Case and whitespace are ignored, a region is dropped (`pt-BR` is `pt`) and an alias maps to the Whisper spelling (`iw` is `he`); Cantonese is `yue`. Language detection is restricted to the set, with or without `multilingual`. If `language` is also sent it must be one of them (422 `invalid_language` otherwise). If `language` is omitted, detection still runs, restricted to the set. An unknown code, or more than 5, is refused with 422 `invalid_language` before anything is charged.
  - `transcript` string: Optional: a transcript you already have for this audio. When supplied we skip our own speech-to-text, use your transcript's speaker turns as the diarization, and name the speakers from it — so results come back with real participant names. Supplying one overrides `transcription`: our ASR is skipped either way, and you are charged less because that stage is not billed. A start_millis/end_millis trim is rejected: timestamps would not line up with the trimmed audio. A media_url source is accepted — we download it first, then apply your transcript once processing completes. That apply then delivers `callback_url` (success or failure). An uploaded file has no download wait: it applies in the same request and its callback fires normally.
  - `transcript_format` string: Format of `transcript`. 'auto' (the default) detects it. Supported: 'auto', 'text', 'tldv_json', 'teams_vtt', 'zoom_vtt', 'vtt', 'srt'. Works with tl;dv, Zoom, Microsoft Teams, Otter, Fathom, Tactiq and most .vtt/.srt exports. Google Meet's own transcript is not supported yet — it timestamps only every 5 minutes, which cannot be aligned to the audio.
  - `transcript_offset_millis` integer: Milliseconds added to every timestamp in `transcript` to place it on the media timeline. Positive means the transcript starts later than the recording (transcription began after record). Negative means it starts earlier (transcription running before record). 0 (the default) is today's behaviour. A negative offset that places any turn before 0 ms is rejected. Ignored when no `transcript` is supplied.
  - `audio_type` 'generic' | 'contact_center_call': Declared recording type (not a file format). 'generic' (the default) is a generic recording: no stance pass. 'contact_center_call' marks a support/sales call so speaker roles and stance analysis can apply. Omit (or send empty) for generic. Unrecognised values — including the spelling 'contact_centre_call' — are rejected. A call uploaded as video starts generic; PUT the companion audio id after processing completes. POST /v1/audios does not accept audio_type — tag afterwards via PUT /v1/audios/{id}/audio-type.

## Response `200`

Successful Response

- AudioEmotionResponseV2: V2 response model for audio emotion detection with URL source tracking. Supports: - YouTube URLs (audio extracted from video) - Cloud storage URLs (Dropbox, direct URLs, etc.) - Time parameters for all URL types - URL source tracking with media type detection Attributes: id (str): Unique ID of the audio. title (str): Title of the audio. status (str): Processing status (queue, processing, done, etc.). duration (int): Duration in seconds (trimmed duration if time params provided). media_source (str): Source type ("youtube", "dropbox", "public_url", "file_upload"). media_source_url (str): Full URL as provided by user. media_source_type (str): Type of source media ("video" or "audio"). user_id (str): ID of the user who uploaded the audio. created_at (Optional[str]): Timestamp when audio was created.
  - `id` string, required
  - `title` string, required
  - `status` string, required
  - `duration` integer, required
  - `media_source` string, required
  - `media_source_url` string, required
  - `media_source_type` string, required
  - `user_id` string, required
  - `created_at` string, nullable
  - `diarization` boolean, nullable
  - `text_emotion` boolean, nullable
  - `transcription` boolean, nullable
  - `speaker_count` integer, nullable

## Other responses

- `422`: Validation Error

## Changes

- **2026-10-31** `bd825cd86e8c`: 2 info
  - added the new optional request property `expected_languages`
  - added the new optional request property `multilingual`
- **2026-09-22** `536bf48bb9fb`: 3 info
  - the endpoint scheme security `ApiKeyAuth` was added to the API
  - the endpoint scheme security `BearerAuth` was added to the API
  - the endpoint scheme security `OAuth2Delegated` was added to the API
- **2026-09-08** `b10651168511`: 2 info
  - added the new optional request property `audio_type`
  - the `audio_file` request property type was generalized from no type to `string`, and format from no format to `binary`
- **2026-08-20** `74ceee4a5c98`: 2 warning, 11 info
  - removed the request property `speaker_diarization`
  - removed the request property `text_emotion_analysis`
  - added the new optional request property `diarization`
  - added the new optional request property `text_emotion`
  - …9 more

[Operation history](https://skmtc.dev/imentiv/apis/welcome-to-imentiv-ai/changes/v2/audios/post.md)

---

[API](https://skmtc.dev/imentiv/apis/welcome-to-imentiv-ai.md) - [All operations](https://skmtc.dev/imentiv/apis/welcome-to-imentiv-ai/llms.txt) - [OpenAPI document](https://skmtc.dev/imentiv/apis/welcome-to-imentiv-ai/revisions/bc15cec7e794?raw)
