uidudevelopers
Domains

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 / getTask or listNotes / getNote functions 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 (apiKey on 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. priority is low, normal, high or urgent; startDate / endDate are YYYY-MM-DD. parentId makes a subtask, goalId links the task to a goal, statusId places it in a status of its Space. A task is finished either by setting doneAt, or by moving it to a status whose state is completed — 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:

FunctionRecord at
createSpacespace.node — { id, name }, wrapped in an edge
createNotenote.node — { id }, wrapped in an edge
createTasktask — { 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 with deleteSpace(uiduAdmin, { input: { id: spaceId } }).
  • The same from a terminal: uidu spaces create --attributes '{"name":"Product launch"}', then uidu 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_ID and db stand for your own configuration and storage — the SDK doesn't provide them.
  • Instead of doneAt, you can move the task with statusId to a status whose state is completed.

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.

FunctionKindAuthCLIDescription
createNotewriteBearernotes createCreate a note. Returns the payload (with errors) or null; the new note is at note.node.
createSpacewriteBearerspaces createCreate a space, the container tasks live in. Returns the payload (with errors) or null; the new space is at space.node.
createTaskwriteBearertasks createCreate a task, usually in a space (attributes.spaceId). Returns the payload (with errors) or null.
deleteNotewriteBearernotes deleteDelete a note by { input: { id } }. Returns the payload (with errors) or null.
deleteSpacewriteBearerspaces deleteDelete a space by { input: { id } }. Returns the payload (with errors) or null.
deleteTaskwriteBearertasks deleteDelete a task by { input: { id } }. Returns the payload (with errors) or null.
updateNotewriteBearernotes updateUpdate a note: { input: { id, attributes } }. Returns the payload (with errors) or null.
updateSpacewriteBearerspaces updateUpdate a space: { input: { id, attributes } }. Returns the payload (with errors) or null.
updateTaskwriteBearertasks updateUpdate a task, e.g. its statusId or dates: { input: { id, attributes } }. Returns the payload (with errors) or null.

CLI:

Entitylistgetcreateupdatedelete
tasks——✓✓✓
notes——✓✓✓
spaces——✓✓✓

On this page