API reference · Hubtask API 0.1.0
containers
GET /containers
List containers
Query parameters
Responses
200A page of containers ContainerPage4XXAn error per RFC 9457 Problem
curl -X GET "$HUBTASK_URL/containers" \ -H "Authorization: Bearer $HUBTASK_TOKEN" POST /containers
Create container
Headers
Request body application/json — ContainerCreate
curl -X POST "$HUBTASK_URL/containers" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "type": "HUB", "parent_id": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c", "name": "string", "description": "string", "icon": "string", "color_token": "string", "private": false}' GET /containers/{containerId}
Get container
PATCH /containers/{containerId}
Rename container
Changes a container's own descriptive fields. A field that is not sent is left alone; sending description, icon or color_token as null clears it. The name stays unique among the containers at the same level. The policies are not here - they are their own sub-resource, so that a rename and a change of the way a collection works are two operations with two audit entries.
Path parameters
Headers
Request body application/merge-patch+json — ContainerUpdate
curl -X PATCH "$HUBTASK_URL/containers/{containerId}" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H 'If-Match: "<the ETag you read>"' \ -H "Content-Type: application/merge-patch+json" \ -d '{ "name": "string", "description": "string", "icon": "string", "color_token": "string"}' DELETE /containers/{containerId}
Trash container
A soft delete: the hub or collection and everything under it move to the trash under one deletion - a hub takes its collections, and every collection takes its entries. It all stays for the tenant's trash retention period, 30 days by default, and comes back as one act through :restore until the retention job removes it for good. Anything already in the trash from an earlier deletion keeps that deletion rather than joining this one. Needs the owner's right to delete a container. Idempotent.
Path parameters
Headers
Responses
204Moved to the trash4XXAn error per RFC 9457 Problem
curl -X DELETE "$HUBTASK_URL/containers/{containerId}" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H 'If-Match: "<the ETag you read>"' PUT /containers/{containerId}/policies
Update container policies
Replaces a collection's policies - the way it works, as opposed to what it is called. A key that is not sent falls back to its default rather than keeping the stored value: this is a PUT, and a document that partly remembers what it replaced is one nobody can reason about. A hub carries no policies and is refused.
Path parameters
Headers
Request body application/json — ContainerPolicies
curl -X PUT "$HUBTASK_URL/containers/{containerId}/policies" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H 'If-Match: "<the ETag you read>"' \ -H "Content-Type: application/json" \ -d '{ "completion_policy": "MANUAL", "auto_assign": { "strategy": "FIXED", "candidates": [ {} ] }}' PUT /containers/{containerId}/privacy
Set hub privacy
Makes a hub private - reached only by people holding a role on it, on a collection in it or on an entry in one, and no longer by the workspace's own roles, its owners and administrators included - or shared again. Making it private needs the right to create hubs and the role OWNER on the hub itself; sharing it again needs OWNER on the hub. A hub nobody may see answers not found. Refused with containers.private_hub_has_groups while a group holds a role in the hub, and with containers.private_only_hubs on a collection. Every device that loses the hub is told. Writing what is already stored changes nothing.
Path parameters
Headers
Request body application/json — HubPrivacy
Codes this operation names
curl -X PUT "$HUBTASK_URL/containers/{containerId}/privacy" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H 'If-Match: "<the ETag you read>"' \ -H "Content-Type: application/json" \ -d '{ "private": true}' POST /containers/{containerId}:move
Move container
Moves a collection into another hub, and ranks it there. The name has to be free at the destination; a collision is refused rather than resolved. A hub sits in nothing and cannot be moved.
Path parameters
Headers
Request body application/json
curl -X POST "$HUBTASK_URL/containers/{containerId}:move" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "target_parent_id": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c", "before_container_id": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c"}' POST /containers/{containerId}:reorder
Reorder container
Ranks a container within the level it already sits in: a hub among the tenant's hubs, a collection among its hub's collections. The position is given as the container to place it before; omitting it appends to the end of the level. This is the only way to rank a hub. :move ranks a collection as a consequence of naming the hub it goes into - which is why its target_parent_id is required - and a hub sits in nothing, so an operation whose destination is a hub cannot express it. Every Container answers an order_key, so without this one the rank of a hub is a field the API reports and nothing can change. The rank is a fractional index, so an insertion between two neighbours renumbers nothing else and two offline devices can insert into the same list without either one's order being discarded. An archived container is read-only (I-C3) and is refused, as it is for every other write. Idempotent: asking for the position a container already holds writes nothing.
Path parameters
Headers
Request body application/json
curl -X POST "$HUBTASK_URL/containers/{containerId}:reorder" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" \ -H 'If-Match: "<the ETag you read>"' \ -H "Content-Type: application/json" \ -d '{ "before_container_id": "018f6e2a-2b7c-7c1e-9b1a-3d5e6f7a8b9c"}' POST /containers/{containerId}:restore
Restore container
Takes one container deletion back out of the trash, whole: the hub, its collections, and every entry that went in with them. Exactly what went in together comes back - a separate, younger deletion inside the same subtree stays where it is, because a restore is keyed on the deletion rather than on the subtree. A container archived when it was deleted comes back archived. Needs the same right as the deletion, which is the owner's. Idempotent.
Path parameters
Headers
curl -X POST "$HUBTASK_URL/containers/{containerId}:restore" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" POST /containers/{containerId}:archive
Archive container
Archives the container. An archived container is read-only, and everything below it inherits that: a collection in an archived hub refuses writes without being archived itself, which is what effective_archived reports. Idempotent - archiving an archived container changes nothing.
Path parameters
Headers
curl -X POST "$HUBTASK_URL/containers/{containerId}:archive" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)" POST /containers/{containerId}:unarchive
Unarchive container
Makes the container writable again. A collection that was archived in its own right stays archived when its hub is unarchived - unarchiving restores what was archived, not what was merely covered by it. Idempotent.
Path parameters
Headers
curl -X POST "$HUBTASK_URL/containers/{containerId}:unarchive" \ -H "Authorization: Bearer $HUBTASK_TOKEN" \ -H "Idempotency-Key: $(uuidgen)"