---
title: "Create asset"
method: POST
path: "/asset.create"
---

# Create asset

`POST /asset.create`

Creates a file Asset and returns instructions for uploading its bytes directly
to the resumable-uploads service. Unlike [item.upload](/docs/chat-api/item-upload),
the file bytes never pass through the API itself, so this endpoint supports much
larger files (up to 5 GiB).

## Upload Flow

1. Call this endpoint with the file's `name` (and optionally its `size` in bytes).
2. Upload the raw file bytes in a single request: replay `uploadMethod` against
   `uploadUrl`, send every entry of `uploadHeaders`, and put the file in the request body.
3. Processing starts automatically once the bytes land — there is no separate
   "complete" call.
4. Reference the `assetId`:
   - `purpose: "file"` (default) — attach to a chat message via
     [chat.post](/docs/chat-api/chat-post)'s `assetIds` field.
   - `purpose: "story"` — post as a story via [story.post](/docs/roam-api/post-story).

A freshly-uploaded asset may take a few seconds to process (videos take longer).
Endpoints that consume the asset return a 400 with a "still processing" message
until processing completes.

## Purposes

| Purpose | Use | Access |
|---------|-----|--------|
| `file` (default) | Chat message attachments | Organization and Personal |
| `story` | Story media (photo or video) | Personal only |

Story assets are owned by the authenticated user (stories are posted as you, not as
a bot) and expire about 48 hours after creation. Because the media must outlive the
story's 24-hour lifetime, call [story.post](/docs/roam-api/post-story) within about
23 hours of creating the asset; after that the asset is rejected and a new one must
be created.

**Access:** Organization and Personal. `purpose: "story"` is Personal only.

**Required scope:** `item:write` (for `purpose: "file"`), `chat:send_message` or `chat:write` (for `purpose: "story"`)

---

**OpenAPI Spec:** [openapi.json](https://developer.ro.am/openapi.json)

## Request body

- object
  - `name` string, required — File name, including its extension. Processing determines the media type from the extension.
  - `size` integer — Size of the file in bytes, if known. Maximum 5 GiB.
  - `purpose` 'file' | 'story' — What the asset will be used for. `file` (default) for chat message attachments; `story` for story media (Personal tokens only).

## Response `200`

Upload instructions for the created asset.

- object
  - `assetId` string, uuid — ID of the created asset.
  - `uploadUrl` string, uri — URL to upload the file bytes to.
  - `uploadMethod` string — HTTP method to use for the upload request.
  - `uploadHeaders` object — Headers to send verbatim with the upload request.

## Other responses

- `400`
- `401`
- `403`
- `405`
- `500` — An internal error occured.

---

[API](https://skmtc.net/ro/apis/roam-hq-api.md) · [All operations](https://skmtc.net/ro/apis/roam-hq-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/ro/roam-hq-api/versions/5acda723f971/schema)
