Skip to content

Examples

Practical, copy-paste examples for the tasks most integrations need first. Every call goes to the fixed Drive host and carries your authentication key as a bearer token:

Terminal window
export OPTIWORK_KEY="opk_xxxxxxxxxxxxxxxxxxxxxxxx"
export OPTIWORK_API="https://work.optidata.cloud/api"

Get the key in Optiwork at work.optidata.cloud/user/settings/security (My account > Profile > Security). Keys are short-lived — when a call returns 401, fetch a fresh one from that page and retry.

The examples use drive 1, which is the drive of a standard tenant. Read the real id from GET /drives/config.json rather than hard-coding it. Ids and names below are fictional; responses are trimmed to the fields each example is about.

A folder is a node with type: 1. Post it to the folder you want it created in — here, company folder 300754.

Terminal window
curl --request POST \
--url "$OPTIWORK_API/drives/1/nodes/300754" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '{ "name": "Contracts 2026", "type": 1 }'
{
"id": 665201,
"parent_id": 300754,
"drive_id": 1,
"type": 1,
"name": "Contracts 2026",
"is_folder": true,
"is_file": false,
"created_at": "2026-08-19T12:41:02.000000Z"
}

To create at the top level of the drive instead — a new company folder — post to /drives/1/nodes with no parent id.

Reference: POST /drives/{drive}/nodes/{node} · POST /drives/{drive}/nodes

Same endpoint, type: 2, sent as multipart/form-data with the bytes in file. The response is the created node, with its content attributes filled in.

Terminal window
curl --request POST \
--url "$OPTIWORK_API/drives/1/nodes/665201" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--header "Accept: application/json" \
--form "name=NDA.pdf" \
--form "type=2" \
--form "file=@./NDA.pdf"
{
"id": 665198,
"parent_id": 665201,
"type": 2,
"name": "NDA.pdf",
"is_file": true,
"content_mime_type": "application/pdf",
"content_size_bytes": 148213
}

A name that collides with a sibling, or that contains characters the storage layer forbids, comes back as 422 with a per-field errors map.

Reference: POST /drives/{drive}/nodes/{node}

Two endpoints answer this, and which one you want depends on why you are asking.

Opening a folder in a UI — the node itself plus a page of its children, sorted and filterable:

Terminal window
curl --request GET \
--url "$OPTIWORK_API/drives/1/nodes/665201?pageSize=2&orderBy=name&order=asc" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--header "Accept: application/json"
{
"node": { "id": 665201, "name": "Contracts 2026", "is_folder": true },
"pagination": {
"current_page": 1,
"per_page": 2,
"data": [
{ "id": 665198, "name": "NDA.pdf", "type": 2, "content_size_bytes": 148213 },
{ "id": 665199, "name": "Signed", "type": 1 }
]
}
}

Walking the tree — a leaner payload ordered by id, with the caller’s effective permissions on the folder attached to the first page:

Terminal window
curl --request GET \
--url "$OPTIWORK_API/drives/1/nodes/665201/children?pageSize=100" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--header "Accept: application/json"

To find the folders you can start from, list the company folders of the drive with GET /drives/{drive}/nodes/company/folders.

Reference: GET /drives/{drive}/nodes/{node} · GET /drives/{drive}/nodes/{node}/children

Streams the bytes inline, with the file’s own MIME type — what you point an image or PDF preview at.

Terminal window
curl --request GET \
--url "$OPTIWORK_API/drives/1/nodes/665198/content" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--output NDA.pdf

Same bytes, delivered as an attachment. This one is gated separately: a company policy can withhold downloading from users who may still view the file, and the download is written to the node’s audit trail.

Terminal window
curl --request GET \
--url "$OPTIWORK_API/drives/1/nodes/665198/content/download" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--output NDA.pdf

To decide whether a download is needed at all, ask for the metadata instead — size, MIME type and hash, with no bytes on the wire.

Terminal window
curl --request GET \
--url "$OPTIWORK_API/drives/1/nodes/665198/content/meta" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--header "Accept: application/json"

Reference: GET …/content · GET …/content/download · GET …/content/meta

Uploading a new version keeps the old one in the node’s history.

Terminal window
curl --request POST \
--url "$OPTIWORK_API/drives/1/nodes/665198/content/file" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--header "Accept: application/json" \
--form "file=@./NDA-signed.pdf"

If another user could be editing the same file, take a lock first and pass its id as node_lock_id; a stale or foreign lock is rejected instead of silently overwriting their work.

To make sure you do not overwrite a version you never saw, send the hash_sha256 you last read on node.content as base_content_hash:

Terminal window
curl --request POST \
--url "$OPTIWORK_API/drives/1/nodes/665198/content/file" \
--header "Authorization: Bearer $OPTIWORK_KEY" \
--header "Accept: application/json" \
--form "file=@./NDA-signed.pdf" \
--form "base_content_hash=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"

The upload is accepted only if that is still the hash of the file’s current content; otherwise it answers 409 and writes nothing. A file with no stored hash yet matches no base, so leave the field out for its first content. The accepted base comes back on the new version as node.content.base_content_hash. An upload of the same bytes as the current content creates no new version, so it returns the base already stored on that version, not the one you sent.

Reference: POST /drives/{drive}/nodes/{node}/content/file

Status Shape When
401 {"error": "…"} Missing, malformed or expired authentication key
403 {"message": "This action is unauthorized."} The caller lacks the permission level the operation needs
404 {"message": "…"} No such node, or it does not belong to the given drive
409 {"error": "…", "status": 409, "help": ""} base_content_hash is not the file’s current content — someone saved a newer version; or a repeated chunk finish of committed content with a different or missing fileHash
422 {"message": "…", "errors": { … }} Validation failed; errors is keyed by field
423 {"error": "…", "status": 423, "help": ""} Another write of the same file held it too long (a base-carrying write or a chunk finish); nothing was written — retry the same request after the Retry-After seconds
429 {"message": "Too Many Attempts."} Rate limit exceeded — retry after the window resets

Note the asymmetry: authentication failures and Drive’s own domain errors (such as the 409 and 423) answer with error, everything else with message.