Upload to a signed URL
Consume a pre-signed URL minted by create_signed_upload_url to upload bytes.
Server-side counterpart to create_signed_upload_url. Sends a multipart PUT to the pre-signed endpoint, attaching the bytes the holder of the token wants stored at path.
Most apps hand the pre-signed URL straight to a browser/mobile client and let it PUT directly. This method exists for the (less common) case where a Ruby worker holds the token and needs to perform the upload itself — for example, an intermediary that receives bytes from an untrusted source, validates them, and forwards under the signed token.
Signature
supabase.storage.from(bucket_id).upload_to_signed_url(path,token:,file:,content_type: nil,cache_control: nil,metadata: nil,headers: nil)Parameters
| Name | Type | Required | Description |
|---|---|---|---|
path | String | Required | Destination object path. MUST match the path that was passed to create_signed_upload_url — the token is bound to it. |
token | String | Required | The bearer token returned by create_signed_upload_url (the parsed ?token= value). |
file | String, IO, Pathname | Required | Bytes source. Same shape rules as upload(): a String is raw bytes, an IO/File or Pathname is read. |
content_type | String | Optional | MIME type. Defaults to text/plain;charset=UTF-8 when omitted. |
cache_control | String, Integer | Optional | Cache lifetime in seconds. Sent as Cache-Control: max-age=<n>. Defaults to the storage3 default ("3600") when omitted. |
metadata | Hash | Optional | Arbitrary metadata. JSON-encoded then base64-encoded into x-metadata, plus repeated as a multipart form field. |
headers | Hash | Optional | Extra HTTP headers merged into the request. |
Returns
Same Struct as upload. path carries the relative path you uploaded to; full_path (alias fullPath) carries the bucket-prefixed key returned by storage-api.
Example — pre-sign on the server, upload via Ruby worker
# Step 1 — mint the URL with service-role credentials.
signed = supabase_admin.storage.from("uploads").create_signed_upload_url(
"incoming/report-#{job_id}.csv"
)
# Step 2 — somewhere else (intermediary worker, no service-role key needed)
# the same Ruby code consumes the token to push bytes.
supabase_anon.storage.from("uploads").upload_to_signed_url(
signed.path,
token: signed.token,
file: File.open("./report.csv", "rb"),
content_type: "text/csv"
)Example — raw String body
supabase.storage.from("uploads").upload_to_signed_url(
signed.path,
token: signed.token,
file: "col_a,col_b\n1,2\n3,4\n",
content_type: "text/csv"
)See the upload callout for the String-is-bytes rule on file:.