Calendar
Deliveries, posts, meetings and dates.
Privacy and analytics
We use necessary technical cookies and, only with your consent, analytics and marketing pixels to improve the website and measure campaigns.
Deliveries, posts, meetings and dates.
Deliveries, tasks, campaigns, social posts, meetings, events and marked dates between two dates, at most 62 days apart, in the caller time zone.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/calendar.window |
| MCP tool | calendar_window |
| Scope | calendar.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Nödo, Voice, MCP, API, Chat, Screens, Apps |
| Status | Available |
| Widget | calendar_week |
Input
{
from: string
to: string
kinds?: Array<"delivery" | "task" | "campaign" | "social" | "meeting" | "event" | "marked_date">
timeZone?: string // ≤ 64 · default "Europe/Madrid"
}Output
{
events: Array<{
id: string
kind: "delivery" | "task" | "campaign" | "social" | "meeting" | "event" | "marked_date"
title: string
start: string
end: string | null
allDay: boolean
link: string | null
}>
}Creates, changes or deletes a marked date (launch, event, holiday) that the whole brand team sees. Only its creator or a brand owner/admin may delete it.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.dates.save |
| MCP tool | calendar_dates_save |
| Scope | calendar.write |
| Minimum role | Member |
| Human confirmation | Yes |
| Doors | Nödo, MCP, API, Chat, Screens, Apps |
| Status | Available |
| Widget | confirm |
Input
{
op: "upsert"
id?: string // uuid
title: string // ≤ 120
date: string
endDate?: string
note?: string // ≤ 500
}
| {
op: "delete"
id: string // uuid
}Output
{
ok: true
id?: string
revision?: integer // -9007199254740991–9007199254740991
}Schedules a brand meeting at a local date and time with its duration and place. The rest of the brand is told (never its creator). Returns the stored meeting.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.meetings.create |
| MCP tool | calendar_meetings_create |
| Scope | calendar.write |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
title: string // ≤ 300
description?: string // ≤ 10000
date: string
time: string
durationMinutes?: integer // 1–1440 · default 60
location?: string // ≤ 500
}Output
{
meeting: {
id: string // uuid
}
}Saves the notes of a meeting and nothing else (link, agenda and date stay). Its creator or whoever administers the brand may write them.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.meetings.update_notes |
| MCP tool | calendar_meetings_update_notes |
| Scope | calendar.write |
| Minimum role | Member |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
meetingId: string // uuid
notes: string // ≤ 100000
}Output
{
ok: true
}Removes a meeting for everyone at once (soft delete). Whoever removed it can take it back for ten minutes with calendar.meetings.restore; a meeting still to come is announced as cancelled once that window passes.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.meetings.trash |
| MCP tool | calendar_meetings_trash |
| Scope | calendar.write |
| Minimum role | Admin |
| Human confirmation | Yes |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
meetingId: string // uuid
}Output
{
ok: true
}Undo of calendar.meetings.trash: only whoever removed it, within ten minutes (conflict, undo_expired afterwards). The held cancellation notice never goes out.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.meetings.restore |
| MCP tool | calendar_meetings_restore |
| Scope | calendar.write |
| Minimum role | Admin |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
meetingId: string // uuid
}Output
{
ok: true
}Adds one of the brand's own events to its calendar, all day or timed, in the given IANA time zone. startsOn/endsOn are the local days of startsAt/endsAt. Returns the stored event.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.brand_events.create |
| MCP tool | calendar_brand_events_create |
| Scope | calendar.write |
| Minimum role | Member |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
title: string // ≤ 160
description?: string | null
location?: string | null
allDay: boolean
startsOn: string
endsOn: string
startsAt: string // date-time
endsAt: string // date-time
timeZone: string // ≤ 80
}Output
{
event: Record<string, unknown>
}Replaces the fields of one of the brand's own calendar events, with the same rules as creating one. Returns the stored event.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.brand_events.update |
| MCP tool | calendar_brand_events_update |
| Scope | calendar.write |
| Minimum role | Member |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
eventId: string // uuid
title: string // ≤ 160
description?: string | null
location?: string | null
allDay: boolean
startsOn: string
endsOn: string
startsAt: string // date-time
endsAt: string // date-time
timeZone: string // ≤ 80
}Output
{
event: Record<string, unknown>
}Deletes one of the brand's own calendar events. Only whoever created it, or someone who administers the brand (owner or admin), may: anyone else gets forbidden (detail not_own_entry). Deliveries, tasks and posts are not events and are never touched.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.brand_events.delete |
| MCP tool | calendar_brand_events_delete |
| Scope | calendar.write |
| Minimum role | Member |
| Human confirmation | Yes |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
eventId: string // uuid
}Output
{
ok: true
}Marks a date on the brand calendar, optionally repeating every recurrenceInterval days, weeks, months or years until recurrenceEndsOn. Returns the stored marked date.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.marked_dates.create |
| MCP tool | calendar_marked_dates_create |
| Scope | calendar.write |
| Minimum role | Member |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
title: string // ≤ 160
notes?: string | null
startsOn: string
startsAt: string // date-time
timeZone: string // ≤ 80
recurrence: "none" | "daily" | "weekly" | "monthly" | "yearly"
recurrenceInterval: integer // 1–365
recurrenceEndsOn?: string | null
}Output
{
markedDate: {
id: string // uuid
brand_id: string // uuid
title: string
notes: string | null
starts_on: string
starts_at: string
time_zone: string
recurrence: string // none, daily, weekly, monthly or yearly.
recurrence_interval: integer // -9007199254740991–9007199254740991
recurrence_ends_on: string | null
created_at: string
updated_at: string
}
}Replaces the fields of one marked date of the brand, its repetition included. Returns the stored marked date.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.marked_dates.update |
| MCP tool | calendar_marked_dates_update |
| Scope | calendar.write |
| Minimum role | Member |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
markedDateId: string // uuid
title: string // ≤ 160
notes?: string | null
startsOn: string
startsAt: string // date-time
timeZone: string // ≤ 80
recurrence: "none" | "daily" | "weekly" | "monthly" | "yearly"
recurrenceInterval: integer // 1–365
recurrenceEndsOn?: string | null
}Output
{
markedDate: {
id: string // uuid
brand_id: string // uuid
title: string
notes: string | null
starts_on: string
starts_at: string
time_zone: string
recurrence: string // none, daily, weekly, monthly or yearly.
recurrence_interval: integer // -9007199254740991–9007199254740991
recurrence_ends_on: string | null
created_at: string
updated_at: string
}
}Deletes one marked date of the brand, every repetition included. Only whoever created it, or someone who administers the brand (owner or admin), may: anyone else gets forbidden (detail not_own_entry).
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.marked_dates.delete |
| MCP tool | calendar_marked_dates_delete |
| Scope | calendar.write |
| Minimum role | Member |
| Human confirmation | Yes |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
markedDateId: string // uuid
}Output
{
ok: true
}Saves how the caller sees this brand's calendar: first weekday (0 Sunday, 1 Monday), last view, category filters and an optional IANA time zone (null follows the device). Affects only the caller. Returns the stored preferences.
| Field | Value |
|---|---|
| Kind | Write |
| HTTP method | POST /api/v1/calendar.preferences.save |
| MCP tool | calendar_preferences_save |
| Scope | calendar.write |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Screens, Apps |
| Status | Available |
Input
{
weekStartsOn: 0 | 1
lastView: "agenda" | "day" | "week" | "month" | "year"
activeFilters: string[] // ≤ 40 items
timeZone?: string | null // default null
}Output
{
preferences: {
userId: string
brandId: string
weekStartsOn: integer // 0–1 · 0 Sunday, 1 Monday.
lastView: "agenda" | "day" | "week" | "month" | "year"
activeFilters: string[] // Categories in display order; every category means «all».
timeZone: string | null // IANA zone; null follows the device.
sourceDeviceId: string | null
updatedAt: string | null
}
}What happens at the brand in the next days (posts, deliveries, meetings, dates) in the zone the person saved for its calendar, else fallbackTimeZone. savedTimeZone is that saved zone, if any.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/calendar.upcoming |
| MCP tool | calendar_upcoming |
| Scope | calendar.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | API, MCP, Screens, Apps, Nödo |
| Status | Available |
Input
{
days?: integer // 1–14 · default 8
fallbackTimeZone: string // ≤ 64
asClient?: boolean // Read as the brand sees it (a staff viewer previewing as client). Only narrows.
}Output
{
events: Record<string, unknown>[]
timeZone: string
savedTimeZone: string | null
}The events and per-day summary of a window of the brand calendar exactly as the screen draws them (work dates, posts, campaigns, meetings, the brand's own events and marked dates), with what the reader can edit. from/to are instants (at most 380 days apart); mode: "summary" returns the day summary only. For the compact agent shape use calendar.window.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/calendar.screen.window |
| MCP tool | calendar_screen_window |
| Scope | calendar.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Screens, Apps, API, MCP |
| Status | Available |
Input
{
brandShortId?: string // ≤ 80 · The brand's short id, for the links; read when absent.
from: string // date-time
to: string // date-time
timeZone: string // ≤ 80
filters: string[] // ≤ 12 items
mode?: "detail" | "summary" // default "detail"
preview?: boolean // Staff previewing the brand as a client: edit controls are left out.
}Output
{
brandId: string // uuid
from: string
to: string
timeZone: string
mode: "detail" | "summary"
events: Array<{
id: string
sourceId: string
brandId: string
kind: string
title: string
status: string | null
allDay: boolean
startsAt: string | null
endsAt: string | null
startsOn: string | null
endsOn: string | null
href: string | null
recurrence: string | null // Marked dates only: none, daily, weekly, monthly or yearly.
recurrenceInterval: integer | null
recurrenceEndsOn: string | null
notes?: string | null
subtitle?: string | null
statusTone?: string // neutral, progress, attention, done or failed.
needsAction?: boolean
workId?: string | null
workHref?: string | null
editable?: boolean
deletable?: boolean
facts?: {
kind: string
}
}>
summary: Array<{
date: string
total: integer // -9007199254740991–9007199254740991
counts: Record<string, integer>
}>
canManage: boolean
canDeleteAny?: boolean
}What the calendar paints on opening: the reader's preferences and the window they land on (the requested view and date, else the device's, else their last view; today in their zone). seed is null when no time zone is known (neither saved nor reported by the device).
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/calendar.screen.page |
| MCP tool | calendar_screen_page |
| Scope | calendar.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Screens, Apps, API |
| Status | Available |
Input
{
brandShortId?: string // ≤ 80
view?: string | null
date?: string | null
device?: {
view: string // ≤ 20
grid: boolean
timeZone: string | null
}
| null
preview?: boolean // Staff previewing the brand as a client: edit controls are left out.
}Output
{
preferences: {
userId: string
brandId: string
weekStartsOn: integer // 0–1 · 0 Sunday, 1 Monday.
lastView: "agenda" | "day" | "week" | "month" | "year"
activeFilters: string[] // Categories in display order; every category means «all».
timeZone: string | null // IANA zone; null follows the device.
sourceDeviceId: string | null
updatedAt: string | null
}
seed: {
data: {
brandId: string // uuid
from: string
to: string
timeZone: string
mode: "detail" | "summary"
events: Array<{
id: string
sourceId: string
brandId: string
kind: string
title: string
status: string | null
allDay: boolean
startsAt: string | null
endsAt: string | null
startsOn: string | null
endsOn: string | null
href: string | null
recurrence: string | null // Marked dates only: none, daily, weekly, monthly or yearly.
recurrenceInterval: integer | null
recurrenceEndsOn: string | null
notes?: string | null
subtitle?: string | null
statusTone?: string // neutral, progress, attention, done or failed.
needsAction?: boolean
workId?: string | null
workHref?: string | null
editable?: boolean
deletable?: boolean
facts?: {
kind: string
}
}>
summary: Array<{
date: string
total: integer // -9007199254740991–9007199254740991
counts: Record<string, integer>
}>
canManage: boolean
canDeleteAny?: boolean
}
}
| null
}How the caller sees this brand's calendar: first weekday, last view, category filters and time zone (null follows the device). calendar.preferences.save changes it.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/calendar.preferences.get |
| MCP tool | calendar_preferences_get |
| Scope | calendar.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Screens, Apps, API |
| Status | Available |
Input
{}Output
{
preferences: {
userId: string
brandId: string
weekStartsOn: integer // 0–1 · 0 Sunday, 1 Monday.
lastView: "agenda" | "day" | "week" | "month" | "year"
activeFilters: string[] // Categories in display order; every category means «all».
timeZone: string | null // IANA zone; null follows the device.
sourceDeviceId: string | null
updatedAt: string | null
}
}Everything one calendar event holds once opened (a work date, post, campaign, meeting, brand event or marked date), by the id the window gave it. detail is null when it no longer exists.
| Field | Value |
|---|---|
| Kind | Read |
| HTTP method | POST /api/v1/calendar.events.detail |
| MCP tool | calendar_events_detail |
| Scope | calendar.read |
| Minimum role | Viewer |
| Human confirmation | No |
| Doors | Screens, Apps, API, MCP |
| Status | Available |
Input
{
brandShortId?: string // ≤ 80
eventId: string // ≤ 120
}Output
{
detail: Record<string, unknown> | null
}Updated on January 1, 1970