# Audio API Developer Guide

Source: https://dev.arcxp.com/audio-center/developer-docs/arc-audio-api-developer-guide/

Developer guide for Arc XP's Audio API.

**API Reference:** [View the complete Arc XP Audio API specification](https://dev.arcxp.com/api/content-administration/audio-api/)

## Introduction

The Arc XP Audio API provides management, processing, and delivery tools for audio content.

- Audio file upload, processing, and metadata management
- Playlist, podcast, and episode management, including RSS feed generation
- Text-to-speech audio generation and full-text search across all content types
- Real-time processing notifications and waveform data for visualization

## Use the API

New to the Arc XP Audio API and looking for a quick start? Check out the tutorials for [creating an audio clip](https://dev.arcxp.com/audio-center/tutorials/creating-an-audio-clip/), [creating a podcast](https://dev.arcxp.com/audio-center/tutorials/creating-a-podcast/), [creating a playlist](https://dev.arcxp.com/audio-center/tutorials/creating-a-playlist/), [text-to-speech](https://dev.arcxp.com/audio-center/tutorials/text-to-speech/), or [extracting audio from video](https://dev.arcxp.com/audio-center/tutorials/extracting-audio-from-video/).

### Base URL structure

The API endpoint follows this pattern:

```
https://api.[org].arcpublishing.com/audiocenter/api/editorial
```

Replace `[org]` with your organization identifier. Different environments use subdomains:

- Production: `https://api.[org].arcpublishing.com/audiocenter/api/editorial`
- Sandbox: `https://api.sandbox.[org].arcpublishing.com/audiocenter/api/editorial`

### Authentication

All API requests require authentication by using a Bearer token in the `Authorization` header.

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/
```

Retrieve API tokens from the Arc Developer Center. Read more about the developer center [here](https://dev.arcxp.com/api/accessing-arcxp-apis/).

### Audio types

The API supports three high-level types:

- Audio Clips: general purpose audio; most use cases will fall under this category.
- Audio Playlists: a logical collection of audio clips.
- Podcasts: RSS-based podcast feeds with episodes, following the [Apple Podcasts RSS specification](https://podcasters.apple.com/support/823-podcast-requirements).

### Supported file formats

| WAV                              | MP3                               | FLAC                      | M4A                        | MP4                                         |
| -------------------------------- | --------------------------------- | ------------------------- | -------------------------- | ------------------------------------------- |
| Only supported for source audio. | Common compressed delivery format | Lossless compressed audio | AAC audio in MP4 container | Video (audio track extracted automatically) |

> **Note:**
> 
> Though we support transcoding or encoding of already-compressed content, we recommend LPCM WAV files for optimal quality. We also support MP3 for source files; in this case, we recommend bit rates of at least 128 kbps.

> **Tip:**
> 
> The API accepts MP4 video files as input. It automatically extracts the audio track and discards the video stream. See the [extracting audio from video](https://dev.arcxp.com/audio-center/tutorials/extracting-audio-from-video/) tutorial for details.

### Common operations

### Audio clips

### List audio clips

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/
```

### Filter results

You can filter clips by using query parameters:

- `include_tags` / `exclude_tags`: Filter by tags
- `processing_status`: Filter by `create`, `processing`, `ready`, or `failed`
- `publishing_status`: Filter by `not_published`, `published`, `scheduled`, `pending`, or `failed`
- `sites`: Filter by site IDs
- `creator` / `last_edited_by`: Filter by the actor who created or last edited the clip
- Date filters: `created_after`, `created_before`, `updated_after`, `updated_before`

### Pagination

The API supports pagination by using the `max_results` query parameter, which defaults to 10 (up to 100). For better performance, we recommend keeping this value at 10\. If more results exist, the response body includes a `next_page_token` field.

To fetch the next page of results, repeat the request with the `page_token` query parameter set to the value of `next_page_token`.

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/?page_token=YOUR_TOKEN&max_results=20"
```

> **Note:**
> 
> The page token will _not_ preserve filters; you must supply the same filters for consistent results.

### Get an audio clip

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/{audio_id}
```

### Create an audio clip

Creation returns a `201 Created` status with the resource URL in the `Location` header.

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/ \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My New Audio Clip",
    "description": "A description of the clip",
    "tags": ["news"]
  }'
```

### Upload audio file

The recommended way to attach audio to an existing clip record uses the two-step presigned-URL flow: request a presigned URL, then upload the file bytes directly to it.

Terminal window

```bash
curl -X POST "https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/{audio_id}/upload/presigned?file_name=audio.mp3" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

The response includes an `upload_url` for the direct upload and a `notification_url` for processing updates. Upload the file bytes to the returned URL as a second step:

Terminal window

```bash
curl -X PUT "PRESIGNED_UPLOAD_URL" \
  -H "Content-Type: audio/mp3" \
  --upload-file /path/to/your/file.mp3
```

The presigned URL’s signature covers `Content-Type: audio/{extension}`, where `extension` denotes the file extension you passed as `file_name` (for example, `audio/wav`, `audio/flac`, `audio/m4a`, or `audio/mp4` for a video file uploaded for audio extraction). This value must match the `Content-Type` header on your `PUT` request exactly, or the upload fails with a signature error.

After the upload completes, subscribe to the `notification_url` or retrieve the clip record to check processing status.

> **Deprecated:**
> 
> The following deprecated endpoint stays available for backward compatibility only. Prefer the presigned-URL flow described earlier.
> 
> Terminal window
> 
> ```bash
> curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/{audio_id}/upload \
>  -H "Authorization: Bearer YOUR_API_TOKEN" \
>  -F "file=@/path/to/your/audio.mp3"
> ```

### Publish an audio clip

Once the audio record reaches `ready` state, you can publish it.

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/{audio_id}/publish \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Scheduled publishing

You can schedule a clip for future publication by providing the `schedule_at` query parameter with a UTC ISO 8601 timestamp.

Terminal window

```bash
curl -X POST "https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/{audio_id}/publish?schedule_at=2025-12-25T12:00:00Z" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Unpublish an audio clip

Remove a published clip from delivery. As with publish, it accepts an optional `rendition` and a `schedule_at` query parameter (a time zone-aware timestamp) to unpublish at a future time, and streams progress when called with `Accept: text/event-stream`.

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/{audio_id}/unpublish \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Retrieve the audio file or waveform

Get a deliverable for a clip: a CDN URL for the encoded audio, and optionally its waveform data. Pass `rendition` (defaults to `aac-standard`) to select a rendition, and `waveform=true` to include the condensed amplitude data set.

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/{audio_id}/binary?waveform=true"
```

The response has the `uri` for the audio and, when requested, `waveform` data. For public playback delivery (authenticated with your Arc XP API token through an `x-api-key` header instead of the editorial API’s Bearer token), see the [Delivery / Playback API](https://dev.arcxp.com/audio-center/developer-docs/delivery-playback-api/).

### Playlists

Playlists group audio clips into an ordered collection. For a step-by-step walkthrough, see the [playlist tutorial](https://dev.arcxp.com/audio-center/tutorials/creating-a-playlist/).

### List playlists

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/playlists/
```

### Create a playlist

Include a list of clip IDs with their positions:

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/playlists/ \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "clip_id": "first_clip_id", "position": 1 },
      { "clip_id": "second_clip_id", "position": 2 }
    ],
    "tags": ["morning-news"]
  }'
```

### Update a playlist

Use `PATCH` for partial updates or `PUT` for full replacement:

Terminal window

```bash
curl -X PATCH https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/playlists/{playlist_id} \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "clip_id": "second_clip_id", "position": 1 },
      { "clip_id": "first_clip_id", "position": 2 }
    ]
  }'
```

### Delete a playlist

Terminal window

```bash
curl -X DELETE https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/playlists/{playlist_id} \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

> **Note:**
> 
> Deleting a playlist does not delete the audio clips it has.

### Text-to-speech

The API can generate spoken audio from text input. For a full walkthrough including voice preview and pronunciation dictionaries, see the [text-to-speech tutorial](https://dev.arcxp.com/audio-center/tutorials/text-to-speech/).

### List available voices

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/settings/voices
```

This returns the full catalog of voices available to your account. Of those, only voices already added to your organization’s settings are valid for previewing or generating speech. Fetch `GET /settings` and read `tts_settings.voices` for the `id` values that actually work, or add a catalog voice to your settings first (see [Configure Voices](https://dev.arcxp.com/audio-center/tutorials/text-to-speech/#configure-voices) in the text-to-speech tutorial).

### Preview a voice

Generate a short (\~10 second) audio sample without creating a clip record:

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/tts/preview \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "input_text": "A short sample of this voice.",
    "voice_id": "voice_abc123"
  }'
```

### Generate an audio clip from text

Creates a new audio clip and starts text-to-speech synthesis in a single request:

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/clips/tts \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Article Narration",
    "input_text": "The full text to be narrated, up to 30,000 characters.",
    "voice_id": "voice_abc123"
  }'
```

Pronunciation dictionaries configured for your organization apply automatically; see the [Pronunciation Dictionaries](https://dev.arcxp.com/audio-center/tutorials/text-to-speech/#pronunciation-dictionaries) section of the text-to-speech tutorial. The request accepts a `pronunciation_ids` field, but it has no effect: only the organization-level dictionary applies.

> **Tip:**
> 
> The podcast API also supports generating an episode through text-to-speech (TTS); see [Create an episode through TTS](#create-an-episode-via-tts).

As with other async operations, include `Accept: text/event-stream` to receive Server-Sent Events (SSE) progress updates.

### Podcasts

Podcasts use RSS feeds with episodes. The API handles RSS generation and feed delivery. For a step-by-step walkthrough, see the [podcast tutorial](https://dev.arcxp.com/audio-center/tutorials/creating-a-podcast/).

### List podcasts

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/
```

### Filter results

You can filter podcasts by using query parameters:

- `include_tags` / `exclude_tags`: Filter by tags
- `sites`: Filter by site IDs
- Date filters: `created_after`, `created_before`, `updated_after`, `updated_before`

### Get a podcast

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}
```

### Create a podcast

Include channel metadata that defines the podcast’s RSS feed identity. You must supply a `title`, `description`, `image`, and at least one [iTunes category](https://podcasters.apple.com/support/1691-apple-podcasts-categories).

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/ \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": {
      "title": "My Podcast",
      "description": "A podcast about interesting topics.",
      "image": { "href": "https://example.com/artwork.jpg" },
      "categories": [{ "text": "Technology" }]
    }
  }'
```

You can retrieve the full list of supported categories from the categories endpoint:

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/meta/podcasts/categories
```

### Update a podcast

Use `PATCH` for partial updates or `PUT` for full replacement:

Terminal window

```bash
curl -X PATCH https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id} \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": {
      "title": "Updated Podcast Title",
      "description": "Updated description.",
      "image": { "href": "https://example.com/artwork.jpg" },
      "categories": [{ "text": "Technology" }]
    }
  }'
```

### Publish / unpublish a podcast

Publishing makes the podcast’s RSS feed available on the public internet. Once published, you can submit the feed URL to directories like [Apple Podcasts](https://podcasters.apple.com/) and Spotify.

Terminal window

```bash
# Publish
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}/publish \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Unpublish
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}/unpublish \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Delete a podcast

Terminal window

```bash
curl -X DELETE https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id} \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Episodes

Episodes belong to a podcast. Each episode maintains a separate audio upload, processing lifecycle, and publish state, independent of the podcast and other episodes.

### Create an episode

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}/episodes \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Episode 1: Getting Started",
    "description": "In this episode we cover the basics."
  }'
```

### Create an episode via TTS

Instead of uploading audio, you can generate an episode’s audio from text in a single request. You must supply `title`, `description`, `input_text`, and `voice_id`. The request also accepts `pronunciation_ids`, but it has no effect: only your organization’s configured pronunciation dictionary applies.

Terminal window

```bash
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}/episodes/tts \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Episode 2: Deep Dive",
    "description": "Generated narration.",
    "input_text": "The full text to be narrated.",
    "voice_id": "voice_abc123"
  }'
```

As with clip TTS, include `Accept: text/event-stream` to receive SSE progress.

### Upload episode audio

As with audio clips, the recommended approach uses the two-step presigned-URL flow:

Terminal window

```bash
curl -X POST "https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}/episodes/{episode_guid}/upload/presigned?file_name=episode.mp3" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

The response includes an `upload_url` for the direct upload and a `notification_url` for processing updates. Upload the file bytes to the returned URL as a second step:

Terminal window

```bash
curl -X PUT "PRESIGNED_UPLOAD_URL" \
  -H "Content-Type: audio/mp3" \
  --upload-file /path/to/your/file.mp3
```

The presigned URL’s signature covers `Content-Type: audio/{extension}`, where `extension` denotes the file extension you passed as `file_name` (for example, `audio/wav`, `audio/flac`, `audio/m4a`, or `audio/mp4` for a video file uploaded for audio extraction). This value must match the `Content-Type` header on your `PUT` request exactly, or the upload fails with a signature error.

After the upload completes, subscribe to the `notification_url` or retrieve the episode record to check processing status.

> **Deprecated:**
> 
> The following deprecated endpoint stays available for backward compatibility only. Prefer the presigned-URL flow described earlier.
> 
> Terminal window
> 
> ```bash
> curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}/episodes/{episode_guid}/upload \
>  -H "Authorization: Bearer YOUR_API_TOKEN" \
>  -F "file=@/path/to/episode.mp3"
> ```

### Publish / unpublish an episode

Publishing an episode automatically publishes the podcast’s RSS feed as well. The feed includes only individually published episodes: publishing one episode never causes unpublished episodes to appear. The feed has only the episodes you have published.

Terminal window

```bash
# Publish
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}/episodes/{episode_guid}/publish \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Unpublish
curl -X POST https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/podcasts/{podcast_id}/episodes/{episode_guid}/unpublish \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

### Settings

Organization-level settings control how the API encodes and delivers audio. Use the settings endpoint to view and customize encoding profiles for your tenant.

### Get settings

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/settings/
```

Returns the current encoding profiles and text-to-speech settings for your organization.

### Encoding profiles

Encoding profiles control which audio format the API produces when you upload audio. You can configure profiles independently for audio clips and podcast episodes.

| Profile      | Codec | Bit Rate | Output Format | Description                                       |
| ------------ | ----- | -------- | ------------- | ------------------------------------------------- |
| aac-standard | AAC   | 128 kbps | .m4a          | Default. Good balance of quality and file size.   |
| aac-quality  | AAC   | 256 kbps | .m4a          | Higher quality AAC for premium content.           |
| mp3-standard | MP3   | 128 kbps | .mp3          | Standard MP3 for broad compatibility.             |
| flac         | FLAC  | Lossless | .flac         | Lossless compression. Not available for podcasts. |

Both `audio_clip` and `podcast` default to `aac-standard`.

> **Note:**
> 
> Encoding profiles for podcasts support only AAC and MP3 formats and exclude FLAC.

### Update encoding profiles

Use `PATCH` to update one or both encoding profiles:

Terminal window

```bash
curl -X PATCH https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/settings/ \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "encoding_profiles": {
      "audio_clip": "aac-quality",
      "podcast": "mp3-standard"
    }
  }'
```

The response confirms the updated settings:

```json
{
  "encoding_profiles": {
    "audio_clip": "aac-quality",
    "podcast": "mp3-standard"
  },
  "tts_settings": { ... }
}
```

> **Tip:**
> 
> Changing an encoding profile affects all **future** uploads. The API does not re-encode existing audio that has already finished processing.

### Search

The API provides full-text search across audio clips, playlists, and podcasts.

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/search/?text=breaking+news"
```

### Filter by content type

By default, search returns all content types you have permission to view. To restrict results to specific types, use the `content_types` parameter:

Terminal window

```bash
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.[org].arcpublishing.com/audiocenter/api/editorial/v1/search/?text=interview&content_types=AudioClip&content_types=Podcast"
```

Supported values: `AudioClip`, `AudioPlaylist`, `Podcast`.

### More filters

Search supports the same filtering parameters as the list endpoints:

- `include_tags` / `exclude_tags`: Filter by tags
- `sites`: Filter by site IDs
- Date filters: `created_after`, `created_before`, `updated_after`, `updated_before`

Search results also support pagination through `max_results` and `page_token`.

## API concepts

### Operation conventions

### Creation

- Creation operations return a 201 response including the ID of the new resource, and a `Location` header pointing to the new resource.
- The presigned-upload flow (recommended) doesn’t take an `Accept: text/event-stream` header itself — subscribe to the `notification_url` it returns for streaming progress instead. The older direct-upload endpoints (deprecated) do return an SSE stream when you supply `Accept: text/event-stream`.

### Reading

- Get-many operations return up to `max_results` items and a continuation token (if applicable). The continuation token will not preserve filters, so make sure to reuse filters for consistent results.
- You can sort list and search results with `sort_field` (`created_at` (default), `updated_at`, `title`, `score`, or `_id`) and `sort_direction` (`asc` or `desc`, default `desc`).

### Destruction

- Deleting a record marks its binaries for removal. An async process permanently purges these binaries within 30 days. If you need a binary recovered, contact support. We do not guarantee binary recovery.

### Date and time conventions

All date and time values in the Audio API **must** include [ISO 8601](https://en.wikipedia.org/wiki/ISO%5F8601) time zone information.

For example, `2025-12-25T12:00:00Z` represents December 25, 2025, at 12:00 UTC.

The API always returns date and time values in UTC.

### Examples

```javascript
new Date().toISOString();
```

```python
datetime.now(UTC).isoformat()
```

### Metadata

We do not currently synchronize audio clip and podcast tags with the Arc XP Tags API. For now, we use these tags only for filtering and organization.

### Renditions

Each audio record can have a set of “renditions” associated with it: the encoded, deliverable versions of the audio. The original source file is never included in `renditions`; see `can_normalize` under [Response Fields](#response-fields).

Your organization’s [encoding profile](#encoding-profiles) determines the format of the delivery rendition. By default, the API encodes audio as AAC at 128 kbps (`aac-standard`).

### Response fields

Clip and episode responses include their metadata plus lifecycle and capability fields. A few merit closer attention (see the API specification for the full schema):

- `processing_status` and `publishing_status`: the lifecycle states described below.
- `duration`: length in seconds, derived from the file once processed.
- `renditions`: the available encoded renditions.
- `ai_generated`: `true` when text-to-speech produced the audio rather than an upload.
- `can_normalize`: `true` when you can loudness-normalize the item in place. The original source file is not exposed in `renditions`, so clients must rely on this flag to decide whether to offer the [normalize](https://dev.arcxp.com/audio-center/developer-docs/audio-studio-api/) action.

### Audio lifecycle

Audio records have two lifecycle states:

- processing status
- publishing status

### Processing state

An audio record with no attached binary starts in a `create` state. After you add an audio binary, the API moves the record to `processing`. Once the API finishes preparing the audio data for delivery, the record moves to `ready`. Note that waveform data is not available until the audio record reaches `ready` state.

If the API encounters an error during processing, the record moves to `failed` state.

(These are the exact values returned in the record’s `processing_status` field and accepted by the `processing_status` filter.)

### Processing notifications via server-sent events

If you call the upload endpoint with `Accept: text/event-stream`, instead of immediately returning a JSON response, the API streams Server-Sent Events (SSE) with progress notifications as it processes the audio.

These represent workflow-level notifications, distinct from the stored processing status on the record. The notifications include:

- `encoding_started`: Encoding has begun.
- `encoding_analyzing`: Audio analysis is in progress.
- `encoding_complete`: Encoding finished successfully.
- `encoding_failed`: An error occurred during encoding.

For text-to-speech operations, the API also emits these notifications:

- `tts_started`, `tts_analyzing_text_complete`, `tts_generating_speech`, `tts_generating_speech_complete`, `tts_failed`

### Publishing state

You can only publish audio records that are in the `ready` processing state.

The `publishing_status` field starts as `not_published`. It becomes `published` when you publish the record, `scheduled` if you schedule a future publish, and `pending` while a publish is actively running.

If the API encounters an error during publishing, the record moves to `failed` state.

(These are the exact values returned in the record’s `publishing_status` field and accepted by the `publishing_status` filter.)

> **Tip:**
> 
> To replace a published audio file, upload a new binary. The API automatically triggers publishing again if the clip is already marked as published.

> **Note:**
> 
> Episodes follow the same processing and publishing lifecycle as audio clips. Additionally, the podcast itself has a separate publish state that controls whether the RSS feed is publicly available.

### Scheduled publishing

As detailed in the [common operations](#scheduled-publishing) section, you can schedule audio publishing ahead of time. Generally, we place no restriction on how far in the future you can set a schedule, but we recommend keeping it within a month.

### Waveforms

The Audio API provides binned and quantized representations of the audio file’s sonic data. Typically, the API bins this data to 100 units and quantizes it to int16; avoid using it for high-fidelity edit or analysis operations.

This waveform data supports visualization tools, such as the Arc XP Audio Player. We do not guarantee the schema of this data.
