Upload SDK

Prepared Uploads

Understand the signed upload instructions returned by prepareUpload().

A prepared upload is the result returned by prepareUpload().

const preparedUpload = await uploader.prepareUpload("avatar", {
  filename: "profile.png",
  contentType: "image/png",
  size: 120_000,
});

It contains the instructions the client needs to upload the file directly to the selected provider.

{
  strategy: "multipart",
  method: "POST",
  url: "https://provider.example.com/upload",
  headers: {},
  fields: {
    // Provider-specific signed fields
  },
  key: "avatars/profile-550e8400-e29b-41d4-a716-446655440000.png",
  expiresAt: "2026-07-21T12:00:00.000Z"
}

The response shape stays the same across AWS S3 and ImageKit. The returned URL and signed fields depend on the selected provider.

Response fields

FieldDescription
strategyHow the client should send the upload
methodThe HTTP method to use
urlThe provider endpoint
headersHeaders required by the request
fieldsSigned multipart form fields
keyThe generated storage key
expiresAtWhen the upload target expires

strategy

strategy: "multipart"

Upload SDK currently prepares multipart form uploads.

The client must create FormData, add every returned field, and then add the file.

Here, multipart means one multipart POST request. It does not mean a chunked or resumable upload.

method

method: "POST"

Use the returned HTTP method:

await fetch(preparedUpload.url, {
  method: preparedUpload.method,
  body: formData,
});

Prepared uploads currently use POST.

url

url: "https://provider.example.com/upload"

This is the provider endpoint that receives the file.

The exact URL depends on the selected storage profile.

  • AWS S3 returns an endpoint for the configured bucket and region.
  • ImageKit returns its upload endpoint.

Do not build provider upload URLs manually in client code.

headers

headers: {}

Pass the returned headers to fetch():

await fetch(preparedUpload.url, {
  method: preparedUpload.method,
  headers: preparedUpload.headers,
  body: formData,
});

The object may be empty.

fields

fields: {
  // Provider-specific signed fields
}

These are the form fields required by the provider.

They may include:

  • A generated key or filename
  • A signed policy
  • A signature or token
  • The declared content type
  • Metadata
  • Provider-specific settings

The exact field names differ between AWS S3 and ImageKit.

Add every field to FormData without changing it:

const formData = new FormData();

for (const [name, value] of Object.entries(
  preparedUpload.fields,
)) {
  formData.append(name, value);
}

formData.append("file", file);

Changing or removing a signed field can cause the provider to reject the upload.

key

key: "avatars/profile-550e8400-e29b-41d4-a716-446655440000.png"

This is the storage key generated by Upload SDK.

It contains the asset's key prefix and the generated filename.

Client filename:
Profile Photo.PNG

Generated key:
avatars/profile-photo-550e8400-e29b-41d4-a716-446655440000.png

Use the key when you need to reference the intended upload location.

expiresAt

expiresAt: "2026-07-21T12:00:00.000Z"

This is the time after which the prepared upload should no longer be used.

It is returned as an ISO 8601 date string.

The value comes from the asset's expiresIn configuration and the selected provider's supported limits.

When the target expires, request a new prepared upload.

Do not try to change the expiration or signed fields in the browser.

Uploading the file

Use the prepared upload to create the provider request:

async function uploadToProvider(
  file: File,
  preparedUpload: PrepareUploadOutput,
): Promise<void> {
  const formData = new FormData();

  for (const [name, value] of Object.entries(
    preparedUpload.fields,
  )) {
    formData.append(name, value);
  }

  formData.append("file", file);

  const response = await fetch(preparedUpload.url, {
    method: preparedUpload.method,
    headers: preparedUpload.headers,
    body: formData,
  });

  if (!response.ok) {
    throw new Error("The provider rejected the upload.");
  }
}

The same client flow works with AWS S3 and ImageKit. Only the returned provider values change.

What preparation means

A successful call to prepareUpload() means:

  • The selected asset was found.
  • The reported file information passed its rules.
  • A storage key was generated.
  • The provider created a signed upload target.

It does not mean:

  • The client uploaded the file.
  • The provider accepted the upload.
  • The object exists.
  • The file contents are valid or safe.

Preparation, upload completion, and file verification are separate stages.

Rules to remember

  • Add every returned field to FormData.
  • Do not change signed values.
  • Use the returned URL, method, and headers.
  • Do not manually set the multipart Content-Type.
  • Do not reuse an expired target.
  • Do not treat key as proof of upload.
  • Keep provider credentials on the server.

Next steps

On this page