I see examples and manuals of uploading files to Supabase Storage for all client libraries, but no complete information for plain HTTP protocol (say, using curl
).
Both the Supabase Storage API's Reference Manual and Swagger UI documentation describe the API in detail, but miss one important detail: the base URL to use.
What you need:
{bucket}
below.storage.objects
that allows INSERT for authenticated users.{ref}
below.{anon-key}
below.{bearer-auth-token}
below./path/to/file.ext
. Use that absolute path in place of {path-and-filename.ext}
below, and use the filename and extension in place of {filename.ext}
below.Now, a working upload command would look like this:
curl \ -X POST "https://{ref}.supabase.co/storage/v1/object/{bucket}/{filename.ext}" \ --data-binary "@{path-and-filename.ext}" \ -H "apikey: {anon-key}" \ -H "Authorization: Bearer {bearer-auth-token}"
Notes:
The URL path must be prefixed with storage/v1/
. This is the part I had to test / reverse engineer. The manual still mentions apiv0/
, which is outdated, and also misses to mention the storage/
prefix. The Swagger UI docs mentions neither storage/
nor v1/
, but both are required.
In the request URL https://{ref}.supabase.co/storage/v1/object/{bucket}/{filename.ext}
you can actually set {filename.ext}
to any filename with extension that you want to use to save the file server-side. It does not have to be the same as the file's local filename. You can even include any path you like.
On success, the result will be a JSON object {"Key": "{bucket}/{filename.ext}"}
with the values you used in the request URL. This is the key to identify the uploaded file server-side when you want to download, move it etc..
Since path and filename serve as the key to identify the file, trying to upload a file with the same path and filename into the same bucket will result in an error {"statusCode": "409", "error": "Duplicate", "message": "The resource already exists"}
.