# Uploads [View original](https://ittybit.com/docs/uploads) ## Simple uploads Simple uploads are – as the name suggests – the easiest way to upload files to your project. They're a great fit for many use cases, and often the ideal place to start when first adding file uploads to your app. *** ### How it works You make an [authenticated](/api#authentication) `PUT` request to the url you want to serve the file from. You pass the bytes of the file in the request body. When the upload completes, ittybit will return a [File object](/docs/files) in the response. *** ### Authentication If you already have the file on your server (or in a server route or serverless function), then you can authenticate the request with your [API Key](/docs/keys). If you're uploading from a client app, take a look at [signed uploads](/docs/uploads/signed). You should never include your API key in client-side code. *** ### Example For example, if your project's delivery domain is `https://you.ittybit.net`[^1], and you want to call the file `image.png`, then you'd make a `PUT` request to `https://you.ittybit.net/image.png`. ```js const response = await fetch('https://you.ittybit.net/image.png', { method: 'PUT', headers: { 'Authorization': 'Bearer ITTYBIT_API_KEY', }, body: file, }); ``` The `filename` and `folder` will be inferred from the url. *** ## File object When your upload completes, ittybit will return a [File object](/docs/files) in the response. ```js const { meta, data, error } = await response.json(); ``` The `meta` object contains information about the request. The `data` object contains the file object. ```js console.log(data); ``` ```json { "id": "file_abcdefgh1234", "kind": "image", "type": "image/png", "width": 3000, "height": 2000, "filesize": 12345678, "url": "https://you.ittybit.net/image.png", "created": "2025-01-01T01:23:45Z", "updated": "2025-01-01T01:23:45Z" } ``` You can persist this info to your database, and use it to serve the file to your users. The `error` object will only be present if the upload failed. *** ## Resumable uploads If you need to handle larger files (100MB+), or your users are prone to unstable internet connections, then we recommend using resumable uploads. This breaks the file into chunks and sends them to the server separately. It means you can send chunks in parallel, and if one chunk fails, you can retry that chunk without having to restart the whole upload. File size limits are based on your org's billing status and plan. If you receive `413 Request Entity Too Large` errors, please [contact us](/support) and we can increase your limit. *** ### How it works You send smaller pieces of the file (chunks) to the server across multiple requests. You add a `Content-Range` header which covers the byte range that is being sent. If it's the final chunk, we combine the chunks and return a [File object](/docs/files) *** ### Example The basic request is very similar to simple uploads. For example, to send the first 16MB of a 100MB file: ```js fetch('https://you.ittybit.net/big-video.mp4',{ method: 'PUT', headers: { 'Authorization': 'Bearer ITTYBIT_API_KEY', 'Content-Range': 'bytes=0-16777216/100000000' }, body: chunk, }); ``` ```json // Returns 202 Accepted ``` Then, you send the next chunk: ```js fetch('https://you.ittybit.net/big-video.mp4',{ method: 'PUT', headers: { 'Authorization': 'Bearer ITTYBIT_API_KEY', 'Content-Range': 'bytes=16777216-33554432/100000000' }, body: chunk, }); ``` ```json // Returns 202 Accepted ``` And so on, until you've sent all the chunks. If it's the final chunk (we work this out from the `Content-Range` header value), then we will check that we have all the chunks available, and we will process the full file: ```js fetch('https://you.ittybit.net/big-video.mp4',{ method: 'PUT', headers: { 'Authorization': 'Bearer ITTYBIT_API_KEY', 'Content-Range': 'bytes=83886080-99999999/100000000' }, body: chunk, }); ``` ````json // Returns 201 Created { "id": "file_abcdefgh1234", "media_id": "med_abcdefgh1234", "type": "video/mp4", "width": 1280, "height": 720, "filesize": 12345678, "duration": 2.0, "frames": 50, "fps": 25, "url": "https://you.ittybit.net/big-video.mp4", "status": "ready", "created": "2024-01-01Z10:10:10.1010", "version": "171450000" } Then any subsequent GET requests to the deliver url will return the uploaded file GET "https://you.ittybit.net/big-video.mp4" ```json // Returns 200 OK Content-Type: "video/mp4" Content-Length: 100000000 (video data) ```` *** ## Media library If you just need to quickly add a file or two, you can use the media library from the [ittybit dashboard](https://app.ittybit.com). Drag-and-drop files onto the window, or use the 'Add Files' button to start an upload. *** [^1]: You get a free `*.ittybit.net` domain when you create a project. You can also add [Custom Domains](/docs/domains) in your project settings.