Uploads & assets
Upload files with signed tickets, confirm media and manage source assets and processed versions.
Check upload limits
Section titled “Check upload limits”Read the allowed formats and size/dimension/duration limits before sending a file. Upload acceptance does not guarantee every tool can process that source; individual tools have their own limits.
/api/v1/assets/upload-limitsRequest example
curl --include --fail-with-body --silent --show-error --max-time 60 \ --request GET 'https://app.berserkapi.com/api/v1/assets/upload-limits' \ --header "Authorization: Bearer $GLACIER_API_KEY"// Node.js 22+; save as example.mjs, then: node example.mjsconst key = process.env.GLACIER_API_KEY;if (!key) throw new Error('Set GLACIER_API_KEY');const response = await fetch('https://app.berserkapi.com/api/v1/assets/upload-limits', { method: 'GET', headers: { Authorization: `Bearer ${key}`, }, signal: AbortSignal.timeout(60_000),});const text = await response.text();if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);console.log(response.status, text);# Python 3.10+; standard library; python example.pyimport osimport urllib.requestimport urllib.error
headers = {"Authorization": "Bearer " + os.environ["GLACIER_API_KEY"]}request = urllib.request.Request( "https://app.berserkapi.com/api/v1/assets/upload-limits", method="GET", headers=headers,)try: with urllib.request.urlopen(request, timeout=60) as response: print(response.status, response.read().decode("utf-8"))except urllib.error.HTTPError as error: raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8')}") from error// Go 1.22+; go run example.gopackage main
import ( "fmt" "io" "net/http" "os" "time")
func main() { key := os.Getenv("GLACIER_API_KEY") if key == "" { panic("Set GLACIER_API_KEY") } req, err := http.NewRequest("GET", "https://app.berserkapi.com/api/v1/assets/upload-limits", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer " + key) client := &http.Client{Timeout: 60 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() data, err := io.ReadAll(res.Body) if err != nil { panic(err) } if res.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, data)) } fmt.Println(res.StatusCode, string(data))}// cargo add reqwest@0.13 --features blocking// Save in src/main.rs, then: cargo runuse std::{env, error::Error, time::Duration};
fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(60)).build()?; let response = client.request(reqwest::Method::GET, "https://app.berserkapi.com/api/v1/assets/upload-limits") .bearer_auth(env::var("GLACIER_API_KEY")?) .send()?; let status = response.status(); let text = response.text()?; if !status.is_success() { return Err(format!("HTTP {status}: {text}").into()); } println!("{status} {text}"); Ok(())}// Java 17+; save as Example.java, then: java Example.javaimport java.net.URI;import java.net.http.*;import java.time.Duration;import java.util.Objects;
class Example { public static void main(String[] args) throws Exception { var key = Objects.requireNonNull(System.getenv("GLACIER_API_KEY")); var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build(); var request = HttpRequest.newBuilder(URI.create("https://app.berserkapi.com/api/v1/assets/upload-limits")) .timeout(Duration.ofSeconds(60)) .header("Authorization", "Bearer " + key) .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body()); System.out.println(response.statusCode() + " " + response.body()); }}// .NET 8+; dotnet new console; replace Program.cs; dotnet runusing System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;
var key = Environment.GetEnvironmentVariable("GLACIER_API_KEY") ?? throw new InvalidOperationException("Set GLACIER_API_KEY");using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };using var request = new HttpRequestMessage(new HttpMethod("GET"), "https://app.berserkapi.com/api/v1/assets/upload-limits");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);using var response = await client.SendAsync(request);var text = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode) throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");Console.WriteLine($"{(int)response.StatusCode} {text}");Response fields · 200
imageobjectrequiredExpand fields / variants
maxAspectinteger · int64requiredmaxBytesinteger · int64requiredmaxDurationMsinteger · int64requiredmaxFrameRateinteger · int64requiredmaxFramesinteger · int64requiredmaxPixelsinteger · int64requiredmaxSideinteger · int64requiredminSideinteger · int64required
videoobjectrequiredExpand fields / variants
maxAspectinteger · int64requiredmaxBytesinteger · int64requiredmaxDurationMsinteger · int64requiredmaxFrameRateinteger · int64requiredmaxFramesinteger · int64requiredmaxPixelsinteger · int64requiredmaxSideinteger · int64requiredminSideinteger · int64required
Request an upload ticket
Section titled “Request an upload ticket”Send the file name, MIME type and exact byte length. Replace 123456 in the example with the size of your file. The 201 response contains assetId, uploadUrl, method, headers (an array of name/value pairs), fileField and expiresAt. Save this response locally as ticket.json for the next step; it contains a temporary signed URL, so keep it private.
/api/v1/assets/uploadsRequest body fields · application/json
mimeTypestringrequiredmultipartbooleanoptionalnamestringrequiredsizeBytesinteger · int64required
Request example
curl --include --fail-with-body --silent --show-error --max-time 60 \ --request POST 'https://app.berserkapi.com/api/v1/assets/uploads' \ --header "Authorization: Bearer $GLACIER_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{ "name": "input.png", "mimeType": "image/png", "sizeBytes": 123456}'// Node.js 22+; save as example.mjs, then: node example.mjsconst key = process.env.GLACIER_API_KEY;if (!key) throw new Error('Set GLACIER_API_KEY');const response = await fetch('https://app.berserkapi.com/api/v1/assets/uploads', { method: 'POST', headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "name": "input.png", "mimeType": "image/png", "sizeBytes": 123456}), signal: AbortSignal.timeout(60_000),});const text = await response.text();if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);console.log(response.status, text);# Python 3.10+; standard library; python example.pyimport osimport urllib.requestimport urllib.error
headers = {"Authorization": "Bearer " + os.environ["GLACIER_API_KEY"]}headers["Content-Type"] = "application/json"request = urllib.request.Request( "https://app.berserkapi.com/api/v1/assets/uploads", method="POST", headers=headers, data="""{ "name": "input.png", "mimeType": "image/png", "sizeBytes": 123456}""".encode("utf-8"),)try: with urllib.request.urlopen(request, timeout=60) as response: print(response.status, response.read().decode("utf-8"))except urllib.error.HTTPError as error: raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8')}") from error// Go 1.22+; go run example.gopackage main
import ( "fmt" "io" "net/http" "os" "strings" "time")
func main() { key := os.Getenv("GLACIER_API_KEY") if key == "" { panic("Set GLACIER_API_KEY") } req, err := http.NewRequest("POST", "https://app.berserkapi.com/api/v1/assets/uploads", strings.NewReader(`{ "name": "input.png", "mimeType": "image/png", "sizeBytes": 123456}`)) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer " + key) req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 60 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() data, err := io.ReadAll(res.Body) if err != nil { panic(err) } if res.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, data)) } fmt.Println(res.StatusCode, string(data))}// cargo add reqwest@0.13 --features blocking// Save in src/main.rs, then: cargo runuse std::{env, error::Error, time::Duration};
fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(60)).build()?; let response = client.request(reqwest::Method::POST, "https://app.berserkapi.com/api/v1/assets/uploads") .bearer_auth(env::var("GLACIER_API_KEY")?) .header("Content-Type", "application/json") .body(r#"{ "name": "input.png", "mimeType": "image/png", "sizeBytes": 123456}"#) .send()?; let status = response.status(); let text = response.text()?; if !status.is_success() { return Err(format!("HTTP {status}: {text}").into()); } println!("{status} {text}"); Ok(())}// Java 17+; save as Example.java, then: java Example.javaimport java.net.URI;import java.net.http.*;import java.time.Duration;import java.util.Objects;
class Example { public static void main(String[] args) throws Exception { var key = Objects.requireNonNull(System.getenv("GLACIER_API_KEY")); var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build(); var request = HttpRequest.newBuilder(URI.create("https://app.berserkapi.com/api/v1/assets/uploads")) .timeout(Duration.ofSeconds(60)) .header("Authorization", "Bearer " + key) .header("Content-Type", "application/json") .method("POST", HttpRequest.BodyPublishers.ofString("""{ "name": "input.png", "mimeType": "image/png", "sizeBytes": 123456}""")) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body()); System.out.println(response.statusCode() + " " + response.body()); }}// .NET 8+; dotnet new console; replace Program.cs; dotnet runusing System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;
var key = Environment.GetEnvironmentVariable("GLACIER_API_KEY") ?? throw new InvalidOperationException("Set GLACIER_API_KEY");using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };using var request = new HttpRequestMessage(new HttpMethod("POST"), "https://app.berserkapi.com/api/v1/assets/uploads");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);request.Content = new StringContent("""{ "name": "input.png", "mimeType": "image/png", "sizeBytes": 123456}""", Encoding.UTF8, "application/json");using var response = await client.SendAsync(request);var text = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode) throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");Console.WriteLine($"{(int)response.StatusCode} {text}");Response fields · 201
assetIdstringrequiredexpiresAtstring · date-timerequiredfileFieldstring | nullrequiredheadersstring[][]requiredExpand fields / variants
stringmethod"PUT" | "POST"requireduploadUrlstringrequired
Send the file bytes
Section titled “Send the file bytes”These examples use the default PUT ticket and stream input.png to the returned URL. Use the exact returned headers. This is a storage request: it has no API-key header and does not go through /api/v1.
# Save the upload-ticket response as ticket.json. Requires jq.# The ticket must be for input.png with its exact byte length.test "$(jq -r '.method' ticket.json)" = PUT || exit 1headers=()while IFS= read -r header; do headers+=(--header "$header"); done < <( jq -r '.headers[] | .[0] + ": " + .[1]' ticket.json)curl --fail-with-body --silent --show-error --max-time 1800 \ --request PUT "$(jq -r '.uploadUrl' ticket.json)" \ "${headers[@]}" --upload-file input.png// Node.js 22+; example.mjsimport { readFile, stat } from 'node:fs/promises';import { createReadStream } from 'node:fs';const ticket = JSON.parse(await readFile('ticket.json', 'utf8'));if (ticket.method !== 'PUT') throw new Error('Request a default PUT ticket');const headers = Object.fromEntries(ticket.headers);headers['Content-Length'] = String((await stat('input.png')).size);const response = await fetch(ticket.uploadUrl, { method: 'PUT', headers, body: createReadStream('input.png'), duplex: 'half', signal: AbortSignal.timeout(1_800_000),});if (!response.ok) throw new Error(await response.text());console.log('Uploaded; now confirm asset', ticket.assetId);# Python 3.10+; standard libraryimport jsonimport osimport urllib.requestwith open('ticket.json', encoding='utf-8') as source: ticket = json.load(source)if ticket['method'] != 'PUT': raise ValueError('Request a default PUT ticket')headers = dict(ticket['headers'])headers['Content-Length'] = str(os.path.getsize('input.png'))with open('input.png', 'rb') as source: request = urllib.request.Request(ticket['uploadUrl'], data=source, headers=headers, method='PUT') with urllib.request.urlopen(request, timeout=1800) as response: print(response.status, 'Confirm asset', ticket['assetId'])// go run upload.gopackage mainimport ( "encoding/json" "fmt" "net/http" "os" "time")func main() { var ticket struct { AssetID string UploadURL string Method string Headers [][2]string } raw, err := os.ReadFile("ticket.json") if err != nil { panic(err) } if err = json.Unmarshal(raw, &ticket); err != nil { panic(err) } if ticket.Method != "PUT" { panic("Request a default PUT ticket") } file, err := os.Open("input.png") if err != nil { panic(err) } defer file.Close() info, err := file.Stat() if err != nil { panic(err) } req, err := http.NewRequest("PUT", ticket.UploadURL, file) if err != nil { panic(err) } req.ContentLength = info.Size() for _, h := range ticket.Headers { req.Header.Set(h[0], h[1]) } res, err := (&http.Client{Timeout: 30 * time.Minute}).Do(req) if err != nil { panic(err) } defer res.Body.Close() if res.StatusCode >= 300 { panic(res.Status) } fmt.Println("Uploaded; confirm asset", ticket.AssetID)}// cargo add reqwest@0.13 --features blocking// cargo add serde_jsonuse std::{error::Error, fs::File, time::Duration};fn main() -> Result<(), Box<dyn Error>> { let ticket: serde_json::Value = serde_json::from_reader(File::open("ticket.json")?)?; if ticket["method"] != "PUT" { return Err("Request a default PUT ticket".into()); } let file = File::open("input.png")?; let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(1800)).build()?; let mut request = client.put(ticket["uploadUrl"].as_str().ok_or("Missing uploadUrl")?) .header("Content-Length", file.metadata()?.len()); for header in ticket["headers"].as_array().ok_or("Missing headers")? { request = request.header(header[0].as_str().ok_or("Invalid header")?, header[1].as_str().ok_or("Invalid header")?); } request.body(reqwest::blocking::Body::new(file)).send()?.error_for_status()?; println!("Uploaded; confirm asset {}", ticket["assetId"]); Ok(())}// Java 17+; add com.fasterxml.jackson.core:jackson-databind to your project.import com.fasterxml.jackson.databind.ObjectMapper;import java.nio.file.Path;import java.net.URI;import java.net.http.*;import java.time.Duration;class Upload { public static void main(String[] args) throws Exception { var ticket = new ObjectMapper().readTree(Path.of("ticket.json").toFile()); if (!ticket.get("method").asText().equals("PUT")) throw new IllegalArgumentException("Request a default PUT ticket"); var request = HttpRequest.newBuilder(URI.create(ticket.get("uploadUrl").asText())) .timeout(Duration.ofMinutes(30)); for (var header : ticket.get("headers")) request.header(header.get(0).asText(), header.get(1).asText()); var response = HttpClient.newHttpClient().send(request .PUT(HttpRequest.BodyPublishers.ofFile(Path.of("input.png"))).build(), HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException(response.body()); System.out.println("Uploaded; confirm asset " + ticket.get("assetId").asText()); }}// .NET 8+; Program.csusing System;using System.IO;using System.Net.Http;using System.Text.Json;using var ticket = JsonDocument.Parse(await File.ReadAllTextAsync("ticket.json"));var root = ticket.RootElement;if (root.GetProperty("method").GetString() != "PUT") throw new InvalidOperationException("Request a default PUT ticket");using var client = new HttpClient { Timeout = TimeSpan.FromMinutes(30) };using var file = File.OpenRead("input.png");using var request = new HttpRequestMessage(HttpMethod.Put, root.GetProperty("uploadUrl").GetString());request.Content = new StreamContent(file);foreach (var header in root.GetProperty("headers").EnumerateArray()) { var name = header[0].GetString()!; var value = header[1].GetString(); if (!request.Headers.TryAddWithoutValidation(name, value)) request.Content.Headers.TryAddWithoutValidation(name, value);}using var response = await client.SendAsync(request);response.EnsureSuccessStatusCode();Console.WriteLine("Uploaded; confirm asset " + root.GetProperty("assetId").GetString());If you explicitly request multipart: true, the ticket instead uses POST. Send a multipart/form-data body with the file under the returned fileField, keep the returned headers, and let your HTTP library set the multipart boundary. Do not use the PUT example for a POST ticket.
Confirm completion
Section titled “Confirm completion”After the storage request succeeds, confirm with the ticket’s assetId. The service checks the actual media and adds it to your library. This call is idempotent. If the upload response was lost, try completion with the known asset ID before starting another upload. Pending uploads are absent from list/detail responses; keep your ticket until completion succeeds.
/api/v1/assets/{assetId}/completePath, query and headers
| Parameter | Location | Type & constraints |
|---|---|---|
assetIdrequired | path | string |
Request example
curl --include --fail-with-body --silent --show-error --max-time 60 \ --request POST 'https://app.berserkapi.com/api/v1/assets/ASSET_ID/complete' \ --header "Authorization: Bearer $GLACIER_API_KEY"// Node.js 22+; save as example.mjs, then: node example.mjsconst key = process.env.GLACIER_API_KEY;if (!key) throw new Error('Set GLACIER_API_KEY');const response = await fetch('https://app.berserkapi.com/api/v1/assets/ASSET_ID/complete', { method: 'POST', headers: { Authorization: `Bearer ${key}`, }, signal: AbortSignal.timeout(60_000),});const text = await response.text();if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);console.log(response.status, text);# Python 3.10+; standard library; python example.pyimport osimport urllib.requestimport urllib.error
headers = {"Authorization": "Bearer " + os.environ["GLACIER_API_KEY"]}request = urllib.request.Request( "https://app.berserkapi.com/api/v1/assets/ASSET_ID/complete", method="POST", headers=headers,)try: with urllib.request.urlopen(request, timeout=60) as response: print(response.status, response.read().decode("utf-8"))except urllib.error.HTTPError as error: raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8')}") from error// Go 1.22+; go run example.gopackage main
import ( "fmt" "io" "net/http" "os" "time")
func main() { key := os.Getenv("GLACIER_API_KEY") if key == "" { panic("Set GLACIER_API_KEY") } req, err := http.NewRequest("POST", "https://app.berserkapi.com/api/v1/assets/ASSET_ID/complete", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer " + key) client := &http.Client{Timeout: 60 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() data, err := io.ReadAll(res.Body) if err != nil { panic(err) } if res.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, data)) } fmt.Println(res.StatusCode, string(data))}// cargo add reqwest@0.13 --features blocking// Save in src/main.rs, then: cargo runuse std::{env, error::Error, time::Duration};
fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(60)).build()?; let response = client.request(reqwest::Method::POST, "https://app.berserkapi.com/api/v1/assets/ASSET_ID/complete") .bearer_auth(env::var("GLACIER_API_KEY")?) .send()?; let status = response.status(); let text = response.text()?; if !status.is_success() { return Err(format!("HTTP {status}: {text}").into()); } println!("{status} {text}"); Ok(())}// Java 17+; save as Example.java, then: java Example.javaimport java.net.URI;import java.net.http.*;import java.time.Duration;import java.util.Objects;
class Example { public static void main(String[] args) throws Exception { var key = Objects.requireNonNull(System.getenv("GLACIER_API_KEY")); var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build(); var request = HttpRequest.newBuilder(URI.create("https://app.berserkapi.com/api/v1/assets/ASSET_ID/complete")) .timeout(Duration.ofSeconds(60)) .header("Authorization", "Bearer " + key) .method("POST", HttpRequest.BodyPublishers.noBody()) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body()); System.out.println(response.statusCode() + " " + response.body()); }}// .NET 8+; dotnet new console; replace Program.cs; dotnet runusing System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;
var key = Environment.GetEnvironmentVariable("GLACIER_API_KEY") ?? throw new InvalidOperationException("Set GLACIER_API_KEY");using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };using var request = new HttpRequestMessage(new HttpMethod("POST"), "https://app.berserkapi.com/api/v1/assets/ASSET_ID/complete");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);using var response = await client.SendAsync(request);var text = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode) throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");Console.WriteLine($"{(int)response.StatusCode} {text}");Response fields · 200
coverUrlstring | nullrequiredcreatedAtstring · date-timerequireddurationMsinteger | null · int64requiredexpiresAtstring | null · date-timerequiredheightinteger · int64requiredidstringrequiredisPublicbooleanrequiredkind"image" | "video"requiredmimeTypestringrequirednamestringrequiredsizeBytesinteger · int64requiredthumbnailUrlstring | nullrequiredupdatedAtstring · date-timerequiredurlstringrequiredversionCountinteger · int64requiredwidthinteger · int64required
List and paginate assets
Section titled “List and paginate assets”Use scope=mine for your assets or scope=public for samples. scope=all is the default. Optional filters include kind and search. Pass nextCursor back as the cursor query parameter until it is null. The example requests 24 assets.
/api/v1/assetsPath, query and headers
| Parameter | Location | Type & constraints |
|---|---|---|
scopeoptional | query | "all" | "mine" | "public" |
kindoptional | query | "image" | "video" |
searchoptional | query | stringmaxLength: 100 |
limitoptional | query | integer · int64minimum: 1 · maximum: 100 · default: 24 |
cursoroptional | query | string |
Request example
curl --include --fail-with-body --silent --show-error --max-time 60 \ --request GET 'https://app.berserkapi.com/api/v1/assets?scope=mine&limit=24' \ --header "Authorization: Bearer $GLACIER_API_KEY"// Node.js 22+; save as example.mjs, then: node example.mjsconst key = process.env.GLACIER_API_KEY;if (!key) throw new Error('Set GLACIER_API_KEY');const response = await fetch('https://app.berserkapi.com/api/v1/assets?scope=mine&limit=24', { method: 'GET', headers: { Authorization: `Bearer ${key}`, }, signal: AbortSignal.timeout(60_000),});const text = await response.text();if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);console.log(response.status, text);# Python 3.10+; standard library; python example.pyimport osimport urllib.requestimport urllib.error
headers = {"Authorization": "Bearer " + os.environ["GLACIER_API_KEY"]}request = urllib.request.Request( "https://app.berserkapi.com/api/v1/assets?scope=mine&limit=24", method="GET", headers=headers,)try: with urllib.request.urlopen(request, timeout=60) as response: print(response.status, response.read().decode("utf-8"))except urllib.error.HTTPError as error: raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8')}") from error// Go 1.22+; go run example.gopackage main
import ( "fmt" "io" "net/http" "os" "time")
func main() { key := os.Getenv("GLACIER_API_KEY") if key == "" { panic("Set GLACIER_API_KEY") } req, err := http.NewRequest("GET", "https://app.berserkapi.com/api/v1/assets?scope=mine&limit=24", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer " + key) client := &http.Client{Timeout: 60 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() data, err := io.ReadAll(res.Body) if err != nil { panic(err) } if res.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, data)) } fmt.Println(res.StatusCode, string(data))}// cargo add reqwest@0.13 --features blocking// Save in src/main.rs, then: cargo runuse std::{env, error::Error, time::Duration};
fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(60)).build()?; let response = client.request(reqwest::Method::GET, "https://app.berserkapi.com/api/v1/assets?scope=mine&limit=24") .bearer_auth(env::var("GLACIER_API_KEY")?) .send()?; let status = response.status(); let text = response.text()?; if !status.is_success() { return Err(format!("HTTP {status}: {text}").into()); } println!("{status} {text}"); Ok(())}// Java 17+; save as Example.java, then: java Example.javaimport java.net.URI;import java.net.http.*;import java.time.Duration;import java.util.Objects;
class Example { public static void main(String[] args) throws Exception { var key = Objects.requireNonNull(System.getenv("GLACIER_API_KEY")); var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build(); var request = HttpRequest.newBuilder(URI.create("https://app.berserkapi.com/api/v1/assets?scope=mine&limit=24")) .timeout(Duration.ofSeconds(60)) .header("Authorization", "Bearer " + key) .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body()); System.out.println(response.statusCode() + " " + response.body()); }}// .NET 8+; dotnet new console; replace Program.cs; dotnet runusing System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;
var key = Environment.GetEnvironmentVariable("GLACIER_API_KEY") ?? throw new InvalidOperationException("Set GLACIER_API_KEY");using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };using var request = new HttpRequestMessage(new HttpMethod("GET"), "https://app.berserkapi.com/api/v1/assets?scope=mine&limit=24");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);using var response = await client.SendAsync(request);var text = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode) throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");Console.WriteLine($"{(int)response.StatusCode} {text}");Response fields · 200
itemsobject[]requiredExpand fields / variants
coverUrlstring | nullrequiredcreatedAtstring · date-timerequireddurationMsinteger | null · int64requiredexpiresAtstring | null · date-timerequiredheightinteger · int64requiredidstringrequiredisPublicbooleanrequiredkind"image" | "video"requiredmimeTypestringrequirednamestringrequiredsizeBytesinteger · int64requiredthumbnailUrlstring | nullrequiredupdatedAtstring · date-timerequiredurlstringrequiredversionCountinteger · int64requiredwidthinteger · int64required
nextCursorstring | nullrequiredtotalinteger · int64required
Inspect an asset and its versions
Section titled “Inspect an asset and its versions”The response contains asset and versions. Keep the version ID if you want a later task to use it as sourceVersionId. File URLs are temporary; request fresh details when needed. Processing a public sample can create an owned copy; follow the assetId returned by the task.
/api/v1/assets/{assetId}Path, query and headers
| Parameter | Location | Type & constraints |
|---|---|---|
assetIdrequired | path | string |
Request example
curl --include --fail-with-body --silent --show-error --max-time 60 \ --request GET 'https://app.berserkapi.com/api/v1/assets/ASSET_ID' \ --header "Authorization: Bearer $GLACIER_API_KEY"// Node.js 22+; save as example.mjs, then: node example.mjsconst key = process.env.GLACIER_API_KEY;if (!key) throw new Error('Set GLACIER_API_KEY');const response = await fetch('https://app.berserkapi.com/api/v1/assets/ASSET_ID', { method: 'GET', headers: { Authorization: `Bearer ${key}`, }, signal: AbortSignal.timeout(60_000),});const text = await response.text();if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);console.log(response.status, text);# Python 3.10+; standard library; python example.pyimport osimport urllib.requestimport urllib.error
headers = {"Authorization": "Bearer " + os.environ["GLACIER_API_KEY"]}request = urllib.request.Request( "https://app.berserkapi.com/api/v1/assets/ASSET_ID", method="GET", headers=headers,)try: with urllib.request.urlopen(request, timeout=60) as response: print(response.status, response.read().decode("utf-8"))except urllib.error.HTTPError as error: raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8')}") from error// Go 1.22+; go run example.gopackage main
import ( "fmt" "io" "net/http" "os" "time")
func main() { key := os.Getenv("GLACIER_API_KEY") if key == "" { panic("Set GLACIER_API_KEY") } req, err := http.NewRequest("GET", "https://app.berserkapi.com/api/v1/assets/ASSET_ID", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer " + key) client := &http.Client{Timeout: 60 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() data, err := io.ReadAll(res.Body) if err != nil { panic(err) } if res.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, data)) } fmt.Println(res.StatusCode, string(data))}// cargo add reqwest@0.13 --features blocking// Save in src/main.rs, then: cargo runuse std::{env, error::Error, time::Duration};
fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(60)).build()?; let response = client.request(reqwest::Method::GET, "https://app.berserkapi.com/api/v1/assets/ASSET_ID") .bearer_auth(env::var("GLACIER_API_KEY")?) .send()?; let status = response.status(); let text = response.text()?; if !status.is_success() { return Err(format!("HTTP {status}: {text}").into()); } println!("{status} {text}"); Ok(())}// Java 17+; save as Example.java, then: java Example.javaimport java.net.URI;import java.net.http.*;import java.time.Duration;import java.util.Objects;
class Example { public static void main(String[] args) throws Exception { var key = Objects.requireNonNull(System.getenv("GLACIER_API_KEY")); var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build(); var request = HttpRequest.newBuilder(URI.create("https://app.berserkapi.com/api/v1/assets/ASSET_ID")) .timeout(Duration.ofSeconds(60)) .header("Authorization", "Bearer " + key) .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body()); System.out.println(response.statusCode() + " " + response.body()); }}// .NET 8+; dotnet new console; replace Program.cs; dotnet runusing System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;
var key = Environment.GetEnvironmentVariable("GLACIER_API_KEY") ?? throw new InvalidOperationException("Set GLACIER_API_KEY");using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };using var request = new HttpRequestMessage(new HttpMethod("GET"), "https://app.berserkapi.com/api/v1/assets/ASSET_ID");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);using var response = await client.SendAsync(request);var text = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode) throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");Console.WriteLine($"{(int)response.StatusCode} {text}");Response fields · 200
assetobjectrequiredExpand fields / variants
coverUrlstring | nullrequiredcreatedAtstring · date-timerequireddurationMsinteger | null · int64requiredexpiresAtstring | null · date-timerequiredheightinteger · int64requiredidstringrequiredisPublicbooleanrequiredkind"image" | "video"requiredmimeTypestringrequirednamestringrequiredsizeBytesinteger · int64requiredthumbnailUrlstring | nullrequiredupdatedAtstring · date-timerequiredurlstringrequiredversionCountinteger · int64requiredwidthinteger · int64required
versionsobject[]requiredExpand fields / variants
assetIdstringrequiredcreatedAtstring · date-timerequireddownloadUrlstringrequireddurationMsinteger | null · int64requiredframeCountinteger | null · int64requiredframeRatenumber | null · doublerequiredheightinteger · int64requiredidstringrequiredindexinteger · int64requiredlabelstringrequiredmaskUrlstring | nullrequiredmimeTypestringrequiredpreviewPendingbooleanrequiredpreviewUrlstring | nullrequiredsizeBytesinteger · int64requiredsourceVersionIdstring | nullrequiredthumbnailUrlstring | nullrequiredtoolIdstring | nullrequiredurlstringrequiredwatermarkMarksobject[]requiredExpand fields / variants
colorstringoptionalpattern: "^#[0-9a-fA-F]{6}$"
endMsinteger · int64optionalminimum: 0
heightnumber · doublerequiredminimum: 0 · maximum: 1
kind"positive" | "negative" | "absent" | "suggested"optionalobjectIdinteger · int64optionalminimum: 0 · maximum: 7
strokesobject[]optionalmaxItems: 64
Expand fields / variants
pointsnumber · double[][]requiredminItems: 1 · maxItems: 4000
Expand fields / variants
number · doubleradiusnumber · doublerequiredminimum: 0 · maximum: 0.25
timeMsinteger · int64optionalminimum: 0
widthnumber · doublerequiredminimum: 0 · maximum: 1
xnumber · doublerequiredminimum: 0 · maximum: 1
ynumber · doublerequiredminimum: 0 · maximum: 1
watermarkObjectsobject[]requiredExpand fields / variants
namestringrequiredminLength: 1 · maxLength: 24
objectIdinteger · int64requiredminimum: 0 · maximum: 7
widthinteger · int64required
Rename an asset
Section titled “Rename an asset”Only supplied fields are changed. Names are trimmed and need not be unique.
/api/v1/assets/{assetId}Path, query and headers
| Parameter | Location | Type & constraints |
|---|---|---|
assetIdrequired | path | string |
Request body fields · application/json
namestringoptionalminLength: 1 · maxLength: 255
Request example
curl --include --fail-with-body --silent --show-error --max-time 60 \ --request PATCH 'https://app.berserkapi.com/api/v1/assets/ASSET_ID' \ --header "Authorization: Bearer $GLACIER_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{ "name": "Enhanced photo"}'// Node.js 22+; save as example.mjs, then: node example.mjsconst key = process.env.GLACIER_API_KEY;if (!key) throw new Error('Set GLACIER_API_KEY');const response = await fetch('https://app.berserkapi.com/api/v1/assets/ASSET_ID', { method: 'PATCH', headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ "name": "Enhanced photo"}), signal: AbortSignal.timeout(60_000),});const text = await response.text();if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);console.log(response.status, text);# Python 3.10+; standard library; python example.pyimport osimport urllib.requestimport urllib.error
headers = {"Authorization": "Bearer " + os.environ["GLACIER_API_KEY"]}headers["Content-Type"] = "application/json"request = urllib.request.Request( "https://app.berserkapi.com/api/v1/assets/ASSET_ID", method="PATCH", headers=headers, data="""{ "name": "Enhanced photo"}""".encode("utf-8"),)try: with urllib.request.urlopen(request, timeout=60) as response: print(response.status, response.read().decode("utf-8"))except urllib.error.HTTPError as error: raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8')}") from error// Go 1.22+; go run example.gopackage main
import ( "fmt" "io" "net/http" "os" "strings" "time")
func main() { key := os.Getenv("GLACIER_API_KEY") if key == "" { panic("Set GLACIER_API_KEY") } req, err := http.NewRequest("PATCH", "https://app.berserkapi.com/api/v1/assets/ASSET_ID", strings.NewReader(`{ "name": "Enhanced photo"}`)) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer " + key) req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 60 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() data, err := io.ReadAll(res.Body) if err != nil { panic(err) } if res.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, data)) } fmt.Println(res.StatusCode, string(data))}// cargo add reqwest@0.13 --features blocking// Save in src/main.rs, then: cargo runuse std::{env, error::Error, time::Duration};
fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(60)).build()?; let response = client.request(reqwest::Method::PATCH, "https://app.berserkapi.com/api/v1/assets/ASSET_ID") .bearer_auth(env::var("GLACIER_API_KEY")?) .header("Content-Type", "application/json") .body(r#"{ "name": "Enhanced photo"}"#) .send()?; let status = response.status(); let text = response.text()?; if !status.is_success() { return Err(format!("HTTP {status}: {text}").into()); } println!("{status} {text}"); Ok(())}// Java 17+; save as Example.java, then: java Example.javaimport java.net.URI;import java.net.http.*;import java.time.Duration;import java.util.Objects;
class Example { public static void main(String[] args) throws Exception { var key = Objects.requireNonNull(System.getenv("GLACIER_API_KEY")); var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build(); var request = HttpRequest.newBuilder(URI.create("https://app.berserkapi.com/api/v1/assets/ASSET_ID")) .timeout(Duration.ofSeconds(60)) .header("Authorization", "Bearer " + key) .header("Content-Type", "application/json") .method("PATCH", HttpRequest.BodyPublishers.ofString("""{ "name": "Enhanced photo"}""")) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body()); System.out.println(response.statusCode() + " " + response.body()); }}// .NET 8+; dotnet new console; replace Program.cs; dotnet runusing System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;
var key = Environment.GetEnvironmentVariable("GLACIER_API_KEY") ?? throw new InvalidOperationException("Set GLACIER_API_KEY");using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };using var request = new HttpRequestMessage(new HttpMethod("PATCH"), "https://app.berserkapi.com/api/v1/assets/ASSET_ID");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);request.Content = new StringContent("""{ "name": "Enhanced photo"}""", Encoding.UTF8, "application/json");using var response = await client.SendAsync(request);var text = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode) throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");Console.WriteLine($"{(int)response.StatusCode} {text}");Response fields · 200
coverUrlstring | nullrequiredcreatedAtstring · date-timerequireddurationMsinteger | null · int64requiredexpiresAtstring | null · date-timerequiredheightinteger · int64requiredidstringrequiredisPublicbooleanrequiredkind"image" | "video"requiredmimeTypestringrequirednamestringrequiredsizeBytesinteger · int64requiredthumbnailUrlstring | nullrequiredupdatedAtstring · date-timerequiredurlstringrequiredversionCountinteger · int64requiredwidthinteger · int64required
Delete a processed version
Section titled “Delete a processed version”This removes a processed output version. The original cannot be deleted through this endpoint; remove the whole asset instead. A successful deletion returns 204 with no body.
/api/v1/assets/{assetId}/versions/{versionId}Path, query and headers
| Parameter | Location | Type & constraints |
|---|---|---|
assetIdrequired | path | string |
versionIdrequired | path | string |
Request example
curl --include --fail-with-body --silent --show-error --max-time 60 \ --request DELETE 'https://app.berserkapi.com/api/v1/assets/ASSET_ID/versions/VERSION_ID' \ --header "Authorization: Bearer $GLACIER_API_KEY"// Node.js 22+; save as example.mjs, then: node example.mjsconst key = process.env.GLACIER_API_KEY;if (!key) throw new Error('Set GLACIER_API_KEY');const response = await fetch('https://app.berserkapi.com/api/v1/assets/ASSET_ID/versions/VERSION_ID', { method: 'DELETE', headers: { Authorization: `Bearer ${key}`, }, signal: AbortSignal.timeout(60_000),});const text = await response.text();if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);console.log(response.status, text);# Python 3.10+; standard library; python example.pyimport osimport urllib.requestimport urllib.error
headers = {"Authorization": "Bearer " + os.environ["GLACIER_API_KEY"]}request = urllib.request.Request( "https://app.berserkapi.com/api/v1/assets/ASSET_ID/versions/VERSION_ID", method="DELETE", headers=headers,)try: with urllib.request.urlopen(request, timeout=60) as response: print(response.status, response.read().decode("utf-8"))except urllib.error.HTTPError as error: raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8')}") from error// Go 1.22+; go run example.gopackage main
import ( "fmt" "io" "net/http" "os" "time")
func main() { key := os.Getenv("GLACIER_API_KEY") if key == "" { panic("Set GLACIER_API_KEY") } req, err := http.NewRequest("DELETE", "https://app.berserkapi.com/api/v1/assets/ASSET_ID/versions/VERSION_ID", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer " + key) client := &http.Client{Timeout: 60 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() data, err := io.ReadAll(res.Body) if err != nil { panic(err) } if res.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, data)) } fmt.Println(res.StatusCode, string(data))}// cargo add reqwest@0.13 --features blocking// Save in src/main.rs, then: cargo runuse std::{env, error::Error, time::Duration};
fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(60)).build()?; let response = client.request(reqwest::Method::DELETE, "https://app.berserkapi.com/api/v1/assets/ASSET_ID/versions/VERSION_ID") .bearer_auth(env::var("GLACIER_API_KEY")?) .send()?; let status = response.status(); let text = response.text()?; if !status.is_success() { return Err(format!("HTTP {status}: {text}").into()); } println!("{status} {text}"); Ok(())}// Java 17+; save as Example.java, then: java Example.javaimport java.net.URI;import java.net.http.*;import java.time.Duration;import java.util.Objects;
class Example { public static void main(String[] args) throws Exception { var key = Objects.requireNonNull(System.getenv("GLACIER_API_KEY")); var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build(); var request = HttpRequest.newBuilder(URI.create("https://app.berserkapi.com/api/v1/assets/ASSET_ID/versions/VERSION_ID")) .timeout(Duration.ofSeconds(60)) .header("Authorization", "Bearer " + key) .method("DELETE", HttpRequest.BodyPublishers.noBody()) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body()); System.out.println(response.statusCode() + " " + response.body()); }}// .NET 8+; dotnet new console; replace Program.cs; dotnet runusing System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;
var key = Environment.GetEnvironmentVariable("GLACIER_API_KEY") ?? throw new InvalidOperationException("Set GLACIER_API_KEY");using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };using var request = new HttpRequestMessage(new HttpMethod("DELETE"), "https://app.berserkapi.com/api/v1/assets/ASSET_ID/versions/VERSION_ID");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);using var response = await client.SendAsync(request);var text = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode) throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");Console.WriteLine($"{(int)response.StatusCode} {text}");Response fields · 204
No response body. Do not attempt to parse empty JSON.
Delete an asset
Section titled “Delete an asset”Deletes the owned asset and cancels its related tasks. Use this only when the original and its versions are no longer needed. Public samples cannot be deleted. Success returns 204 with no body.
/api/v1/assets/{assetId}Path, query and headers
| Parameter | Location | Type & constraints |
|---|---|---|
assetIdrequired | path | string |
Request example
curl --include --fail-with-body --silent --show-error --max-time 60 \ --request DELETE 'https://app.berserkapi.com/api/v1/assets/ASSET_ID' \ --header "Authorization: Bearer $GLACIER_API_KEY"// Node.js 22+; save as example.mjs, then: node example.mjsconst key = process.env.GLACIER_API_KEY;if (!key) throw new Error('Set GLACIER_API_KEY');const response = await fetch('https://app.berserkapi.com/api/v1/assets/ASSET_ID', { method: 'DELETE', headers: { Authorization: `Bearer ${key}`, }, signal: AbortSignal.timeout(60_000),});const text = await response.text();if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);console.log(response.status, text);# Python 3.10+; standard library; python example.pyimport osimport urllib.requestimport urllib.error
headers = {"Authorization": "Bearer " + os.environ["GLACIER_API_KEY"]}request = urllib.request.Request( "https://app.berserkapi.com/api/v1/assets/ASSET_ID", method="DELETE", headers=headers,)try: with urllib.request.urlopen(request, timeout=60) as response: print(response.status, response.read().decode("utf-8"))except urllib.error.HTTPError as error: raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8')}") from error// Go 1.22+; go run example.gopackage main
import ( "fmt" "io" "net/http" "os" "time")
func main() { key := os.Getenv("GLACIER_API_KEY") if key == "" { panic("Set GLACIER_API_KEY") } req, err := http.NewRequest("DELETE", "https://app.berserkapi.com/api/v1/assets/ASSET_ID", nil) if err != nil { panic(err) } req.Header.Set("Authorization", "Bearer " + key) client := &http.Client{Timeout: 60 * time.Second} res, err := client.Do(req) if err != nil { panic(err) } defer res.Body.Close() data, err := io.ReadAll(res.Body) if err != nil { panic(err) } if res.StatusCode >= 300 { panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, data)) } fmt.Println(res.StatusCode, string(data))}// cargo add reqwest@0.13 --features blocking// Save in src/main.rs, then: cargo runuse std::{env, error::Error, time::Duration};
fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(60)).build()?; let response = client.request(reqwest::Method::DELETE, "https://app.berserkapi.com/api/v1/assets/ASSET_ID") .bearer_auth(env::var("GLACIER_API_KEY")?) .send()?; let status = response.status(); let text = response.text()?; if !status.is_success() { return Err(format!("HTTP {status}: {text}").into()); } println!("{status} {text}"); Ok(())}// Java 17+; save as Example.java, then: java Example.javaimport java.net.URI;import java.net.http.*;import java.time.Duration;import java.util.Objects;
class Example { public static void main(String[] args) throws Exception { var key = Objects.requireNonNull(System.getenv("GLACIER_API_KEY")); var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build(); var request = HttpRequest.newBuilder(URI.create("https://app.berserkapi.com/api/v1/assets/ASSET_ID")) .timeout(Duration.ofSeconds(60)) .header("Authorization", "Bearer " + key) .method("DELETE", HttpRequest.BodyPublishers.noBody()) .build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() >= 300) throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body()); System.out.println(response.statusCode() + " " + response.body()); }}// .NET 8+; dotnet new console; replace Program.cs; dotnet runusing System;using System.Net.Http;using System.Net.Http.Headers;using System.Text;
var key = Environment.GetEnvironmentVariable("GLACIER_API_KEY") ?? throw new InvalidOperationException("Set GLACIER_API_KEY");using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60) };using var request = new HttpRequestMessage(new HttpMethod("DELETE"), "https://app.berserkapi.com/api/v1/assets/ASSET_ID");request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", key);using var response = await client.SendAsync(request);var text = await response.Content.ReadAsStringAsync();if (!response.IsSuccessStatusCode) throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {text}");Console.WriteLine($"{(int)response.StatusCode} {text}");Response fields · 204
No response body. Do not attempt to parse empty JSON.