> ## Documentation Index
> Fetch the complete documentation index at: https://developer.audioshake.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from Jobs

> Move from the legacy Jobs API to the Tasks API

The Tasks API replaces the legacy Jobs API. This page covers the key structural differences and maps every legacy concept to its equivalent so you can migrate your integration.

For a full reference of the legacy API, see the [Legacy API Reference](/legacy-api).

## The most important difference

In the legacy API, **one job processes one model**. If you needed vocals, instrumental, and drums, you submitted three separate jobs.

In the Tasks API, **one task can process multiple models**. You submit one request with a `targets` array — each target specifying a model and output format — and all outputs are produced together.

<CodeGroup>
  ```bash Legacy — 3 separate jobs theme={null}
  # Job 1: vocals
  curl -X POST "https://groovy.audioshake.ai/job" \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -d '{ "metadata": { "name": "vocals", "format": "wav" }, "assetId": "<id>" }'

  # Job 2: instrumental
  curl -X POST "https://groovy.audioshake.ai/job" \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -d '{ "metadata": { "name": "instrumental", "format": "wav" }, "assetId": "<id>" }'

  # Job 3: drums
  curl -X POST "https://groovy.audioshake.ai/job" \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -d '{ "metadata": { "name": "drums", "format": "wav" }, "assetId": "<id>" }'
  ```

  ```bash Tasks API — 1 task theme={null}
  curl -X POST "https://api.audioshake.ai/tasks" \
    -H "x-api-key: $AUDIOSHAKE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "assetId": "<id>",
      "targets": [
        { "model": "vocals", "formats": ["wav"] },
        { "model": "instrumental", "formats": ["wav"] },
        { "model": "drums", "formats": ["wav"] }
      ]
    }'
  ```
</CodeGroup>

## Concept mapping

| Legacy (Jobs API)                        | Tasks API                                                               |
| ---------------------------------------- | ----------------------------------------------------------------------- |
| Base URL: `groovy.audioshake.ai`         | Base URL: `api.audioshake.ai`                                           |
| Auth: `Authorization: Bearer TOKEN`      | Auth: `x-api-key: YOUR_KEY`                                             |
| Token via support email                  | Self-serve API keys in the [dashboard](https://dashboard.audioshake.ai) |
| `POST /upload` or `POST /upload/link`    | `POST /assets`                                                          |
| `POST /job` (one model per job)          | `POST /tasks` (multiple models per task via `targets`)                  |
| `GET /job/<id>`                          | `GET /tasks/<id>`                                                       |
| `metadata.name`                          | `targets[].model`                                                       |
| `metadata.format`                        | `targets[].formats[]` (now an array)                                    |
| `callbackUrl` in the job body            | Webhooks registered separately via `POST /webhooks`                     |
| Response wrapped in `{ "job": { ... } }` | Response is a flat task object                                          |

## Request body structure

The job request body uses a `metadata` object to specify the model and format. The Tasks API flattens this into a `targets` array.

<CodeGroup>
  ```json Legacy job body theme={null}
  {
    "metadata": {
      "name": "vocals",
      "format": "wav"
    },
    "assetId": "<asset-id>",
    "callbackUrl": "https://your-app.com/webhooks"
  }
  ```

  ```json Tasks API body theme={null}
  {
    "assetId": "<asset-id>",
    "targets": [
      { "model": "vocals", "formats": ["wav"] }
    ]
  }
  ```
</CodeGroup>

## Authentication

<CodeGroup>
  ```bash Legacy theme={null}
  curl -X GET "https://groovy.audioshake.ai/job/<id>" \
    -H "Authorization: Bearer YOUR_API_TOKEN"
  ```

  ```bash Tasks API theme={null}
  curl -X GET "https://api.audioshake.ai/tasks/<id>" \
    -H "x-api-key: $AUDIOSHAKE_API_KEY"
  ```
</CodeGroup>

Generate your Tasks API key in [Settings → API Keys](https://dashboard.audioshake.ai) — no need to contact support.

## Uploading a file

The endpoint path and field names are the same. Only the auth header changes.

<CodeGroup>
  ```bash Legacy theme={null}
  curl -X POST "https://groovy.audioshake.ai/upload" \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: multipart/form-data" \
    -F 'file=@song.mp3;type=audio/mpeg'
  ```

  ```bash Tasks API theme={null}
  curl -X POST "https://api.audioshake.ai/assets" \
    -H "x-api-key: $AUDIOSHAKE_API_KEY" \
    -H "Content-Type: multipart/form-data" \
    -F 'file=@song.mp3;type=audio/mp3'
  ```
</CodeGroup>

Both return an object with an `id` field. Use that as `assetId` in your processing request.

## Webhooks

In the legacy API, you passed `callbackUrl` inside each job request. In the Tasks API, register your endpoint once — all task completion events are then delivered automatically.

```bash theme={null}
curl -X POST "https://api.audioshake.ai/webhooks" \
  -H "x-api-key: $AUDIOSHAKE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks"
  }'
```

See [Using Webhooks](/api-reference/tasks/webhooks) for full setup details.

## Migration checklist

<Steps>
  <Step title="Generate a Tasks API key">
    Go to [Settings → API Keys](https://dashboard.audioshake.ai) and create a new key.
  </Step>

  <Step title="Update your base URL">
    Replace `https://groovy.audioshake.ai` with `https://api.audioshake.ai`.
  </Step>

  <Step title="Update authentication">
    Replace `Authorization: Bearer TOKEN` with `x-api-key: YOUR_KEY`.
  </Step>

  <Step title="Update file upload">
    Replace `POST /upload` with `POST /assets`. The response `id` field is the same — use it as `assetId`.
  </Step>

  <Step title="Consolidate jobs into one task">
    Replace each group of per-model job requests with a single `POST /tasks` request. Move each `metadata.name` into a target's `model` field, and each `metadata.format` into `formats` (as an array).
  </Step>

  <Step title="Register webhooks separately">
    If you used `callbackUrl`, register your endpoint once via `POST /webhooks` and remove `callbackUrl` from your task requests.
  </Step>

  <Step title="Update response handling">
    The legacy response wraps the job in a `{ "job": { ... } }` envelope. The Tasks API response is a flat object — update any code that reads `response.job.id` to read `response.id` instead.
  </Step>

  <Step title="Update status polling">
    Replace `GET /job/<id>` with `GET /tasks/<id>`. Output download links are in the `targets[].outputAssets` array.
  </Step>
</Steps>

## Questions?

Contact [support@audioshake.ai](mailto:support@audioshake.ai) if you run into issues during migration.
