Warpbin API
Warpbin brings an event's photos and videos together in one gallery. Guests open a link or scan a QR code and upload from their phone; the host manages everything from the gallery's Manage page. The API lets your software take part too: event apps and photographers use it to create galleries, upload into them, sort files into albums, and keep track of what's there, how often it's shared and downloaded, and what to delete.
How it works
Four steps from nothing to your first photo in a gallery:
- 1Get an API keyRequest one from usSee how →
- 2Get a galleryOne-time or ProSee how →
- 3Upload photos and videosSend each file to the gallerySee how →
- 4See them arriveIn the gallery, in Manage, and through the APISee how →
And much more
Albums, listing and deleting files, share and download counts.
Building with an AI assistant?
Paste this prompt into it. It sends your assistant to a plain-text copy of these docs, written for language models.
I'm building with the Warpbin API. Read its reference at https://warpbin.com/docs/api/llms.txt and use only the endpoints, fields and errors it documents.
Assistant can't open links? Open llms.txt and paste the whole file instead.
How it fits together
Your key acts for your account. Whatever you do through the API, the host sees in Manage, and the other way round: it's one gallery, not a copy.
Your account · The API key acts for it
Gallery · One event: a guest link, and a Manage page for the host
Album · Optional groups, such as one per part of the event
File · A photo, video or other file, known by its filename
At a glance
Base URLhttps://warpbin.com/api/v1AuthYour key in an X-API-Key header (Authentication)FormatJSON in and out; files go up as uploads and come down as bytesIdsA gallery's id, an album's album_id, and a file's filename (Concepts)Quick start
From nothing to your first photo in a gallery. The two calls run on their own, so you can paste them one at a time.
- 1
Get an API key
Email contact@warpbin.com for a key. It starts with
wb_live_and acts for your Warpbin account; send it with every request (Authentication). - 2
Get a gallery
Buy a gallery, one-time or Pro. Its id is the part after
/manage/in its Manage link (a custom guest link isn't the id).Any gallery takes uploads. To list, delete and sort its files into albums, the gallery must be on the Pro subscription of the account your key belongs to; with Pro you can also create galleries through the API.
- 3
Upload photos and videos
Send each file to the gallery. The answer has the name it was stored under, which is the file's id from now on. For videos, big files or phone networks, use a resumable upload: it survives dropped connections and never stores a file twice.
Requestimport requestswith 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',# 'album_id': '…', to put it in an album},)print(response.json()['filename'])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"} - 4
See them arrive
Open the gallery link: the photo is there for guests, and in Manage for the host. It shows as
processingfor a few seconds while its previews are made, thenready. On a Pro gallery you can list the files yourself:Requestimport requestspage = requests.get('https://warpbin.com/api/v1/galleries/abc123xyz/files',headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},params={'limit': 100}, # add 'album_id' for one album).json()files, next_after = page['files'], page['next_after']Response · 200 OK{"files": [{"filename": "IMG_0001.jpg","album_id": "3f2b8c1e-5d4a-4f7b-9e2c-1a6d0b7e91c4","type": "image","size": 2483112,"status": "ready","capture_time": "2026-10-26T14:05:40Z","uploaded_at": "2026-10-26T14:05:52Z","shares": 3,"downloads": 1}],"next_after": null}
Next: read Concepts for how galleries, albums and files fit together, or browse the API reference.
Authentication
Send your API key with every request, in either of these headers. The key acts for your account: it can manage the galleries your account owns.
X-API-KeyheaderThe key as it is: wb_live_xxx
AuthorizationheaderAs a bearer token: Bearer wb_live_xxx
Errors
No key sent
{
"error": "API key required",
"type": "MISSING_API_KEY"
}The key isn't valid
{
"error": "Invalid API key",
"type": "INVALID_API_KEY"
}Galleries, albums and files
Three things, each inside the one before. Every call names the gallery it works on, and most name an album or a file in it.
Galleries
One event's photos and videos, with a link for guests and a Manage page for the host. Its id is in the Manage link, warpbin.com/manage/{gallery_id}. Galleries used to be called drives, so some endpoints name the id drive_id or id; it's the same value.
Your key can upload into any gallery that takes uploads. Listing, deleting and albums work on the galleries of your account's Pro subscription; others answer NOT_GALLERY_OWNER.
admin_idThe gallery's admin password (the pd in its Manage link). You only send it to upload into a gallery whose host turned guest uploads off.Albums
Optional groups inside a gallery, such as one per part of the event. A file is in one album or none. Album names are unique in a gallery, and an album keeps its album_id when the host renames it, so store the id rather than the name. Uploading never creates an album: create it first.
Files
A file's id is its filename: the name it was stored under, which the upload tells you. It never changes. If the gallery already has a file by that name, the new one gets a free name (photo_2.jpg).
statusprocessing while its previews are made, then ready, or failed when the file is stored but no preview could be madeHidden filesFiles the host hid from guests are still listed, and you can manage them like any otherPhotosJPEG, PNG, GIF, WebP, HEIC, AVIFVideosMP4, MOV, AVI, WebM, MKVOther filesPDF, TXT and others, kept as they areErrors and retries
A request that fails answers with an HTTP status and a JSON body: error says what went wrong in plain words, and type is a stable code to branch on. Each endpoint lists its own errors; these are shared.
{"error": "No gallery with this id.","type": "GALLERY_NOT_FOUND"}
Any request
Missing or invalid API key
{
"error": "API key required",
"type": "MISSING_API_KEY"
}Too many requests: wait and retry
Too Many RequestsSomething failed on our side: safe to retry. The type varies by route; branch on the status.
{
"error": "Server error, try again",
"type": "SERVER_ERROR"
}Any /v1/galleries/… request
No gallery with that id
{
"error": "No gallery with this id.",
"type": "GALLERY_NOT_FOUND"
}The gallery belongs to another account
{
"error": "This gallery belongs to a different account than this API key.",
"type": "NOT_GALLERY_OWNER"
}The gallery has expired (GALLERY_EXPIRED) or been deleted (GALLERY_DELETED): it can't change any more
{
"error": "Gallery has expired",
"type": "GALLERY_EXPIRED"
}Paging
Lists come a page at a time, ordered by name. Ask for the next page with after, the next_after of the page before; it's null on the last page. Because pages continue from a name rather than a position, deleting items while you page never makes you skip one.
limitintegerItems per page, 1 to 1000. Default 100.
afterstringThe next_after you were given. Leave it out for the first page.
Rate limits
Requests are rate limited per client to keep the service steady. Past the limit you get 429 Too Many Requests; wait a moment and retry. Resumable uploads have their own, higher limit, so sending chunks never competes with your other calls. Normal use never hits either; email contact@warpbin.com if you think you're being limited by mistake.
API reference
Endpoints
Every endpoint, in the order an integration uses them: the gallery, its albums, uploads, then the files. Each lists its parameters, its answer and the errors only it returns; errors any request can get are in Errors and retries.
Create a gallery
/v1/createGalleryCreate a gallery owned by your account. The answer has its id and admin password, ready to use. The older /v1/createDrive does the same.
Body
alt_tenant_urlstringA custom address for the gallery, as in warpbin.com/brazil-trip
Response
drive_idThe gallery's idadmin_idIts admin password (the pd in its Manage link)drive_urlThe guest linkmanage_urlThe host's Manage pageErrors
No active Pro subscription
{
"success": false,
"message": "Active Pro subscription required"
}That custom address isn't allowed (its message says why)
{
"success": false,
"message": "…"
}That custom address is taken
{
"success": false,
"message": "This alternative URL is already in use by another gallery"
}import requestsresponse = 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_id'], gallery['drive_url'])
{"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"}
Create an album
/v1/galleries/{gallery_id}/albumsAlbums group a gallery's files, for example by part of the event. Names are unique in a gallery, so creating a name that exists returns that album with 200 instead of a new one with 201: a retried create never makes a second album. Keep the album_id: it stays the same if the host renames the album in Manage.
Body
namestringrequiredUp to 255 characters, without commas, semicolons or line breaks
Response
album_idIts id, for uploads and the other album callsnameIts namefile_countFiles in it, still-processing ones includedcreated_atWhen it was createdErrors
Name not allowed
{
"error": "Album names cannot be empty",
"type": "INVALID_ALBUM_NAME"
}The gallery belongs to a different account than this key
{
"error": "This gallery belongs to a different account than this API key.",
"type": "NOT_GALLERY_OWNER"
}import requestsresponse = requests.post('https://warpbin.com/api/v1/galleries/abc123xyz/albums',headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},json={'name': 'Reception'},)album = response.json() # 201 new, 200 already thereprint(album['album_id'])
{"album_id": "3f2b8c1e-5d4a-4f7b-9e2c-1a6d0b7e91c4","name": "Reception","file_count": 48,"created_at": "2026-10-26T14:03:11Z"}
List albums
/v1/galleries/{gallery_id}/albumsThe gallery's albums by name, a page at a time (see Paging).
Query
limitintegerAlbums per page, 1 to 1000. Default 100.
afterstringThe next_after of the page before
Response
albumsAlbums, each as Create an album returns itnext_afterThe after for the next page, or null on the lastErrors
The gallery belongs to a different account than this key
{
"error": "This gallery belongs to a different account than this API key.",
"type": "NOT_GALLERY_OWNER"
}import requestspage = requests.get('https://warpbin.com/api/v1/galleries/abc123xyz/albums',headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},params={'limit': 100},).json()albums, next_after = page['albums'], page['next_after']
{"albums": [{"album_id": "3f2b8c1e-5d4a-4f7b-9e2c-1a6d0b7e91c4","name": "Reception","file_count": 48,"created_at": "2026-10-26T14:03:11Z"}],"next_after": null}
Get an album
/v1/galleries/{gallery_id}/albums/{album_id}One album, with how many files are in it now.
Errors
album_id isn't an id
{
"error": "album_id 'day-1' is not a valid id.",
"type": "INVALID_ALBUM_ID"
}No album with that id in this gallery
{
"error": "No album with this id in this gallery.",
"type": "ALBUM_NOT_FOUND"
}The gallery belongs to a different account than this key
{
"error": "This gallery belongs to a different account than this API key.",
"type": "NOT_GALLERY_OWNER"
}import requestsalbum = requests.get('https://warpbin.com/api/v1/galleries/abc123xyz/albums/3f2b8c1e-5d4a-4f7b-9e2c-1a6d0b7e91c4',headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},).json()print(album['file_count'])
{"album_id": "3f2b8c1e-5d4a-4f7b-9e2c-1a6d0b7e91c4","name": "Reception","file_count": 48,"created_at": "2026-10-26T14:03:11Z"}
Delete an album
/v1/galleries/{gallery_id}/albums/{album_id}Delete an album. Its photos and videos stay in the gallery, in no album, unless you ask for them to go too. Deleting an album that's already gone succeeds, with no files deleted.
Query
delete_filesbooleantrue deletes every photo and video in the album as well, originals and previews. Default false.
Response
deleted_filesThe filenames it deleted (empty without delete_files)Errors
Storage kept some of its files, so the album stays: send the same delete again
{
"error": "2 of its files couldn't be deleted from storage, so the album was kept. Try again.",
"type": "STORAGE_ERROR"
}album_id isn't an id
{
"error": "album_id 'day-1' is not a valid id.",
"type": "INVALID_ALBUM_ID"
}The gallery belongs to a different account than this key
{
"error": "This gallery belongs to a different account than this API key.",
"type": "NOT_GALLERY_OWNER"
}import requestsresponse = requests.delete('https://warpbin.com/api/v1/galleries/abc123xyz/albums/3f2b8c1e-5d4a-4f7b-9e2c-1a6d0b7e91c4',headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},params={'delete_files': 'true'},)print(response.json()['deleted_files'])
{"deleted_files": ["IMG_0001.jpg", "IMG_0002.jpg"]}
Resumable upload
/v1/tus/v1/tus/{upload_id}/v1/tus/{upload_id}/v1/tus/{upload_id}The recommended way to upload: files go in chunks and pick up where they stopped after a dropped connection, using the open TUS 1.0 protocol (creation and termination extensions). Any TUS client library works: point it at /v1/tus, add your API key header and set the metadata below.
POST opens a session and returns its address in Location. PATCH sends the bytes in order. After an interruption, HEAD tells you the Upload-Offset to continue from. The upload is done when the offset reaches Upload-Length; DELETE abandons a session you won't finish.Upload-Metadata
Sent with the POST as the standard TUS Upload-Metadata header (comma-separated key base64(value) pairs, which TUS libraries encode for you).
drive_idstringrequiredThe gallery to upload into
filenamestringrequiredThe file's name, with its extension. If the gallery already has that name, the file is stored under a free one (video_2.mp4); a finished upload tells you which.
session_idstringrequiredA UUID you make, grouping the uploads of one client session
album_idstringThe album to put it in. Checked before any bytes are sent: an album that doesn't exist refuses the upload at once. Albums are never made by uploading; create them first.
admin_idstringThe gallery's admin password. Needed only when the gallery has guest uploads turned off.
user_idstringYour own id for who uploaded it, if you want to keep one
consent_givenbooleanThe uploader agreed to the gallery's terms (default false)
When it's done
The last PATCH answers 204 and the file is processed in the background (previews, video playback). It shows in List files straight away with status: processing, then ready.
HEAD answers 200 with Upload-Offset equal to Upload-Length and an Upload-Metadata header holding the stored filename. Sending the last PATCH again answers 204 and writes nothing, so a retry never stores a copy. TUS libraries already treat this as success.Limits
File sizeUp to 50 GB (Tus-Max-Size on OPTIONS /v1/tus)Chunk sizeAny size but empty. 1 to 10 MiB suits most networks; go smaller on poor ones.Unfinished sessionsKept up to 24 hours, and lost on a server restart. A 404 or 410 on a session you know means nothing was stored: start that file again with a new POST.Errors
Required metadata missing
{
"error": "Missing required field: session_id",
"type": "MISSING_FIELD"
}An album name was sent (album or album_name): create the album, then send its album_id
{
"error": "Uploads take album_id, not an album name. Create the album first and send its id.",
"type": "ALBUM_NAME_NOT_SUPPORTED"
}album_id isn't an id
{
"error": "album_id 'day-1' is not a valid id.",
"type": "INVALID_ALBUM_ID"
}No album with that album_id in this gallery (it may have been deleted)
{
"error": "No album 3f2b…e91c in this gallery. It may have been deleted.",
"type": "ALBUM_NOT_FOUND"
}The gallery has expired. Don't retry.
{
"error": "This gallery has expired. Uploads are not allowed.",
"type": "DRIVE_EXPIRED"
}Guest uploads are off and no admin_id was sent. Don't retry.
{
"error": "Uploads are disabled for this gallery. Admin ID required.",
"type": "UPLOADS_DISABLED"
}The plan is full. Don't retry.
{
"error": "Upload not allowed",
"type": "PLAN_LIMIT_EXCEEDED"
}Unknown or lost session: start again with a new POST
{
"error": "Upload not found"
}Offset mismatch: ask HEAD for the offset, then continue from server_offset
{
"error": "Offset mismatch - client and server out of sync",
"type": "OFFSET_MISMATCH",
"server_offset": 106954752,
"client_offset": 107003904
}Session expired: start again with a new POST
{
"error": "Upload has expired"
}File too large
{
"error": "File size exceeds maximum allowed size",
"type": "FILE_TOO_LARGE",
"max_size": 53687091200
}Server storage is briefly full: wait and retry
{
"error": "Server storage critical. Uploads temporarily disabled to prevent system crash.",
"type": "DISK_SPACE_CRITICAL"
}# pip install tuspyimport uuidfrom tusclient import clienttus_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()),'album_id': '3f2b8c1e-5d4a-4f7b-9e2c-1a6d0b7e91c4', # optional},)# Sends chunks and resumes from the server-confirmed# offset after an interruptionuploader.upload()
# POST /v1/tus: session createdHTTP/1.1 201 CreatedTus-Resumable: 1.0.0Location: /api/v1/tus/3f2a9c1e-...# PATCH /v1/tus/{upload_id}: chunk acceptedHTTP/1.1 204 No ContentTus-Resumable: 1.0.0Upload-Offset: 5242880# HEAD /v1/tus/{upload_id}: where to resumeHTTP/1.1 200 OKTus-Resumable: 1.0.0Upload-Offset: 106954752Upload-Length: 296201395# HEAD /v1/tus/{upload_id}: upload already finished# (Upload-Metadata carries the stored filename, here "video_2.mp4")HTTP/1.1 200 OKTus-Resumable: 1.0.0Upload-Offset: 296201395Upload-Length: 296201395Upload-Metadata: filename dmlkZW9fMi5tcDQ=
Simple upload
/v1/uploadFileOne request per file, as a multipart form. Fine for small photos on a steady connection; use a resumable upload for videos, big files or mobile networks. A retry after a lost response stores the file again under a new name (photo_2.jpg), which a resumable upload never does.
Form fields
file_contentsfilerequiredThe file
filenamestringrequiredIts name, with its extension
drive_idstringrequiredThe gallery to upload into
album_idstringThe album to put it in. An album that doesn't exist refuses the upload.
admin_idstringThe gallery's admin password. Needed only when the gallery has guest uploads turned off.
user_idstringYour own id for who uploaded it, if you want to keep one
consent_givenbooleanThe uploader agreed to the gallery's terms (default false)
Response
filenameThe name it was stored under: the file's idfile_preview_urlIts page in the gallery (opens without a key)file_download_urlThe original, through Download a fileThe answer is 202 Accepted: the file is processed in the background, so its page shows it a few seconds to minutes later, depending on its size.
Errors
A required field is missing
{
"error": "Missing required field: drive_id",
"type": "MISSING_FIELD"
}No gallery with that drive_id
{
"error": "Invalid gallery ID",
"type": "INVALID_DRIVE_ID"
}An album name was sent (album or album_name): create the album, then send its album_id
{
"error": "Uploads take album_id, not an album name. Create the album first and send its id.",
"type": "ALBUM_NAME_NOT_SUPPORTED"
}album_id isn't an id
{
"error": "album_id 'day-1' is not a valid id.",
"type": "INVALID_ALBUM_ID"
}No album with that album_id in this gallery (it may have been deleted)
{
"error": "No album 3f2b…e91c in this gallery. It may have been deleted.",
"type": "ALBUM_NOT_FOUND"
}The gallery has expired
{
"error": "This gallery has expired. Uploads are not allowed.",
"type": "DRIVE_EXPIRED"
}Guest uploads are off and no admin_id was sent
{
"error": "Uploads are disabled for this gallery. Admin ID required.",
"type": "UPLOADS_DISABLED"
}The gallery's storage is full
{
"error": "Uploading this file would exceed the gallery's storage limit.",
"type": "STORAGE_SPACE"
}import requestswith 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',# 'album_id': '…', to put it in an album},)print(response.json()['filename'])
{"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"}
List files
/v1/galleries/{gallery_id}/filesEvery photo, video and other file in the gallery, or in one album, by name a page at a time (see Paging). Hidden and still-processing files are included. A file that was deleted is simply no longer listed.
Query
album_idstringOnly this album's files
limitintegerFiles per page, 1 to 1000. Default 100.
afterstringThe next_after of the page before
Each file
filenameIts idalbum_idIts album, or nulltypeimage, video or othersizeBytesstatusprocessing (being prepared), ready, or failed (stored, but its preview couldn't be made)capture_timeWhen it was taken, from the photo's own data, or nulluploaded_atWhen it arrivedsharesTimes guests shared it: the photo itself, its link, or a copied linkdownloadsTimes it was downloaded on its own (not as part of a whole-gallery zip), counted since October 2026. Downloads through this API's getFile count too.Errors
album_id isn't an id
{
"error": "album_id 'day-1' is not a valid id.",
"type": "INVALID_ALBUM_ID"
}The gallery belongs to a different account than this key
{
"error": "This gallery belongs to a different account than this API key.",
"type": "NOT_GALLERY_OWNER"
}import requestspage = requests.get('https://warpbin.com/api/v1/galleries/abc123xyz/files',headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},params={'limit': 100}, # add 'album_id' for one album).json()files, next_after = page['files'], page['next_after']
{"files": [{"filename": "IMG_0001.jpg","album_id": "3f2b8c1e-5d4a-4f7b-9e2c-1a6d0b7e91c4","type": "image","size": 2483112,"status": "ready","capture_time": "2026-10-26T14:05:40Z","uploaded_at": "2026-10-26T14:05:52Z","shares": 3,"downloads": 1}],"next_after": null}
Get file links
/v1/fileInfo?drive_id={drive_id}&filename={filename}A file's page and download links, for example to show or send once an upload is done. Your own galleries answer for every file; another gallery answers only for files its guests can see.
Query
drive_idstringrequiredThe gallery
filenamestringrequiredThe file
Response
filenameThe filefile_preview_urlIts page in the gallery (opens without a key)file_download_urlThe original, through Download a fileErrors
A parameter is missing
{
"error": "Missing 'filename' parameter",
"type": "MISSING_PARAMETER"
}No gallery with that drive_id
{
"error": "Invalid gallery ID",
"type": "INVALID_DRIVE_ID"
}No such file, or one this key may not see
{
"error": "File not found",
"type": "NOT_FOUND"
}import requestsinfo = requests.get('https://warpbin.com/api/v1/fileInfo',headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},params={'drive_id': 'abc123xyz', 'filename': 'photo.jpg'},).json()print(info['file_preview_url'])
{"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"}
Download a file
/v1/getFile?id={drive_id}&file={filename}The original file, as uploaded, with its content type. Your own galleries answer for every file; another gallery follows its host's rules (hidden files and turned-off downloads stay closed). Note the short names: id is the gallery, file the filename.
Query
idstringrequiredThe gallery (its drive_id)
filestringrequiredThe file (its filename)
Errors
A parameter is missing
{
"error": "Missing 'file' parameter",
"type": "MISSING_PARAMETER"
}Not a filename
{
"error": "Invalid filename format",
"type": "INVALID_FILENAME"
}No such file, or one this key may not download
{
"error": "File not found",
"type": "NOT_FOUND"
}Storage didn't answer: retry
{
"error": "Storage is unavailable, try again",
"type": "STORAGE_ERROR"
}import requestsresponse = 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)
Delete a file
/v1/galleries/{gallery_id}/files/{filename}Delete a file for good: its original and previews go at once, from guests' screens too. Answers 204 whether the file was there or already gone, so it's safe to repeat. A file still being processed can be deleted too. Encode the filename for the path.
Errors
Storage kept the file: send the same delete again
{
"error": "Storage wouldn't delete the file. Try again.",
"type": "STORAGE_ERROR"
}The gallery belongs to a different account than this key
{
"error": "This gallery belongs to a different account than this API key.",
"type": "NOT_GALLERY_OWNER"
}import requestsfrom urllib.parse import quoteresponse = requests.delete('https://warpbin.com/api/v1/galleries/abc123xyz/files/' + quote('IMG_0001.jpg'),headers={'X-API-Key': 'wb_live_xxxxxxxxxxxx'},)print(response.status_code) # 204