> ## Documentation Index
> Fetch the complete documentation index at: https://www.spacebring.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# File uploads

> Upload images, videos, and documents through the Spacebring API and attach them to events, benefits, products, resources, guides, posts, companies, and contract templates

Files never pass through the Spacebring API. You ask the API for an upload, send the file bytes straight to storage, then reference the file when you create or update the object it belongs to.

## Upload a file

1. **Create the upload.** Call the upload endpoint of the object you are working with and declare the file's `mimeType` and exact `size` in bytes. The response carries a `key` and an `upload` block with a presigned URL.

   * For a video, also declare its `width` and `height` in pixels. An image's dimensions are read from the file.

   ```json theme={null}
   {
     "media": {
       "key": "1757585000-6ba7b810-9dad-41d1-80b4-00c04fd430c8",
       "mimeType": "image/jpeg",
       "size": 248113,
       "status": "pending",
       "upload": {
         "method": "PUT",
         "url": "https://…amazonaws.com/1757585000-6ba7b810-…?X-Amz-Signature=…",
         "headers": { "Content-Type": "image/jpeg", "Content-Length": "248113" },
         "expirationDate": "2026-09-11T10:31:00.000Z"
       }
     }
   }
   ```

2. **Send the file.** Make a `PUT` request to `upload.url` with the raw file bytes as the body and exactly the `upload.headers` returned. Do not send a multipart form and do not add your Spacebring credentials. Storage rejects the request when the size or type differs from what you declared, or when the URL has passed its `expirationDate`.

   ```bash theme={null}
   curl -X PUT "$UPLOAD_URL" \
     -H "Content-Type: image/jpeg" \
     -H "Content-Length: 248113" \
     --data-binary @cover.jpg
   ```

3. **Attach the file.** Pass the `key` on the create or update request of the object. The object response then carries the public `url` of the file.
   * Event, benefit, or product: set `media[0].key`.
   * Resource or post: add `{ "key": "…" }` to `media`. A resource lists its images in display order, the first being its cover.
   * Company: set `logo.key`.
   * Contract template: set `template.file.key`.
   * Guide: add the upload's `url` to the guide `description` as a Markdown image, `![alt text](url)`. A link to any other image stays a plain link.

<Warning>
  The upload URL is valid for 60 seconds and the key for one hour. A file that is not attached to an object within the hour is deleted.
</Warning>

## Errors

* Creating an upload with an unsupported `mimeType` or a `size` above the limit returns `400` with a `validationError` naming the field.
* Attaching a key whose file has not reached storage yet returns `409` with the code `fileUploadPending`. Wait for the `PUT` request to finish and retry.
* Attaching a key that is unknown, expired, already attached, or created by another network returns `400` with the code `fileUploadNotFound`. Create a new upload.
* Attaching an image to a post when the stored file is not a readable image returns `400` with the code `fileNotValid`. Upload the file again.

In each case the object is not created or updated. Branch on `code` in the response body, not on the message.

## Upload endpoints

Each object type that accepts files has its own upload endpoint and its own limits.

| Object | Create upload | Types | Max size |
| :- | :- | :- | :- |
| Event | [Create a media upload](/docs/developer/api/events/create-a-media-upload) | JPEG, PNG, WebP, GIF | 5 MB |
| Benefit | [Create a media upload](/docs/developer/api/benefits/create-a-media-upload) | JPEG, PNG, WebP, GIF | 5 MB |
| Product | [Create a media upload](/docs/developer/api/shop/create-a-media-upload) | JPEG, PNG, WebP, GIF | 5 MB |
| Resource | [Create a media upload](/docs/developer/api/resources/create-a-media-upload) | JPEG, PNG, WebP, GIF | 5 MB |
| Guide | [Create a media upload](/docs/developer/api/guides/create-a-media-upload) | JPEG, PNG, WebP, GIF, MP4, QuickTime, WebM | 5 MB for images, 50 MB for videos |
| Post | [Create a media upload](/docs/developer/api/feed/create-a-media-upload) | JPEG, PNG, WebP, GIF, MP4, QuickTime, WebM | 5 MB for images, 50 MB for videos |
| Company | [Create a logo upload](/docs/developer/api/community/create-a-logo-upload) | JPEG, PNG, WebP, GIF | 5 MB |
| Contract template | [Create a template upload](/docs/developer/api/contracts/create-a-template-upload) | DOCX | 50 MB |
