xPlantAPI
API referenceSOPs and runs

List SOPs

The workspace's standard operating procedures, most recently updated first — drafts and archived ones included, with status saying which. Summaries only: fetch one SOP to read the steps of the version in force.

GET/api/v1/sops
Scope read:sops

Editing an SOP moves it to the front of the list, so an SOP edited while you page through can move between pages: it may appear twice, or not at all.

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size. Values above 200 are capped at 200. Default 50. From 1 to 200.
offsetintegerNoNumber 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.
cursorstringNoContinue 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/sops?limit=50" \
  -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.

FieldTypeRequiredDescription
idstring (uuid)Yes—
titlestringYes—
descriptionstring | nullYes—
categorystring | nullYesThe kind of procedure, such as media-prep, sterilization or tissue-culture.
statusstring | nullYesdraft, active or archived.
levelstring | nullYesWho it is written for: beginner, intermediate, advanced or expert.
tagsstring[]Yes—
equipmentstring[]YesEquipment the procedure calls for.
estimatedTimeMinutesnumber | nullYesHow long one run is expected to take, in minutes.
durationHoursnumber | nullYesThe procedure's duration in hours, as the lab recorded it.
currentVersionintegerYesThe newest version number. It can be a draft; the version the lab works from is the one Get an SOP returns.
updatedAtstring | nullYes—
createdAtstring | nullYes—
Response
{
  "ok": true,
  "data": [
    {
      "id": "2e4f6a8c-0b1d-4e3f-9a5b-7c9d1e3f5a7b",
      "title": "Phalaenopsis flower-stalk node initiation",
      "description": "Surface-sterilise nodes from a healthy flower stalk and place them onto initiation medium.",
      "category": "tissue-culture",
      "status": "active",
      "level": "intermediate",
      "tags": [
        "initiation",
        "orchid"
      ],
      "equipment": [
        "laminar flow hood",
        "autoclave"
      ],
      "estimatedTimeMinutes": 45,
      "durationHours": null,
      "currentVersion": 3,
      "updatedAt": "2026-09-18T11:04:52.000Z",
      "createdAt": "2026-06-02T08:30:00.000Z"
    }
  ]
}

The envelope can also carry meta:

FieldTypeRequiredDescription
next_cursorstring | nullYesPass as cursor to fetch the next page. null means this is the last page.
Response headerMeaning
X-Request-IdIdentifies this request. Include it when you contact support.

Errors

StatusCodeWhen
401UNAUTHORIZEDThe key is missing, malformed or revoked, or its owner is no longer a member of the workspace.
402PAID_PLAN_REQUIREDThe 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.
403FORBIDDENThe 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.
403DEVICE_TOKEN_NOT_ACCEPTEDA device token was sent; this operation needs a workspace API key.
422VALIDATION_ERRORBoth cursor and offset were sent; use one.
422INVALID_CURSORThe cursor is malformed, or came from a different list or different filters. Start again without it.
429RATE_LIMIT_EXCEEDEDToo many requests for this key, device token or workspace. Wait Retry-After seconds.
500SOP_QUERY_FAILEDThe SOPs could not be read. Retry later.

Branch on code, never on the error text. See Errors.

On this page