List media files
The photos and files attached to one plant, explant, contamination log or SOP, newest first. Each carries a view_url: a link to the file itself that works for 15 minutes. List again for fresh links, and never store one.
https://app.xplantpro.com/ api/ v1/ assetsread:assetsQuery parameters
| Name | Type | Required | Description |
|---|---|---|---|
target | "plant" | "explant" | "contamination" | "sop" | Yes | The kind of record whose files to list: plant, explant, contamination, sop. |
target_id | string (uuid) | Yes | The id of that record. |
limit | integer | No | Page size. Values above 200 are capped at 200. Default 50. From 1 to 200. |
offset | integer | No | Number of records to skip. Prefer cursor where a list offers it: an offset shifts when records are added ahead of it. Default 0. At least 0. |
cursor | string | No | Continue from the previous page: pass its meta.next_cursor unchanged, with the same filters. Treat it as opaque. Not combinable with offset. Up to 2048 characters. |
Example
curl "https://app.xplantpro.com/api/v1/assets?target=explant&target_id=7c1d9e2a-3b4f-4a5c-8d6e-1f2a3b4c5d6e" \
-H "Authorization: Bearer $XPLANT_API_KEY"Response
200 with { "ok": true, "data": … }. data is an array. To get the next page, pass meta.next_cursor back as cursor; it is null on the last page. See Pagination.
| Field | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes | — |
target | "plant" | "explant" | "contamination" | "sop" | Yes | The kind of record the file is attached to. |
target_id | string (uuid) | Yes | The id of that record. |
kind | string | Yes | What the file is: photo, video, annotation, document, diagram, scan, audio, other. Images attached through the API are photo. |
file_name | string | null | Yes | The file's name as xPlant shows it. |
content_type | string | null | Yes | The file's media type, for example image/jpeg, image/png. |
caption | string | null | Yes | The note stored with the file. |
captured_at | string | null | Yes | When the photo was taken, where that was recorded. ISO 8601. |
uploaded_by | string | null | Yes | User id of the workspace member who added the file. |
created_at | string | null | Yes | When the file was added. ISO 8601. |
view_url | string | null | Yes | A link to the file itself, valid for 15 minutes from this response. Fetch the asset again for a fresh link, and never store one. null when the file cannot be linked. |
view_url_expires_at | string | null | Yes | When view_url stops working. ISO 8601. |
{
"ok": true,
"data": [
{
"id": "8c2f1a6e-4b3d-4f7a-9e21-5d6c7b8a9f10",
"target": "explant",
"target_id": "3f9a2c1e-7b4d-4e8f-a6c5-1d2e3f4a5b6c",
"kind": "photo",
"file_name": "vessel-12-week-3.png",
"content_type": "image/png",
"caption": "Callus forming at the cut edge",
"captured_at": null,
"uploaded_by": "0d7e4b9a-6f21-4c3e-8a5b-2e9f1c7d4a60",
"created_at": "2026-09-25T14:20:11.000Z",
"view_url": "https://files.example.com/vessel-12-week-3.png?signature=4f9c2e",
"view_url_expires_at": "2026-09-25T14:35:11.000Z"
}
]
}The envelope can also carry meta:
| Field | Type | Required | Description |
|---|---|---|---|
next_cursor | string | null | Yes | Pass as cursor to fetch the next page. null means this is the last page. |
| Response header | Meaning |
|---|---|
X-Request-Id | Identifies this request. Include it when you contact support. |
Errors
| Status | Code | When |
|---|---|---|
401 | UNAUTHORIZED | The key is missing, malformed or revoked, or its owner is no longer a member of the workspace. |
402 | PAID_PLAN_REQUIRED | The workspace's plan does not include the API. The full API is included with xPlant+ Teams and Enterprise; on Hobby and Pro Lab, keys can connect devices only. |
403 | FORBIDDEN | The key lacks a scope this operation requires, or its owner's current role in the workspace cannot use it — a key never does more than its owner can in xPlant. error names the scope, and for a role, the role it needs. |
403 | DEVICE_TOKEN_NOT_ACCEPTED | A device token was sent; this operation needs a workspace API key. |
404 | NOT_FOUND | target_id does not name a record of that kind in the key's workspace. |
422 | VALIDATION_ERROR | Both cursor and offset were sent; use one. |
422 | INVALID_CURSOR | The cursor is malformed, or came from a different list or different filters. Start again without it. |
422 | VALIDATION_ERROR | target or target_id is missing or not valid. |
429 | RATE_LIMIT_EXCEEDED | Too many requests for this key, device token or workspace. Wait Retry-After seconds. |
500 | ASSET_QUERY_FAILED | The files could not be read. Retry later. |
Branch on code, never on the error text. See Errors.
Add a comment
Adds a comment to a plant, explant, contamination log, task, media recipe or SOP, as the key's owner. It is the same comment the app makes: members it names are notified, the author of the comment it replies to is told, the people following a task hear about it, and it appears in the record's activity.
Attach a media file
Attaches an image to a plant, explant, contamination log or SOP in the workspace. It appears on that record in xPlant exactly like a photo added in the app. Send the image as image_url or as image_base64 — exactly one.