Spaces, tasks & notes
Create, update and delete the workspace's Spaces, tasks and notes from a server or the CLI.
- Use it for: Server integration
- Reads: none
- Writes: Bearer (
apiKey) — server-side only - CLI:
uidu tasks,uidu notes,uidu spaces - Auth: what each token can do and where it may run — Authentication
Spaces are the areas a uidu workspace is organised into (a team, a project, a department); tasks are the work inside them and notes the workspace's documents. The SDK covers them for provisioning and automation: seed a new Space with its starter tasks, open a task from an external system, file a note from a webhook.
Mental model
Workspace
├─→ Space (name, kind, color, icon, isPrivate, isLocked, isHidden)
│ └─→ Task (name, body, spaceId, statusId, priority, startDate / endDate,
│ parentId, goalId, workspaceTagIds, private, doneAt)
└─→ Note (name, body, icon, isPrivate, folderId)- Write-only today. There are no
listSpaces/getSpace,listTasks/getTaskorlistNotes/getNotefunctions yet. Keep the ids the create calls return — in your own database, next to the external record they came from — if you need to update or delete those records later. - Every function is authoring: it needs an account Bearer token (
apiKeyon the client) and runs under the workspace's permissions. Use it server-side (route handler, server action, script) or through the CLI — never from the browser, and not from a custom app, whose session token is refused for tasks and notes. - Rich text fields (
body,description) take a Tiptap/ProseMirror JSON document ({ type: 'doc', content: [...] }). - Tasks.
priorityislow,normal,highorurgent;startDate/endDateareYYYY-MM-DD.parentIdmakes a subtask,goalIdlinks the task to a goal,statusIdplaces it in a status of its Space. A task is finished either by settingdoneAt, or by moving it to a status whose state iscompleted— uidu derives the task's state from its status. - Notes don't belong to a Space: their attributes have no
spaceId. They live in the workspace, optionally in a folder (folderId).
Payload shapes differ. Each function returns the mutation payload with errors rather than
throwing — always check it. Where the record sits:
| Function | Record at |
|---|---|
createSpace | space.node — { id, name }, wrapped in an edge |
createNote | note.node — { id }, wrapped in an edge |
createTask | task — { id, name }, not wrapped |
update* / delete* | space / task / note — { id } |
Use cases
Seed a new Space with its starter tasks
Goal: a provisioning script that creates a project Space and fills it with a checklist, one item with a subtask.
// scripts/seed-launch.ts — server-side
import { createClient, createSpace, createTask } from '@uidu/client';
const uiduAdmin = createClient({
workspace: process.env.UIDU_WORKSPACE!,
apiKey: process.env.UIDU_API_KEY!, // never shipped to a browser
});
const space = await createSpace(uiduAdmin, {
input: { attributes: { name: 'Product launch', isPrivate: false, color: '#22c55e' } },
});
if (space?.errors?.length) throw new Error(space.errors.map((e) => e.name).join(', '));
const spaceId = space!.space!.node!.id; // createSpace wraps the space in an edge
const doc = (text: string) => ({
type: 'doc',
content: [{ type: 'paragraph', content: [{ type: 'text', text }] }],
});
const release = await createTask(uiduAdmin, {
input: {
attributes: {
name: 'Draft the press release',
spaceId,
priority: 'high', // 'low' | 'normal' | 'high' | 'urgent'
startDate: '2026-10-12',
endDate: '2026-10-16',
body: doc('One page, two quotes.'),
},
},
});
const releaseId = release?.task?.id; // createTask is not wrapped: task.id
await createTask(uiduAdmin, {
input: { attributes: { name: 'Collect the quotes', spaceId, parentId: releaseId } },
});- Rename or lock the Space later with
updateSpace(uiduAdmin, { input: { id: spaceId, attributes: { name: 'Launch — Q4', isLocked: true } } }); remove it withdeleteSpace(uiduAdmin, { input: { id: spaceId } }). - The same from a terminal:
uidu spaces create --attributes '{"name":"Product launch"}', thenuidu tasks create --attributes '{"name":"…","spaceId":"…"}'— every verb in CLI commands.
Create tasks from an external system
Goal: a webhook from an issue tracker (or a form, or a CRM) opens a task in uidu, and closes it when the external item is resolved.
// app/api/webhooks/tracker/route.ts
import { createTask, updateTask, deleteTask } from '@uidu/client';
import { uiduAdmin } from '@/lib/uidu-admin'; // createClient({ workspace, apiKey })
import { db } from '@/lib/db'; // your own store: external id → uidu task id
export async function POST(req: Request) {
const event = await req.json(); // verify the sender's signature first
if (event.type === 'issue.opened') {
const result = await createTask(uiduAdmin, {
input: {
attributes: {
name: event.issue.title,
spaceId: process.env.UIDU_SUPPORT_SPACE_ID,
priority: event.issue.urgent ? 'urgent' : 'normal',
},
},
});
if (result?.errors?.length) {
return Response.json({ errors: result.errors }, { status: 422 });
}
// no listTasks / getTask: this mapping is the only way back to the task
await db.taskLinks.insert({ externalId: event.issue.id, taskId: result!.task!.id });
}
if (event.type === 'issue.resolved') {
const link = await db.taskLinks.find(event.issue.id);
if (link) {
await updateTask(uiduAdmin, {
input: { id: link.taskId, attributes: { doneAt: new Date().toISOString() } },
});
}
}
if (event.type === 'issue.deleted') {
const link = await db.taskLinks.find(event.issue.id);
if (link) await deleteTask(uiduAdmin, { input: { id: link.taskId } });
}
return new Response(null, { status: 204 });
}UIDU_SUPPORT_SPACE_IDanddbstand for your own configuration and storage — the SDK doesn't provide them.- Instead of
doneAt, you can move the task withstatusIdto a status whose state iscompleted.
File a note from a webhook
Goal: when a meeting tool posts a transcript summary, file it as a workspace note.
'use server';
import { createNote } from '@uidu/client';
import { uiduAdmin } from '@/lib/uidu-admin';
export async function fileMeetingNote(title: string, paragraphs: string[]) {
const result = await createNote(uiduAdmin, {
input: {
attributes: {
name: title,
isPrivate: false,
body: {
type: 'doc',
content: paragraphs.map((text) => ({
type: 'paragraph',
content: [{ type: 'text', text }],
})),
},
},
},
});
if (result?.errors?.length) return { ok: false, errors: result.errors };
// like createSpace, the note comes wrapped in an edge — keep the id to edit it later
return { ok: true, noteId: result!.note!.node!.id };
}- Later edits:
updateNote(uiduAdmin, { input: { id: noteId, attributes: { name: 'Launch retro (final)' } } });deleteNote(uiduAdmin, { input: { id: noteId } })removes it. Both return{ errors, note: { id } }.
API at a glance
Every @uidu/client function in Spaces, tasks & notes, generated from the source — the full reference has the rest of the SDK.
| Function | Kind | Auth | CLI | Description |
|---|---|---|---|---|
createNote | write | Bearer | notes create | Create a note. Returns the payload (with errors) or null; the new note is at note.node. |
createSpace | write | Bearer | spaces create | Create a space, the container tasks live in. Returns the payload (with errors) or null; the new space is at space.node. |
createTask | write | Bearer | tasks create | Create a task, usually in a space (attributes.spaceId). Returns the payload (with errors) or null. |
deleteNote | write | Bearer | notes delete | Delete a note by { input: { id } }. Returns the payload (with errors) or null. |
deleteSpace | write | Bearer | spaces delete | Delete a space by { input: { id } }. Returns the payload (with errors) or null. |
deleteTask | write | Bearer | tasks delete | Delete a task by { input: { id } }. Returns the payload (with errors) or null. |
updateNote | write | Bearer | notes update | Update a note: { input: { id, attributes } }. Returns the payload (with errors) or null. |
updateSpace | write | Bearer | spaces update | Update a space: { input: { id, attributes } }. Returns the payload (with errors) or null. |
updateTask | write | Bearer | tasks update | Update a task, e.g. its statusId or dates: { input: { id, attributes } }. Returns the payload (with errors) or null. |
CLI:
| Entity | list | get | create | update | delete |
|---|---|---|---|---|---|
tasks | — | — | ✓ | ✓ | ✓ |
notes | — | — | ✓ | ✓ | ✓ |
spaces | — | — | ✓ | ✓ | ✓ |