Board

One board: read it, create it, change it, copy its structure, archive it.

GET /api/data/board

Parameters

NameTypeRequiredDescription
idintegeryesThe board's id.
curl -X GET "https://boards.example.com/api/data/board?id=123" \
  -H "X-API-Key: $LOKALBOARDS_KEY"
const response = await fetch("https://boards.example.com/api/data/board?id=123", {
  headers: {
    "X-API-Key": apiKey,
  },
});

if (!response.ok) throw new Error(await response.text());

const data = await response.json();
<script setup>
const config = useRuntimeConfig();

const { data, error } = await useAsyncData("board", () =>
  $fetch("https://boards.example.com/api/data/board?id=123", {
    headers: { "X-API-Key": config.lokalBoardsKey },
  }),
);
</script>

<template>
  <pre v-if="data">{{ data }}</pre>
  <p v-else-if="error">{{ error.message }}</p>
</template>
import { useEffect, useState } from "react";

export function Example({ apiKey }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    const controller = new AbortController();

    fetch("https://boards.example.com/api/data/board?id=123", {
      headers: { "X-API-Key": apiKey },
      signal: controller.signal,
    })
      .then((response) => response.json())
      .then(setData)
      .catch((error) => {
        if (error.name !== "AbortError") console.error(error);
      });

    return () => controller.abort();
  }, [apiKey]);

  return <pre>{JSON.stringify(data, null, 2)}</pre>;
}
<?php

$ch = curl_init('https://boards.example.com/api/data/board?id=123');

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: ' . $apiKey,
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

Response

{
  "board": {
    "id": 123,
    "user": "8f3c1e2a-5b7d-4a91-9c8e-2d6f0b4a7e13",
    "name": "Product Roadmap",
    "style": "kanban",
    "image": null,
    "color": "#2563eb",
    "status": "private"
  }
}

POST /api/data/board

Creates a board, or updates one when id is given.

Parameters

NameTypeRequiredDescription
idintegernoPresent means update, absent means create.
userIdstringyesThe owner. Must be the account the key belongs to.
namestringyesThe board's name.
stylestringyeskanban or todo.
statusstringyesprivate or public.
imagestring | nullnoA cover image for the tile. Clears color.
colorstring | nullnoA hex colour for the tile. Clears image. Anything that is not a hex colour becomes null.
curl -X POST "https://boards.example.com/api/data/board" \
  -H "X-API-Key: $LOKALBOARDS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "8f3c1e2a-5b7d-4a91-9c8e-2d6f0b4a7e13",
    "name": "Product Roadmap",
    "style": "kanban",
    "status": "private",
    "image": null,
    "color": "#2563eb"
  }'
const response = await fetch("https://boards.example.com/api/data/board", {
  method: "POST",
  headers: {
    "X-API-Key": apiKey,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    userId: "8f3c1e2a-5b7d-4a91-9c8e-2d6f0b4a7e13",
    name: "Product Roadmap",
    style: "kanban",
    status: "private",
    image: null,
    color: "#2563eb",
  }),
});

if (!response.ok) throw new Error(await response.text());

const data = await response.json();
<script setup>
const config = useRuntimeConfig();
const pending = ref(false);

async function saveBoard() {
  pending.value = true;
  try {
    return await $fetch("https://boards.example.com/api/data/board", {
      method: "POST",
      headers: { "X-API-Key": config.lokalBoardsKey },
      body: {
        userId: "8f3c1e2a-5b7d-4a91-9c8e-2d6f0b4a7e13",
        name: "Product Roadmap",
        style: "kanban",
        status: "private",
        image: null,
        color: "#2563eb",
      },
    });
  } finally {
    pending.value = false;
  }
}
</script>

<template>
  <button :disabled="pending" @click="saveBoard()">Save board</button>
</template>
import { useState } from "react";

export function Example({ apiKey }) {
  const [pending, setPending] = useState(false);

  async function saveBoard() {
    setPending(true);

    const response = await fetch("https://boards.example.com/api/data/board", {
      method: "POST",
      headers: {
        "X-API-Key": apiKey,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        userId: "8f3c1e2a-5b7d-4a91-9c8e-2d6f0b4a7e13",
        name: "Product Roadmap",
        style: "kanban",
        status: "private",
        image: null,
        color: "#2563eb",
      }),
    });

    setPending(false);
    return response.json();
  }

  return (
    <button disabled={pending} onClick={saveBoard}>
      Save board
    </button>
  );
}
<?php

$ch = curl_init('https://boards.example.com/api/data/board');

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: ' . $apiKey,
    'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'userId' => "8f3c1e2a-5b7d-4a91-9c8e-2d6f0b4a7e13",
    'name' => "Product Roadmap",
    'style' => "kanban",
    'status' => "private",
    'image' => null,
    'color' => "#2563eb",
]));

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

PATCH /api/data/board

Reorders the areas of a board in one call — the whole order, not one move.

Parameters

NameTypeRequiredDescription
boardIdintegeryesThe board whose areas are being reordered.
areasintegeryesEvery area id, in the order they should appear.
curl -X PATCH "https://boards.example.com/api/data/board" \
  -H "X-API-Key: $LOKALBOARDS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"boardId": 123, "areas": [12, 10, 11]}'
const response = await fetch("https://boards.example.com/api/data/board", {
  method: "PATCH",
  headers: {
    "X-API-Key": apiKey,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    boardId: 123,
    areas: [12, 10, 11],
  }),
});

if (!response.ok) throw new Error(await response.text());

const data = await response.json();
<script setup>
const config = useRuntimeConfig();
const pending = ref(false);

async function reorderAreas() {
  pending.value = true;
  try {
    return await $fetch("https://boards.example.com/api/data/board", {
      method: "PATCH",
      headers: { "X-API-Key": config.lokalBoardsKey },
      body: {
        boardId: 123,
        areas: [12, 10, 11],
      },
    });
  } finally {
    pending.value = false;
  }
}
</script>

<template>
  <button :disabled="pending" @click="reorderAreas()">Save order</button>
</template>
import { useState } from "react";

export function Example({ apiKey }) {
  const [pending, setPending] = useState(false);

  async function reorderAreas() {
    setPending(true);

    const response = await fetch("https://boards.example.com/api/data/board", {
      method: "PATCH",
      headers: {
        "X-API-Key": apiKey,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        boardId: 123,
        areas: [12, 10, 11],
      }),
    });

    setPending(false);
    return response.json();
  }

  return (
    <button disabled={pending} onClick={reorderAreas}>
      Save order
    </button>
  );
}
<?php

$ch = curl_init('https://boards.example.com/api/data/board');

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: ' . $apiKey,
    'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'boardId' => 123,
    'areas' => [12, 10, 11],
]));

$response = json_decode(curl_exec($ch), true);
curl_close($ch);

POST /api/data/board-duplicate

Copies a board's structure: the board and its columns, and none of its cards.

The copy takes the style and the colour, and the name you give it. It belongs to whoever asked for it rather than to whoever owned the original, and it is private whatever the original was — a new board with nothing in it is nobody else's business yet. Archived columns are left behind, being no longer part of the board's shape.

Seeing a board is enough to take a copy of its shape, so this needs read access rather than ownership: the result is a board of your own holding nothing but column names.

Parameters

NameTypeRequiredDescription
boardIdintegeryesThe board to copy.
namestringyesThe new board's name. Trimmed, and at most 255 characters.

What comes back

FieldTypeDescription
boardobjectThe new board: id, name, style, image, color and status.
areasintegerHow many columns were copied.
curl -X POST "https://boards.example.com/api/data/board-duplicate" \
  -H "X-API-Key: $LOKALBOARDS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "boardId": 123, "name": "Theaterprojekt" }'
const response = await fetch(
  "https://boards.example.com/api/data/board-duplicate",
  {
    method: "POST",
    headers: { "X-API-Key": apiKey, "Content-Type": "application/json" },
    body: JSON.stringify({ boardId: 123, name: "Theaterprojekt" }),
  },
);

if (!response.ok) throw new Error(await response.text());

const { board, areas } = await response.json();
<script setup>
const config = useRuntimeConfig();

async function startFrom(boardId, name) {
  const { board } = await $fetch(
    "https://boards.example.com/api/data/board-duplicate",
    {
      method: "POST",
      headers: { "X-API-Key": config.lokalBoardsKey },
      body: { boardId, name },
    },
  );
  return board.id;
}
</script>
async function startFrom(apiKey, boardId, name) {
  const response = await fetch(
    "https://boards.example.com/api/data/board-duplicate",
    {
      method: "POST",
      headers: { "X-API-Key": apiKey, "Content-Type": "application/json" },
      body: JSON.stringify({ boardId, name }),
    },
  );

  if (!response.ok) throw new Error(await response.text());

  const { board } = await response.json();
  return board.id;
}
<?php

$ch = curl_init('https://boards.example.com/api/data/board-duplicate');

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: ' . $apiKey,
    'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'boardId' => 123,
    'name' => 'Theaterprojekt',
]));

$board = json_decode(curl_exec($ch), true)['board'];
curl_close($ch);

DELETE /api/data/board

Archives a board with everything on it. Owner only. It leaves every dashboard it was on and can be restored from the archive on yours.

This archives rather than deletes. Since v0.36.0 the row stays, everything hanging off it stays, and it disappears from every list — the board, the dashboard, search and the reminders — until it is restored. Pass permanent for the old, irreversible behaviour.

Pass permanent=true to delete it outright instead, with its areas, cards, comments, attachments and uploaded files. That one is not reversible.

Parameters

NameTypeRequiredDescription
idintegeryesThe board's id.
curl -X DELETE "https://boards.example.com/api/data/board?id=123" \
  -H "X-API-Key: $LOKALBOARDS_KEY"
const response = await fetch("https://boards.example.com/api/data/board?id=123", {
  method: "DELETE",
  headers: {
    "X-API-Key": apiKey,
  },
});

if (!response.ok) throw new Error(await response.text());

const data = await response.json();
<script setup>
const config = useRuntimeConfig();
const pending = ref(false);

async function deleteBoard() {
  pending.value = true;
  try {
    return await $fetch("https://boards.example.com/api/data/board?id=123", {
      method: "DELETE",
      headers: { "X-API-Key": config.lokalBoardsKey },
    });
  } finally {
    pending.value = false;
  }
}
</script>

<template>
  <button :disabled="pending" @click="deleteBoard()">Delete board</button>
</template>
import { useState } from "react";

export function Example({ apiKey }) {
  const [pending, setPending] = useState(false);

  async function deleteBoard() {
    setPending(true);

    const response = await fetch("https://boards.example.com/api/data/board?id=123", {
      method: "DELETE",
      headers: {
        "X-API-Key": apiKey,
      },
    });

    setPending(false);
    return response.json();
  }

  return (
    <button disabled={pending} onClick={deleteBoard}>
      Delete board
    </button>
  );
}
<?php

$ch = curl_init('https://boards.example.com/api/data/board?id=123');

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: ' . $apiKey,
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);