Storage
S3-compatible buckets and objects with presigned URLs.
1. Overview
https://api.infrai.cc/v1/storageAuthorization: Bearer $INFRAI_API_KEY# Call any /v1/storage capability over raw HTTP — no SDK to install.
# curl:
curl https://api.infrai.cc/v1/storage/... \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json"2. Methods (22)
2.1storage.bucket.create
Create an object-storage bucket. Bucket names must be 3-63 lowercase letters, digits, dots, or hyphens, start and end with a letter or digit, and use canonical region codes such as cn-beijing or ap-singapore.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Required | Bucket name. Length 3-63; lowercase letters, digits, dots, and hyphens only; must start and end with a letter or digit. Prefer name in new integrations; bucket is accepted as an alias. |
bucket | string | Optional | Alias for name. Prefer name in new integrations. |
vendor | string | Optional | Pin a specific vendor instead of auto-routing. |
region | "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-southeast-1" | "ap-northeast-1" | "cn-hangzhou" | "cn-beijing" | "auto" | "ap-singapore" | "ap-hongkong" | "ap-tokyo" | "ap-bangkok" | "na-siliconvalley" | null | Optional | Storage region code, for example cn-beijing for Beijing or ap-singapore for Singapore. Do not pass localized city names such as beijing; unsupported regions return INVALID_REGION. |
acl | "private" | "signed-only" | Optional | Bucket access control. Defaults to private; currently only private and signed-only are supported. public and public-read are not supported.default: "private" |
Returns
Bucket { bucket, vendor, region, created_at, acl? }| Name | Type | Description |
|---|---|---|
bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
name | string | Human-readable name for this resource |
vendor | "r2" | "s3" | "oss" | "cos" | Vendor that handled or will handle this request |
region | string | null | Geographic region where this resource is located or processed |
acl | "private" | "signed-only" | Access control list for the bucket or object |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
cors_rules | object[] | CORS configuration rules for the bucket |
lifecycle_rules | object[] | Lifecycle management rules for the bucket |
lifecycle_rules[].prefix | string | Match objects whose key starts with this.e.g. tmp/ |
lifecycle_rules[].expire_days | integer | null | Auto-delete after N days.≥ 1e.g. 1 |
lifecycle_rules[].transition_class | string | null | Transition to colder storage class (e.g. "glacier"). |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/bucket/create \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "example"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/bucket/create",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'name': 'example'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/create",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "example"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/create",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "example"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"name": "example"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/bucket/create", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/bucket/create"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"name\": \"example\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/bucket/create");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"name\": \"example\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/bucket/create");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"name\": \"example\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/bucket/create")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"name": "example"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/bucket/create")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"name": "example"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.2storage.bucket.list
List your buckets.
Returns
{ items: Bucket[] }| Name | Type | Description |
|---|---|---|
items | object[] | Array of result items in this page |
items[].bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
items[].name | string | Human-readable name for this resource |
items[].vendor | "r2" | "s3" | "oss" | "cos" | Vendor that handled or will handle this request |
items[].region | string | null | Geographic region where this resource is located or processed |
items[].acl | "private" | "signed-only" | Access control list for the bucket or object |
items[].created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
items[].cors_rules | object[] | CORS configuration rules for the bucket |
items[].lifecycle_rules | object[] | Lifecycle management rules for the bucket |
items[].lifecycle_rules[].prefix | string | Match objects whose key starts with this.e.g. tmp/ |
items[].lifecycle_rules[].expire_days | integer | null | Auto-delete after N days.≥ 1e.g. 1 |
items[].lifecycle_rules[].transition_class | string | null | Transition to colder storage class (e.g. "glacier"). |
next_cursor | string | null | Opaque cursor to fetch the next page; null/absent if this is the last page |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000 \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/storage/bucket/list?bucket_id=bkt_42&prefix=uploads%2F&limit=1000")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.3storage.object.presign
Create a presigned URL for uploading or downloading an object. For op=put, send the file binary bytes to the returned URL using the returned method.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Bucket name. |
key | string | Required | Object key (path) within the bucket. |
op | "get" | "put" | Required | Purpose of the presigned URL: get creates a download URL; put creates an upload URL. For op=put, send the file binary bytes to the returned url using the response method.e.g. put |
expires_seconds | number | Optional | Presigned URL lifetime in seconds.≥ 1 |
Returns
PresignedUrl { url, method, expires_at, headers? }| Name | Type | Description |
|---|---|---|
url | string | URL for this resource or endpoint |
method | "PUT" | "POST" | Authentication method used (e.g. email_otp, oauth, password) |
headers | object | null | Custom HTTP headers to include in requests or responses |
fields | object | null | For POST form uploads. |
expires_at | string | ISO 8601 timestamp when this resource or token expiresformat: date-time |
max_bytes | integer | null | Maximum allowed file size in bytes≥ 0 |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"bucket_id": "bkt_42", "key": "uploads/photo.jpg", "ttl_seconds": 3600}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'bucket_id': 'bkt_42', 'key': 'uploads/photo.jpg', 'ttl_seconds': 3600},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"bucket_id": "bkt_42", "key": "uploads/photo.jpg", "ttl_seconds": 3600}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"bucket_id": "bkt_42", "key": "uploads/photo.jpg", "ttl_seconds": 3600}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"bucket_id": "bkt_42", "key": "uploads/photo.jpg", "ttl_seconds": 3600}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"bucket_id\": \"bkt_42\", \"key\": \"uploads/photo.jpg\", \"ttl_seconds\": 3600}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"bucket_id\": \"bkt_42\", \"key\": \"uploads/photo.jpg\", \"ttl_seconds\": 3600}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"bucket_id\": \"bkt_42\", \"key\": \"uploads/photo.jpg\", \"ttl_seconds\": 3600}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"bucket_id": "bkt_42", "key": "uploads/photo.jpg", "ttl_seconds": 3600}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"bucket_id": "bkt_42", "key": "uploads/photo.jpg", "ttl_seconds": 3600}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.4storage.object.delete
Delete a single object from a bucket. After deletion, head/get report the object as not found.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Bucket name. |
key | string | Required | Object key (path) within the bucket. |
Returns
{ ok: boolean }| Name | Type | Description |
|---|---|---|
bucket | string | Bucket the object was deleted from |
key | string | Key of the deleted object |
deleted | boolean | Whether the object existed and was deleted |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X DELETE https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.delete(
"https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("DELETE", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.delete("https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.5storage.bucket.get
Get bucket meta information
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
Returns
Bucket { bucket_id, name, vendor, region, acl, created_at, cors_rules, lifecycle_rules }| Name | Type | Description |
|---|---|---|
bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
name | string | Human-readable name for this resource |
vendor | "r2" | "s3" | "oss" | "cos" | Vendor that handled or will handle this request |
region | string | null | Geographic region where this resource is located or processed |
acl | "private" | "signed-only" | Access control list for the bucket or object |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
cors_rules | object[] | CORS configuration rules for the bucket |
lifecycle_rules | object[] | Lifecycle management rules for the bucket |
lifecycle_rules[].prefix | string | Match objects whose key starts with this.e.g. tmp/ |
lifecycle_rules[].expire_days | integer | null | Auto-delete after N days.≥ 1e.g. 1 |
lifecycle_rules[].transition_class | string | null | Transition to colder storage class (e.g. "glacier"). |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/storage/bucket/get/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/bucket/get/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/get/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/get/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/storage/bucket/get/BUCKET", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/bucket/get/BUCKET"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/storage/bucket/get/BUCKET");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/bucket/get/BUCKET");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/bucket/get/BUCKET")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/storage/bucket/get/BUCKET")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.6storage.bucket.delete
Delete a bucket. Empty buckets can be deleted directly; non-empty buckets require force=true, otherwise STORAGE_DELETE_NOT_FORCED is returned.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Bucket name |
force | boolean | Optional | Whether to force-delete a non-empty bucket. Defaults to false: if objects remain, the API returns STORAGE_DELETE_NOT_FORCED; true deletes the bucket and its objects. |
idempotency_key | string | Optional | Idempotency key; derived automatically when omitted. |
Returns
BucketDeleteResult { deleted }| Name | Type | Description |
|---|---|---|
deleted | boolean | Whether the resource was successfully deleted |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X DELETE https://api.infrai.cc/v1/storage/bucket/delete/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.delete(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.infrai.cc/v1/storage/bucket/delete/BUCKET", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/bucket/delete/BUCKET"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("DELETE", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.infrai.cc/v1/storage/bucket/delete/BUCKET");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/bucket/delete/BUCKET");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/bucket/delete/BUCKET")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.delete("https://api.infrai.cc/v1/storage/bucket/delete/BUCKET")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.7storage.bucket.usage
Query bucket usage
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
Returns
BucketUsageResult { byte_count, object_count, as_of }| Name | Type | Description |
|---|---|---|
byte_count | integer | Total bytes stored in the bucket≥ 0 |
object_count | integer | Number of objects in the bucket≥ 0 |
as_of | string | ISO 8601 timestamp when the usage was measuredformat: date-time |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/storage/bucket/usage/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/bucket/usage/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/usage/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/usage/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/storage/bucket/usage/BUCKET", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/bucket/usage/BUCKET"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/storage/bucket/usage/BUCKET");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/bucket/usage/BUCKET");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/bucket/usage/BUCKET")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/storage/bucket/usage/BUCKET")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.8storage.bucket.set_lifecycle
Set bucket lifecycle rules.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Bucket name. |
rules | Array<{ prefix: string; expire_days?: number; transition_class?: string }> | Required | Lifecycle rule list. Each rule can include prefix, expire_days, and transition_class; expire_days is measured in days and must be at least 1. The submitted rules replace the current list.e.g. [{"prefix":"tmp/","expire_days":1}] |
idempotency_key | string | Optional | Idempotency key; derived automatically when omitted. |
Returns
Bucket { bucket_id, name, vendor, region, acl, created_at, cors_rules, lifecycle_rules }| Name | Type | Description |
|---|---|---|
bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
name | string | Human-readable name for this resource |
vendor | "r2" | "s3" | "oss" | "cos" | Vendor that handled or will handle this request |
region | string | null | Geographic region where this resource is located or processed |
acl | "private" | "signed-only" | Access control list for the bucket or object |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
cors_rules | object[] | CORS configuration rules for the bucket |
lifecycle_rules | object[] | Lifecycle management rules for the bucket |
lifecycle_rules[].prefix | string | Match objects whose key starts with this.e.g. tmp/ |
lifecycle_rules[].expire_days | integer | null | Auto-delete after N days.≥ 1e.g. 1 |
lifecycle_rules[].transition_class | string | null | Transition to colder storage class (e.g. "glacier"). |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"rules": [{"prefix": "tmp/", "expire_days": 1}]}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'rules': [{'prefix': 'tmp/', 'expire_days': 1}]},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"rules": [{"prefix": "tmp/", "expire_days": 1}]}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"rules": [{"prefix": "tmp/", "expire_days": 1}]}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"rules": [{"prefix": "tmp/", "expire_days": 1}]}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"rules\": [{\"prefix\": \"tmp/\", \"expire_days\": 1}]}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"rules\": [{\"prefix\": \"tmp/\", \"expire_days\": 1}]}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"rules\": [{\"prefix\": \"tmp/\", \"expire_days\": 1}]}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"rules": [{"prefix": "tmp/", "expire_days": 1}]}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"rules": [{"prefix": "tmp/", "expire_days": 1}]}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.9storage.bucket.set_notification
Subscribe storage object events to a callback URL.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Bucket name. |
events | ("object.created" | "object.deleted" | "multipart.completed")[] | Required | Event types to subscribe to. Supported values are object.created, object.deleted, and multipart.completed.≥ 1 iteme.g. ["object.created","object.deleted","multipart.completed"] |
target | { url: string } | Required | Callback target. Pass {"url":"https://..."}; when an event fires, the endpoint receives a JSON POST with X-Infrai-Event and body fields event/type, account_id, bucket, key, timestamp, and subscription_id.e.g. {"url":"https://example.com/storage-events"} |
idempotency_key | string | Optional | Idempotency key; derived automatically when omitted. |
Returns
BucketSetNotificationResult { subscription_id }| Name | Type | Description |
|---|---|---|
subscription_id | string | Unique identifier for this subscription |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"events": ["object.created", "object.deleted", "multipart.completed"], "target": {"url": "https://example.com/storage-events"}}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'events': ['object.created', 'object.deleted', 'multipart.completed'], 'target': {'url': 'https://example.com/storage-events'}},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"events": ["object.created", "object.deleted", "multipart.completed"], "target": {"url": "https://example.com/storage-events"}}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"events": ["object.created", "object.deleted", "multipart.completed"], "target": {"url": "https://example.com/storage-events"}}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"events": ["object.created", "object.deleted", "multipart.completed"], "target": {"url": "https://example.com/storage-events"}}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"events\": [\"object.created\", \"object.deleted\", \"multipart.completed\"], \"target\": {\"url\": \"https://example.com/storage-events\"}}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"events\": [\"object.created\", \"object.deleted\", \"multipart.completed\"], \"target\": {\"url\": \"https://example.com/storage-events\"}}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"events\": [\"object.created\", \"object.deleted\", \"multipart.completed\"], \"target\": {\"url\": \"https://example.com/storage-events\"}}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"events": ["object.created", "object.deleted", "multipart.completed"], "target": {"url": "https://example.com/storage-events"}}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/bucket/set_notification/BUCKET")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"events": ["object.created", "object.deleted", "multipart.completed"], "target": {"url": "https://example.com/storage-events"}}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.10storage.object.put
Upload an object server-side with JSON data_base64. Base64 upload is intended for small files and is not recommended above 1 MB; use presigned direct upload or multipart direct upload for larger files.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
key | string | Required | Object key (path) |
data_base64 | string | Required | Object bytes encoded as a base64 string in the JSON request body. A data: URL is also accepted. Base64 upload is intended for small files and is not recommended above 1 MB. |
data | string | null | Optional | Alias for data_base64. |
file_base64 | string | null | Optional | Alias for data_base64. |
content_type | string | Optional | The MIME type of the object |
metadata | Record<string, string> | Optional | Any user-defined metadata key-value pair |
cache_control | string | Optional | Cache-Control header |
storage_class | string | Optional | Storage class (default standard)default: "standard" |
idempotency_key | string | Optional | Idempotent key; automatically derived by content hash when omitted |
Returns
StorageObject { bucket_id, key, size_bytes, etag, content_type, metadata, created_at, last_modified }| Name | Type | Description |
|---|---|---|
bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
key | string | Unique identifier key for this resource |
size_bytes | integer | Size of the resource in bytes≥ 0 |
etag | string | ETag hash of the object content |
content_type | string | null | MIME type of the object |
metadata | object | null | Arbitrary key-value metadata attached to this resource |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
last_modified | string | null | ISO 8601 timestamp when the object was last modifiedformat: date-time |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X PUT https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"data_base64": "sample"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.put(
"https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'data_base64': 'sample'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY",
{
method: "PUT",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"data_base64": "sample"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY",
{
method: "PUT",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"data_base64": "sample"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"data_base64": "sample"}`)
req, _ := http.NewRequest("PUT", "https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("PUT", HttpRequest.BodyPublishers.ofString("{\"data_base64\": \"sample\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("PUT"), "https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"data_base64\": \"sample\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"data_base64\": \"sample\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Put.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"data_base64": "sample"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.put("https://api.infrai.cc/v1/storage/object/put/BUCKET/KEY")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"data_base64": "sample"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.11storage.object.get
Download object content as JSON metadata plus base64-encoded data_base64.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
key | string | Required | Object key (path) |
Returns
object bytes (application/octet-stream)| Name | Type | Description |
|---|---|---|
found | boolean | Whether the object was found |
status | string | "found" or "not_found" |
key | string | Key of the requested object |
size_bytes | integer | Size of the object in bytes (present only when found) |
data_base64 | string | Base64-encoded object content (present only when found) |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/storage/object/get/BUCKET/KEY")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.12storage.object.head
Query object meta information
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
key | string | Required | Object key (path) |
Returns
ObjectHeadResult { found, status, key, size_bytes, etag, content_type, metadata, last_modified }| Name | Type | Description |
|---|---|---|
found | boolean | Whether the resource was found |
status | "found" | "not_found" | Current status of this resource |
key | string | null | Unique identifier key for this resource |
size_bytes | integer | null | Size of the resource in bytes≥ 0 |
etag | string | null | ETag hash of the object content |
content_type | string | null | MIME type of the object |
metadata | object | null | Arbitrary key-value metadata attached to this resource |
last_modified | string | null | ISO 8601 timestamp when the object was last modifiedformat: date-time |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/storage/object/head/BUCKET/KEY")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.13storage.object.list
List objects in bucket
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
prefix | string | Optional | List only objects whose keys begin with this prefix |
delimiter | string | Optional | S3-style directory separators (e.g. /), merging keys into common_prefixes |
cursor | string | Optional | paging cursor from last next_cursor |
limit | number | Optional | The maximum number of items returned this time (1-1000) |
Returns
ObjectListResult { items: StorageObject[], next_cursor, common_prefixes }| Name | Type | Description |
|---|---|---|
items | object[] | Array of result items in this page |
items[].bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
items[].key | string | Unique identifier key for this resource |
items[].size_bytes | integer | Size of the resource in bytes≥ 0 |
items[].etag | string | ETag hash of the object content |
items[].content_type | string | null | MIME type of the object |
items[].metadata | object | null | Arbitrary key-value metadata attached to this resource |
items[].created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
items[].last_modified | string | null | ISO 8601 timestamp when the object was last modifiedformat: date-time |
next_cursor | string | null | Opaque cursor to fetch the next page; null/absent if this is the last page |
common_prefixes | string[] | null | S3-style folder prefixes when a delimiter was supplied to object.list. |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X GET https://api.infrai.cc/v1/storage/object/list/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/object/list/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/list/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/list/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.infrai.cc/v1/storage/object/list/BUCKET", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/list/BUCKET"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("GET"), "https://api.infrai.cc/v1/storage/object/list/BUCKET");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/list/BUCKET");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/list/BUCKET")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.infrai.cc/v1/storage/object/list/BUCKET")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.14storage.object.copy
Copy an object within or across buckets while preserving content_type and custom metadata.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
src_bucket | string | Required | Source bucket name |
src_key | string | Required | source object key |
dst_bucket | string | Required | Target bucket name |
dst_key | string | Required | target object key |
idempotency_key | string | Optional | Idempotent key; automatically derived when omitted |
Returns
StorageObject { bucket_id, key, size_bytes, etag, content_type, metadata, created_at, last_modified }| Name | Type | Description |
|---|---|---|
bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
key | string | Unique identifier key for this resource |
size_bytes | integer | Size of the resource in bytes≥ 0 |
etag | string | ETag hash of the object content |
content_type | string | null | MIME type of the object |
metadata | object | null | Arbitrary key-value metadata attached to this resource |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
last_modified | string | null | ISO 8601 timestamp when the object was last modifiedformat: date-time |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/object/copy \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"src_bucket": "sample", "src_key": "sample", "dst_bucket": "sample", "dst_key": "sample"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/object/copy",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'src_bucket': 'sample', 'src_key': 'sample', 'dst_bucket': 'sample', 'dst_key': 'sample'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/copy",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"src_bucket": "sample", "src_key": "sample", "dst_bucket": "sample", "dst_key": "sample"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/copy",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"src_bucket": "sample", "src_key": "sample", "dst_bucket": "sample", "dst_key": "sample"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"src_bucket": "sample", "src_key": "sample", "dst_bucket": "sample", "dst_key": "sample"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/object/copy", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/copy"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"src_bucket\": \"sample\", \"src_key\": \"sample\", \"dst_bucket\": \"sample\", \"dst_key\": \"sample\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/object/copy");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"src_bucket\": \"sample\", \"src_key\": \"sample\", \"dst_bucket\": \"sample\", \"dst_key\": \"sample\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/copy");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"src_bucket\": \"sample\", \"src_key\": \"sample\", \"dst_bucket\": \"sample\", \"dst_key\": \"sample\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/copy")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"src_bucket": "sample", "src_key": "sample", "dst_bucket": "sample", "dst_key": "sample"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/object/copy")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"src_bucket": "sample", "src_key": "sample", "dst_bucket": "sample", "dst_key": "sample"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.15storage.object.delete_batch
Delete objects in a batch, returning deleted and errors; missing keys are reported in errors.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
keys | string[] | Required | Object keys to delete, 1-1000 items. Missing keys are returned in errors with code STORAGE_OBJECT_NOT_FOUND.1–1000 items |
idempotency_key | string | Optional | Idempotent keys; when omitted, the key collection content hash is automatically derived |
Returns
ObjectDeleteBatchResult { deleted, errors }| Name | Type | Description |
|---|---|---|
deleted | string[] | Keys successfully deleted. |
errors | object[] | Array of per-item errors (for batch operations) |
errors[].key | string | - |
errors[].code | string | Error code from errors/registry.yaml. |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"keys": ["sample"]}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'keys': ['sample']},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"keys": ["sample"]}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"keys": ["sample"]}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"keys": ["sample"]}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"keys\": [\"sample\"]}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"keys\": [\"sample\"]}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"keys\": [\"sample\"]}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"keys": ["sample"]}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/object/delete_batch/BUCKET")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"keys": ["sample"]}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.16storage.object.set_acl
Set object access policy. Current supported ACL values are private and signed-only; public/public-read are not supported.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
key | string | Required | Object key (path) |
acl | "private" | "signed-only" | Required | Access policy. Supported values are private and signed-only; public and public-read are not supported, and public_url is always null. |
idempotency_key | string | Optional | Idempotent key; automatically derived when omitted |
Returns
ObjectSetAclResult { acl, public_url }| Name | Type | Description |
|---|---|---|
acl | "private" | "signed-only" | Access control list for the bucket or object |
public_url | string | null | Always null (public-read removed; no permanent public direct link). |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"acl": "private"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'acl': 'private'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"acl": "private"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"acl": "private"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"acl": "private"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"acl\": \"private\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"acl\": \"private\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"acl\": \"private\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"acl": "private"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/object/set_acl/BUCKET/KEY")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"acl": "private"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.17storage.object.set_metadata
Update an object content_type, cache_control, and custom metadata. metadata uses replacement semantics.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
key | string | Required | Object key (path) |
content_type | string | Optional | The MIME type of the object |
cache_control | string | Optional | Cache-Control header |
metadata | Record<string, string> | Optional | Custom metadata key/value pairs. Passing metadata replaces the previous metadata instead of merging with it; omitted metadata preserves the old value. |
idempotency_key | string | Optional | Idempotent key; automatically derived when omitted |
Returns
StorageObject { bucket_id, key, size_bytes, etag, content_type, metadata, created_at, last_modified }| Name | Type | Description |
|---|---|---|
bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
key | string | Unique identifier key for this resource |
size_bytes | integer | Size of the resource in bytes≥ 0 |
etag | string | ETag hash of the object content |
content_type | string | null | MIME type of the object |
metadata | object | null | Arbitrary key-value metadata attached to this resource |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
last_modified | string | null | ISO 8601 timestamp when the object was last modifiedformat: date-time |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/object/set_metadata/BUCKET/KEY")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.18storage.multipart.create
Initiate a multipart upload
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | bucket name |
key | string | Required | Object key (path) |
content_type | string | Optional | The MIME type of the object |
idempotency_key | string | Optional | Idempotent key; automatically derived when omitted |
Returns
MultipartUpload { upload_id, bucket_id, key, started_at, part_size_min, part_count_max }| Name | Type | Description |
|---|---|---|
upload_id | string | Unique identifier for this multipart upload |
bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
key | string | Unique identifier key for this resource |
started_at | string | ISO 8601 timestamp when execution startedformat: date-time |
part_size_min | integer | null | Vendor minimum part size (≥5 MiB for S3).≥ 5242880 |
part_count_max | integer | null | Maximum number of parts allowed1–10000 |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/multipart/create/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"key": "sample"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/multipart/create/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'key': 'sample'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/create/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"key": "sample"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/create/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"key": "sample"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"key": "sample"}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/multipart/create/BUCKET", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/multipart/create/BUCKET"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"key\": \"sample\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/multipart/create/BUCKET");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"key\": \"sample\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/multipart/create/BUCKET");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"key\": \"sample\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/multipart/create/BUCKET")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"key": "sample"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/multipart/create/BUCKET")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"key": "sample"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.19storage.multipart.presign_part
Generate a presigned upload URL for one part. Upload that part binary with the returned method and pass the returned ETag to complete.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
upload_id | string | Required | Multipart upload ID |
part_number | number | Required | Part number, starting at 1. Except for the final part, the binary part uploaded to this URL usually must be at least 5 MiB.≥ 1 |
Returns
MultipartPresignPartResult { url, method, headers, expires_at }| Name | Type | Description |
|---|---|---|
url | string | URL for this resource or endpoint |
method | "PUT" | Authentication method used (e.g. email_otp, oauth, password) |
headers | object | null | Custom HTTP headers to include in requests or responses |
expires_at | string | ISO 8601 timestamp when this resource or token expiresformat: date-time |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"upload_id": "sample", "part_number": 1}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'upload_id': 'sample', 'part_number': 1},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"upload_id": "sample", "part_number": 1}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"upload_id": "sample", "part_number": 1}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"upload_id": "sample", "part_number": 1}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"upload_id\": \"sample\", \"part_number\": 1}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"upload_id\": \"sample\", \"part_number\": 1}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"upload_id\": \"sample\", \"part_number\": 1}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"upload_id": "sample", "part_number": 1}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/multipart/presign_part/UPLOAD_ID/PART_NUMBER")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"upload_id": "sample", "part_number": 1}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.20storage.multipart.upload_part
Upload a single shard
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
upload_id | string | Required | Multipart upload ID |
part_number | number | Required | Fragment serial number (starting from 1)≥ 1 |
body | bytes | Required | Slice byte content |
idempotency_key | string | Optional | Idempotent key; automatically derived when omitted |
Returns
MultipartPart { part_number, etag }| Name | Type | Description |
|---|---|---|
part_number | integer | Part number in the multipart upload1–10000 |
etag | string | ETag hash of the object content |
size_bytes | integer | null | Size of the resource in bytes≥ 0 |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X PUT https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"upload_id": "sample", "part_number": 1, "data_base64": "sample"}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.put(
"https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'upload_id': 'sample', 'part_number': 1, 'data_base64': 'sample'},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER",
{
method: "PUT",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"upload_id": "sample", "part_number": 1, "data_base64": "sample"}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER",
{
method: "PUT",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"upload_id": "sample", "part_number": 1, "data_base64": "sample"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"upload_id": "sample", "part_number": 1, "data_base64": "sample"}`)
req, _ := http.NewRequest("PUT", "https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("PUT", HttpRequest.BodyPublishers.ofString("{\"upload_id\": \"sample\", \"part_number\": 1, \"data_base64\": \"sample\"}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("PUT"), "https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"upload_id\": \"sample\", \"part_number\": 1, \"data_base64\": \"sample\"}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"upload_id\": \"sample\", \"part_number\": 1, \"data_base64\": \"sample\"}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Put.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"upload_id": "sample", "part_number": 1, "data_base64": "sample"}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.put("https://api.infrai.cc/v1/storage/multipart/upload_part/UPLOAD_ID/PART_NUMBER")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"upload_id": "sample", "part_number": 1, "data_base64": "sample"}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.21storage.multipart.complete
Complete multipart upload
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
upload_id | string | Required | Multipart upload ID |
parts | MultipartPart[] | Required | Uploaded part list, each with part_number and etag, 1-10000 items. Use the ETag returned by each part upload.1–10000 items |
idempotency_key | string | Optional | Idempotent key; automatically derived when omitted |
Returns
StorageObject { bucket_id, key, size_bytes, etag, content_type, metadata, created_at, last_modified }| Name | Type | Description |
|---|---|---|
bucket_id | string | Unique identifier for this storage bucketpattern: ^bkt_[A-Za-z0-9]{20,}$ |
key | string | Unique identifier key for this resource |
size_bytes | integer | Size of the resource in bytes≥ 0 |
etag | string | ETag hash of the object content |
content_type | string | null | MIME type of the object |
metadata | object | null | Arbitrary key-value metadata attached to this resource |
created_at | string | ISO 8601 timestamp when this resource was createdformat: date-time |
last_modified | string | null | ISO 8601 timestamp when the object was last modifiedformat: date-time |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X POST https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"parts": [{"part_number": 1, "etag": "sample"}]}'# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'parts': [{'part_number': 1, 'etag': 'sample'}]},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"parts": [{"part_number": 1, "etag": "sample"}]}),
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"parts": [{"part_number": 1, "etag": "sample"}]}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"bytes"
"fmt"
"net/http"
"os"
)
func main() {
body := []byte(`{"parts": [{"part_number": 1, "etag": "sample"}]}`)
req, _ := http.NewRequest("POST", "https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\"parts\": [{\"part_number\": 1, \"etag\": \"sample\"}]}"))
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("POST"), "https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
req.Content = new StringContent("{\"parts\": [{\"part_number\": 1, \"etag\": \"sample\"}]}", System.Text.Encoding.UTF8, "application/json");
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
"Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"parts\": [{\"part_number\": 1, \"etag\": \"sample\"}]}");
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
req["Content-Type"] = "application/json"
req.body = '{"parts": [{"part_number": 1, "etag": "sample"}]}'
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.post("https://api.infrai.cc/v1/storage/multipart/complete/UPLOAD_ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.header("Content-Type", "application/json")
.body(r#"{"parts": [{"part_number": 1, "etag": "sample"}]}"#)
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}2.22storage.multipart.abort
Abort a multipart upload. After success, the upload_id is invalid and later presign_part/complete calls return STORAGE_MULTIPART_INCONSISTENT.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
upload_id | string | Required | Multipart upload ID |
idempotency_key | string | Optional | Idempotent key; automatically derived when omitted |
Returns
MultipartAbortResult { aborted }| Name | Type | Description |
|---|---|---|
aborted | boolean | Whether the multipart upload was successfully aborted |
Example
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."curl -X DELETE https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.delete(
"https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);// Zero-install REST call — no SDK required (short-term the API is REST-only).
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}// Zero-install REST call — no SDK required (short-term the API is REST-only).
import java.net.URI;
import java.net.http.*;
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID"))
.header("Authorization", "Bearer " + System.getenv("INFRAI_API_KEY"))
.method("DELETE", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> resp = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());// Zero-install REST call — no SDK required (short-term the API is REST-only).
using System;
using System.Net.Http;
var client = new HttpClient();
var req = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID");
var key = Environment.GetEnvironmentVariable("INFRAI_API_KEY");
req.Headers.Add("Authorization", "Bearer " + key);
var resp = await client.SendAsync(req);
Console.WriteLine(await resp.Content.ReadAsStringAsync());<?php
// Zero-install REST call — no SDK required (short-term the API is REST-only).
$ch = curl_init("https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("INFRAI_API_KEY"),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;# Zero-install REST call — no SDK required (short-term the API is REST-only).
require "net/http"
require "uri"
uri = URI("https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer #{ENV['INFRAI_API_KEY']}"
res = http.request(req)
puts res.body// Zero-install REST call — no SDK required (short-term the API is REST-only). (uses the reqwest + tokio crates)
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.delete("https://api.infrai.cc/v1/storage/multipart/abort/UPLOAD_ID")
.header("Authorization", format!("Bearer {}", env::var("INFRAI_API_KEY")?))
.send()
.await?;
println!("{}", resp.text().await?);
Ok(())
}Advanced: pin a vendor
By default infrai routes each call to the best available provider — you do not pick a vendor. As an escape hatch, this capability accepts an optional vendor parameter to pin one specific provider. Every live vendor for this capability is available in real time from the discovery endpoint for the capability id — see the discovery API.
GET /v1/discovery/{capability}storage.bucket.create
3. All capabilities
Every routed capability in this module — the complete public REST contract. The methods above are the guided walkthrough; this index is the full reference.
storage.bucket.createPOST /v1/storage/bucket/createCreate an object storage bucket. Bucket names must be 3-63 lowercase letters, digits, dots, or hyphens and start/end with a letter or digit; `region` must be a canonical region code.
Parameters (6)
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Required | Bucket name. Length 3-63; lowercase letters, digits, dots, and hyphens only; must start and end with a letter or digit. Example: demo-files. |
bucket | string | null | Optional | Alias for name. Prefer name in new integrations. |
vendor | string | null | Optional | Pin to a specific storage vendor. |
region | "us-east-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-southeast-1" | "ap-northeast-1" | "cn-hangzhou" | "cn-beijing" | "auto" | "ap-singapore" | "ap-hongkong" | "ap-tokyo" | "ap-bangkok" | "na-siliconvalley" | null | Optional | Optional storage region code. Pass a canonical code such as cn-beijing for Beijing or ap-singapore for Singapore; localized city names are rejected. |
acl | string | Optional | Bucket access control. Defaults to private; currently only private and signed-only are supported. public and public-read are not supported.default: "private" |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.bucket.deleteDELETE /v1/storage/bucket/delete/{bucket}Delete an object storage bucket (idempotent). Empty buckets can be deleted directly; non-empty buckets require `force=true`, otherwise the API returns STORAGE_DELETE_NOT_FORCED.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
storage.bucket.getGET /v1/storage/bucket/get/{bucket}Retrieve a bucket's metadata (provider, region, ACL, CORS, and lifecycle rules).
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
storage.bucket.listGET /v1/storage/bucket/listList the account's object storage buckets.
No request parameters.
storage.bucket.notification.deleteDELETE /v1/storage/bucket/notification/delete/{bucket}/{subscription_id}Delete an event notification subscription from a storage bucket.
Parameters (2)
| Name | Type | Required | Description |
|---|---|---|---|
subscription_id | string | Required | Path parameter. |
bucket | string | Required | Path parameter. |
storage.bucket.notificationsGET /v1/storage/bucket/notifications/{bucket}List event notification subscriptions for a storage bucket.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
storage.bucket.set_corsPOST /v1/storage/bucket/set_cors/{bucket}Set browser CORS rules for a storage bucket.
Parameters (3)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
rules | object[] | Required | Complete replacement CORS rule set. An empty array clears CORS configuration. |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.bucket.set_lifecyclePOST /v1/storage/bucket/set_lifecycle/{bucket}Set bucket lifecycle rules by key prefix; expire_days is measured in days and must be at least 1.
Parameters (3)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
rules | object[] | Required | Lifecycle rule set governing object expiration/transition. Each rule supports prefix, expire_days, and transition_class. The whole list replaces the existing rule set.e.g. [{"prefix":"tmp/","expire_days":1}] |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.bucket.set_notificationPOST /v1/storage/bucket/set_notification/{bucket}Subscribe storage object events to a callback URL; Infrai sends JSON POST notifications with X-Infrai-Event.
Parameters (4)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
events | ("object.created" | "object.deleted" | "multipart.completed")[] | Required | Event types that trigger a notification. Supported values are object.created, object.deleted, and multipart.completed.≥ 1 iteme.g. ["object.created","object.deleted","multipart.completed"] |
target | object | Required | Notification callback target. For public API usage, pass target.url.e.g. {"url":"https://example.com/storage-events"} |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.bucket.usageGET /v1/storage/bucket/usage/{bucket}Query a bucket's usage statistics: object count, bytes stored, and measurement timestamp.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
storage.multipart.abortDELETE /v1/storage/multipart/abort/{upload_id}Abort a multipart upload and invalidate the upload_id.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
upload_id | string | Required | Path parameter. |
storage.multipart.completePOST /v1/storage/multipart/complete/{upload_id}Complete a multipart upload, assembling parts into the final StorageObject.
Parameters (3)
| Name | Type | Required | Description |
|---|---|---|---|
upload_id | string | Required | Path parameter. |
parts | object[] | Required | Uploaded parts (part number + ETag) to assemble into the final object, in order.1–10000 items |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.multipart.createPOST /v1/storage/multipart/create/{bucket}Initiate a multipart upload, returning an upload_id and part size/count limits.
Parameters (4)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
key | string | Required | Destination object key (path) for the multipart upload. |
content_type | string | null | Optional | MIME type of the object |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.multipart.presign_partPOST /v1/storage/multipart/presign_part/{upload_id}/{part_number}Generate a presigned upload URL for a single part; upload the part binary with the returned method.
Parameters (3)
| Name | Type | Required | Description |
|---|---|---|---|
upload_id | string | Required | Id of the multipart upload. |
part_number | integer | Required | 1-based index of the part being uploaded. Except for the final part, S3-compatible multipart uploads usually require each part to be at least 5 MiB.≥ 1 |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.multipart.upload_partPUT /v1/storage/multipart/upload_part/{upload_id}/{part_number}Upload the bytes of a single part, returning that part's etag.
Parameters (6)
| Name | Type | Required | Description |
|---|---|---|---|
upload_id | string | Required | Id of the multipart upload. |
part_number | integer | Required | 1-based index of this part.≥ 1 |
data_base64 | string | Required | Base64-encoded part bytes (the part payload — required). Aliases data/file_base64 are also accepted by the server. |
data | string | null | Optional | Base64-encoded part bytes (alias of data_base64/file_base64). |
file_base64 | string | null | Optional | Base64-encoded part bytes (alias). |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.object.copyPOST /v1/storage/object/copyCopy an object within or across buckets, preserving content_type and metadata.
Parameters (5)
| Name | Type | Required | Description |
|---|---|---|---|
src_bucket | string | Required | Source bucket to copy from. |
src_key | string | Required | Source object key (path) to copy from. |
dst_bucket | string | Required | Destination bucket to copy into. |
dst_key | string | Required | Destination object key (path) to write. |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.object.deleteDELETE /v1/storage/object/delete/{bucket}/{key}Delete a storage object (idempotent).
Parameters (2)
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Required | Path parameter. |
bucket | string | Required | Path parameter. |
storage.object.delete_batchPOST /v1/storage/object/delete_batch/{bucket}Delete up to 1000 objects in one call, returning deleted keys plus per-key errors.
Parameters (3)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
keys | string[] | Required | Object keys to delete in one batch. Missing keys are returned in errors with code STORAGE_OBJECT_NOT_FOUND.1–1000 items |
idempotency_key | string | null | Optional | Optional; SDK auto-derives from the content_hash of the key set when omitted. |
storage.object.getGET /v1/storage/object/get/{bucket}/{key}Download an object's contents as JSON metadata plus base64-encoded data_base64.
Parameters (2)
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Required | Path parameter. |
bucket | string | Required | Path parameter. |
storage.object.headGET /v1/storage/object/head/{bucket}/{key}Fetch an object's existence and metadata (size, etag, content_type, metadata) without the body.
Parameters (2)
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Required | Path parameter. |
bucket | string | Required | Path parameter. |
storage.object.listGET /v1/storage/object/list/{bucket}List objects in a bucket, supporting prefix, delimiter, and cursor pagination.
Parameters (1)
| Name | Type | Required | Description |
|---|---|---|---|
bucket | string | Required | Path parameter. |
storage.object.presignPOST /v1/storage/object/presign/{bucket}/{key}Generate a presigned URL for direct client upload or download of an object (idempotent). For `op=put`, use the returned URL with its returned method (usually PUT) to upload raw binary bytes directly; do not send the Infrai API key to the presigned URL.
Parameters (8)
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Required | Path parameter. |
bucket | string | Required | Path parameter. |
op | "get" | "put" | Required | Operation type: get creates a download URL; put creates an upload URL for direct binary upload.e.g. put |
expires_seconds | integer | null | Optional | TTL of the presigned URL (defaults: get=3600, put=300).≥ 1 |
content_type | string | null | Optional | For op=put: constrain the upload content type. |
max_bytes | integer | null | Optional | For op=put: cap the upload size.≥ 0 |
response_disposition | string | null | Optional | For op=get: Content-Disposition for the download filename. |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.object.putPUT /v1/storage/object/put/{bucket}/{key}Upload an object server-side with JSON `data_base64`. Base64 upload is intended for small files and is not recommended above 1 MB; use presigned or multipart direct upload for larger files.
Parameters (10)
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Required | Path parameter. |
bucket | string | Required | Path parameter. |
data_base64 | string | Required | REQUIRED. The object bytes, base64-encoded as a bare base64 string or data: URL. Intended for small files; not recommended above 1 MB. |
data | string | null | Optional | Alias for data_base64 (base64-encoded object bytes). |
file_base64 | string | null | Optional | Alias for data_base64 (base64-encoded object bytes). |
content_type | string | null | Optional | MIME type of the object |
metadata | object | null | Optional | Arbitrary user metadata key/value pairs. |
cache_control | string | null | Optional | Cache-Control header value |
storage_class | string | null | Optional | Storage class (e.g. standard, infrequent_access)default: "standard" |
idempotency_key | string | null | Optional | Optional; SDK auto-derives a content-hash key (bucket_id+key+content) when omitted. |
storage.object.set_aclPOST /v1/storage/object/set_acl/{bucket}/{key}Set object access policy. Current supported ACL values are private and signed-only; public/public-read are not supported.
Parameters (4)
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Required | Path parameter. |
bucket | string | Required | Path parameter. |
acl | "private" | "signed-only" | Required | Access policy. Supported values: private, signed-only. public/public-read are not supported; public_url remains null. |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
storage.object.set_metadataPOST /v1/storage/object/set_metadata/{bucket}/{key}Update a stored object's content-type, cache-control, and custom metadata; metadata replaces previous metadata.
Parameters (6)
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Required | Path parameter. |
bucket | string | Required | Path parameter. |
content_type | string | null | Optional | MIME type of the object |
cache_control | string | null | Optional | Cache-Control header value |
metadata | object | null | Optional | Custom metadata key/value pairs. Passing metadata replaces the previous metadata instead of merging with it; omit metadata to preserve the old value. |
idempotency_key | string | null | Optional | Client-provided idempotency key; prevents duplicate execution on retry |
4. End-to-end example
A production-style walkthrough of this module: configure once, then run the flow. It exercises most of the module's APIs.
A copy-paste-runnable single-file Python program (stdlib only, no SDK): set your INFRAI_API_KEY, run it, and walk this module's core flow with REAL billed calls — later steps reuse real fields returned by earlier ones. The 12-line helper is the entire integration.
#!/usr/bin/env python3
"""Infrai · storage — runnable real-app example (single file, zero deps).
Copy this file, set your key, run it: every step is a REAL call to
api.infrai.cc, billed at the real (tiny) per-call price, printing the
live JSON response. Get a key at https://infrai.cc/login (Google/
GitHub sign-in grants $2 free credit); add funds at
https://infrai.cc/billing. No SDK — the 12-line helper below is the
entire integration."""
import json
import os
from urllib import error, request
KEY = os.environ.get("INFRAI_API_KEY") or "ifr_..." # <- your key
BASE = "https://api.infrai.cc"
# Same raw HTTPS POST/GET as every per-method example on this page —
# wrapped once for reuse. There is nothing else to it: no SDK.
def infrai(method, path, body=None):
req = request.Request(
BASE + path, method=method,
data=json.dumps(body).encode() if body is not None else None,
headers={"Authorization": f"Bearer {KEY}",
"Content-Type": "application/json"})
try:
with request.urlopen(req, timeout=60) as r:
return json.loads(r.read())
except error.HTTPError as e:
return json.loads(e.read())
def show(label, resp):
print(f"\n== {label} ==")
print(json.dumps(resp, indent=2, ensure_ascii=False))
return resp
# 1) storage.bucket.create — POST /v1/storage/bucket/create · Create an object storage bucket. Bucket names must be 3-63 lowercase letters, digits, dots, or hyphens and start/end with a letter or digit; `region` must be a canonical region code.
r1 = show("storage.bucket.create", infrai("POST", "/v1/storage/bucket/create", {"name":"demo-bucket"}))
# 2) storage.object.presign — POST /v1/storage/object/presign/{bucket}/{key} · Generate a presigned URL for direct client upload or download of an object (idempotent). For `op=put`, use the returned URL with its returned method (usually PUT) to upload raw binary bytes directly; do not send the Infrai API key to the presigned URL.
bucket_2 = (r1.get("data") or {}).get("name") or ""
r2 = show("storage.object.presign", infrai("POST", f"/v1/storage/object/presign/{bucket_2}/hello.txt", {"op":"put","expires_seconds":300}))
# 3) storage.bucket.list — GET /v1/storage/bucket/list · List the account's object storage buckets.
r3 = show("storage.bucket.list", infrai("GET", "/v1/storage/bucket/list"))
One-time prep (each example is assumed to be complete):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."# 1) Auth: every call is a raw HTTPS request to the Infrai gateway carrying
# only your project key. No SDK, no install.
# Get your key: sign in with Google/GitHub at https://infrai.cc/login for a
# project key + $2 free credit (email sign-in starts at $0). On 402
# INSUFFICIENT_CREDIT, add funds at https://infrai.cc/billing (or POST
# /v1/account/topup and open the returned checkout_url).
export INFRAI_API_KEY="ifr_..." # from https://infrai.cc/login
# 2) storage.bucket.create
curl -X POST https://api.infrai.cc/v1/storage/bucket/create \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "example"}'
# 3) storage.bucket.list
curl -X GET https://api.infrai.cc/v1/storage/bucket/list \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 4) storage.object.presign
curl -X POST https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"op": "put"}'
# Use data.url from the response above to upload the file bytes directly.
# Do not include the Infrai Authorization header on this PUT request.
curl -X PUT "PASTE_RETURNED_DATA_URL_HERE" \
-H "Content-Type: application/octet-stream" \
--data-binary @upload.bin
# 5) storage.object.delete
curl -X DELETE https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 6) storage.bucket.get
curl -X GET https://api.infrai.cc/v1/storage/bucket/get/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 7) storage.bucket.delete
curl -X DELETE https://api.infrai.cc/v1/storage/bucket/delete/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY"
# Non-empty buckets require force=true; otherwise the API returns STORAGE_DELETE_NOT_FORCED.
curl -X DELETE https://api.infrai.cc/v1/storage/bucket/delete/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"force": true}'
# 8) storage.bucket.usage
curl -X GET https://api.infrai.cc/v1/storage/bucket/usage/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 9) storage.bucket.set_lifecycle
curl -X POST https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"rules": [{"prefix": "tmp/", "expire_days": 1}]}'
# 1) Auth: every call is a raw HTTPS request carrying only your project key.
# No SDK to install — just the `requests` library.
import os, requests
BASE = "https://api.infrai.cc"
HEADERS = {
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
"Content-Type": "application/json",
}
# 2) storage.bucket.create
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/bucket/create",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'name': 'example'},
)
resp.raise_for_status()
print(resp.json())
# 3) storage.bucket.list
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/bucket/list",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 4) storage.object.presign
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'op': 'put'},
)
resp.raise_for_status()
print(resp.json())
# Use data['data']['url'] from the response above to upload raw bytes.
# Do not include the Infrai Authorization header on this PUT request.
with open("upload.bin", "rb") as f:
upload_resp = requests.put(resp.json()["data"]["url"], data=f, headers={"Content-Type": "application/octet-stream"})
upload_resp.raise_for_status()
# 5) storage.object.delete
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.delete(
"https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 6) storage.bucket.get
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/bucket/get/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 7) storage.bucket.delete
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.delete(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# Non-empty buckets require force=True; otherwise the API returns STORAGE_DELETE_NOT_FORCED.
resp = requests.delete(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
headers={"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}"},
json={"force": True},
)
resp.raise_for_status()
print(resp.json())
# 8) storage.bucket.usage
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.get(
"https://api.infrai.cc/v1/storage/bucket/usage/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
)
resp.raise_for_status()
print(resp.json())
# 9) storage.bucket.set_lifecycle
# Zero-install REST call — no SDK required (short-term the API is REST-only).
import os, requests
resp = requests.post(
"https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET",
headers={
"Authorization": f"Bearer {os.environ['INFRAI_API_KEY']}",
},
json={'rules': [{'prefix': 'tmp/', 'expire_days': 1}]},
)
resp.raise_for_status()
print(resp.json())
// 1) Auth: every call is a raw HTTPS request carrying only your project key.
// No SDK to install — just the built-in fetch().
const BASE = "https://api.infrai.cc";
const HEADERS = {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
};
// 2) storage.bucket.create
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/create",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "example"}),
},
);
console.log(await resp.json());
// 3) storage.bucket.list
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 4) storage.object.presign
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"op": "put"}),
},
);
console.log(await resp.json());
// Use data.url from the response above to upload raw bytes.
// Do not include the Infrai Authorization header on this PUT request.
const uploadUrl = "PASTE_RETURNED_DATA_URL_HERE";
const { readFile } = await import("node:fs/promises");
const fileBytes = await readFile("upload.bin");
const uploadResp = await fetch(uploadUrl, {
method: "PUT",
headers: { "Content-Type": "application/octet-stream" },
body: fileBytes,
});
if (!uploadResp.ok) throw new Error(`upload ${uploadResp.status}`);
// 5) storage.object.delete
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 6) storage.bucket.get
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/get/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 7) storage.bucket.delete
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// Non-empty buckets require force=true; otherwise the API returns STORAGE_DELETE_NOT_FORCED.
const forceDeleteResp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ force: true }),
},
);
console.log(await forceDeleteResp.json());
// 8) storage.bucket.usage
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/usage/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
console.log(await resp.json());
// 9) storage.bucket.set_lifecycle
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"rules": [{"prefix": "tmp/", "expire_days": 1}]}),
},
);
console.log(await resp.json());
// 1) Auth: every call is a raw HTTPS request carrying only your project key.
// No SDK to install — just the built-in fetch(), typed.
const BASE = "https://api.infrai.cc";
const HEADERS: Record<string, string> = {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
};
// 2) storage.bucket.create
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/create",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"name": "example"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 3) storage.bucket.list
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/list",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 4) storage.object.presign
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/presign/BUCKET/KEY",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"op": "put"}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// Use data.url from the response above to upload raw bytes.
// Do not include the Infrai Authorization header on this PUT request.
const uploadUrl = "PASTE_RETURNED_DATA_URL_HERE";
const { readFile } = await import("node:fs/promises");
const fileBytes = await readFile("upload.bin");
const uploadResp = await fetch(uploadUrl, {
method: "PUT",
headers: { "Content-Type": "application/octet-stream" },
body: fileBytes,
});
if (!uploadResp.ok) throw new Error(`upload ${uploadResp.status}`);
// 5) storage.object.delete
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/object/delete/BUCKET/KEY",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 6) storage.bucket.get
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/get/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 7) storage.bucket.delete
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// Non-empty buckets require force=true; otherwise the API returns STORAGE_DELETE_NOT_FORCED.
const forceDeleteResp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/delete/BUCKET",
{
method: "DELETE",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ force: true }),
},
);
console.log(await forceDeleteResp.json());
// 8) storage.bucket.usage
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/usage/BUCKET",
{
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
},
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
// 9) storage.bucket.set_lifecycle
// Zero-install REST call — no SDK required (short-term the API is REST-only).
const resp = await fetch(
"https://api.infrai.cc/v1/storage/bucket/set_lifecycle/BUCKET",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INFRAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"rules": [{"prefix": "tmp/", "expire_days": 1}]}),
},
);
if (!resp.ok) throw new Error(`infrai ${resp.status}`);
const data: unknown = await resp.json();
console.log(data);
5. Developer guides
Move from endpoint details to complete workflows, production patterns and troubleshooting guides verified against the live API.
Storage developer guides