Your First 10 Minutes With Filestack, Signup to First Upload

Posted on
Your First 10 Minutes With Filestack, Signup to First Upload

Signup gives you an API key. The key gets you an upload. The upload gives you a handle, and the handle is the only thing you need for every transformation and delivery URL after that. Those four steps are the whole first session with Filestack, and each one takes minutes rather than hours. The walkthrough below runs all four and shows what each returned.

Get a key

Sign up at dev.filestack.com. The form asks for a name, a company email and a password, and it shows the free plan allowance next to the fields you are filling in.

The Filestack free signup form showing the free plan allowance beside the account fields
The Filestack free signup form, with the free plan allowance of 1 GB bandwidth, 500 uploads, 1,000 transformations and 1 GB storage shown alongside the account fields

 

Your API key appears in the developer portal as soon as the account exists. It is about 20 characters, it identifies your application, and it is not a secret in the way a password is. It goes in client-side JavaScript on purpose, because that is how browser uploads reach us without a round trip through your server first.

The app secret is different. It stays on your server, it signs security policies, and nothing in this walkthrough needs it.

Your first upload

Two paths get a file in. Pick the one that matches where you are sitting.

Uploading from a browser

The picker is a hosted upload interface. Loading the script and calling picker() is the shortest route to a working upload, and it handles the retry and chunking work that hand-rolled <input type="file"> code usually skips.

<script src="https://static.filestackapi.com/filestack-js/3.x.x/filestack.min.js"></script>
<button id="pick">Upload a file</button>

<script>
  const client = filestack.init('YOUR_API_KEY');

  document.getElementById('pick').onclick = () => {
    client.picker({
      accept: ['image/*'],
      maxFiles: 5,
      onUploadDone: ({ filesUploaded }) => console.log(filesUploaded[0].handle),
    }).open();
  };
</script>

Click the button and the picker opens over your page. My Device is the local file system. The icons down the left are the other sources the free plan includes, so a multi file upload UI with Google Drive and a URL tab costs you nothing beyond the fromSources array.

The Filestack picker open over a page showing the My Device drop zone and source icons
The Filestack picker open over a page, showing the My Device drop zone and source icons for link, web search, Facebook, Instagram and Google Drive

 

Choose a file and it appears in a review list with its size before anything is sent. Nothing uploads until you press Upload, which is worth knowing when you are testing against a quota.

The Filestack picker review list showing one selected file before upload
The picker review list showing one selected file, lighthouse.jpg at 105KB, with Deselect All, Upload more and Upload buttons

 

Press it and onUploadDone fires with one entry in filesUploaded. The handle field on that entry is what every URL below uses.

Uploading without a browser

If you are on a server or just want to see the response shape, one POST does it:

curl -X POST -F "fileUpload=@photo.jpg" \
  "https://www.filestackapi.com/api/store/S3?key=YOUR_API_KEY"

which returns:

{
  "url": "https://cdn.filestackcontent.com/0J0PpoBYScqJrHF8lbrO",
  "size": 107013,
  "type": "image/jpeg",
  "filename": "photo.jpg"
}

That is the same REST API upload file endpoint the SDKs sit on top of, so the handle it returns behaves identically. The 20 characters at the end of that URL are the handle.

What the handle is for

The handle is the file. Every delivery and processing URL is the handle with tasks in front of it:

https://cdn.filestackcontent.com/TASK/HANDLE

Your API key does not go in that URL. The handle already identifies the application that owns the file, so adding the key puts a credential in front of your users for nothing.

Join the Filestack developer community on Discord

Your first transformation

Put a task in front of the handle and the file changes on the way out. Resize is the one to try first, because the result is obvious:

https://cdn.filestackcontent.com/resize=width:300/0J0PpoBYScqJrHF8lbrO
The uploaded lighthouse photograph delivered at 300 pixels wide through the Filestack CDN
The uploaded lighthouse photograph delivered at 300 pixels wide through the Filestack CDN

 

The 107,013 byte original came back as 42,214 bytes at 300 pixels wide. Nothing was stored to produce that. The transformation ran at request time and the result was cached, which is why you never generate thumbnail variants ahead of time or keep them anywhere.

Tasks chain left to right. Adding a format change on the end took the same request to 32,854 bytes:

https://cdn.filestackcontent.com/resize=width:300/output=format:webp/0J0PpoBYScqJrHF8lbrO

Order matters, because each task acts on what the previous one produced. Resize first and the encoder is working on a smaller image. The reasoning behind picking a format at all is in the guide to convert to webp, and the full parameter set for every task is in the processing API reference.

Crop, rotate, watermark, compress and quality all work the same way on a free key, as does face detection, so you can blur faces in a URL without training anything. The image editing api guide covers how the tasks combine.

Where the file lives now

At the CDN, already, on a public URL. There is no publish step and no bucket to configure. The default response carries cache-control: public, max-age=2667950, so once an edge has served a transformation it keeps serving it without rerunning anything.

Set your own expiry when you need a shorter one:

https://cdn.filestackcontent.com/cache=expiry:3600/resize=width:300/0J0PpoBYScqJrHF8lbrO

The Filestack CDN then answers that URL with cache-control: public, max-age=3600. How the edges pick up files and how long they hold them is covered in file delivery.

Public by default matters for the next thing you build. Anyone with the handle can read the file, which is right for a portfolio and wrong for invoices, and the fix is a signed policy rather than a different upload call. A secure file upload service is a configuration you turn on later, not a separate product.

When something comes back wrong

Every failure here answers in plain text, so read the body rather than guessing from the status code.

What you sent Status Body
A handle that does not exist 400 Bad Request
A task name with a typo 400 validation error: task not found: “resiz”
A parameter name with a typo 400 validation error: invalid parameter widht for resize task
An operation your plan does not include 403 You don’t have permission to perform this task: ocr. Please check your access settings

 

That last one is the boundary worth knowing early. Operations that read and interpret a file, such as optical character recognition, tagging, captioning and enhancement, run on the higher plans. Everything that changes a file’s shape, size or format runs on the free plan, which is most of what a first project needs.

What to try next

The quotas are 500 uploads, 1,000 transformations, 1 GB of bandwidth and 1 GB of storage a month, checked on the free plan page on 6 August 2026. A prototype does not come near them.

Three directions from here, depending on what you are building:

Wire it into your framework. The same three lines work in a React file upload component or behind an ordinary HTML form, with import * as filestack from 'filestack-js' instead of the script tag. In Next.js the component needs 'use client', because the picker needs a browser.

Chain transformations. Crop, then resize, then encode, in one URL, is the pattern behind every responsive image you will serve. Order matters, because resizing first means the encoder has fewer pixels to work on.

Take the whole lifecycle seriously. Once uploads are real user files, storage, transformation and delivery become one system. The image upload service guide covers how those pieces fit together.

 

 

Read More →