Betav1

Warpbin API

Programmatic access to upload, retrieve, and manage files on Warpbin galleries.

“Drive” and “gallery” are the same thing. Galleries were formerly called drives, so field and parameter names keep the drive_ prefix (e.g. drive_id, drive_url) for backwards compatibility. They refer to your gallery throughout this API.

Base URL

All API requests use this base URL. Append the endpoint path to make your calls.

https://warpbin.com/api/v1

How to Use This API

1

Get an API Key

Reach out to contact@warpbin.com to request your API key. Keys are tied to your account and start with wb_live_.

2

Find your gallery identifiers

If you already have a gallery, you can find its identifiers in the URLs you already have:

drive_idthe unique identifier for your gallery
warpbin.com/{drive_id}
admin_idthe admin password for your gallery (only needed for certain operations)
warpbin.com/manage/{drive_id}?pd={admin_id}
3

Create galleries programmatically

Pro

If you have an active Pro subscription on the email associated with your API key, you can use the /createGallery endpoint to create new galleries via the API. The response includes the drive_id and admin_id for immediate use.

Authentication

Include your API key in every request using one of the following headers. You only need to pick one — they are interchangeable.

Pick one header

X-API-Keystring

Your Warpbin API key as-is — wb_live_xxx

Authorizationstring

Bearer token format — Bearer wb_live_xxx

Error responses
401

Missing API key

{
  "error": "API key required",
  "type": "MISSING_API_KEY"
}
401

Invalid API key

{
  "error": "Invalid API key",
  "type": "INVALID_API_KEY"
}

Code example

Authentication
import requests
headers = {'X-API-Key': 'wb_live_xxxxxxxxxxxx'}
# Or use Bearer token
headers = {'Authorization': 'Bearer wb_live_xxxxxxxxxxxx'}

Upload File

POST/v1/uploadFile

Upload a file to a gallery and get instant access URLs. Files are processed asynchronously after upload. The returned URLs will not display the uploaded photo or video until the file is done processing. This can take a couple seconds to minutes depending on the file size.

Form data parameters

file_contentsfilerequired

The file to upload

filenamestringrequired

Filename including extension

drive_idstringrequired

Target gallery identifier

consent_givenboolean

User consent for processing (default: false)

user_idstring

User identifier for tracking

admin_idstring

The gallery's admin password. Required when public uploads are disabled on the gallery.

Response fields

filenameFinal filename after sanitization
file_preview_urlURL to view the file (no API key required)
file_download_urlDirect download URL (requires API key)
Errors
400

Missing required fields

{
  "error": "Missing required field: drive_id",
  "type": "MISSING_FIELD"
}
400

Invalid gallery ID

{
  "error": "Invalid gallery ID",
  "type": "INVALID_DRIVE_ID"
}
507

Storage limit exceeded

{
  "error": "Uploading this file would exceed the gallery's storage limit.",
  "type": "STORAGE_SPACE"
}

Code example

Request
import requests
with open('photo.jpg', 'rb') as f:
response = requests.post(
'https://warpbin.com/api/v1/uploadFile',
headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},
files={'file_contents': f},
data={
'filename': 'photo.jpg',
'drive_id': 'abc123xyz'
}
)
result = response.json()
print(result['file_preview_url'])
Response · 202 Accepted
{
"message": "File upload accepted for processing.",
"filename": "photo_2.jpg",
"file_preview_url": "https://warpbin.com/file?id=abc123xyz&file=photo_2.jpg",
"file_download_url": "https://warpbin.com/api/v1/getFile?id=abc123xyz&file=photo_2.jpg"
}

Resumable Upload (TUS)

POST/v1/tus
PATCH/v1/tus/{upload_id}
HEAD/v1/tus/{upload_id}
DELETE/v1/tus/{upload_id}

Upload large files in chunks with per-byte resume, using the open TUS 1.0 protocol (extensions: creation, termination). Prefer this over /v1/uploadFile for videos and other large files, or on unreliable networks. Any standard TUS client library works — point it at the endpoint, add your API key header, and set the metadata below.

Lifecycle: POST creates a session and returns its URL in the Location header. Send data with sequential PATCH requests. After an interruption, HEAD returns the confirmed Upload-Offset to resume from. The upload completes implicitly when the offset reaches Upload-Length; use DELETE to abandon a session you will not finish.

Upload-Metadata fields

Sent on the create request as the standard TUS Upload-Metadata header (comma-separated key base64(value) pairs — TUS client libraries encode this for you).

drive_idstringrequired

Target gallery identifier

filenamestringrequired

Filename including extension. If the name already exists in the gallery, the stored name is made unique on completion (e.g. video_2.mp4), so prefer unique filenames to look files up afterwards.

session_idstringrequired

Client-generated identifier (e.g. a UUID) grouping uploads from one client session

consent_givenboolean

User consent for processing (default: false)

user_idstring

User identifier for tracking

album_idstring

Album to place the file in

admin_idstring

The gallery's admin password. Required when public uploads are disabled on the gallery.

Limits and session lifetime

Max file size50 GB, advertised via Tus-Max-Size on OPTIONS /v1/tus
Chunk sizeAny size per PATCH (empty chunks rejected). 1–10 MiB is a good default; use smaller chunks on unreliable networks.
Session retentionUp to 24 hours. Sessions inactive for extended periods may be cleaned up earlier when the server is under storage pressure.
Lost sessionsSessions do not survive server restarts or deploys. If a known session returns 404 or 410, restart that file with a new POST from byte 0.
After completion: the file is processed asynchronously, exactly like /v1/uploadFile. The final PATCH returns 204 with no body — poll /v1/fileInfo with your drive_id and filename to get the preview and download URLs once processing finishes. A session disappears once complete, so a retried final PATCH returns 404 without creating a duplicate.
Errors
400

Missing required metadata

{
  "error": "Missing required field: session_id",
  "type": "MISSING_FIELD"
}
404

Unknown or lost session — restart the file with a new POST

{
  "error": "Upload not found"
}
409

Offset mismatch — resync with HEAD, then resume from server_offset

{
  "error": "Offset mismatch - client and server out of sync",
  "type": "OFFSET_MISMATCH",
  "server_offset": 106954752,
  "client_offset": 107003904
}
410

Session expired — restart the file with a new POST

{
  "error": "Upload has expired"
}
413

File exceeds maximum size

{
  "error": "File size exceeds maximum allowed size",
  "type": "FILE_TOO_LARGE",
  "max_size": 53687091200
}
403

Upload not allowed (gallery expired, uploads disabled, or plan limit) — do not retry

{
  "error": "Upload not allowed",
  "type": "PLAN_LIMIT_EXCEEDED"
}
507

Server storage temporarily critical — back off and retry later

{
  "error": "Server storage critical. Uploads temporarily disabled to prevent system crash.",
  "type": "DISK_SPACE_CRITICAL"
}

Code example

Request
# pip install tuspy
import uuid
from tusclient import client
tus_client = client.TusClient(
'https://warpbin.com/api/v1/tus',
headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},
)
uploader = tus_client.uploader(
'video.mp4',
chunk_size=5 * 1024 * 1024,
metadata={
'drive_id': 'abc123xyz',
'filename': 'video.mp4',
'session_id': str(uuid.uuid4()),
},
)
# Sends chunks and transparently resumes from the
# server-confirmed offset after an interruption
uploader.upload()
Response headers
# POST /v1/tus — session created
HTTP/1.1 201 Created
Tus-Resumable: 1.0.0
Location: /api/v1/tus/3f2a9c1e-...
# PATCH /v1/tus/{upload_id} — chunk accepted
HTTP/1.1 204 No Content
Tus-Resumable: 1.0.0
Upload-Offset: 5242880
# HEAD /v1/tus/{upload_id} — where to resume
HTTP/1.1 200 OK
Tus-Resumable: 1.0.0
Upload-Offset: 106954752
Upload-Length: 296201395

Retrieve File

GET/v1/getFile?id={drive_id}&file={filename}

Download a file from a gallery. Returns the raw file data with appropriate content-type headers for direct download or display.

This endpoint uses shortened parameter names: id is your drive_id and file is the filename.

Query parameters

idstringrequired

Your drive_id — the gallery to retrieve from

filestringrequired

The filename to retrieve (same as filename in other endpoints)

Errors
400

Missing drive ID

{
  "error": "Missing 'id' parameter",
  "type": "MISSING_PARAMETER"
}
400

Invalid gallery ID

{
  "error": "Invalid gallery ID",
  "type": "INVALID_DRIVE_ID"
}
400

Missing filename

{
  "error": "Missing 'file' parameter",
  "type": "MISSING_PARAMETER"
}
400

Invalid filename

{
  "error": "Invalid filename format",
  "type": "INVALID_FILENAME"
}
403

Access denied

{
  "error": "File not found or access denied",
  "type": "ACCESS_DENIED"
}
404

File not found

{
  "error": "File not found in storage",
  "type": "NOT_FOUND"
}

Code example

Request
import requests
response = requests.get(
'https://warpbin.com/api/v1/getFile',
headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},
params={'id': 'abc123xyz', 'file': 'photo.jpg'}
)
with open('photo.jpg', 'wb') as f:
f.write(response.content)

Response

Returns raw file data with appropriate Content-Type headers.

File Info

GET/v1/fileInfo?drive_id={drive_id}&filename={filename}

Get the preview and download URLs for a file without downloading its content.

Query parameters

drive_idstringrequired

Gallery identifier

filenamestringrequired

Filename to look up

Response fields

filenameFilename as stored on the gallery
file_preview_urlURL to view in Warpbin (no API key required)
file_download_urlDirect download URL (requires API key)
Errors
400

Missing parameters

{
  "error": "Missing 'drive_id' parameter",
  "type": "MISSING_PARAMETER"
}
400

Invalid gallery ID

{
  "error": "Invalid gallery ID",
  "type": "INVALID_DRIVE_ID"
}
400

Missing filename

{
  "error": "Missing 'filename' parameter",
  "type": "MISSING_PARAMETER"
}
404

File not found

{
  "error": "File not found",
  "type": "NOT_FOUND"
}

Code example

Request
import requests
response = requests.get(
'https://warpbin.com/api/v1/fileInfo',
headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},
params={'drive_id': 'abc123xyz', 'filename': 'photo.jpg'}
)
info = response.json()
print(info['file_preview_url'])
Response · 200 OK
{
"filename": "photo.jpg",
"file_preview_url": "https://warpbin.com/file?id=abc123xyz&file=photo.jpg",
"file_download_url": "https://warpbin.com/api/v1/getFile?id=abc123xyz&file=photo.jpg"
}

Create Gallery

POST/v1/createGallery

Create a new Warpbin gallery linked to your account. Returns the gallery credentials and URL for immediate use.

The legacy endpoint /v1/createDrive continues to work and is fully equivalent — both names hit the same handler.
Requires an active Pro subscription on the email associated with your API key.

Request body

alt_tenant_urlstring

Custom gallery URL slug that helps you identify it in your dashboard (e.g. "brazil-trip")

Response fields

drive_idUnique drive identifier for API calls
admin_idAdmin password for drive management (the pd value in your manage URL)
drive_urlPublic URL to access the drive
manage_urlManagement panel URL for drive settings
Store credentials securely. The drive_id and admin_id (admin password) are returned at creation time — save them for future API calls. You can also find them later in your manage URL (/manage/{drive_id}?pd={admin_id}) or view all your galleries on your dashboard.
Errors
403

No active subscription

{
  "success": false,
  "drive_id": null,
  "admin_id": null,
  "drive_url": null,
  "manage_url": null,
  "message": "Active Pro subscription required"
}
500

Server error

{
  "success": false,
  "drive_id": null,
  "admin_id": null,
  "drive_url": null,
  "manage_url": null,
  "message": "Failed to create gallery"
}

Code example

Request
import requests
response = requests.post(
'https://warpbin.com/api/v1/createGallery',
headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},
json={'alt_tenant_url': 'my-project'}
)
gallery = response.json()
print(gallery['drive_url'])
Response
{
"success": true,
"drive_id": "abc123xyz",
"admin_id": "UxCIkRbY",
"drive_url": "https://warpbin.com/abc123xyz",
"manage_url": "https://warpbin.com/manage/abc123xyz?pd=UxCIkRbY",
"message": "Gallery created successfully"
}

Rate Limits

API requests are subject to a global rate limit to ensure service stability. Excessive requests will receive a 429 Too Many Requests response. This should not be hit for any legitimate use case. Reach out to us if you think we are incorrectly rate limiting you.