Skip to main content
POST
https://api.zipkit.io
/
api
/
v1
/
zips
curl -X POST https://api.zipkit.io/v1/zips \
  -H "Authorization: Bearer your-access-token" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      {
        "url": "https://app.zipkit.io/onboarding/success.jpg",
        "filename": "success.jpg"
      },
      {
        "url": "https://app.zipkit.io/onboarding/welcome.txt",
        "filename": "welcome.txt"
      }
    ],
    "bucket_name": "my-bucket",
    "key": "example.zip",
    "service": "s3",
    "metadata": {
      "user_id": "user_123",
      "order_id": "order_456"
    }
  }'
{
  "data": {
    "uuid": "clx7g2m4p0000xyz123abc",
    "status": "none",
    "metadata": {
      "user_id": "user_123",
      "order_id": "order_456"
    }
  }
}

Overview

The Create Zip endpoint accepts a list of URLs pointing to remote files, downloads them, bundles them into a zip archive, and uploads the result to your configured cloud storage bucket. Zip creation is asynchronous - the endpoint returns immediately with a job ID, and the actual processing happens in the background.

Endpoint

POST /api/v1/zips

Authentication

Requires a valid access token in the Authorization header:
Authorization: Bearer YOUR_ACCESS_TOKEN
See Authentication for details.

Request Body

urls
array
required
An array of file objects to include in the zip archive. Each object specifies a URL to fetch and the desired filename in the zip.Structure: Each object must contain:
  • url (string, required): URL to fetch the file from. Must be publicly accessible.
  • filename (string, required): Desired filename for this file in the zip archive.
Requirements:
  • At least 1 file object required
  • Files will be included in the zip in the order provided
Example:
[
  {
    "url": "https://example.com/documents/report.pdf",
    "filename": "monthly-report.pdf"
  },
  {
    "url": "https://example.com/images/photo.jpg",
    "filename": "header-image.jpg"
  }
]
bucket_name
string
required
The name of the S3 or R2 bucket where the zip archive will be stored. This must match a bucket you’ve configured in your project settings.
key
string
required
The filename for the zip archive in your bucket.Example: "reports/monthly-report-2025-11.zip"
service
string
The cloud storage service to use. Defaults to "s3" if not specified.Options:
  • "s3" - AWS S3 (default)
  • "r2" - Cloudflare R2
metadata
object
Custom metadata to attach to this zip. Accepts any valid JSON object. This metadata will be:
  • Stored with the zip in the database
  • Returned in all API responses (POST and GET)
  • Included in webhook payloads when the zip completes
Use cases:
  • Track internal references (user IDs, order IDs, etc.)
  • Store custom identifiers for your application
  • Pass through contextual information to webhook handlers
Example:
{
  "user_id": "user_123",
  "order_id": "order_456",
  "reference": "Q4-2025"
}
curl -X POST https://api.zipkit.io/v1/zips \
  -H "Authorization: Bearer your-access-token" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      {
        "url": "https://app.zipkit.io/onboarding/success.jpg",
        "filename": "success.jpg"
      },
      {
        "url": "https://app.zipkit.io/onboarding/welcome.txt",
        "filename": "welcome.txt"
      }
    ],
    "bucket_name": "my-bucket",
    "key": "example.zip",
    "service": "s3",
    "metadata": {
      "user_id": "user_123",
      "order_id": "order_456"
    }
  }'
{
  "data": {
    "uuid": "clx7g2m4p0000xyz123abc",
    "status": "none",
    "metadata": {
      "user_id": "user_123",
      "order_id": "order_456"
    }
  }
}
data
object
The response data object containing zip information.
data.uuid
string
Unique identifier (UUID) for this zip job. Use this to retrieve the zip status via GET /api/v1/zips/:id.
data.status
string
Current status of the zip job. Will be "none" when first created.Possible values:
  • none - Job created, not yet started processing
  • processing - Currently downloading files and creating zip
  • succeeded - zip successfully created and uploaded to your bucket
  • failed - Job failed during processing
data.metadata
object
The custom metadata object provided in the request. Returns the exact metadata you sent, or an empty object {} if none was provided.

Zip Creation Process

After you create a zip job, ZipKit performs these steps asynchronously:
  1. Validates the bucket ID and URLs
  2. Downloads each file from the provided URLs
  3. Creates a zip archive containing all downloaded files
  4. Uploads the zip to your configured cloud storage bucket
  5. Sends a webhook notification (if configured)
The entire process typically takes a few seconds to a few minutes, depending on:
  • Number of files
  • Size of files
  • Network speed when downloading from source URLs
  • Upload speed to your cloud storage

Checking Status

The Create Zip endpoint returns immediately - it doesn’t wait for the zip to be created. To check the status: Use webhooks (recommended): Configure a webhook to receive automatic notifications when the zip completes

Error Responses

All errors follow a consistent JSON format:
{
  "error": {
    "type": "error_type",
    "code": "error_code",
    "message": "Human-readable description",
    "param": "field_name or null"
  }
}

401 Unauthorized

Returned when authentication fails.

Missing Authorization Header

{
  "error": {
    "type": "authentication_error",
    "code": "authentication_required",
    "message": "No API key provided. Include your API key in the Authorization header using Bearer auth.",
    "param": null
  }
}

Invalid API Key

{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "Invalid API key provided.",
    "param": null
  }
}
Solution: Check that you’re including a valid Authorization header.

404 Not Found

Returned when the specified bucket doesn’t exist or doesn’t belong to your project. Solution: Verify the bucket_name matches a bucket you’ve configured in your project.

422 Unprocessable Entity

Returned when a required parameter is missing or invalid.

Missing Required Parameter

{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "Missing required parameter: bucket_name",
    "param": "bucket_name"
  }
}
Common causes:
  • Missing bucket_name, key, or urls parameter

Invalid Parameter

{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "is invalid",
    "param": "urls"
  }
}
Common causes:
  • urls is not an array or is empty
  • Invalid URL format
  • Invalid data types

Best Practices

Make sure all URLs are accessible and return the expected files. ZipKit will attempt to download from each URL - if a URL is inaccessible, the zip job may fail.
Specify a meaningful key parameter to organize your zips in your bucket (e.g., "reports/monthly-2025-11.zip" instead of letting ZipKit auto-generate one).
Very large files or many files can take longer to process. Use webhooks to track completion.
Provide clear, descriptive filenames for each file in the zip (e.g., monthly-report-2025-11.pdf instead of file.pdf). This makes the zip contents easier to understand for end users.
Ensure your destination bucket exists and has proper write permissions for the credentials configured in your project.

Zip File Location

When the zip is complete, it will be stored in your specified bucket at the key you provided. Example: If you set "key": "reports/monthly-2025-11.zip", the zip will be stored at:
my-bucket/reports/monthly-2025-11.zip
You can then access the file using your cloud storage provider’s SDK, console, or direct URL.

Limits and Quotas

Rate Limits: API rate limits may apply depending on your plan. Contact support for details on your specific limits.