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

# Cancel Upload

> Cancel an in-progress upload.

<Info>
  **Permission Required**: `project:manage-build-storage`
</Info>

Cancel an in-progress upload. This is especially useful for multipart uploads where you want to abort before completion.

## Query Parameters

<ParamField query="build_id" type="string" required>
  Build ID to cancel
</ParamField>

<ParamField query="object_key" type="string" required>
  Object key from [initiate upload](/api-reference/builds/initiate-upload) response
</ParamField>

<ParamField query="upload_id" type="string">
  Upload ID (required for multipart uploads)
</ParamField>

## Response

<ResponseField name="success" type="boolean" required>
  Always `true` on successful cancellation
</ResponseField>

<RequestExample>
  ```bash cURL (Single-Part) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  curl -X DELETE "https://nunu.ai/api/v1/project/your-project-id/builds/upload?build_id=123e4567-e89b-12d3-a456-426614174000&object_key=abc123-def456/app.apk" \
    -H "X-Api-Key: YOUR_API_TOKEN"
  ```

  ```bash cURL (Multipart) theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  curl -X DELETE "https://nunu.ai/api/v1/project/your-project-id/builds/upload?build_id=123e4567-e89b-12d3-a456-426614174000&object_key=abc123-def456/app.apk&upload_id=ExampleUploadId123" \
    -H "X-Api-Key: YOUR_API_TOKEN"
  ```

  ```typescript JavaScript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  const params = new URLSearchParams({
    build_id: "123e4567-e89b-12d3-a456-426614174000",
    object_key: "abc123-def456/app.apk",
    // For multipart, also add:
    // upload_id: "ExampleUploadId123",
  });

  const response = await fetch(
    `https://nunu.ai/api/v1/project/your-project-id/builds/upload?${params}`,
    {
      method: "DELETE",
      headers: {
        "X-Api-Key": process.env.NUNU_API_TOKEN,
      },
    }
  );
  const data = await response.json();
  ```

  ```python Python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  import requests
  import os

  params = {
      "build_id": "123e4567-e89b-12d3-a456-426614174000",
      "object_key": "abc123-def456/app.apk"
      # For multipart, also add:
      # "upload_id": "ExampleUploadId123"
  }

  response = requests.delete(
      "https://nunu.ai/api/v1/project/your-project-id/builds/upload",
      headers={"X-Api-Key": os.environ["NUNU_API_TOKEN"]},
      params=params
  )
  data = response.json()
  ```
</RequestExample>

<ResponseExample>
  ```json 200 Success theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  {
    "success": true
  }
  ```

  ```json 404 Not Found theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  {
    "error": "Upload not found",
    "code": "UPLOAD_NOT_FOUND"
  }
  ```
</ResponseExample>

***

## When to Use

<CardGroup cols={2}>
  <Card title="Abort Failed Upload" icon="xmark">
    Cancel a stuck or failed upload immediately
  </Card>

  <Card title="Reclaim Storage" icon="database">
    Free up reserved storage capacity before timeout
  </Card>
</CardGroup>

## Automatic Cleanup

<Info>
  Uploads have a configurable timeout (default: 10 minutes for single-part, 60 minutes for multipart). After timeout:

  * Reserved storage capacity is reclaimed
  * Incomplete uploads are marked for cleanup
  * Partially uploaded parts are removed
</Info>

You can set a custom timeout when [initiating the upload](/api-reference/builds/initiate-upload) with the `upload_timeout` field (1-1440 minutes).


## OpenAPI

````yaml DELETE /project/{projectId}/builds/upload
openapi: 3.1.0
info:
  title: nunu.ai API
  description: >-
    The nunu.ai Public API allows you to programmatically interact with your
    projects, manage test runs, and upload builds.
  version: 1.0.0
servers:
  - url: https://nunu.ai/api/v1
security:
  - apiKeyAuth: []
paths:
  /project/{projectId}/builds/upload:
    parameters:
      - name: projectId
        in: path
        required: true
        schema:
          type: string
        description: >-
          The project ID. You can copy it from the project settings page or the
          project URL in the dashboard.
    delete:
      tags:
        - Builds
      summary: Cancel Upload
      description: Cancel an in-progress upload.
      operationId: cancelUpload
      parameters:
        - name: build_id
          in: query
          required: true
          description: Build ID to cancel
          schema:
            type: string
        - name: object_key
          in: query
          required: true
          description: Object key for the upload
          schema:
            type: string
        - name: upload_id
          in: query
          description: Upload ID (required for multipart uploads)
          schema:
            type: string
      responses:
        '200':
          description: Upload cancelled successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
        '404':
          description: Upload not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
        code:
          type: string
        details:
          type: object
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key
      description: API key for authentication

````