> For the complete documentation index, see [llms.txt](https://developers.trooply.co.uk/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.trooply.co.uk/assets.md).

# Assets

## List your assets

> Returns a paginated list of the calling actor's own assets.

```json
{"openapi":"3.1.1","info":{"title":"Trooply API","version":"1.0"},"servers":[{"url":"https://api.trooply.co.uk/"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Bearer access token. Generate one from the **Developer** area of your Trooply account and send it as `Authorization: Bearer <token>`.","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"SuccessResponse":{"type":"object","properties":{"data":{},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}},"ResponseMeta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"request_id":{"type":"string","format":"uuid"},"total":{"type":"integer"}}},"Asset":{"type":"object","properties":{"content_type":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"etag":{"type":"string"},"id":{"type":"string","format":"uuid"},"object_key":{"type":"string"},"original_filename":{"type":"string"},"owner_id":{"type":"string","format":"uuid"},"public_url":{"description":"PublicURL is the URL the bytes can be fetched from. For public assets it is\nthe stable CDN URL; for private assets it is a short-lived presigned GET\nURL that expires (re-fetch the asset to obtain a fresh one).","type":"string"},"size_bytes":{"type":"integer"},"status":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"visibility":{"type":"string","enum":["public","private"]}}},"ErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}}},"ErrorDetail":{"type":"object","properties":{"code":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"string"}},"message":{"type":"string"},"request_id":{"type":"string","format":"uuid"},"status":{"type":"integer"}}}}},"paths":{"/v1/assets":{"get":{"description":"Returns a paginated list of the calling actor's own assets.","tags":["assets"],"summary":"List your assets","parameters":[{"schema":{"type":"integer","default":1,"minimum":1},"description":"Page number, 1-based","name":"page","in":"query"},{"schema":{"type":"integer","default":20,"maximum":100,"minimum":1},"description":"Items per page","name":"per_page","in":"query"}],"responses":{"200":{"description":"Paginated list of your assets","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}}}}]}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage is not configured/available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Register an asset and get an upload URL

> Creates a pending asset owned by the caller and returns a short-lived presigned PUT URL the client uploads bytes to. Call finalize once the upload completes.

```json
{"openapi":"3.1.1","info":{"title":"Trooply API","version":"1.0"},"servers":[{"url":"https://api.trooply.co.uk/"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Bearer access token. Generate one from the **Developer** area of your Trooply account and send it as `Authorization: Bearer <token>`.","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"SuccessResponse":{"type":"object","properties":{"data":{},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}},"ResponseMeta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"request_id":{"type":"string","format":"uuid"},"total":{"type":"integer"}}},"CreateAssetResult":{"type":"object","properties":{"asset":{"$ref":"#/components/schemas/Asset"},"expires_at":{"type":"string","format":"date-time"},"upload_url":{"type":"string"}}},"Asset":{"type":"object","properties":{"content_type":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"etag":{"type":"string"},"id":{"type":"string","format":"uuid"},"object_key":{"type":"string"},"original_filename":{"type":"string"},"owner_id":{"type":"string","format":"uuid"},"public_url":{"description":"PublicURL is the URL the bytes can be fetched from. For public assets it is\nthe stable CDN URL; for private assets it is a short-lived presigned GET\nURL that expires (re-fetch the asset to obtain a fresh one).","type":"string"},"size_bytes":{"type":"integer"},"status":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"visibility":{"type":"string","enum":["public","private"]}}},"ErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}}},"ErrorDetail":{"type":"object","properties":{"code":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"string"}},"message":{"type":"string"},"request_id":{"type":"string","format":"uuid"},"status":{"type":"integer"}}},"CreateAssetRequest":{"type":"object","required":["filename"],"properties":{"content_type":{"type":"string","maxLength":255},"filename":{"type":"string","maxLength":512,"minLength":1},"visibility":{"description":"Visibility selects which bucket the object is stored in. \"public\" (the\ndefault when omitted) serves bytes from the CDN; \"private\" keeps them in\nthe private bucket, readable only via short-lived presigned URLs.","type":"string","enum":["public","private"]}}}}},"paths":{"/v1/assets":{"post":{"description":"Creates a pending asset owned by the caller and returns a short-lived presigned PUT URL the client uploads bytes to. Call finalize once the upload completes.","tags":["assets"],"summary":"Register an asset and get an upload URL","responses":{"201":{"description":"The pending asset plus a short-lived presigned upload URL and its expiry","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CreateAssetResult"}}}]}}}},"400":{"description":"Malformed JSON body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation failed; see error.fields","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage is not configured/available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssetRequest"}}},"description":"Asset to register","required":true}}}}}
```

## Get an asset

> Returns a single asset's metadata and public URL.

```json
{"openapi":"3.1.1","info":{"title":"Trooply API","version":"1.0"},"servers":[{"url":"https://api.trooply.co.uk/"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Bearer access token. Generate one from the **Developer** area of your Trooply account and send it as `Authorization: Bearer <token>`.","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"SuccessResponse":{"type":"object","properties":{"data":{},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}},"ResponseMeta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"request_id":{"type":"string","format":"uuid"},"total":{"type":"integer"}}},"Asset":{"type":"object","properties":{"content_type":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"etag":{"type":"string"},"id":{"type":"string","format":"uuid"},"object_key":{"type":"string"},"original_filename":{"type":"string"},"owner_id":{"type":"string","format":"uuid"},"public_url":{"description":"PublicURL is the URL the bytes can be fetched from. For public assets it is\nthe stable CDN URL; for private assets it is a short-lived presigned GET\nURL that expires (re-fetch the asset to obtain a fresh one).","type":"string"},"size_bytes":{"type":"integer"},"status":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"visibility":{"type":"string","enum":["public","private"]}}},"ErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}}},"ErrorDetail":{"type":"object","properties":{"code":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"string"}},"message":{"type":"string"},"request_id":{"type":"string","format":"uuid"},"status":{"type":"integer"}}}}},"paths":{"/v1/assets/{asset_id}":{"get":{"description":"Returns a single asset's metadata and public URL.","tags":["assets"],"summary":"Get an asset","parameters":[{"schema":{"type":"string","format":"uuid"},"description":"Asset ID","name":"asset_id","in":"path","required":true}],"responses":{"200":{"description":"The requested asset, including its public URL","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Asset"}}}]}}}},"400":{"description":"asset_id is not a valid UUID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No asset with that ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage is not configured/available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Delete an asset

> Removes the underlying object from storage and soft-deletes the asset record. Owner only.

```json
{"openapi":"3.1.1","info":{"title":"Trooply API","version":"1.0"},"servers":[{"url":"https://api.trooply.co.uk/"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Bearer access token. Generate one from the **Developer** area of your Trooply account and send it as `Authorization: Bearer <token>`.","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"ErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}}},"ErrorDetail":{"type":"object","properties":{"code":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"string"}},"message":{"type":"string"},"request_id":{"type":"string","format":"uuid"},"status":{"type":"integer"}}}}},"paths":{"/v1/assets/{asset_id}":{"delete":{"description":"Removes the underlying object from storage and soft-deletes the asset record. Owner only.","tags":["assets"],"summary":"Delete an asset","parameters":[{"schema":{"type":"string","format":"uuid"},"description":"Asset ID","name":"asset_id","in":"path","required":true}],"responses":{"204":{"description":"Asset deleted"},"400":{"description":"asset_id is not a valid UUID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"You do not own this asset","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No asset with that ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage is not configured/available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Finalize an uploaded asset

> Verifies the uploaded object exists in storage, records its real size / content-type / etag, and marks the asset ready. Owner only.

```json
{"openapi":"3.1.1","info":{"title":"Trooply API","version":"1.0"},"servers":[{"url":"https://api.trooply.co.uk/"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"description":"Bearer access token. Generate one from the **Developer** area of your Trooply account and send it as `Authorization: Bearer <token>`.","type":"apiKey","name":"Authorization","in":"header"}},"schemas":{"SuccessResponse":{"type":"object","properties":{"data":{},"meta":{"$ref":"#/components/schemas/ResponseMeta"}}},"ResponseMeta":{"type":"object","properties":{"page":{"type":"integer"},"per_page":{"type":"integer"},"request_id":{"type":"string","format":"uuid"},"total":{"type":"integer"}}},"Asset":{"type":"object","properties":{"content_type":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"etag":{"type":"string"},"id":{"type":"string","format":"uuid"},"object_key":{"type":"string"},"original_filename":{"type":"string"},"owner_id":{"type":"string","format":"uuid"},"public_url":{"description":"PublicURL is the URL the bytes can be fetched from. For public assets it is\nthe stable CDN URL; for private assets it is a short-lived presigned GET\nURL that expires (re-fetch the asset to obtain a fresh one).","type":"string"},"size_bytes":{"type":"integer"},"status":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"visibility":{"type":"string","enum":["public","private"]}}},"ErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}}},"ErrorDetail":{"type":"object","properties":{"code":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"string"}},"message":{"type":"string"},"request_id":{"type":"string","format":"uuid"},"status":{"type":"integer"}}}}},"paths":{"/v1/assets/{asset_id}/finalize":{"post":{"description":"Verifies the uploaded object exists in storage, records its real size / content-type / etag, and marks the asset ready. Owner only.","tags":["assets"],"summary":"Finalize an uploaded asset","parameters":[{"schema":{"type":"string","format":"uuid"},"description":"Asset ID","name":"asset_id","in":"path","required":true}],"responses":{"200":{"description":"The finalized asset (status: ready)","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessResponse"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Asset"}}}]}}}},"400":{"description":"asset_id is not a valid UUID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"You do not own this asset","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No asset with that ID, or its object is missing from storage","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Object storage is not configured/available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.trooply.co.uk/assets.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
