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

# adapt.auto_cut_down

> Fetch the current state of an auto-cut request.

Pass `?wait=true` to long-poll for up to 20 seconds, returning early once
the operation reaches `ready` or `failed`.



## OpenAPI

````yaml /openapi.json get /v1/adapt.auto_cut_down
openapi: 3.1.0
info:
  title: Soundpiece API
  description: >

    # Soundpiece API


    The Soundpiece API gives you programmatic access to Soundpiece's audio

    generation, separation, and adaptation capabilities. Generate songs from

    lyrics, separate stems from a mix, cut audio to length — anything you can do

    in the Soundpiece app, you can do over HTTP.


    This is an **RPC-style API**, similar in shape to Slack's or Stripe's APIs.

    Each endpoint is a named action like `create.new_song` or

    `adapt.separate_stems`. There are no resource hierarchies to learn — pick
    the

    action you want and call it.


    ## Getting started


    1. Get your API key from your account dashboard. Each key comes with a
    webhook
       signing secret — save both, they're shown once.
    2. Authenticate with `Authorization: Bearer <your-api-key>`.

    3. Submit work with a `PUT` to the action endpoint. You'll get back a
    response
       with `status: processing`.
    4. Poll the same endpoint with `GET` and `?wait=true` to wait up to 20
    seconds
       for the result, or use webhooks to be notified when work is done.

    ### Example: generate a song


    ```http

    PUT /rpc/create.new_song

    Authorization: Bearer <your-api-key>

    Content-Type: application/json


    {
      "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
      "lyrics": "I've been driving all night, my hands wet on the wheel",
      "prompt": "Synthwave, melancholic, mid-tempo"
    }

    ```


    You'll get back:


    ```json

    {
      "song": {
        "id": "op_01h7k...",
        "status": "processing",
        "created_at": "2026-05-20T12:34:56Z",
        "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
        "lyrics": "I've been driving all night, my hands wet on the wheel",
        "prompt": "Synthwave, melancholic, mid-tempo",
        "reference": null,
        "outputs": null,
        "error": null
      }
    }

    ```


    Poll with `GET /rpc/create.new_song?id=op_01h7k…&wait=true` until `status`
    is

    `ready` (`outputs` populated) or `failed` (`error` populated).


    ## Method shapes


    Each method is either a *command* (writes state) or a *query* (reads state).


    | Kind | Verb | Body | Notes |

    |---|---|---|---|

    | Command (idempotent) | `PUT` | JSON | Used to submit work. Include an
    `idempotency_key` to retry safely. |

    | Query | `GET` | none | Used to poll for operation state. |


    Responses are JSON unless otherwise noted.


    ## Authentication


    All endpoints require an API key passed as a Bearer token:


    ```http

    Authorization: Bearer <your-api-key>

    ```


    Keys start with the prefix `spk_` — the prefix is part of the key, so use
    the

    value exactly as the dashboard shows it. Keep keys secret — anyone with your

    key can use your account.


    You can manage keys in your account dashboard: create new ones, list
    existing

    ones, revoke compromised ones. **The key value and webhook signing secret
    are

    shown once at creation** — save them somewhere safe.


    ## Idempotency


    Every `PUT` request takes an `idempotency_key` field — a UUID you choose. If

    you send the same request twice with the same key, we return the original

    response without doing the work again. This is the safe way to retry over an

    unreliable network.


    The key is also echoed back in every response and webhook delivery, so you

    can correlate work end-to-end on your side without keeping a
    request-id-to-state

    map.


    ## Operation status lifecycle


    Every operation moves through three statuses:


    - **`processing`** — submitted; we're working on it. `output`/`outputs` and
      `error` are both `null`.
    - **`ready`** — done. The `output` (or `outputs`) field is populated.

    - **`failed`** — something went wrong. The `error` field is populated with a
      `code` and `message`.

    `output`/`outputs` and `error` are mutually exclusive — exactly one or the

    other is populated when the operation terminates.


    ## Polling vs webhooks


    Two ways to find out when an operation is done:


    **Polling** — call the same endpoint with `GET` and an `id`. Add
    `?wait=true`

    to long-poll for up to 20 seconds. Repeat if you get back `processing`.


    **Webhooks** — supply a `callback_url` in the original `PUT` request. We

    `POST` the final response to that URL when the operation reaches `ready` or

    `failed`. See the *Webhooks* section below for signature verification.


    **Polling is canonical.** Webhooks are a best-effort latency optimisation;
    if

    you didn't receive one within a reasonable window, fall back to polling.

    Don't rely on webhook receipt as proof of operation state.


    ## Downloads


    When an operation is `ready`, each output carries a signed URL you can use
    to

    download the audio as a FLAC file (44.1 kHz). These URLs are time-limited;

    check the `expires_at` field on each output. If a URL has expired, call the

    matching `get` endpoint again — we'll generate a fresh one.


    Don't cache the URL itself; it's signed against a short window. Do cache the

    audio you downloaded if you need to reuse it.


    ## Webhooks


    If you supply a `callback_url` in a `PUT` request, we'll `POST` the final

    response to that URL when the operation reaches `ready` or `failed`. The

    payload is:


    ```json

    {
      "type": "create.new_song.ready",
      "data": { "...the same DTO you'd get from polling..." }
    }

    ```


    We sign every webhook so you can verify it came from us. Each delivery

    includes three headers (following the [Standard
    Webhooks](https://www.standardwebhooks.com/)

    spec):


    - `webhook-id` — a stable id for this event. Retries reuse the same id, so
      consumers can dedupe.
    - `webhook-timestamp` — Unix seconds when we first attempted delivery.

    - `webhook-signature` — `v1,<base64(HMAC-SHA256(secret,
    "<id>.<timestamp>.<body>"))>`.
      Multiple signatures are space-separated during secret rotation.

    Verify by computing the HMAC with your signing secret and comparing in

    constant time. Reject the request if the signature doesn't match, or if the

    timestamp is more than 5 minutes from the current time.


    We retry failed deliveries with exponential backoff. `5xx` responses and

    connection errors get retried; `4xx` responses (other than `429`) fail

    immediately — fix your endpoint and we'll deliver the next one.


    ## Errors


    When an operation itself fails (e.g. the model rejected your prompt), the

    response has `status: "failed"` with a populated `error`:


    ```json

    {
      "code": "content_policy",
      "message": "The provided lyrics were rejected by our content policy."
    }

    ```


    HTTP-level errors (`4xx` / `5xx`) return a JSON body with a `detail` field —

    either a string message, or a list of `{loc, msg, type}` entries pinpointing

    which field of the request body failed validation. `5xx` responses on `PUT`

    endpoints are safely retryable — the same `idempotency_key` will land at

    most once.


    ## Versioning


    We avoid breaking changes to request and response shapes. New fields will

    appear on responses additively; deprecated fields will be marked as such
    with

    notice before removal. If an unavoidable breaking change is ever needed, it

    will be on a versioned URL path so existing clients keep working.
  version: 0.1.0
servers:
  - url: https://api.soundpiece.co
    description: Production
security: []
tags:
  - name: Create
    description: >

      Generate new audio from a prompt, reference track, or lyrics.


      Each endpoint follows the same pattern: `PUT` to submit work, `GET` to
      poll.

      The `PUT` returns immediately with `status: processing`; the `GET` returns
      the

      same DTO with updated status until it reaches `ready` or `failed`.


      Generation can take anywhere from a few seconds to a minute or so
      depending

      on length and current capacity. Use `?wait=true` on the `GET` to long-poll

      for up to 20 seconds, or supply a `callback_url` on the `PUT` to be
      notified.
  - name: Adapt
    description: >

      Transform existing audio — separate stems, cut to a target duration.


      These endpoints take an audio input as a URL (see the `AudioSource`
      schema)

      and produce a derived output. The same async-status pattern as `create.*`

      applies.
paths:
  /v1/adapt.auto_cut_down:
    get:
      tags:
        - Adapt
      summary: adapt.auto_cut_down
      description: >-
        Fetch the current state of an auto-cut request.


        Pass `?wait=true` to long-poll for up to 20 seconds, returning early
        once

        the operation reaches `ready` or `failed`.
      operationId: adapt.auto_cut_down.poll
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: string
            pattern: ^op_[0-9a-z]{26}$
            title: Id
            description: >-
              A unique identifier for an operation, prefixed `op_`. Returned
              from any `PUT` endpoint; pass it to the matching `GET` to poll, or
              use it to correlate webhook deliveries with your records.
        - name: wait
          in: query
          required: false
          schema:
            type: boolean
            description: >-
              If true, long-poll for up to 20 seconds waiting for the operation
              to reach `ready` or `failed`.
            default: false
            title: Wait
          description: >-
            If true, long-poll for up to 20 seconds waiting for the operation to
            reach `ready` or `failed`.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdaptAutoCutDownResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    AdaptAutoCutDownResponse:
      properties:
        auto_cut:
          $ref: '#/components/schemas/AutoCut'
      type: object
      required:
        - auto_cut
      title: AdaptAutoCutDownResponse
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    AutoCut:
      properties:
        id:
          type: string
          pattern: ^op_[0-9a-z]{26}$
          title: Id
          description: >-
            A unique identifier for an operation, prefixed `op_`. Returned from
            any `PUT` endpoint; pass it to the matching `GET` to poll, or use it
            to correlate webhook deliveries with your records.
        status:
          type: string
          enum:
            - processing
            - ready
            - failed
          title: Status
          description: >-
            Current state of the operation. `processing` means work is in
            flight; `ready` means the result is available (the
            `output`/`outputs` field is populated); `failed` means something
            went wrong (the `error` field is populated).
        created_at:
          type: string
          format: date-time
          title: Created At
          description: When this operation was created (ISO-8601, UTC).
        idempotency_key:
          type: string
          format: uuid
          title: Idempotency Key
          description: >-
            A unique UUID you choose. Send the same key to retry safely; we'll
            return the original response without doing the work again.
        target_duration:
          type: number
          maximum: 300
          minimum: 5
          title: Target Duration
          description: >-
            The desired output duration in seconds. This is a target, not an
            exact length — the result may be slightly shorter or longer to land
            on a natural cut point. Must be between 5 seconds and 5 minutes
            (enforced up front; out of range is a `422`), and at most twice the
            source duration. Because the source duration is only known after the
            source is fetched and decoded, exceeding twice the source surfaces
            asynchronously as a `failed` operation with
            `target_duration_too_long`. See [errors](/errors).
        output:
          anyOf:
            - $ref: '#/components/schemas/AudioOutput'
            - type: 'null'
          description: Populated when `status` is `ready`.
        error:
          anyOf:
            - $ref: '#/components/schemas/AutoCutError'
            - type: 'null'
          description: >-
            Populated when `status` is `failed`. The `code` is a stable
            machine-readable identifier; `message` is a human-readable
            description.
      type: object
      required:
        - id
        - status
        - created_at
        - idempotency_key
        - target_duration
      title: AutoCut
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    AudioOutput:
      properties:
        url:
          type: string
          maxLength: 2083
          minLength: 1
          format: uri
          title: Url
          description: >-
            A signed URL to download the audio as a FLAC file (44.1 kHz).
            Time-limited; see `expires_at`. Don't cache the URL itself.
        expires_at:
          type: string
          format: date-time
          title: Expires At
          description: >-
            When the URL stops working (ISO-8601, UTC). Call the matching `get`
            endpoint again to receive a fresh URL.
        duration:
          type: number
          title: Duration
          description: Duration in seconds.
      type: object
      required:
        - url
        - expires_at
        - duration
      title: AudioOutput
    AutoCutError:
      properties:
        code:
          anyOf:
            - type: string
              enum:
                - internal_error
                - generation_timeout
            - type: string
              enum:
                - source_unreachable
                - source_format_unsupported
                - source_too_short
                - source_too_long
                - source_too_large
            - type: string
              const: target_duration_too_long
          title: Code
          description: >-
            Stable machine-readable error code — safe to branch on. This
            endpoint can only return the codes listed here.
        message:
          type: string
          title: Message
          description: Human-readable error message.
      type: object
      required:
        - code
        - message
      title: AutoCutError
      description: >-
        Error for `auto_cut_down` — the source-transform set plus the
        target-duration

        failures (the requested cut length is out of range for the ingested
        source).

        No content-policy path, so no `tos_violation`.

````