Back to API Reference

Upload Files with SAS URL

Generate a temporary upload URL, then PUT your file directly to Azure Blob Storage.

Endpoint

POST /api/upload/sas-url

This endpoint returns a signed upload URL (`uploadUrl`) that is valid for about 1 hour. Upload the file using a `PUT` request with `x-ms-blob-type: BlockBlob`.

Authentication Options

Desktop/backend (Bearer token)

Include Authorization: Bearer YOUR_ACCESS_TOKEN and send userId in the JSON body. Examples below use your session or localStorage when set.

Step 1: Request a SAS Upload URL

Example (Bearer token)
curl -X POST https://api.genvrresearch.com/api/upload/sas-url \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "YOUR_USER_ID",
    "fileName": "holiday-photo.jpg",
    "category": "imagegen"
  }'
Response
{
  "success": true,
  "uploadUrl": "https://userdatagenvr.blob.core.windows.net/temp/YOUR_USER_ID/upload_...jpg?sv=...",
  "blobPath": "YOUR_USER_ID/upload_...jpg",
  "container": "temp",
  "account": "userdatagenvr",
  "expiresAt": "2026-05-15T17:53:05Z",
  "instructions": {
    "method": "PUT",
    "headers": {
      "x-ms-blob-type": "BlockBlob",
      "Content-Type": "application/octet-stream"
    }
  }
}

Step 2: Upload File with PUT

Example (curl upload)
curl -X PUT "$UPLOAD_URL_FROM_STEP_1" \
  -H "x-ms-blob-type: BlockBlob" \
  -H "Content-Type: image/jpeg" \
  --data-binary "@holiday-photo.jpg"

A successful Azure blob upload usually returns `201 Created` with an empty body.

JavaScript End-to-End Example

Browser or Node.js
async function uploadWithSas(file, accessToken, userId) {
  // 1) Request SAS URL
  const sasRes = await fetch("https://api.genvrresearch.com/api/upload/sas-url", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${accessToken}`,
    },
    body: JSON.stringify({
      userId,
      fileName: file.name,
      category: "imagegen",
    }),
  });

  if (!sasRes.ok) {
    throw new Error("Failed to create SAS URL");
  }

  const sasData = await sasRes.json();
  if (!sasData.success || !sasData.uploadUrl) {
    throw new Error(sasData.error || "SAS URL missing");
  }

  // 2) Upload binary file to Azure Blob Storage
  const uploadRes = await fetch(sasData.uploadUrl, {
    method: "PUT",
    headers: {
      "x-ms-blob-type": "BlockBlob",
      "Content-Type": file.type || "application/octet-stream",
    },
    body: file,
  });

  if (!uploadRes.ok) {
    throw new Error(`Azure upload failed with status ${uploadRes.status}`);
  }

  return {
    blobPath: sasData.blobPath,
    container: sasData.container,
    account: sasData.account,
    expiresAt: sasData.expiresAt,
  };
}

// Example: uploadWithSas(file, "YOUR_ACCESS_TOKEN", "YOUR_USER_ID");

Important Notes

Blob-scoped security: the generated SAS URL is for one exact blob path (container + blob name). It cannot be reused to upload to other blob names.
SAS URLs are short-lived. If you receive auth errors on upload, request a new SAS URL and retry.