Skip to main content

Upload URLs

Upload URLs are secure, time-limited URLs that allow you to upload files directly to Sterndesk’s storage without routing data through our API servers.

Why Direct-to-Storage Uploads?

Sterndesk uses direct-to-storage uploads rather than routing files through our API servers. This architecture provides several advantages:
  • Long-running uploads — Slow or unstable connections can complete uploads without timing out API requests
  • Larger file support — Direct storage uploads handle large files more efficiently than API servers
  • Dedicated bandwidth — Upload traffic goes directly to storage infrastructure, keeping API servers responsive for other operations
  • Reliability — Storage services are optimized for handling file transfers with built-in retry and resumption capabilities

How Upload URLs Work

When you create an upload through an Upload Collector, Sterndesk generates a unique pre-signed URL for each file you want to upload. These URLs are:
  • Secure — Each URL contains cryptographic signatures that authorize the upload
  • Time-limited — URLs expire after a configurable duration (up to 1 hour)
  • File-specific — Each file in an upload gets its own dedicated URL

Pre-signed URLs

Sterndesk uses AWS S3 pre-signed URLs to enable direct uploads to storage. You don’t need to understand the technical details of how AWS generates these signatures—simply use the URL as provided. The pre-signed URL encodes:
  • The target storage location
  • The expected file size
  • A cryptographic signature for authorization
  • An expiration timestamp

Creating Upload URLs

To get upload URLs, call the Create Upload endpoint with your upload collector ID and file specifications:
curl -X POST "https://api.sterndesk.com/r/uploads" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "upload_collector_id": "usrc_abc123...",
    "files": [
      {"size_bytes": 1048576},
      {"size_bytes": 2097152}
    ],
    "upload_expiration": "600s"
  }'
The response contains a pre-signed URL for each file:
{
  "pre_signs": [
    {
      "url": "https://storage.example.com/...",
      "strategy": "UPLOAD_STRATEGY_PUT"
    },
    {
      "url": "https://storage.example.com/...",
      "strategy": "UPLOAD_STRATEGY_PUT"
    }
  ]
}

Uploading a File

Each file must be uploaded using an HTTP PUT request to its corresponding pre-signed URL:
curl -X PUT "PRE_SIGNED_URL" \
  --data-binary @/path/to/your/file.pdf
Upload all files in the order they were specified when creating the upload. The first pre-signed URL corresponds to the first file specification, and so on.

File Size Declaration

When creating an upload, you must declare the exact size of each file in bytes using the size_bytes field. This is critical because:
  1. Pre-signed URLs are size-locked — The URL signature includes the expected file size. Uploading a file of a different size will fail.
  2. Storage allocation — Sterndesk pre-allocates storage and validates that uploads don’t exceed limits.
  3. Security — Size locking prevents abuse by ensuring only the declared content can be uploaded.

How to Determine File Size

Get the file size before creating the upload:
// Browser
const fileSize = file.size;

// Node.js
const fs = require('fs');
const stats = fs.statSync('/path/to/file.pdf');
const fileSize = stats.size;
import os

file_size = os.path.getsize('/path/to/file.pdf')

Common Errors

HTTP 403 Forbidden — Size Mismatch

Cause: The file you’re uploading is a different size than what was declared when creating the upload. Solution: Ensure the size_bytes value matches the exact file size in bytes. Re-create the upload with the correct size if needed.
SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided.

HTTP 403 Forbidden — Expired URL

Cause: The pre-signed URL has expired. URLs are valid for the duration specified in upload_expiration (maximum 1 hour). Solution: Create a new upload to get fresh pre-signed URLs. Upload files promptly after receiving URLs.

HTTP 403 Forbidden — Access Denied

Cause: The URL has already been used to upload a file, or the signature is otherwise invalid. Solution: Each pre-signed URL can only be used once. If you need to re-upload a file, create a new upload.

Upload Status: EXPIRED

Cause: The upload window closed before all files were transferred. Solution: Ensure all files are uploaded within the expiration window. For large files or slow connections, request a longer upload_expiration duration (up to 1 hour).

Best Practices

Verify file sizes

Always measure file size immediately before creating an upload to ensure accuracy.

Upload promptly

Start uploading as soon as you receive pre-signed URLs to avoid expiration.

Handle errors gracefully

Implement retry logic that creates new uploads on failure rather than reusing expired URLs.

Upload in order

Upload files in the same order as their specifications to maintain correct file-to-URL mapping.

API Reference

For complete details on creating uploads and managing upload URLs, see the Upload API Reference.

Next Steps