Descript API (1.0)

Download OpenAPI specification:

License: Proprietary

Descript API documentation.

Getting started

The Descript API lets you programmatically create projects, import media, and edit your projects — all without opening the app.

To sign up for access and learn more, visit descript.com/enterprise/api-early-access.

Import media into a new project

You can create a new project, import media, and place the media into a composition all in one API request using the import endpoint. This step also transcribes and processes the media so that it's ready for you or the agent to edit.

To import files, pass in public or pre-signed URIs. Currently, the API does not support uploading a file directly. To test the API with an example file, use the demo video included in the sample request below.

Importing and processing is an asynchronous job, so the response payload will contain a job_id for you to query the status of the job and information about the newly created project. Note that project_id and project_url are returned immediately alongside job_id, but opening the project in Descript will not always show the API's processing state in real time. To prevent unintended changes, we recommend that you do not make any changes to the project until the job has stopped.

Request

curl -X POST https://descriptapi.com/v1/jobs/import/project_media \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project_name": "My First Video",
    "add_media": {
      "demo.mp4": {
        "url": "https://test-files.descriptapi.com/demo_video.mp4"
      }
    },
    "add_compositions": [
      {
        "name": "Demo Video",
        "clips": [
          { "media": "demo.mp4" }
        ]
      }
    ]
  }'

Response

{
  "job_id": "project-media-import-9d635d5b",
  "drive_id": "c9c5c47e",
  "project_id": "e2f89ce6",
  "project_url": "https://web.descript.com/e2f89ce6"
}

Check for import completion

Poll the job status endpoint using the job_id from the last step to check whether the import job is finished processing. When it is, you'll see job_state: "stopped". You can then check the results object to see its full results.

You can also pass in a callback_url as a part of the first import request, and we'll ping you when the job has stopped with the same response payload.

Request

curl https://descriptapi.com/v1/jobs/project-media-import-9d635d5b \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Response

{
  "job_id": "project-media-import-9d635d5b",
  "job_type": "import/project_media",
  "job_state": "stopped",
  "project_id": "e2f89ce6",
  "project_url": "https://web.descript.com/e2f89ce6",
  "result": {
    "status": "success",
    "media_status": {
      "main.mp4": {
        "status": "success",
        "duration_seconds": 69.477006
      }
    },
    "created_compositions": [
      { "id": "f8e5088a-4d53-4aab-9d4f-c6624b7d7622", "name": "Demo Video" }
    ]
  }
}

Prompt for edits with Agent Underlord

Once your media is imported, you can use the agent edit endpoint to prompt Underlord for edits, just as you would in the app. Because it's an API, conversation and follow up questions aren't practical. So we recommend framing your edits as a one-shot prompt with all the information the agent needs.

Editing can take some time, so the response also returns a job_id that you can use to check the status of the job. You can also pass in a callback_url as a part of an agent request, and we'll ping you when the job has stopped.

Request

curl -X POST https://descriptapi.com/v1/jobs/agent \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "e2f89ce6",
    "prompt": "Add studio sound and captions"
  }'

Response

{
  "job_id": "project-agent-edit-e2f89ce6",
  "drive_id": "c9c5c47e",
  "project_id": "e2f89ce6",
  "project_url": "https://web.descript.com/e2f89ce6"
}

Wait for the agent to complete its job

Poll the job status endpoint using the job_id. When the agent job completes successfully, the response includes a summary of what it accomplished (see the result.agent_response field). Use the project URL to open the project in Descript and review Underlord's changes.

Request

curl https://descriptapi.com/v1/jobs/project-agent-edit-e2f89ce6 \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Once the agent job is successfully complete, you’ll see a response from the agent with a brief summary of what it accomplished. You can then use the project url to review its changes directly in Descript.

Response

{
    "job_id":"project-agent-edit-e2f89ce6",
    "job_type":"agent",
  "project_id":"YOUR_PROJECT_ID",
    "project_url":"https://web.descript.com/e2f89ce6",
    "job_state":"stopped",
    "created_at":"2026-02-09T05:42:27.554Z",
    "stopped_at":"2026-02-09T05:43:15.296Z",
    "drive_id":"1df135a5-dc4a-4dc3-8f7d-681cfbe961e4",
    "result":{
        "status":"success",
    "agent_response":"Done! I've applied Studio Sound to enhance your audio quality and added classic karaoke-style captions to your video.",
        "project_changed":true,
        "media_seconds_used":0,
        "ai_credits_used":32
  }
}

Using the CLI

The CLI wraps the API into a simple to use command line tool with interactive flows for setting up authentication, importing, and prompting the agent. It also has built-in polling for job completion.

Requirements

Before installing the CLI, you'll need Node.js installed on your computer. Node.js is a JavaScript runtime that allows you to run JavaScript programs from the command line.

Required version: Node.js 24 or higher

Check if Node.js is already installed

Open your terminal (or Command Prompt on Windows) and run:

node --version

If you see a version number like v24.x.x or higher, you're all set and can skip to the next section. If you see an error or a lower version number, follow the installation steps below.

Installing Node.js

Choose the installation method for your operating system:

macOS

Option 1: Using the installer (recommended for beginners)

  1. Visit nodejs.org
  2. Download the "LTS" (Long Term Support) version
  3. Open the downloaded file and follow the installation prompts

Option 2: Using Homebrew

brew install node

Windows

  1. Visit nodejs.org
  2. Download the "LTS" (Long Term Support) version for Windows
  3. Run the downloaded installer and follow the installation prompts

Linux

Ubuntu/Debian:

# Install Node.js from NodeSource
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs

Fedora/RHEL/CentOS:

# Install Node.js from NodeSource
curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -
sudo dnf install -y nodejs

After installation, verify it worked by running node --version again.

Install and set up

First, install the latest version of the CLI using npm.

npm install -g @descript/platform-cli@latest

Next, configure the CLI with your API key.

descript-api config set api-key

Setting up the CLI

Import media

Use the import command to create a project by passing a project name and the link to any media you want to upload, or run descript-api import for interactive mode. The CLI shows live progress and outputs the project ID when done.

descript-api import \
  --name "My First Project" \
  --media "https://test-files.descriptapi.com/demo-video.mp4"

Interactive CLI import

Use the agent

Use the agent command to edit a project by passing in the project id and an Underlord prompt.

descript-api agent \
  --project-id YOUR_PROJECT_ID \
  --prompt "Remove filler words and add Studio Sound to all clips"

You can also ask Underlord create a new project from a prompt alone by writing the script for you!

descript-api edit --new \
  --prompt "Write a script about how to make great coffee"

API Endpoints

Import media, edit projects with AI, and query jobs and projects.

Import media and sequences

Import media files into a new or existing project and create compositions.

This endpoint can:

  • Create a new project if project_id is not provided
  • Import media files from URLs
  • Create multitrack sequences
  • Create compositions (timelines) from existing or new media in the project
  • Trigger transcription and other background processing tasks

Media URL requirements

  • URLs must be accessible by Descript servers
  • URLs must support HTTP Range requests
  • Recommended to sign URLs for 12-48 hours to reduce chance of failure
  • Supported file types

Async Operations

Imports run in the background and return a job_id. Monitor progress via the GET /jobs/{job_id} endpoint.

Dynamic webhook

If callback_url is provided, Descript will POST the job status to that URL when the job finishes (successfully or not).

The payload will match the format returned by GET /jobs/{job_id}.

Authorizations:
bearerAuth
Request Body schema: application/json
required

Media import and project creation request

project_id
string <uuid>

[Work in progress] Importing into an existing project is not yet supported. Currently, a new project is always created.

Existing project ID to import media into. If not provided, a new project will be created. When importing into an existing project, media filenames must not conflict with existing files.

project_name
string

Name for the new project. Only used when project_id is not provided.

team_access
string
Enum: "edit" "comment" "none"

[Work in progress] This property is not yet supported and will be ignored if provided.

Access level for the project's drive. Only applicable when creating a new project (when project_id is not provided).

  • edit: Users can edit the project
  • comment: Users can view and comment but not edit
  • none: No shared access (private to owner)
object

Map of media reference IDs (display names with optional folder paths) to media import items. Keys are the display names that will appear in the project (e.g., "Misc/intro.mp4" or "demo.mp4"). Values define how to import each media item (URL import or multitrack sequence).

Array of objects

Optional list of compositions to create in the project

callback_url
string <uri>

Optional webhook URL to call when the job completes or fails. Descript will POST the job status (same format as GET /jobs/{job_id}) to this URL.

Responses

Request samples

Content type
application/json
Example

Most common use case for seeding a project with a simple composition

{}

Response samples

Content type
application/json
{}

Agent edit

Use a background agent to create and edit projects using a natural language prompt.

  • Edit existing project: Provide a project_id to edit an existing project
  • Create new project: Provide a project_name instead of project_id to create a new project

Common use cases

  • Create new content: "create a 30-second video about cooking tips"
  • Apply audio effects: "add studio sound to every clip"
  • Remove filler words: "remove all filler words from the transcript"
  • Create highlights: "create a 30-second highlight reel"
  • Content editing: "remove the section from 1:30 to 2:15"

Async Operations

Agent edits run in the background and return a job_id. Monitor progress via the GET /jobs/{job_id} endpoint.

Dynamic webhook

If callback_url is provided, Descript will POST the job status to that URL when the job completes or fails. The payload will match the format returned by GET /jobs/{job_id}.

Authorizations:
bearerAuth
Request Body schema: application/json
required

AI agent request

project_id
string <uuid>

The ID of an existing project to edit. Mutually exclusive with project_name.

project_name
string

Name for creating a new project. Mutually exclusive with project_id.

composition_id
string <uuid>

[Work in progress] This property is accepted but not yet functional. It will be ignored.

Optional composition ID within the project to edit.

model
string

AI model to use for editing. Defaults to the default model.

prompt
required
string

Natural language instruction for the agent to execute. Examples: "add studio sound to every clip", "remove all filler words", "create a 30-second highlight reel"

callback_url
string <uri>

Optional webhook URL to call when the job completes or fails. Descript will POST the job status (same format as GET /jobs/{job_id}) to this URL.

Responses

Request samples

Content type
application/json
Example
{
  • "project_name": "Cooking Tips Video",
  • "prompt": "create a 30-second video about cooking tips with background music"
}

Response samples

Content type
application/json
{}

WIPList jobs

Work in progress — This endpoint is not yet available and will return an error if called.

List recent jobs with optional filtering by project or job type.

Query parameters allow you to filter the results:

  • Filter by project_id to see all jobs for a project
  • Filter by type to see specific job types (import/project_media, agent)
Authorizations:
bearerAuth
query Parameters
project_id
string <uuid>

Filter by project ID

type
string
Enum: "import/project_media" "agent"

Filter by job type

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    },
  • {
    },
  • {
    }
]

Get job status

Retrieve the status of any job.

The response format varies based on job type and includes type-specific fields.

Authorizations:
bearerAuth
path Parameters
job_id
required
string <uuid>

The job ID

Responses

Response samples

Content type
application/json
Example
{
  • "job_id": "6dc3f30a-58c2-4174-96a6-dc18cf3c7776",
  • "job_type": "import/project_media",
  • "job_state": "stopped",
  • "created_at": "2025-11-18T10:30:00Z",
  • "stopped_at": "2025-11-18T10:35:00Z",
  • "drive_id": "c9c5c47e-158a-49f7-846b-4f6ee2a229a2",
  • "project_id": "9f36ee32-5a2c-47e7-b1a3-94991d3e3ddb",
  • "result": {
    }
}

WIPCancel job

Work in progress — This endpoint is not yet available and will return an error if called.

Cancel a running job.

Authorizations:
bearerAuth
path Parameters
job_id
required
string <uuid>

The job ID

Responses

Response samples

Content type
application/json
{
  • "error": "unauthorized",
  • "message": "Missing or invalid authentication token"
}

Check API status

Work in progress — This endpoint is not yet available and will return an error if called.

Check API availability and validate authentication token.

This endpoint can be used to:

  • Verify that your authentication token is valid
  • Check API connectivity without performing any heavy operations

Returns a success response if the token is valid, or a 401 error if the token is invalid or missing.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "status": "ok"
}

Authentication

Descript API uses a personal token to authenticate your request. You can get your personal token by contacting us.

The personal token should be used as a bearer token in the authorization header.

Example

curl -H "authorization: Bearer ${YOUR_PERSONAL_TOKEN}" -d @datafile.json https://descriptapi.com/v1/edit_in_descript/schema

Rate Limiting

The Descript API implements rate limiting to ensure fair usage and protect service availability. When you exceed the rate limit, the API returns a 429 Too Many Requests response.

Rate Limit Headers

When a rate limit is exceeded, the response includes the following headers:

Header Description
Retry-After Number of seconds to wait before retrying the request
X-RateLimit-Remaining Number of requests remaining in the current window
X-RateLimit-Consumed Number of requests consumed in the current window

Handling Rate Limits

When you receive a 429 response, use the Retry-After header to determine how long to wait before retrying. This approach is more efficient than using fixed delays or exponential backoff alone.