# Simple Uploads [View original](https://ittybit.com/guides/simple-uploads) ## How it works At its most basic, 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. *** ## Upload handler 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). ```js const response = await fetch('https://you.ittybit.net/image.png', { method: 'PUT', headers: { 'Authorization': 'Bearer ITTYBIT_API_KEY', }, body: file, }); ``` 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`. The `filename` and `folder` will be inferred from the url. You should never include your API key in client-side code. If you're uploading from a client app, take a look at [signed uploads](/guides/signed-uploads). *** ## 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. *** [^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.