Notsku APISend notifications to everyone, a team, or one person. GET /v1/boards/{boardId} returns the board only. People are GET /v1/boards/{boardId}/people. Notifications arrive in Notsku (inbox and push).
AuthenticationCreate an org-scoped key in Manage → API. Send it as Authorization: Bearer jb_live_YOUR_KEY. Keys never go in a user’s browser.

Base URL

https://api.notsku.com/functions/v1/public-api
How to send a notificationLook up ids first, then POST /notifications. For one person, audience.type is "people" and people_ids is an array with that membership id.
Send a notification to one personGET /v1/boards — copy board id.GET /v1/boards/{boardId}/people — copy that person’s id. This is a membership id, not their email and not their auth user id.POST /v1/boards/{boardId}/notifications with audience.type "people" and people_ids: ["that-membership-id"]. One person is an array of one id.

cURL

curl -X POST https://api.notsku.com/functions/v1/public-api/v1/boards/{boardId}/notifications \
  -H "Authorization: Bearer jb_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Your shift starts at 16:00",
  "body": "Please open Notsku and confirm.",
  "urgency": "important",
  "audience": {
    "type": "people",
    "people_ids": ["11111111-2222-3333-4444-555555555555"]
  }
}'
Send a notification to one teamGET /v1/boards/{boardId}/teams — copy the team’s id.POST /v1/boards/{boardId}/notifications with audience.type "team" and team_id.

cURL

curl -X POST https://api.notsku.com/functions/v1/public-api/v1/boards/{boardId}/notifications \
  -H "Authorization: Bearer jb_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Kitchen prep list",
  "body": "Check the cooler before open.",
  "urgency": "normal",
  "audience": {
    "type": "team",
    "team_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
  }
}'
Send a notification to everyone on the boardPOST /v1/boards/{boardId}/notifications with audience.type "all". No people_ids or team_id.

cURL

curl -X POST https://api.notsku.com/functions/v1/public-api/v1/boards/{boardId}/notifications \
  -H "Authorization: Bearer jb_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Office closed Friday",
  "body": "The office is closed on Friday.",
  "urgency": "normal",
  "audience": { "type": "all" }
}'
Connect a user to a board1. Your server creates a connect session with the API key.2. Redirect the user to connect_url. They sign in on Notsku and confirm.3. Notsku redirects back with a one-time code. Your server exchanges it for membership_id. Use that id later in people_ids.
MCPOne MCP server, two kinds of keys. Personal keys (Profile) read and reply to your inbox, manage where you are joined, and change notification settings. Organization keys (Manage → API) expose the same operations as this REST API.
MCP URL

MCP URL

https://api.notsku.com/functions/v1/mcp
Send the key as Authorization: Bearer jb_user_… or jb_live_…. On hosted Supabase, if the gateway requires the publishable key in Authorization, put the Notsku key in X-Joinboard-Key instead.

Cursor config

{
  "mcpServers": {
    "joinboard": {
      "url": "https://api.notsku.com/functions/v1/mcp",
      "headers": {
        "Authorization": "Bearer jb_user_YOUR_KEY"
      }
    }
  }
}
Member tools (jb_user_…)
list_inboxList your messages. recipient_id is the message id. open_only true shows only items that still need a reply.

Example

{
  "open_only": true
}
get_messageRead one message (title, body, questions) and mark it viewed. Use recipient_id from list_inbox.

Example

{
  "recipient_id": "11111111-2222-3333-4444-555555555555"
}
reply_to_messageReply to a message. For one question, pass answer (yes/no, an option, or text). For several, pass answers. Acknowledgements use yes.

Example

{
  "recipient_id": "11111111-2222-3333-4444-555555555555",
  "answer": "yes"
}
list_my_boardsList boards you have joined, with your role and per-board notification settings.

Example

{}
update_notification_settingsSet which urgencies you receive on one board. board_id is the organization id from list_my_boards.

Example

{
  "board_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee",
  "notify_normal": true,
  "notify_important": true,
  "notify_urgent": true
}
leave_boardLeave a board. Owners cannot leave until they transfer ownership.

Example

{
  "board_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee"
}
Organization tools (jb_live_…)
list_boardsList the board this organization API key can access.

Example

{}
get_boardGet one board’s metadata. Does not include people or teams.

Example

{
  "board_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee"
}
list_teamsList teams on a board. Use a team id as team_id when sending to that team.

Example

{
  "board_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee"
}
list_peopleList people on a board. Each id is a membership id for send_notification people_ids. Optional state defaults to active; use all for invited or pending.

Example

{
  "board_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee",
  "state": "active"
}
send_notificationSend a notification to everyone, one team, or specific people. Recipients get it in the Notsku inbox and as a push notification. people_ids are membership ids from list_people.

Example

{
  "board_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee",
  "title": "Your shift starts at 16:00",
  "body": "Please open Notsku and confirm.",
  "urgency": "important",
  "audience_type": "people",
  "people_ids": ["11111111-2222-3333-4444-555555555555"]
}
create_connect_sessionStart a member connect flow. return_url must be allowlisted on the API key.

Example

{
  "board_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee",
  "return_url": "https://partner.example/joinboard/callback",
  "state": "csrf-token"
}
exchange_connect_codeExchange the one-time code from the connect redirect for a membership id.

Example

{
  "code": "…"
}
Endpoints
GET
/v1/boards
Scope: readList the board this API key can access.Returns metadata only (id, name, slug, description). It does not include people. Use GET /v1/boards/{boardId}/people next.

cURL

curl https://api.notsku.com/functions/v1/public-api/v1/boards \
  -H "Authorization: Bearer jb_live_YOUR_KEY"

Response

{
  "data": [{ "id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee", "name": "Helsinki Store", "slug": "helsinki-store", "description": "Staff board" }]
}
GET
/v1/boards/{boardId}
Scope: readGet one board’s metadata. Returns 404 if the id is not this key’s board.Does not include people or teams. Those are separate URLs under this board id.

cURL

curl https://api.notsku.com/functions/v1/public-api/v1/boards/{boardId} \
  -H "Authorization: Bearer jb_live_YOUR_KEY"

Response

{
  "id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee",
  "name": "Helsinki Store",
  "slug": "helsinki-store",
  "description": "Staff board"
}
GET
/v1/boards/{boardId}/teams
Scope: readList teams on the board.Use a team’s id as audience.team_id when sending to that team.

cURL

curl https://api.notsku.com/functions/v1/public-api/v1/boards/{boardId}/teams \
  -H "Authorization: Bearer jb_live_YOUR_KEY"

Response

{
  "data": [{ "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "name": "Kitchen", "member_count": 4 }]
}
GET
/v1/boards/{boardId}/people
Scope: readList people on the board.Each row’s id is the membership id. Use that id in POST /notifications audience.people_ids. Do not send email or user_id. Default filter is ?state=active. Use ?state=all to include invited or pending people.

cURL

curl https://api.notsku.com/functions/v1/public-api/v1/boards/{boardId}/people \
  -H "Authorization: Bearer jb_live_YOUR_KEY"

Response

{
  "data": [{
    "id": "11111111-2222-3333-4444-555555555555",
    "display_name": "Alex",
    "email": "alex@example.com",
    "role": "member",
    "state": "active",
    "team_ids": []
  }]
}
POST
/v1/boards/{boardId}/notifications
Scope: sendSend a notification. Recipients get it in the Notsku inbox and as a push notification.audience.type must be all, team, or people. For one person, type is still "people" with a one-element people_ids array. people_ids values come from GET /people (membership id). Optional Idempotency-Key header retries the same send safely.

cURL

curl -X POST https://api.notsku.com/functions/v1/public-api/v1/boards/{boardId}/notifications \
  -H "Authorization: Bearer jb_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Your shift starts at 16:00",
  "body": "Please open Notsku and confirm.",
  "urgency": "important",
  "audience": {
    "type": "people",
    "people_ids": ["11111111-2222-3333-4444-555555555555"]
  }
}'

One person

{
  "title": "Your shift starts at 16:00",
  "body": "Please open Notsku and confirm.",
  "urgency": "important",
  "audience": {
    "type": "people",
    "people_ids": ["11111111-2222-3333-4444-555555555555"]
  }
}

Several people

{
  "title": "Cover needed tonight",
  "body": "Can you take 16:00–22:00?",
  "audience": {
    "type": "people",
    "people_ids": [
      "11111111-2222-3333-4444-555555555555",
      "bbbbbbbb-cccc-dddd-eeee-ffffffffffff"
    ]
  }
}

One team

{
  "title": "Kitchen prep list",
  "body": "Check the cooler before open.",
  "audience": {
    "type": "team",
    "team_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
  }
}

Everyone on the board

{
  "title": "Office closed Friday",
  "body": "The office is closed on Friday.",
  "audience": { "type": "all" }
}

Response

{
  "id": "content-item-uuid",
  "campaign_id": "campaign-uuid",
  "recipient_count": 1,
  "audience": {
    "type": "people",
    "people_ids": ["11111111-2222-3333-4444-555555555555"]
  }
}
POST
/v1/boards/{boardId}/connect-sessions
Scope: joinStart a member connect flow. Redirect the user to connect_url. return_url must be allowlisted on the key.Call this from your server. Never put the API key in the user’s browser.

cURL

curl -X POST https://api.notsku.com/functions/v1/public-api/v1/boards/{boardId}/connect-sessions \
  -H "Authorization: Bearer jb_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "return_url": "https://partner.example/joinboard/callback",
  "state": "csrf-token"
}'

Body

{
  "return_url": "https://partner.example/joinboard/callback",
  "state": "csrf-token"
}

Response

{
  "connect_url": "https://app.example/connect/…",
  "token": "…",
  "expires_at": "2026-09-06T12:00:00Z",
  "state": "csrf-token"
}
POST
/v1/connect/exchange
Scope: joinExchange the one-time code from the redirect for the membership id.membership_id in the response is the same id you later pass in people_ids when sending a notification to that person.

cURL

curl -X POST https://api.notsku.com/functions/v1/public-api/v1/connect/exchange \
  -H "Authorization: Bearer jb_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "…" }'

Body

{ "code": "…" }

Response

{
  "board_id": "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee",
  "membership_id": "11111111-2222-3333-4444-555555555555",
  "status": "joined"
}
Errors look like { "error": { "code": "unauthorized", "message": "…" } } with HTTP 401, 403, 404, 422, or 429.

Important messages. Clear answers.

Product

Home