Skip to main content
curl --request POST \
  --url 'https://blob.squarecloud.app/v1/objects?name=myfile&prefix=images&expire=30' \
  --header 'Authorization: YOUR_API_KEY' \
  --form 'file=@./myphone.png'
import fs from 'node:fs';

const form = new FormData();
form.append('file', new Blob([fs.readFileSync('./myphone.png')]), 'myphone.png');

const params = new URLSearchParams({
  name: 'myfile',
  prefix: 'images',
  expire: '30',
});

const response = await fetch(`https://blob.squarecloud.app/v1/objects?${params}`, {
  method: 'POST',
  headers: { Authorization: 'YOUR_API_KEY' },
  body: form,
});
import requests

with open('myphone.png', 'rb') as f:
    response = requests.post(
        'https://blob.squarecloud.app/v1/objects',
        headers={'Authorization': 'YOUR_API_KEY'},
        params={'name': 'myfile', 'prefix': 'images', 'expire': 30},
        files={'file': ('myphone.png', f, 'image/png')},
    )
{
    "status": "success",
    "response": {
        "id": "3155597145698959364/images/test_lxch4k7y-07ee.png",
        "name": "test",
        "prefix": "images",
        "size": 416230,
        "url": "https://public-blob.squarecloud.dev/3155597145698959364/images/test_lxch4k7y-07ee.png"
    }
}
Authorization
string
required
The API key for your account. You can find this in your account settings.
Object Post uploads a single file to Square Cloud Blob Storage and returns a CDN-backed URL you can embed or share directly, without provisioning a bucket or managing ACLs yourself. It backs attachments, generated exports, and user-uploaded media for applications hosted on the platform. The uploaded file’s declared content type must match one of the platform’s allowed MIME types; anything outside that list is rejected as INVALID_FILE_TYPE before the file reaches storage. Objects can be given an automatic expiration between 1 and 365 days, after which they’re no longer served. Once a file is uploaded, browse it with Object List, remove it with Object Delete, or track usage against your plan’s quota with Account Stats.
file
file
required
Use FormData (multipart/form-data). Exactly one file per request.
name
string
required
A string representing the name of the file. (without extension)
Must adhere to the a to z, A to Z, 0 to 9, and _ pattern. (3 to 32 characters)
prefix
string
A string representing the prefix for the file.
Must adhere to the a to z, A to Z, 0 to 9, and _ pattern. (3 to 32 characters)
expire
number
A number indicating the expiration period of the file, ranging from 1 to 365 days.
security_hash
boolean
Set to true if a security hash is required.
auto_download
boolean
Set to true if the file should be set for automatic download.

Rate limits & concurrency

Uploading requires a paid plan.
  • Every account may have at most 4 uploads in progress simultaneously. Starting another upload while 4 are still running returns TOO_MANY_CONCURRENT_UPLOADS (429).
  • Hobby and Standard plans are additionally limited to 1 upload per second (RATE_LIMITED, 429). Pro and Enterprise plans are exempt from the per-second limit.
For security, .html and .svg files are always delivered as downloads (served as application/octet-stream) instead of being rendered inline. Setting auto_download=true applies the same forced-download behavior to any file type.

Allowed MIME types

Uploads are validated against a strict MIME allowlist; anything outside it is rejected with INVALID_FILE_TYPE. The stored file extension is derived server-side from the MIME type.
CategoryMIME types
Videovideo/mp4, video/mpeg, video/webm, video/x-flv, video/x-m4v
Imageimage/jpeg, image/png, image/apng, image/tiff, image/gif, image/webp, image/bmp, image/svg+xml, image/x-icon, image/ico, image/cur, image/heic, image/heif
Audioaudio/wav, audio/ogg, audio/opus, audio/mp4, audio/mpeg, audio/aac
Texttext/html, text/css, text/csv, text/plain, text/x-sql
Applicationapplication/xml, application/sql, application/x-sql, application/x-sqlite3, application/x-pkcs12, application/pdf, application/json, application/javascript

Response

status
string
Indicates whether the call was successful. “success” if successful, “error” if not.
response
object
curl --request POST \
  --url 'https://blob.squarecloud.app/v1/objects?name=myfile&prefix=images&expire=30' \
  --header 'Authorization: YOUR_API_KEY' \
  --form 'file=@./myphone.png'
import fs from 'node:fs';

const form = new FormData();
form.append('file', new Blob([fs.readFileSync('./myphone.png')]), 'myphone.png');

const params = new URLSearchParams({
  name: 'myfile',
  prefix: 'images',
  expire: '30',
});

const response = await fetch(`https://blob.squarecloud.app/v1/objects?${params}`, {
  method: 'POST',
  headers: { Authorization: 'YOUR_API_KEY' },
  body: form,
});
import requests

with open('myphone.png', 'rb') as f:
    response = requests.post(
        'https://blob.squarecloud.app/v1/objects',
        headers={'Authorization': 'YOUR_API_KEY'},
        params={'name': 'myfile', 'prefix': 'images', 'expire': 30},
        files={'file': ('myphone.png', f, 'image/png')},
    )
{
    "status": "success",
    "response": {
        "id": "3155597145698959364/images/test_lxch4k7y-07ee.png",
        "name": "test",
        "prefix": "images",
        "size": 416230,
        "url": "https://public-blob.squarecloud.dev/3155597145698959364/images/test_lxch4k7y-07ee.png"
    }
}

Troubleshooting

// The provided object name is invalid.
// Must adhere to the a to z, A to Z, 0 to 9, and _ pattern.
{
    "status": "error",
    "code": "INVALID_OBJECT_NAME"
}
// The provided object prefix is invalid.
// Must adhere to the a to z, A to Z, 0 to 9, and _ pattern.
{
    "status": "error",
    "code": "INVALID_OBJECT_PREFIX"
}
// The provided expiration value for the object is invalid.
// Must be a number ranging from 1 to 365. (value in days).
{
    "status": "error",
    "code": "INVALID_OBJECT_EXPIRE"
}
// The provided security hash boolean is invalid.
// Just set to true or false. 😅
{
    "status": "error",
    "code": "INVALID_OBJECT_SECURITY_HASH"
}
// The provided auto-download boolean is invalid.
// Just set to true or false. 😅
{
    "status": "error",
    "code": "INVALID_STORAGE_AUTO_DOWNLOAD"
}
The current maximum file size is 100MB. In the future, we plan to increase it to 10GB. For now, the limit is 100MB due to technical and load-balancing constraints.
// The provided file is invalid.
{
    "status": "error",
    "code": "INVALID_FILE"
}
// The provided file type is invalid.
{
    "status": "error",
    "code": "INVALID_FILE_TYPE"
}
// The file size is too small (< 1kb).
{
    "status": "error",
    "code": "FILE_TOO_SMALL"
}