Files
mattermost/api/v4/source/definitions.yaml
T
Nick Misasi 25f3a75cb7 [MM-67163] Scheduled Recaps (#35495)
* docs: map existing codebase with focus on recaps

- STACK.md - Technologies and dependencies
- ARCHITECTURE.md - System design and patterns
- STRUCTURE.md - Directory layout
- CONVENTIONS.md - Code style and patterns
- TESTING.md - Test structure
- INTEGRATIONS.md - External services
- CONCERNS.md - Technical debt and issues

* docs: initialize project

Scheduled AI Recaps — enable recurring scheduled recaps instead of only manual one-off summaries

* chore: add project config

Mode: yolo
Depth: standard
Parallelization: enabled

* docs: complete domain research for scheduled recaps

Research files:
- STACK.md: Job server patterns, ScheduledPosts reference implementation
- FEATURES.md: Table stakes vs differentiators, anti-features to avoid
- ARCHITECTURE.md: Component boundaries, data flow, 5-phase build order
- PITFALLS.md: Timezone, cluster, schema critical pitfalls
- SUMMARY.md: Synthesized findings and roadmap implications

Key findings:
- Use ScheduledPosts polling pattern, not JobServer schedulers
- Store user intent + pre-computed NextRunAt for efficient polling
- Leverage existing recap worker, extend with time_period support
- Critical: Get timezone/schema right in Phase 1 to avoid migrations

* docs: define v1 requirements

35 requirements across 5 categories:
- Scheduling (7)
- Management (8)
- Backend Infrastructure (10)
- Frontend Wizard (7)
- Frontend Scheduled Tab (7)

Topic-based recaps deferred to v2

* docs: create roadmap (5 phases)

* docs(01): capture phase context

Phase 01: Database Foundation
- OpenCode discretion on implementation patterns
- Implicit requirements from downstream phases noted

* docs(01-database-foundation): research phase domain

Phase 1: Database Foundation
- Analyzed existing Recap and ScheduledPost patterns
- Documented schema design for recurring schedules
- Identified timezone/DST handling approach using IANA zones
- Catalogued store interface patterns
- Documented common pitfalls and anti-patterns

* docs(01): create phase plan for database foundation

Phase 01: Database Foundation
- 2 plans in 2 waves
- Wave 1: Model + migration (01-01-PLAN.md)
- Wave 2: Store layer + tests (01-02-PLAN.md)
- Ready for execution

* feat(01-01): create ScheduledRecap model with DST-aware NextRunAt computation

- Add ScheduledRecap struct with all required fields for schedule configuration
- Add day-of-week bitmask constants matching Go's time.Weekday (Sunday=0)
- Add channel mode constants (specific, all_unreads)
- Add time period constants (last_24h, last_week, since_last_read)
- Implement ComputeNextRunAt with timezone-aware scheduling using time.LoadLocation
- Implement IsValid for input validation
- Add PreSave/PreUpdate lifecycle methods
- Add Auditable method for audit logging

* feat(01-01): create database migration for ScheduledRecaps table

- Create ScheduledRecaps table with all required columns
- Add index for user queries (idx_scheduled_recaps_user_id)
- Add index for scheduler polling (idx_scheduled_recaps_next_run_at)
- Add composite index for efficient scheduler query (idx_scheduled_recaps_enabled_next_run)
- Add index for user + soft delete queries (idx_scheduled_recaps_user_delete)
- Add down migration to drop all indexes and table

* test(01-01): add unit tests for ScheduledRecap with DST edge cases

- Test day-of-week bitmask constants and operations
- Test ComputeNextRunAt for Monday-only, weekday, and every-day schedules
- Test timezone handling - different timezones produce different UTC millis
- Test DST spring forward edge case (March 2024) - Go normalizes non-existent times
- Test DST fall back edge case (November 2024) - Go uses first occurrence
- Test error cases: invalid timezone, invalid time format, zero days
- Test IsValid method for all validation rules
- Test PreSave and PreUpdate lifecycle methods
- Test Auditable method returns expected fields
- Fix ComputeNextRunAt to validate time format using regex before parsing

* docs(01-01): complete ScheduledRecap model and migration plan

Tasks completed: 3/3
- Task 1: Create ScheduledRecap model with constants and NextRunAt computation
- Task 2: Create database migration for ScheduledRecaps table
- Task 3: Add unit tests for ComputeNextRunAt with DST edge cases

SUMMARY: .planning/phases/01-database-foundation/01-01-SUMMARY.md

* feat(01-02): add ScheduledRecapStore interface to store.go

- Add ScheduledRecapStore interface with CRUD operations (Save, Get, Update, Delete)
- Add query operations (GetForUser, GetDueBefore)
- Add state update methods (UpdateNextRunAt, MarkExecuted, SetEnabled)
- Register ScheduledRecap() method in main Store interface

* feat(01-02): create SqlScheduledRecapStore implementation

- Implement CRUD operations (Save, Get, Update, Delete with soft delete)
- Implement GetForUser with pagination for user's scheduled recaps
- Implement GetDueBefore for scheduler polling query
- Implement efficient state updates (UpdateNextRunAt, MarkExecuted, SetEnabled)
- Handle JSON serialization/deserialization of ChannelIds array
- Follow existing patterns from recap_store.go

* feat(01-02): register ScheduledRecapStore in SqlStore

- Add scheduledRecap field to SqlStoreStores struct
- Initialize newSqlScheduledRecapStore in NewSqlStore
- Add ScheduledRecap() accessor method to SqlStore

* test(01-02): add comprehensive tests for ScheduledRecapStore

- Test CRUD operations (Save, Get, Update, Delete)
- Test GetForUser with pagination
- Test GetDueBefore scheduler query filtering
- Test state update methods (UpdateNextRunAt, MarkExecuted, SetEnabled)
- Test ChannelIds JSON serialization (array, empty, nil)
- All 13 test cases pass

* docs(01-02): complete ScheduledRecapStore plan

Tasks completed: 4/4
- Add ScheduledRecapStore interface to store.go
- Create SqlScheduledRecapStore implementation
- Register ScheduledRecapStore in SqlStore
- Create comprehensive store tests

SUMMARY: .planning/phases/01-database-foundation/01-02-SUMMARY.md

* fix(01): regenerate store mocks for ScheduledRecapStore

* docs(01): complete Database Foundation phase

Phase 1: Database Foundation
- 2 plans executed (model + store)
- 3 requirements complete (INFRA-01, INFRA-02, INFRA-10)
- Goal verified ✓

* docs(03): research phase scheduler integration domain

Phase 03: Scheduler Integration
- Standard stack identified (Mattermost job system)
- Architecture patterns documented (Scheduler + Worker pattern)
- Cluster-safe execution via leader-only scheduling
- Pitfalls catalogued (duplicate jobs, race conditions)
- Code examples from existing codebase patterns

* docs(02): create phase 2 API layer plans

Phase 02: API Layer
- 2 plans in 2 waves
- Plan 01 (Wave 1): App layer methods for CRUD + pause/resume
- Plan 02 (Wave 2): API handlers, routes, params, audit events
- Ready for execution

* feat(02-01): create App layer CRUD methods for ScheduledRecap

- Add CreateScheduledRecap with session-based userId, validation, NextRunAt computation
- Add GetScheduledRecap to retrieve by ID
- Add GetScheduledRecapsForUser with pagination
- Add UpdateScheduledRecap with NextRunAt recomputation when enabled
- Add DeleteScheduledRecap for soft delete
- Add PauseScheduledRecap to disable without deleting
- Add ResumeScheduledRecap with NextRunAt recomputation before enabling
- Regenerate store layer files for ScheduledRecapStore interface

* docs(02-01): complete App layer CRUD methods plan

Tasks completed: 3/3
- Regenerate store mocks (already complete from Phase 1)
- Create App layer file with CRUD methods
- Verify app layer interfaces (no interface file exists)

SUMMARY: .planning/phases/02-api-layer/02-01-SUMMARY.md

* feat(02-02): add audit event constants for scheduled recaps

- AuditEventCreateScheduledRecap for recap configuration creation
- AuditEventGetScheduledRecap for viewing single recap
- AuditEventGetScheduledRecaps for listing user recaps
- AuditEventUpdateScheduledRecap for configuration updates
- AuditEventDeleteScheduledRecap for recap deletion
- AuditEventPauseScheduledRecap for pausing execution
- AuditEventResumeScheduledRecap for resuming execution

* feat(02-02): add ScheduledRecapId to params and context

- Add ScheduledRecapId field to Params struct
- Parse scheduled_recap_id from URL path variables
- Add RequireScheduledRecapId validation method

* feat(02-02): add route registration for scheduled recaps

- Add ScheduledRecaps and ScheduledRecap routes to Routes struct
- Initialize route prefixes in Init function
- Add InitScheduledRecap call in initialization

* feat(02-02): create API handlers for scheduled recaps

- InitScheduledRecap registers all 7 API routes
- createScheduledRecap validates required fields and creates recap
- getScheduledRecap retrieves with authorization check
- getScheduledRecaps lists user's recaps with pagination
- updateScheduledRecap updates with ownership verification
- deleteScheduledRecap soft deletes with authorization
- pauseScheduledRecap disables execution with ownership check
- resumeScheduledRecap re-enables with NextRunAt recomputation
- All handlers include audit logging and feature flag check

* docs(02-02): complete API handlers plan

Tasks completed: 4/4
- Add audit event constants for scheduled recaps
- Add ScheduledRecapId to params and context
- Add route registration in api.go
- Create API handler file

SUMMARY: .planning/phases/02-api-layer/02-02-SUMMARY.md

* docs(02): complete API Layer phase

Phase 2: API Layer
- 2 plans executed in 2 waves
- 16/16 must-haves verified
- INFRA-05 through INFRA-09 complete
- Ready for Phase 3: Scheduler Integration

* docs(03): create phase plan for scheduler integration

Phase 03: Scheduler Integration
- 2 plans in 2 waves
- Wave 1: Job constant, scheduler, worker
- Wave 2: Job registration, App method
- Ready for execution

* fix(03): revise plan 03-02 Task 2 for worker context compatibility

- CreateRecapFromSchedule now creates recap directly via store
- Uses sr.UserId instead of rctx.Session().UserId (unavailable in worker)
- Creates JobTypeRecap job directly instead of delegating to CreateRecap
- Updated key_links to reflect store and job linkage

* docs(04): capture phase context

Phase 04: Scheduled Tab
- Implementation decisions documented
- Phase boundary established
- Figma references captured (123:62940, 123:19772)

* feat(03-01): add JobTypeScheduledRecap constant

- Add JobTypeScheduledRecap constant with value 'scheduled_recap'
- Add to AllJobTypes slice for job type validation

* feat(03-01): create ScheduledRecap scheduler

- Add Scheduler struct wrapping PeriodicScheduler
- 1-minute polling interval (SchedulerPollingInterval constant)
- Enabled when cfg.FeatureFlags.EnableAIRecaps is true
- ScheduleJob polls GetDueBefore for due recaps
- Creates job with CreateJobOnce for deduplication
- Job data: scheduled_recap_id, user_id, channel_ids, agent_id

* feat(03-01): create ScheduledRecap worker

- Define AppIface interface with CreateRecapFromSchedule method
- Use SimpleWorker pattern following recap/worker.go pattern
- Enabled when cfg.FeatureFlags.EnableAIRecaps is true
- Extract job data: scheduled_recap_id, user_id, channel_ids, agent_id
- Verify ScheduledRecap exists and is enabled before execution
- Call app.CreateRecapFromSchedule to create the actual recap
- Compute next run time using sr.ComputeNextRunAt
- Call MarkExecuted to update LastRunAt, NextRunAt, RunCount atomically
- Disable non-recurring schedules after execution

* docs(03-01): complete job system components plan

Tasks completed: 3/3
- Add JobTypeScheduledRecap constant
- Create scheduler implementation
- Create worker implementation

SUMMARY: .planning/phases/03-scheduler-integration/03-01-SUMMARY.md

* docs(04): create phase 4 plans - Scheduled Tab UI

Phase 04: Frontend - Scheduled Tab
- 4 plans in 4 waves
- Wave 1: TypeScript types + Client4 API methods
- Wave 2: Redux layer (action types, actions, reducer, selectors)
- Wave 3: ScheduledRecapItem component (card UI with toggle, menu)
- Wave 4: Scheduled tab integration with human verification

Covers requirements TAB-01 through TAB-07 and MGMT-01 through MGMT-08

* feat(03-02): add ScheduledRecap job registration in initJobs

- Register JobTypeScheduledRecap with worker and scheduler
- Import scheduled_recap package for job components
- Worker uses App interface for CreateRecapFromSchedule
- Scheduler polls for due recaps at 1-minute intervals

* feat(03-02): implement CreateRecapFromSchedule App method

- Create Recap from ScheduledRecap configuration
- Use sr.UserId instead of session (worker context has no session)
- Create recap record directly via store
- Create JobTypeRecap job to trigger processing
- Handle both specific channels and all_unreads mode

* docs(03-02): complete app integration plan

Tasks completed: 3/3
- Add job registration in initJobs
- Implement CreateRecapFromSchedule App method
- Verify full integration compiles

SUMMARY: .planning/phases/03-scheduler-integration/03-02-SUMMARY.md

* docs(phase-3): complete scheduler integration phase

* feat(04-01): add ScheduledRecap TypeScript types

- Add ScheduledRecap type matching Go model fields
- Add ScheduledRecapInput type for create/update operations
- Types exported via @mattermost/types/recaps

* feat(04-01): add Client4 scheduled recap route and imports

- Add getScheduledRecapsRoute() method returning /scheduled_recaps endpoint
- Import ScheduledRecap and ScheduledRecapInput types

* feat(04-01): add Client4 scheduled recap API methods

- createScheduledRecap: POST /scheduled_recaps
- getScheduledRecaps: GET /scheduled_recaps (paginated)
- getScheduledRecap: GET /scheduled_recaps/:id
- updateScheduledRecap: PUT /scheduled_recaps/:id
- deleteScheduledRecap: DELETE /scheduled_recaps/:id
- pauseScheduledRecap: POST /scheduled_recaps/:id/pause
- resumeScheduledRecap: POST /scheduled_recaps/:id/resume

* docs(04-01): complete TypeScript types and Client4 methods plan

Tasks completed: 3/3
- Add ScheduledRecap TypeScript type
- Add Client4 scheduled recap route helper
- Add Client4 scheduled recap API methods

SUMMARY: .planning/phases/04-scheduled-tab/04-01-SUMMARY.md

* feat(04-02): add scheduled recap action types

- GET_SCHEDULED_RECAPS_REQUEST/SUCCESS/FAILURE
- RECEIVED_SCHEDULED_RECAP and RECEIVED_SCHEDULED_RECAPS
- PAUSE_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE
- RESUME_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE
- DELETE_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE

* feat(04-02): add scheduled recap Redux actions

- getScheduledRecaps: fetches paginated scheduled recaps
- pauseScheduledRecap: pauses a scheduled recap
- resumeScheduledRecap: resumes a paused scheduled recap
- deleteScheduledRecap: deletes a scheduled recap

* feat(04-02): add scheduled recaps to reducer

- Add scheduledRecaps to RecapsState type
- Handle RECEIVED_SCHEDULED_RECAP for single recap
- Handle RECEIVED_SCHEDULED_RECAPS for bulk updates
- Handle DELETE_SCHEDULED_RECAP_SUCCESS for removal

* feat(04-02): add scheduled recap selectors

- getScheduledRecapsState: base selector for raw state
- getAllScheduledRecaps: returns all scheduled recaps as array
- getActiveScheduledRecaps: filters enabled, non-deleted recaps
- getPausedScheduledRecaps: filters disabled, non-deleted recaps
- getScheduledRecapById: returns single recap by ID

* feat(04-02): update GlobalState type for scheduled recaps

- Import ScheduledRecap type from recaps
- Add scheduledRecaps field to recaps entity state

* docs(04-02): complete Redux store and actions plan

Tasks completed: 5/5
- Add scheduled recap action types
- Add scheduled recap Redux actions
- Add scheduled recaps to reducer
- Add scheduled recap selectors
- Update GlobalState type for scheduled recaps

SUMMARY: .planning/phases/04-scheduled-tab/04-02-SUMMARY.md

* feat(04-03): add i18n strings for scheduled recap UI

- Add scheduled tab label
- Add active/paused toggle states
- Add run stats strings (last run, run count, never run, next run)
- Add toast messages for pause/resume/delete
- Add kebab menu labels (edit, delete)
- Add delete confirmation modal strings
- Add empty state strings (title, description, cta)
- Add day formatting strings (weekdays, weekend, everyday, individual days)
- Add schedule format string

* feat(04-03): create useScheduleDisplay hook for schedule formatting

- Add bitmask constants matching Go model (Sun=1, Mon=2, etc.)
- formatDaysOfWeek: smart groupings (Every day, Weekdays, Weekends) or comma-separated
- formatTimeOfDay: locale-appropriate 12/24hr time from HH:MM
- formatSchedule: combines days and time with i18n format string
- formatNextRun: smart relative formatting (Today, Tomorrow, Day name, Date)
- formatLastRun: formatted date or 'Never run'
- formatRunCount: pluralized run count

* feat(04-03): create ScheduledRecapItem component

- Render card with title and schedule pattern subtitle
- Show next run time when schedule is active
- Toggle between Active/Paused states with pause/resume actions
- Run stats (last run, run count) appear on hover
- Kebab menu with Edit and Delete options
- Delete confirmation modal with FormattedMessage
- Use useScheduleDisplay hook for all formatting

* feat(04-03): add ScheduledRecapItem styles

- Card with border, radius, and hover state
- Flexbox layout with title/subtitle and actions
- Title with truncation (ellipsis) for long names
- Subtitle with metadata separator styling
- Run stats with opacity transition on hover
- Toggle button min-width for consistent sizing
- Kebab menu button hover state

* docs(04-03): complete ScheduledRecapItem component plan

Tasks completed: 4/4
- Add i18n strings for scheduled recap UI
- Create useScheduleDisplay hook for schedule formatting
- Create ScheduledRecapItem component
- Add ScheduledRecapItem styles

SUMMARY: .planning/phases/04-scheduled-tab/04-03-SUMMARY.md

* feat(04-04): create ScheduledRecapsEmptyState component

- Empty state displays when no scheduled recaps exist
- Shows illustration with icons, title, description
- CTA button to create first recap
- Supports disabled state when agents bridge is disabled

* feat(04-04): create ScheduledRecapsList component

- Renders empty state when no scheduled recaps exist
- Maps over scheduled recaps to render ScheduledRecapItem
- Passes edit and create handlers through to children

* feat(04-04): add Scheduled tab to main Recaps component

- Add Scheduled tab after Unread and Read tabs
- Fetch scheduled recaps on mount with getScheduledRecaps
- Display ScheduledRecapsList when on scheduled tab
- Wire up edit handler (opens create modal - Phase 5 adds pre-fill)
- Import scheduled_recap_item.scss for styling

* style(04-04): add SCSS styles for scheduled recaps

- Add .scheduled-recaps-list styles (flex column, centered, gap)
- Add .scheduled-recaps-empty-state styles (centered, illustration, text)
- Consistent with existing recap UI styling patterns

* docs(04-04): complete Scheduled tab integration plan

* docs(04): update STATE.md for phase 4 completion

* docs(04): complete Scheduled Tab phase

Phase 4: Scheduled Tab
- 4 plans executed across 4 waves
- 15/15 requirements verified
- Human verified UI works correctly

* docs(05): capture phase context

Phase 05: Enhanced Wizard
- Implementation decisions documented
- Phase boundary established

* docs(05): add research hints for component discovery

* docs(05): research phase domain for enhanced wizard

Phase 05: Enhanced Wizard - Frontend Implementation
- Standard stack identified (existing codebase components)
- Architecture patterns documented (multi-step modal, bitmask days)
- Pitfalls catalogued (timezone, validation, edit mode)
- Code examples from codebase referenced

* docs(05): create phase plan for enhanced wizard

Phase 05: Frontend - Enhanced Wizard
- 6 plans in 3 waves
- Wave 1: Redux actions, DayOfWeekSelector
- Wave 2: ScheduleConfiguration, Run once toggle
- Wave 3: Modal integration, Edit wiring
- Ready for execution

* feat(05-01): add action type constants for create/update scheduled recap

- CREATE_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE
- UPDATE_SCHEDULED_RECAP_REQUEST/SUCCESS/FAILURE

* feat(05-02): create DayOfWeekSelector component

- Bitmask-based day selection matching server model
- Monday-first ordering for work schedule intuition
- XOR toggle for clean state management
- aria-pressed accessibility support

* feat(05-01): add createScheduledRecap async action

- Takes ScheduledRecapInput parameter
- Calls Client4.createScheduledRecap
- Dispatches RECEIVED_SCHEDULED_RECAP on success
- Follows existing pauseScheduledRecap pattern

* feat(05-02): add DayOfWeekSelector styles

- Flexbox layout with 8px gap between buttons
- 40x40px day buttons with hover states
- Selected state uses button-bg color
- Error and disabled state styling

* feat(05-01): add updateScheduledRecap async action

- Takes id and ScheduledRecapInput parameters
- Calls Client4.updateScheduledRecap
- Dispatches RECEIVED_SCHEDULED_RECAP on success
- Follows existing action patterns

* docs(05-02): complete DayOfWeekSelector plan

Tasks completed: 2/2
- DayOfWeekSelector component with bitmask state
- Styled button group with toggle/hover/error states

SUMMARY: .planning/phases/05-enhanced-wizard/05-02-SUMMARY.md

* docs(05-01): complete Redux actions for scheduled recaps plan

Tasks completed: 3/3
- Add action type constants for create/update scheduled recap
- Add createScheduledRecap async action
- Add updateScheduledRecap async action

SUMMARY: .planning/phases/05-enhanced-wizard/05-01-SUMMARY.md

* feat(05-04): add run once toggle to RecapConfiguration

- Add runOnce, setRunOnce, and isEditMode props to Props type
- Import Toggle component
- Add run once toggle section at bottom of Step 1
- Toggle hidden when isEditMode is true
- Include descriptive text below toggle

* feat(05-03): create ScheduleConfiguration component for Step 3

- Add day-of-week selection using DayOfWeekSelector
- Add time picker with 30-minute intervals and locale-aware formatting
- Add time period dropdown (Previous day, Last 3 days, Last 7 days)
- Add custom instructions textarea with 500 char limit
- Add next run preview with timezone support
- Use getCurrentTimezone selector for user timezone

* feat(05-04): add run once toggle styles

- Add .run-once-group with top separator border
- Style toggle and label with proper alignment
- Add description text with left margin for alignment
- Use consistent spacing and typography

* feat(05-03): add Step 3 schedule configuration styles

- Add step-three layout with vertical flex and gap
- Add form-group styling with label and error states
- Add next-run-preview styling with background and subtle text
- Add textarea overrides for custom instructions input

* docs(05-04): complete run once toggle plan

Tasks completed: 2/2
- Add run once toggle to RecapConfiguration
- Add run once toggle styles

SUMMARY: .planning/phases/05-enhanced-wizard/05-04-SUMMARY.md

* docs(05-03): complete ScheduleConfiguration plan

Tasks completed: 2/2
- Create ScheduleConfiguration component
- Add Step 3 styles to SCSS

SUMMARY: .planning/phases/05-enhanced-wizard/05-03-SUMMARY.md

* feat(05-05): add schedule state and edit mode props to modal

- Add editScheduledRecap prop for edit mode detection
- Add schedule state (daysOfWeek, timeOfDay, timePeriod, customInstructions)
- Add runOnce state and validation state (daysError, timeError)
- Add useEffect to pre-fill form in edit mode
- Import createScheduledRecap, updateScheduledRecap actions
- Import ScheduleConfiguration component and getCurrentTimezone selector

* feat(05-06): update handleEditScheduledRecap to pass scheduled recap to modal

- Find scheduled recap by ID from scheduledRecaps array
- Pass editScheduledRecap via dialogProps to CreateRecapModal
- Early return if scheduled recap not found

* feat(05-05): update step navigation for run once and schedule flows

- Update handleNext to clear validation errors on navigation
- Update handlePrevious to clear validation errors on navigation
- Update getTotalSteps for run once (2-3 steps) vs scheduled (always 3)
- Update getActualStep for proper step indicator mapping

* feat(05-05): update renderStep for schedule vs run once flows

- Pass runOnce, setRunOnce, and isEditMode props to RecapConfiguration
- Show ChannelSummary for run once mode at step 3
- Show ScheduleConfiguration for scheduled mode at step 3
- Pass all schedule state props to ScheduleConfiguration component

* feat(05-05): update handleSubmit for immediate and scheduled recaps

- Add schedule field validation for non-run-once mode
- Dispatch createRecap for run once mode (existing behavior)
- Dispatch updateScheduledRecap for edit mode
- Dispatch createScheduledRecap for new scheduled recaps
- Navigate to ?tab=scheduled after creating/editing scheduled recap
- Add proper error messages for schedule validation failures

* feat(05-05): update modal header and button text for edit mode

- Update canProceed to validate schedule fields in step 3
- Add getConfirmButtonText helper for context-aware button text
- Show 'Start recap' for run once, 'Save changes' for edit mode
- Show 'Create schedule' for new scheduled recaps
- Update headerText to show 'Edit your recap' in edit mode

* docs(05-05): complete wizard integration plan

Tasks completed: 5/5
- Add schedule state and edit mode props
- Update step navigation for run once and schedule flows
- Update renderStep for schedule vs run once flows
- Update handleSubmit for immediate and scheduled recaps
- Update modal header and button text for edit mode

SUMMARY: .planning/phases/05-enhanced-wizard/05-05-SUMMARY.md

* fix(05-06): JSON.stringify body in scheduled recap API calls

createScheduledRecap and updateScheduledRecap were passing objects
directly to doFetch body, causing '[object Object]' to be sent instead
of JSON. Fixed to match createRecap pattern.

* fix(05-06): align time period values with server model

Frontend was using 'last_3_days' and 'last_7_days' but server expects
'last_24h', 'last_week', and 'since_last_read'. Updated options to match.

* fix(05-06): remove duplicate border on custom instructions textarea

- GenericModal adds a border to all .form-control elements
- Input widget's Input_fieldset already provides a border container
- This caused a double-border visual glitch on the textarea
- Added border: none to the inner textarea to fix the issue

* fix(05-06): reserve space for next run preview to prevent modal height jump

- Always render next-run-preview container (previously conditionally rendered)
- Use visibility:hidden instead of not rendering when no preview available
- Add non-breaking space placeholder to maintain consistent element height
- Prevents jarring visual jump when user selects a day of the week

* fix(05-06): remove border/background from next-run-preview

- Remove padding, border-radius, and background-color from .next-run-preview
- Style as plain text with subtle color and smaller font size
- Keep margin for appropriate spacing from time selector

* fix(05-06): use abbreviated timezone in next recap preview

- Use Intl.DateTimeFormat with timeZoneName: 'short' to get timezone
  abbreviation (e.g., EST, PST, EDT) instead of full label
- Remove unused getCurrentTimezoneLabel selector import
- Preview now shows 'Monday at 9:00 AM (EST)' instead of
  'Monday at 9:00 AM ((UTC-05:00) Eastern Time (US & Canada))'

* fix(05-06): prevent modal height jump when next run preview appears

- Move next-run-preview inside time-selection-group as helper text
- Add min-height: 16px to reserve space when preview is hidden
- Use visibility: hidden instead of display: none for consistent height
- Reduce step-three gap from 20px to 16px for better spacing
- Add margin-bottom: 0 to form-group to override default spacing

* fix(05-06): add section titles and fix spacing in schedule configuration

- Add section titles per Figma design (Heading 100 style):
  - 'When would you like your summary sent?' as main header
  - 'On which days should your recap run?' for days section
  - 'At what time?' for time section
  - 'Select a time period for your recap to cover' for time period
  - 'Additional instructions for {agentName}' for custom instructions
- Pass agentName prop from parent to show selected agent name
- Fix spacing: reserve space for next-run preview with container
  to prevent time period section from jumping when preview appears
- Update SCSS with schedule-section groups and proper spacing

* fix(05-06): remove duplicate title and fix subtitle-dropdown spacing

- Remove 'When would you like your summary sent?' duplicate title
- Add scoped CSS rule for 12px total spacing between subtitle and dropdown

* fix(05-06): use standard Toggle without text labels for active/paused state

- Remove onText/offText props from Toggle component
- Add ariaLabel for accessibility (describes toggle state and action)
- Update SCSS to remove min-width constraint that was for text display
- Navigation to scheduled tab after creating scheduled recap already works correctly

* fix(05-06): toggle color and tab navigation after creating scheduled recap

- Use btn-toggle-primary class for scheduled recap toggle to display proper button-bg color
- Add useQuery hook to read tab query parameter from URL
- Sync activeTab state with URL tab parameter to enable navigation after modal close

* fix(05-06): sync tab state with URL bidirectionally

- Add handleTabChange callback that updates both state and URL
- Use history.replace() to update URL without polluting browser history
- Remove tab param from URL when switching to 'unread' (default tab)
- Simplify URL sync useEffect to always update from tabParam
- This enables proper navigation after creating scheduled recaps

* fix(05-06): fix navigation to scheduled tab after creating scheduled recap

- Replace useRouteMatch() with getCurrentRelativeTeamUrl selector
- Modal was using route match which returned wrong URL context (modal is rendered at root level)
- Use team selector to get correct team URL for navigation
- Update test to remove unnecessary useRouteMatch mock

* fix(05-06): sort scheduled recaps by newest first

- Update getAllScheduledRecaps selector to sort by create_at descending
- Follows same pattern as other recap selectors (getUnreadRecaps, getReadRecaps)
- Derived selectors (getActiveScheduledRecaps, getPausedScheduledRecaps) inherit sort order

* docs(05-06): complete edit wiring and UI polish plan

* docs(phase-05): complete Enhanced Wizard phase

Phase 5: Enhanced Wizard
- 6 plans executed across 3 waves
- 13 requirements verified
- Multi-step wizard for creating/editing scheduled recaps
- Run once and scheduled flows
- Full edit mode with pre-fill
- Extensive UI polish based on human feedback

All 39 requirements complete. Milestone ready for audit.

* docs(v1): milestone audit complete - all requirements satisfied

- 39/39 requirements verified
- 5/5 phases passed
- 100% cross-phase integration
- 5/5 E2E flows complete
- 2 minor tech debt items (non-blocking)

* chore: remove .planning from git tracking

- Add .planning to .gitignore
- Remove .planning files from git index (kept locally)
- Planning files are for local development only

* feat(06-01): add AIRecapSettings and RecapLimitSettings structs

- RecapLimitSettings with 7 limit fields (recaps/day, scheduled, channels, posts, tokens, posts/day, cooldown)
- AIRecapSettings with master toggle and per-limit enforcement toggles
- SetDefaults methods with sensible defaults (10 recaps/day, 5 scheduled, etc.)
- isValid/IsValid validation methods enforcing natural minimums

* feat(06-01): integrate AIRecapSettings into Config struct

- Add AIRecapSettings field to Config struct
- Call AIRecapSettings.SetDefaults() in Config.SetDefaults()
- Call AIRecapSettings.IsValid() in Config.IsValid()

* test(06-01): add tests for AIRecapSettings and RecapLimitSettings

- TestAIRecapSettingsSetDefaults: verifies all defaults match spec
- TestRecapLimitSettingsValidation: verifies validation rejects invalid values
- TestAIRecapSettingsPreservesExistingValues: verifies SetDefaults preserves existing
- TestAIRecapSettingsIsValid: verifies IsValid delegates to DefaultLimits

* feat(06-02): create EffectiveRecapLimits struct

- Add EffectiveRecapLimits struct with 7 resolved limit fields
- Add LimitSource type with system/group/user constants
- Add UnlimitedValue constant (-1) for disabled limits
- Add IsLimitEnabled helper function for enforcement code

* feat(06-02): create GetEffectiveLimits resolution function

- Add GetEffectiveLimits(userID) returning resolved limits for any user
- Resolve limits from AIRecapSettings.DefaultLimits config
- Apply per-limit enforcement toggles (disabled = -1 unlimited)
- Add helper functions getValueOrDefault and getBoolOrDefault
- Structure for Phase 8 group/user resolution with TODOs

* test(06-02): add tests for GetEffectiveLimits function

- TestGetEffectiveLimitsDefaults verifies system defaults returned
- TestGetEffectiveLimitsWithDisabledToggle verifies -1 returned for disabled limits
- TestGetEffectiveLimitsWithCustomDefaults verifies custom config honored
- TestGetEffectiveLimitsAllTogglesDisabled verifies all -1 when all disabled
- TestGetEffectiveLimitsUnlimitedConfigValue verifies -1 config value honored
- TestIsLimitEnabled verifies helper correctly identifies enabled limits

* feat(07-01): add RecapStatusSkipped constant and SkipReason field

- Add RecapStatusSkipped constant for recaps skipped due to limit violations
- Add SkipReasonDailyLimit and SkipReasonCooldown skip reason constants
- Add ScheduledRecapId field to Recap struct for tracking scheduled recaps
- Add SkipReason field to Recap struct for tracking why recap was skipped
- Update Auditable() method to include new fields
- Update recapColumns and recapToMap to include new fields

* feat(07-01): add store interface methods for limit enforcement

- Add CountForUserSince to RecapStore for daily limit enforcement
- Add GetLastCompletedManualRecap to RecapStore for cooldown checking
- Add CountForUser to ScheduledRecapStore for max scheduled recaps limit
- Update mock implementations for both stores

* feat(07-01): implement store methods in SQL stores

- Implement CountForUser in SqlScheduledRecapStore
  - Counts active (non-deleted, enabled) scheduled recaps for a user
- Implement CountForUserSince in SqlRecapStore
  - Counts recaps since timestamp, excluding skipped recaps
- Implement GetLastCompletedManualRecap in SqlRecapStore
  - Returns most recent completed manual recap (no ScheduledRecapId)
  - Returns nil, nil when no manual recap exists

* feat(07-03): add daily limit check to scheduled recap worker

- Add GetEffectiveLimits and GetUser to AppIface for limit checking
- Check MaxRecapsPerDay before executing scheduled recap
- Create skipped recap record when daily limit exceeded
- Use user's timezone for midnight calculation
- Update next run time even when skipping (scheduler moves on)

* feat(07-03): add cooldown check to manual recap creation

- Check CooldownMinutes before allowing manual recap creation
- Return HTTP 429 with retry-after info when cooldown active
- Only checks against completed manual recaps (per CONTEXT.md)
- Failed recaps don't consume cooldown (checks completed only)

* feat(07-03): add i18n messages for cooldown errors

- Add cooldown_active error with retry info template
- Add cooldown_check_failed error message
- Uses "Your organization's policy limits..." pattern

* feat(07-02): add limit checks to CreateScheduledRecap

- Add max scheduled recaps limit check using CountForUser store method
- Add max channels per recap limit check against ChannelIds length
- Return HTTP 400 with clear error messages when limits exceeded
- Uses GetEffectiveLimits for limit resolution (ENF-01, ENF-02, ENF-08)

* feat(07-02): add i18n error messages for scheduled recap limits

- Add max_scheduled_reached message with "Your organization's policy limits..." pattern
- Add max_channels_exceeded message with limit and requested count
- Add count_failed internal error message

* test(07-04): add unit tests for post/token truncation

- Test proportional post distribution across channels
- Test minimum 1 post per channel guarantee
- Test empty channel handling
- Test token estimation (4 chars/token heuristic)
- Test token limit truncation removes from largest channels

Verifies ENF-05, ENF-06 truncation implementation.

* test(07-05): add ENF-07 permission preservation tests

- Add tests verifying over-limit users can view/edit/delete existing recaps
- Tests confirm management operations do NOT check limits (grandfathering)
- Tests confirm creation IS still blocked when over limit
- Add migration 000151 for missing ScheduledRecapId/SkipReason columns

ENF-07: Limits only block creation, not management of existing resources

* feat(08-01): create UnlimitedNumberSetting component

- Number input with Unlimited checkbox for admin console settings
- When checked: disables input and sets value to -1 (unlimited)
- When unchecked: enables input and sets value to defaultValue
- Supports disabled state and setByEnv footer

* test(08-01): add unit tests for UnlimitedNumberSetting

- Tests rendering with numeric and unlimited values
- Tests checkbox toggle behavior (check/uncheck)
- Tests number input changes
- Tests disabled state and setByEnv footer
- Tests custom unlimited label and placeholder
- 11 test cases covering core functionality

* feat(08-02): add Recaps subsection to admin_definition.tsx

- Import UnlimitedNumberSetting component
- Add 'recaps' subsection under site configuration section
- Include master enable toggle for AI Recap Limits
- Add 3 grouped sections: Quota Limits, Content Limits, Time Limits
- Configure all 7 limit settings with proper config keys
- Add AIRecapSettings and RecapLimitSettings TypeScript types
- All settings disabled when master toggle is off

* feat(08-02): add i18n strings for Recaps admin section

- Add admin.sidebar.recaps for navigation
- Add admin.site.recaps for section title
- Add admin.recaps.enable.* for master toggle
- Add admin.recaps.sections.* for section descriptions
- Add admin.recaps.max*.* for all limit field labels/descriptions
- Add admin.recaps.cooldownMinutes.* for time limit settings
- Add admin.recaps.unlimited for checkbox label
- Total: 24 new i18n strings

* style(08-02): remove section comments to fix lint errors

Remove inline comments that triggered lines-around-comment lint rule

* feat(09-01): add RecapLimitStatus model and App layer logic

- Add RecapLimitStatus, DailyUsageStatus, CooldownStatus structs
- Implement App.GetRecapLimitStatus with daily usage count and cooldown calculation

* feat(09-01): add GET /api/v4/recaps/limit_status endpoint

- Register route and handler
- Return structured limit status
- Add error translation

* feat(09-01): add TypeScript types for limit status

- Export RecapLimitStatus and related types

* feat(09-02): add recap limit status redux integration

- Add Client4.getRecapLimitStatus method
- Add Redux action, reducer, and selector for limit status
- Update GlobalState and initial state to include limitStatus

* fix(09-02): update CreateRecapModal error handling and tests

- Check dispatch result.error instead of try/catch to handle server errors
- Display server error message (e.g. policy limits) inline
- Fix TypeScript errors: displayName property and missing props in tests

* feat(09-03): implement user-facing limit status UI

* Verify Phase 9: User-Facing UX

* Remove UAT artifact

* fix: UI/UX issues (badge, toggle, input, tooltip)

* fix: Increase RecapUsageBadge tooltip z-index

* blank lines

* [MM-67163] checkpoint: scheduled recaps feature working

All phases (01-09) complete and verified:
- Database foundation with DST-aware scheduling
- API layer for CRUD operations
- Job scheduler and worker
- Scheduled tab UI with list/create/edit/delete
- Enhanced wizard with schedule configuration
- Config settings and admin console section
- Limit enforcement (daily, cooldown, token, post)
- User-facing limit status badge

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* [MM-67163] simplify: reduce duplication and fix issues across scheduled recaps

- Extract requireScheduledRecapOwnership helper for 5 API handlers
- Consolidate ResumeScheduledRecap from 4 store calls to 2
- Remove redundant Get() in PauseScheduledRecap
- Extract advanceSchedule helper in worker to deduplicate skip/success paths
- Remove double PreSave() in store Save method
- Remove dead code fallback in GetEffectiveLimits
- Deduplicate ScheduledRecapInput construction in create modal
- Fix missing fetchRecapLimitStatus import (TS error)
- Extract day-of-week bitmask constants to @mattermost/types/recaps
- Fix hardcoded English strings in schedule_display formatNextRun

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Address CodeRabbit review feedback on scheduled recaps

Server fixes:
- Gate getRecapLimitStatus with requireRecapsEnabled guard
- Normalize error mapping (404 vs 500) in scheduled recap handlers
- Enforce MaxChannelsPerRecap limit in UpdateScheduledRecap
- Return explicit error for unsupported all_unreads mode in scheduled recaps
- Add compensation logic to clean up orphan recaps on job creation failure
- Fix proportional post truncation to strictly enforce maxPosts cap
- Add missing CountForUser retry wrapper in RetryLayerScheduledRecapStore
- Handle NULL ScheduledRecapId in manual recap cooldown lookup
- Exclude soft-deleted rows in scheduled recap Get query

Frontend fixes:
- Pass isCreationBlocked to ScheduledRecapsList empty state
- Fix same-day nextRunAt mislabeled as "Tomorrow" in schedule display
- Handle thunk error results in scheduled recap item actions
- Replace scheduled recaps map on full refresh instead of merging

Made-with: Cursor

* Handle thunk error results in scheduled recap toggle handler

Check dispatch result for errors in handleToggle to prevent
false-success UI flows when pause/resume operations fail.

Made-with: Cursor

* Fix CI failures: mock store, permissions, migrations, lint, and Playwright config

- Add ScheduledRecap() to storetest.Store mock and retrylayer test setup
- Register sysconsole_read_ai_recaps / sysconsole_write_ai_recaps permissions
- Renumber scheduled_recaps migration from 150→156 and recap_skip_fields from 151→157 to resolve version conflicts
- Fix ESLint errors in recap components (operator-linebreak, import order, labels, headers, etc.)
- Add AIRecapSettings to Playwright default_config.ts

Made-with: Cursor

* Address CodeRabbit Round 2 review feedback

- Add OpenAPI spec for GET /api/v4/recaps/limit_status with schema
  definitions for RecapLimitStatus, EffectiveRecapLimits,
  DailyUsageStatus, and CooldownStatus
- Set ScheduledRecapId when creating recaps from schedules to prevent
  cooldown logic from treating scheduled recaps as manual
- Handle past nextRunAt timestamps in schedule display: show "Yesterday"
  for -1 day and full date for older past dates

Made-with: Cursor

* Add missing variable declarations for AI recaps permissions

Made-with: Cursor

* Fix jsx-max-props-per-line lint errors in schedule_configuration.tsx

Made-with: Cursor

* Fix stylelint property order in recap SCSS files

Made-with: Cursor

* Update admin sidebar snapshots to include Recaps section

Made-with: Cursor

* Fix Go lint issues and add OpenAPI specs for scheduled_recap endpoints

- Use max/min builtins instead of if-statements (modernize/minmax)
- Use range-over-int syntax for for-loops (modernize/rangeint)
- Fix tautological Monday&Monday test (staticcheck/SA4000)
- Add OpenAPI specs for all 7 scheduled_recap API routes
- Add ScheduledRecap model definition to definitions.yaml

Made-with: Cursor

* Regenerate i18n en.json for recap-related strings

Made-with: Cursor

* Fix gofmt indentation in recap.go

Made-with: Cursor

* Fix scheduled recap CI regressions

Align the scheduled recap soft-delete store test with the current Get behavior and add the missing scheduled recap i18n strings so server and enterprise checks stay in sync.

Made-with: Cursor

* Address CodeRabbit review feedback on scheduled recaps

- Use session user ID instead of client-controlled recap.UserId for
  limit enforcement in UpdateScheduledRecap (security hardening)
- Add missing i18n entry for app.recap.fetch_posts.app_error
- All other review comments were already addressed in prior commits

Made-with: Cursor

* Fix schedule configuration import order

Reorder the moment import so the webapp lint job passes again on the scheduled recap PR.

Made-with: Cursor

* Allow selecting "all unreads" recap type when no current unreads exist

With scheduled recaps, users should be able to select "all unreads" even
without current unread channels since unreads will exist when the schedule
runs. The "run once" toggle is now disabled when all unreads is selected
with no current unreads, preserving the pre-scheduling behavior of
preventing an immediate recap with nothing to summarize.

Made-with: Cursor

* Fix indentation in recap_configuration.tsx to satisfy eslint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix Recaps test mocks for scheduled recap state.

Keep the webapp test shard green by mirroring the new selectors and mount-time actions used by the Recaps page.

Made-with: Cursor

* Update server/channels/app/recap.go

* Update server/channels/app/recap.go

* Update server/channels/app/recap_limits.go

* Update server/channels/app/recap_limits.go

* Update server/channels/app/scheduled_recap.go

* Update server/channels/app/scheduled_recap.go

* Update webapp/channels/src/components/recaps/scheduled_recaps_empty_state.tsx

* Update server/channels/app/scheduled_recap.go

* Fix gofmt formatting in recap limits

Made-with: Cursor

* Fix recap limits for soft-deleted recaps

Keep deleted recaps in quota and cooldown checks so soft deletion cannot bypass AI usage enforcement.

Made-with: Cursor

* Fix translation

* Fix server check-style: concurrent indexes and lint cleanups

- Use CREATE/DROP INDEX CONCURRENTLY in 000168 scheduled recaps migrations
  (required by mattermost-govet concurrentIndex check).
- gofmt validation constants in scheduled_recap.go.
- Replace string += loops in recap tests with strings.Repeat for modernize linter.

Made-with: Cursor

* Fix 000168 migration: run CONCURRENTLY indexes outside transaction

PostgreSQL rejects CREATE/DROP INDEX CONCURRENTLY inside a transaction.
Morph requires -- morph:nontransactional for these migrations, matching
other index migrations in the repo.

Made-with: Cursor

* Stabilize scheduled Recaps for review

Bring the scheduled Recaps work back into a shippable state by tightening backend scheduling and limit semantics, cleaning up the UI flows, and adding focused Recaps E2E coverage.

Made-with: Cursor

* Fix scheduled recaps lint failures

Made-with: Cursor

* Fix scheduled recap Go lint

Made-with: Cursor

* Fix scheduled recaps Playwright check

Made-with: Cursor

* Sync scheduled recaps i18n catalog

Made-with: Cursor

* Fix server recaps CI checks

Made-with: Cursor

* Stabilize recap server CI setup

Made-with: Cursor

* Recaps: enforce token limit, remove dead truncation code, simplify scheduled worker

- Delete unused multi-channel truncation subsystem (FetchAndTruncatePostsForRecap, truncatePostsProportionally)
- Enforce MaxTokensPerRecap in the live recap path (previously a silent no-op)
- Drop redundant non-atomic daily-limit pre-check in the scheduled worker; rely on the atomic check in CreateRecapFromSchedule
- Disable non-recurring schedules on all terminal paths (including daily-limit skips) via finalizeSchedule
- Trim scheduled-recap job payload to scheduled_recap_id
- Exclude skipped recaps from GetRecapsForUser

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps webapp: format schedule times in the schedule timezone, static day i18n, typed schedule fields

- Display next-run and schedule times using the scheduled recap's timezone (shared schedule_time_format helper) instead of browser-local time
- Replace dynamic day-of-week i18n message IDs with static descriptors so strings are extractable/translatable
- Add ScheduledRecapTimePeriod/ScheduledRecapChannelMode union types
- Use shared Button in the scheduled recaps empty state

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps e2e: cover scheduled edit/delete/all-unreads/empty-state and token-limit enforcement

- Add UI coverage for editing, deleting, and the empty state of scheduled recaps
- Add all-unreads scheduled recap modal flow
- Add immediate-recap token-limit enforcement tests (single and per-channel), validating MaxTokensPerRecap truncation end-to-end
- Extend recaps page object and helpers

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: regenerate store layers/mocks and i18n after cleanup; fix lint

- Regenerate timerlayer/retrylayer/RecapStore mock to canonical order
- Drop orphaned app.recap.fetch_posts.app_error i18n key (removed with dead fetch helper)
- Add missing semicolon in UnlimitedNumberSetting props

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: regenerate default roles permissions and admin sidebar snapshot

- Regenerate Cypress default_roles_permissions fixture to include AI Recaps sysconsole permissions
- Update admin sidebar snapshot for the new Recaps section

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: stabilize flaky cooldown round-up test

The cooldown round-up subtest placed the prior recap 30s before a 2-minute
cooldown, leaving only ~30s of slack before the rounded remaining time would
flip from 2 to 1 minute. Under heavily loaded CI this could intermittently fail
the exact-minute assertion. Move the prior recap to 1s ago so the remaining time
sits near the top of the 2-minute band (~59s slack) while still exercising
ceiling rounding.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: store ScheduledRecap.ChannelIds as jsonb

Postgres is the only supported database, so the prior TEXT+JSON-string
workaround for MySQL compatibility is unnecessary. Store ChannelIds in a
jsonb column and type the model field as model.StringArray, which removes the
bespoke marshal/unmarshal and intermediate scan struct in the store.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: gate recap limit settings on the ai_recaps permission

Add access:"ai_recaps" to DefaultLimits and all RecapLimitSettings fields so a
delegated admin with sysconsole_write_ai_recaps can save the limit values,
instead of falling back to requiring manage_system.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: drop bespoke Users row lock for limit enforcement

The recap limit savers were the only SELECT ... FOR UPDATE in the sqlstore.
Conform to the prevailing pattern (e.g. channel_bookmark_store.Save): enforce
MaxScheduledRecaps / MaxRecapsPerDay with a transactional count + insert and no
row lock, accepting the same best-effort behavior under concurrency as channels,
team members, and bookmarks.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: document SaveOnceByTypeAndData dedup semantics

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: use SERIALIZABLE isolation for limit-check inserts

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: mark orphaned recap skipped when job enqueue fails

When CreateJob fails after the recap row is committed, flag the recap
skipped with reason job_creation_failed instead of leaving it pending.
Skipped recaps are excluded from the daily-limit count, so this frees
the quota slot for a recap that will never run, and keeps CreateRecap
consistent with CreateRecapFromSchedule.

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ci: retrigger CI (flaky enterprise npm cache EEXIST)

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ci: retrigger CI (flaky Vet API container init)

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* Recaps: re-check channel read permission at recap execution time

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* fix scheduled recap job server test setup

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ci: retry flaky webapp test

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* ci: retry documentation impact review

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM-67163: Address review feedback: remove unused userID param, return AppError from GetRecapLimitStatus

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* MM-67163: Bulk channel permission check for recap creation, bounded by channel limit

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* chore: rerun CI

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

* chore: rerun CI after network failure

Co-authored-by: nick.misasi <nick.misasi@mattermost.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-07-21 13:10:25 -04:00

5593 lines
171 KiB
YAML

components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
responses:
Forbidden:
description: Do not have appropriate permissions
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
Unauthorized:
description: No access token provided
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
BadRequest:
description: Invalid or missing parameters in URL or request body
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
Conflict:
description: Request conflicts with current state of the resource
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
TooLarge:
description: Content too large
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
NotImplemented:
description: Feature is disabled
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
TooManyRequests:
description: Too many requests
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
InternalServerError:
description: Something went wrong with the server
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
BadGateway:
description: Bad gateway
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
schemas:
User:
type: object
properties:
id:
type: string
create_at:
description: The time in milliseconds a user was created
type: integer
format: int64
update_at:
description: The time in milliseconds a user was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a user was deleted
type: integer
format: int64
username:
type: string
first_name:
type: string
last_name:
type: string
nickname:
type: string
email:
type: string
email_verified:
type: boolean
auth_service:
type: string
roles:
type: string
locale:
type: string
notify_props:
$ref: "#/components/schemas/UserNotifyProps"
props:
type: object
last_password_update:
type: integer
format: int64
last_picture_update:
type: integer
format: int64
failed_attempts:
type: integer
mfa_active:
type: boolean
timezone:
$ref: "#/components/schemas/Timezone"
terms_of_service_id:
description: ID of accepted terms of service, if any. This field is not present
if empty.
type: string
terms_of_service_create_at:
description: The time in milliseconds the user accepted the terms of service
type: integer
format: int64
UsersStats:
type: object
properties:
total_users_count:
type: integer
KnownUsers:
type: array
properties:
items:
type: string
Team:
type: object
properties:
id:
type: string
create_at:
description: The time in milliseconds a team was created
type: integer
format: int64
update_at:
description: The time in milliseconds a team was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a team was deleted
type: integer
format: int64
display_name:
type: string
name:
type: string
description:
type: string
email:
type: string
type:
type: string
allowed_domains:
type: string
invite_id:
type: string
allow_open_invite:
type: boolean
policy_id:
type: string
description: >-
The data retention policy to which this team has been assigned. If no such policy exists,
or the caller does not have the `sysconsole_read_compliance_data_retention` permission,
this field will be null.
TeamStats:
type: object
properties:
team_id:
type: string
total_member_count:
type: integer
TeamExists:
type: object
properties:
exists:
type: boolean
Channel:
type: object
properties:
id:
type: string
create_at:
description: The time in milliseconds a channel was created
type: integer
format: int64
update_at:
description: The time in milliseconds a channel was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a channel was deleted
type: integer
format: int64
team_id:
type: string
type:
type: string
display_name:
type: string
name:
type: string
header:
type: string
purpose:
type: string
last_post_at:
description: The time in milliseconds of the last post of a channel
type: integer
format: int64
total_msg_count:
type: integer
extra_update_at:
description: Deprecated in Mattermost 5.0 release
type: integer
format: int64
creator_id:
type: string
ChannelStats:
type: object
properties:
channel_id:
type: string
member_count:
type: integer
ChannelMember:
type: object
properties:
channel_id:
type: string
user_id:
type: string
roles:
type: string
last_viewed_at:
description: The time in milliseconds the channel was last viewed by the user
type: integer
format: int64
msg_count:
type: integer
mention_count:
type: integer
notify_props:
$ref: "#/components/schemas/ChannelNotifyProps"
last_update_at:
description: The time in milliseconds the channel member was last updated
type: integer
format: int64
ChannelMemberWithTeamData:
allOf:
- $ref: "#/components/schemas/ChannelMember"
- type: object
properties:
team_display_name:
type: string
description: The display name of the team to which this channel belongs.
team_name:
type: string
description: The name of the team to which this channel belongs.
team_update_at:
type: integer
description: The time at which the team to which this channel belongs was last updated.
ChannelData:
type: object
properties:
channel:
$ref: "#/components/schemas/Channel"
member:
$ref: "#/components/schemas/ChannelMember"
ChannelWithTeamData:
allOf:
- $ref: "#/components/schemas/Channel"
- type: object
properties:
team_display_name:
type: string
description: The display name of the team to which this channel belongs.
team_name:
type: string
description: The name of the team to which this channel belongs.
team_update_at:
type: integer
description: The time at which the team to which this channel belongs was last updated.
policy_id:
type: string
description: >-
The data retention policy to which this team has been assigned. If no such policy exists,
or the caller does not have the `sysconsole_read_compliance_data_retention` permission, this field
will be null.
ChannelListWithTeamData:
type: array
items:
$ref: "#/components/schemas/ChannelWithTeamData"
ChannelBookmark:
type: object
properties:
id:
type: string
create_at:
description: The time in milliseconds a channel bookmark was created
type: integer
format: int64
update_at:
description: The time in milliseconds a channel bookmark was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a channel bookmark was deleted
type: integer
format: int64
channel_id:
type: string
owner_id:
description: The ID of the user that the channel bookmark belongs to
type: string
file_id:
description: The ID of the file associated with the channel bookmark
type: string
display_name:
type: string
sort_order:
description: The order of the channel bookmark
type: integer
format: int64
link_url:
description: The URL associated with the channel bookmark
type: string
image_url:
description: The URL of the image associated with the channel bookmark
type: string
emoji:
type: string
type:
type: string
enum: [link, file, board]
target_id:
type: string
description: Mattermost 26-character ID of a referenced Mattermost entity when the bookmark includes one.
original_id:
description: The ID of the original channel bookmark
type: string
parent_id:
description: The ID of the parent channel bookmark
type: string
ChannelBookmarkWithFileInfo:
allOf:
- $ref: "#/components/schemas/ChannelBookmark"
- type: object
properties:
file:
$ref: "#/components/schemas/FileInfo"
UpdateChannelBookmarkResponse:
type: object
properties:
updated:
$ref: "#/components/schemas/ChannelBookmarkWithFileInfo"
deleted:
$ref: "#/components/schemas/ChannelBookmarkWithFileInfo"
View:
type: object
properties:
id:
type: string
description: The unique identifier of the view
channel_id:
type: string
description: The ID of the channel this view belongs to
type:
type: string
enum: [kanban]
creator_id:
type: string
description: The ID of the user who created this view
title:
type: string
description: The title of the view
description:
type: string
description: The description of the view
sort_order:
type: integer
description: The display order of the view within the channel
props:
type: object
description: Arbitrary key-value properties for the view
additionalProperties: true
create_at:
description: The time in milliseconds the view was created
type: integer
format: int64
update_at:
description: The time in milliseconds the view was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds the view was deleted
type: integer
format: int64
ViewPatch:
type: object
description: Fields that can be updated on a view via PATCH
properties:
title:
type: string
description:
type: string
sort_order:
type: integer
props:
type: object
description: Arbitrary key-value properties for the view
additionalProperties: true
ViewsWithCount:
type: object
description: Paginated list of views with total count
properties:
views:
type: array
items:
$ref: "#/components/schemas/View"
total_count:
type: integer
format: int64
description: Total number of views matching the query (ignoring pagination)
Post:
type: object
properties:
id:
type: string
create_at:
description: The time in milliseconds a post was created
type: integer
format: int64
update_at:
description: The time in milliseconds a post was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a post was deleted
type: integer
format: int64
edit_at:
type: integer
format: int64
user_id:
type: string
channel_id:
type: string
root_id:
type: string
original_id:
type: string
message:
type: string
type:
type: string
props:
type: object
hashtag:
type: string
file_ids:
type: array
items:
type: string
pending_post_id:
type: string
metadata:
$ref: "#/components/schemas/PostMetadata"
PostPriority:
type: object
description: Priority metadata associated with a post or draft.
properties:
priority:
type: string
description: The priority label of a post, either empty, important, or urgent.
enum:
- ""
- important
- urgent
requested_ack:
type: boolean
description: Whether the post author has requested acknowledgements.
persistent_notifications:
type: boolean
description: Whether persistent notifications are enabled for the post.
PostInfo:
type: object
description: Additional team and channel context metadata for a post.
properties:
channel_id:
type: string
description: The ID of the channel containing the post.
channel_type:
type: string
description: The type of the channel containing the post.
channel_display_name:
type: string
description: The display name of the channel containing the post.
has_joined_channel:
type: boolean
description: Whether the requesting user is already a member of the channel.
team_id:
type: string
description: The ID of the team containing the channel, if applicable.
team_type:
type: string
description: The type of the team containing the channel, if applicable.
team_display_name:
type: string
description: The display name of the team containing the channel, if applicable.
has_joined_team:
type: boolean
description: Whether the requesting user is already a member of the team.
Draft:
type: object
properties:
create_at:
type: integer
format: int64
update_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
description: Deprecated. Drafts are hard-deleted.
user_id:
type: string
channel_id:
type: string
root_id:
type: string
message:
type: string
type:
type: string
props:
type: object
additionalProperties: true
file_ids:
type: array
items:
type: string
metadata:
$ref: "#/components/schemas/PostMetadata"
priority:
$ref: "#/components/schemas/PostPriority"
DraftUpsertRequest:
type: object
required:
- channel_id
- message
properties:
channel_id:
type: string
root_id:
type: string
message:
type: string
description: Draft message. Set to an empty string to delete the draft.
type:
type: string
props:
type: object
additionalProperties: true
file_ids:
type: array
items:
type: string
priority:
$ref: "#/components/schemas/PostPriority"
NotifyAdminToUpgradeRequest:
type: object
properties:
trial_notification:
type: boolean
required_plan:
type: string
required_feature:
type: string
PluginReattachAddress:
type: object
properties:
Name:
type: string
Net:
type: string
PluginReattachConfig:
type: object
properties:
Protocol:
type: string
ProtocolVersion:
type: integer
Addr:
$ref: "#/components/schemas/PluginReattachAddress"
Pid:
type: integer
Test:
type: boolean
PluginReattachRequest:
type: object
required:
- Manifest
- PluginReattachConfig
properties:
Manifest:
$ref: "#/components/schemas/PluginManifest"
PluginReattachConfig:
$ref: "#/components/schemas/PluginReattachConfig"
InstallMarketplacePluginRequest:
type: object
required:
- id
properties:
id:
type: string
description: The ID of the plugin to install.
version:
type: string
description: Optional plugin version. If omitted, the latest compatible version is installed.
RemoteClusterMsg:
type: object
properties:
id:
type: string
topic:
type: string
create_at:
type: integer
format: int64
payload:
description: Raw message payload.
type: object
additionalProperties: true
RemoteClusterFrame:
type: object
properties:
remote_id:
type: string
msg:
$ref: "#/components/schemas/RemoteClusterMsg"
RemoteClusterPing:
type: object
properties:
sent_at:
type: integer
format: int64
recv_at:
type: integer
format: int64
RemoteClusterResponse:
type: object
properties:
status:
type: string
err:
type: string
payload:
description: Raw response payload.
type: object
additionalProperties: true
PropertyField:
type: object
properties:
id:
type: string
group_id:
type: string
name:
type: string
type:
type: string
description: The type of property
enum: [text, select, multiselect, date, user, multiuser]
object_type:
type: string
description: The type of object this property applies to
enum: [post, channel, user, template]
attrs:
type: object
description: Additional attributes
target_id:
type: string
description: The ID of the target (empty for system-level, team ID for team-level, channel ID for channel-level)
target_type:
type: string
description: The scope level (system, team, channel)
protected:
type: boolean
description: Whether this field is protected from API modification
permission_field:
type: string
description: Permission level for editing the field definition
enum: [none, sysadmin, member]
permission_values:
type: string
description: Permission level for setting values on objects
enum: [none, sysadmin, member]
permission_options:
type: string
description: Permission level for managing options on select/multiselect fields
enum: [none, sysadmin, member]
linked_field_id:
type: string
nullable: true
description: >
The ID of the template field this field is linked to. When set, the field
inherits its type and options from the source template. Can only be set at
creation time. Null when the field is not linked.
create_at:
type: integer
format: int64
update_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
created_by:
type: string
description: User ID of the user who created this property field
updated_by:
type: string
description: User ID of the user who last updated this property field
PropertyFieldPatch:
type: object
properties:
name:
type: string
type:
type: string
attrs:
type: object
linked_field_id:
type: string
description: >
Set to empty string to unlink a linked field. Cannot be set to a new
value on an existing field; linking is only allowed at creation time.
PropertyValue:
type: object
properties:
id:
type: string
target_id:
type: string
target_type:
type: string
group_id:
type: string
field_id:
type: string
value:
type: string
create_at:
type: integer
format: int64
update_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
created_by:
type: string
description: User ID of the user who created this property value
updated_by:
type: string
description: User ID of the user who last updated this property value
FileInfoList:
type: object
properties:
order:
type: array
items:
type: string
example:
- file_info_id1
- file_info_id2
file_infos:
type: object
additionalProperties:
$ref: "#/components/schemas/FileInfo"
next_file_id:
type: string
description: The ID of next file info. Not omitted when empty or not relevant.
prev_file_id:
type: string
description: The ID of previous file info. Not omitted when empty or not relevant.
PostList:
type: object
properties:
order:
type: array
items:
type: string
example:
- post_id1
- post_id12
posts:
type: object
additionalProperties:
$ref: "#/components/schemas/Post"
next_post_id:
type: string
description: The ID of next post. Not omitted when empty or not relevant.
prev_post_id:
type: string
description: The ID of previous post. Not omitted when empty or not relevant.
has_next:
type: boolean
description: Whether there are more items after this page.
PostListWithSearchMatches:
type: object
properties:
order:
type: array
items:
type: string
example:
- post_id1
- post_id12
posts:
type: object
additionalProperties:
$ref: "#/components/schemas/Post"
matches:
description: A mapping of post IDs to a list of matched terms within the post.
This field will only be populated on servers running version 5.1 or
greater with Elasticsearch enabled.
type: object
additionalProperties:
type: array
items:
type: string
example:
post_id1:
- search match 1
- search match 2
PostMetadata:
type: object
description: Additional information used to display a post.
properties:
embeds:
type: array
description: >
Information about content embedded in the post including OpenGraph
previews, image link previews, and message attachments.
This field will be null if the post does not contain embedded content.
items:
type: object
properties:
type:
type: string
description: The type of content that is embedded in this point.
enum:
- image
- message_attachment
- opengraph
- link
url:
type: string
description: The URL of the embedded content, if one exists.
data:
type: object
description: >
Any additional information about the embedded content. Only
used at this time to store OpenGraph metadata.
This field will be null for non-OpenGraph embeds.
emojis:
type: array
description: >
The custom emojis that appear in this point or have been used in
reactions to this post. This field will be null if the post does not contain custom emojis.
items:
$ref: "#/components/schemas/Emoji"
files:
type: array
description: >
The FileInfo objects for any files attached to the post. This field
will be null if the post does not have any file attachments.
items:
$ref: "#/components/schemas/FileInfo"
images:
type: object
description: >
An object mapping the URL of an external image to an object
containing the dimensions of that image. This field will be
null if the post or its embedded content does not reference any external images.
items:
type: object
properties:
height:
type: integer
width:
type: integer
reactions:
type: array
description: >
Any reactions made to this point. This field will be null if no
reactions have been made to this post.
items:
$ref: "#/components/schemas/Reaction"
priority:
allOf:
- $ref: "#/components/schemas/PostPriority"
description: >
Post priority set for this post. This field will be null if no
priority metadata has been set.
acknowledgements:
type: array
description: >
Any acknowledgements made to this point.
items:
$ref: "#/components/schemas/PostAcknowledgement"
TeamMap:
type: object
description: A mapping of teamIds to teams.
properties:
team_id:
$ref: "#/components/schemas/Team"
TeamMember:
type: object
properties:
team_id:
description: The ID of the team this member belongs to.
type: string
user_id:
description: The ID of the user this member relates to.
type: string
roles:
description: The complete list of roles assigned to this team member, as a
space-separated list of role names, including any roles granted
implicitly through permissions schemes.
type: string
delete_at:
description: The time in milliseconds that this team member was deleted.
type: integer
scheme_user:
description: Whether this team member holds the default user role defined by the
team's permissions scheme.
type: boolean
scheme_admin:
description: Whether this team member holds the default admin role defined by the
team's permissions scheme.
type: boolean
explicit_roles:
description: The list of roles explicitly assigned to this team member, as a
space separated list of role names. This list does *not* include any
roles granted implicitly through permissions schemes.
type: string
TeamUnread:
type: object
properties:
team_id:
type: string
msg_count:
type: integer
mention_count:
type: integer
ChannelUnread:
type: object
properties:
team_id:
type: string
channel_id:
type: string
msg_count:
type: integer
mention_count:
type: integer
ChannelUnreadAt:
type: object
properties:
team_id:
description: The ID of the team the channel belongs to.
type: string
channel_id:
description: The ID of the channel the user has access to..
type: string
msg_count:
description: No. of messages the user has already read.
type: integer
mention_count:
description: No. of mentions the user has within the unread posts of the channel.
type: integer
last_viewed_at:
description: time in milliseconds when the user last viewed the channel.
type: integer
Session:
type: object
properties:
create_at:
description: The time in milliseconds a session was created
type: integer
format: int64
device_id:
type: string
voip_device_id:
description: VoIP push token. Same prefix shape as device_id.
type: string
expires_at:
description: The time in milliseconds a session will expire
type: integer
format: int64
id:
type: string
is_oauth:
type: boolean
last_activity_at:
description: The time in milliseconds of the last activity of a session
type: integer
format: int64
props:
type: object
roles:
type: string
team_members:
type: array
items:
$ref: "#/components/schemas/TeamMember"
token:
type: string
user_id:
type: string
FileInfo:
type: object
properties:
id:
description: The unique identifier for this file
type: string
user_id:
description: The ID of the user that uploaded this file
type: string
post_id:
description: If this file is attached to a post, the ID of that post
type: string
create_at:
description: The time in milliseconds a file was created
type: integer
format: int64
update_at:
description: The time in milliseconds a file was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a file was deleted
type: integer
format: int64
name:
description: The name of the file
type: string
extension:
description: The extension at the end of the file name
type: string
size:
description: The size of the file in bytes
type: integer
mime_type:
description: The MIME type of the file
type: string
width:
description: If this file is an image, the width of the file
type: integer
height:
description: If this file is an image, the height of the file
type: integer
has_preview_image:
description: If this file is an image, whether or not it has a preview-sized
version
type: boolean
Preference:
type: object
properties:
user_id:
description: The ID of the user that owns this preference
type: string
category:
type: string
name:
type: string
value:
type: string
UserAuthData:
type: object
properties:
auth_data:
description: Service-specific authentication data. Required and must be non-empty for external authentication services. Omit this field when `auth_service` is `email`.
type: string
auth_service:
description: The authentication service such as "email", "gitlab", or "ldap". Use "email" with omitted `auth_data` to clear external authentication.
type: string
required:
- auth_service
UserAutocomplete:
type: object
properties:
users:
description: A list of users that are the main result of the query
type: array
items:
$ref: "#/components/schemas/User"
out_of_channel:
description: A special case list of users returned when autocompleting in a
specific channel. Omitted when empty or not relevant
type: array
items:
$ref: "#/components/schemas/User"
UserAutocompleteInTeam:
type: object
properties:
in_team:
description: A list of user objects in the team
type: array
items:
$ref: "#/components/schemas/User"
UserAutocompleteInChannel:
type: object
properties:
in_channel:
description: A list of user objects in the channel
type: array
items:
$ref: "#/components/schemas/User"
out_of_channel:
description: A list of user objects not in the channel
type: array
items:
$ref: "#/components/schemas/User"
IncomingWebhook:
type: object
properties:
id:
description: The unique identifier for this incoming webhook
type: string
create_at:
description: The time in milliseconds a incoming webhook was created
type: integer
format: int64
update_at:
description: The time in milliseconds a incoming webhook was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a incoming webhook was deleted
type: integer
format: int64
last_used:
description: The time in milliseconds this incoming webhook was last used to post a message
type: integer
format: int64
channel_id:
description: The ID of a public channel or private group that receives the
webhook payloads
type: string
description:
description: The description for this incoming webhook
type: string
display_name:
description: The display name for this incoming webhook
type: string
OutgoingWebhook:
type: object
properties:
id:
description: The unique identifier for this outgoing webhook
type: string
create_at:
description: The time in milliseconds a outgoing webhook was created
type: integer
format: int64
update_at:
description: The time in milliseconds a outgoing webhook was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a outgoing webhook was deleted
type: integer
format: int64
creator_id:
description: The Id of the user who created the webhook
type: string
team_id:
description: The ID of the team that the webhook watchs
type: string
channel_id:
description: The ID of a public channel that the webhook watchs
type: string
description:
description: The description for this outgoing webhook
type: string
display_name:
description: The display name for this outgoing webhook
type: string
trigger_words:
description: List of words for the webhook to trigger on
type: array
items:
type: string
trigger_when:
description: When to trigger the webhook, `0` when a trigger word is present at
all and `1` if the message starts with a trigger word
type: integer
callback_urls:
description: The URLs to POST the payloads to when the webhook is triggered
type: array
items:
type: string
content_type:
description: The format to POST the data in, either `application/json` or
`application/x-www-form-urlencoded`
default: application/x-www-form-urlencoded
type: string
Reaction:
type: object
properties:
user_id:
description: The ID of the user that made this reaction
type: string
post_id:
description: The ID of the post to which this reaction was made
type: string
emoji_name:
description: The name of the emoji that was used for this reaction
type: string
create_at:
description: The time in milliseconds this reaction was made
type: integer
format: int64
NewTeamMember:
type: object
properties:
id:
description: The user's ID.
type: string
username:
type: string
first_name:
type: string
last_name:
type: string
nickname:
type: string
position:
description: The user's position field value.
type: string
create_at:
description: The creation timestamp of the team member record.
type: integer
NewTeamMembersList:
type: object
properties:
has_next:
description: Indicates if there is another page of new team members that can be fetched.
type: boolean
items:
description: List of new team members.
type: array
items:
$ref: "#/components/schemas/NewTeamMember"
total_count:
description: The total count of new team members for the given time range.
type: integer
Emoji:
type: object
properties:
id:
description: The ID of the emoji
type: string
creator_id:
description: The ID of the user that made the emoji
type: string
name:
description: The name of the emoji
type: string
create_at:
description: The time in milliseconds the emoji was made
type: integer
format: int64
update_at:
description: The time in milliseconds the emoji was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds the emoji was deleted
type: integer
format: int64
Command:
type: object
properties:
id:
description: The ID of the slash command
type: string
token:
description: The token which is used to verify the source of the payload
type: string
create_at:
description: The time in milliseconds the command was created
type: integer
update_at:
description: The time in milliseconds the command was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds the command was deleted, 0 if never deleted
type: integer
format: int64
creator_id:
description: The user id for the commands creator
type: string
team_id:
description: The team id for which this command is configured
type: string
trigger:
description: The string that triggers this command
type: string
method:
description: Is the trigger done with HTTP Get ('G') or HTTP Post ('P')
type: string
username:
description: What is the username for the response post
type: string
icon_url:
description: The url to find the icon for this users avatar
type: string
auto_complete:
description: Use auto complete for this command
type: boolean
auto_complete_desc:
description: The description for this command shown when selecting the command
type: string
auto_complete_hint:
description: The hint for this command
type: string
display_name:
description: Display name for the command
type: string
description:
description: Description for this command
type: string
url:
description: The URL that is triggered
type: string
AutocompleteSuggestion:
type: object
properties:
Complete:
description: Completed suggestion
type: string
Suggestion:
description: Predicted text user might want to input
type: string
Hint:
description: Hint about suggested input
type: string
Description:
description: Description of the suggested command
type: string
IconData:
description: Base64 encoded svg image
type: string
CommandResponse:
type: object
properties:
ResponseType:
description: The response type either in_channel or ephemeral
type: string
Text:
type: string
Username:
type: string
IconURL:
type: string
GotoLocation:
type: string
Attachments:
type: array
items:
$ref: "#/components/schemas/MessageAttachment"
MessageAttachment:
type: object
properties:
Id:
type: string
Fallback:
type: string
Color:
type: string
Pretext:
type: string
AuthorName:
type: string
AuthorLink:
type: string
AuthorIcon:
type: string
Title:
type: string
TitleLink:
type: string
Text:
type: string
Fields:
type: array
items:
$ref: "#/components/schemas/MessageAttachmentField"
ImageURL:
type: string
ThumbURL:
type: string
Footer:
type: string
FooterIcon:
type: string
Timestamp:
description: The timestamp of the message attachment, either type of string or integer
type: string
MessageAttachmentField:
type: object
properties:
Title:
type: string
Value:
description: The value of the attachment, set as string but capable with golang interface
type: string
Short:
type: boolean
StatusOK:
type: object
properties:
status:
description: Will contain "ok" if the request was successful and there was nothing else to return
type: string
OpenGraph:
type: object
description: OpenGraph metadata of a webpage
properties:
type:
type: string
url:
type: string
title:
type: string
description:
type: string
determiner:
type: string
site_name:
type: string
locale:
type: string
locales_alternate:
type: array
items:
type: string
images:
type: array
items:
type: object
description: Image object used in OpenGraph metadata of a webpage
properties:
url:
type: string
secure_url:
type: string
type:
type: string
width:
type: integer
height:
type: integer
videos:
type: array
items:
type: object
description: Video object used in OpenGraph metadata of a webpage
properties:
url:
type: string
secure_url:
type: string
type:
type: string
width:
type: integer
height:
type: integer
audios:
type: array
items:
type: object
description: Audio object used in OpenGraph metadata of a webpage
properties:
url:
type: string
secure_url:
type: string
type:
type: string
article:
type: object
description: Article object used in OpenGraph metadata of a webpage, if type is
article
properties:
published_time:
type: string
modified_time:
type: string
expiration_time:
type: string
section:
type: string
tags:
type: array
items:
type: string
authors:
type: array
items:
type: object
properties:
first_name:
type: string
last_name:
type: string
username:
type: string
gender:
type: string
book:
type: object
description: Book object used in OpenGraph metadata of a webpage, if type is book
properties:
isbn:
type: string
release_date:
type: string
tags:
type: array
items:
type: string
authors:
type: array
items:
type: object
properties:
first_name:
type: string
last_name:
type: string
username:
type: string
gender:
type: string
profile:
type: object
properties:
first_name:
type: string
last_name:
type: string
username:
type: string
gender:
type: string
Audit:
type: object
properties:
id:
type: string
create_at:
description: The time in milliseconds a audit was created
type: integer
format: int64
user_id:
type: string
action:
type: string
extra_info:
type: string
ip_address:
type: string
session_id:
type: string
LdapSettings:
type: object
properties:
Enable:
type: boolean
EnableSync:
type: boolean
LdapServer:
type: string
LdapPort:
type: integer
ConnectionSecurity:
type: string
BaseDN:
type: string
BindUsername:
type: string
BindPassword:
type: string
MaximumLoginAttempts:
type: integer
UserFilter:
type: string
GroupFilter:
type: string
GuestFilter:
type: string
EnableAdminFilter:
type: boolean
AdminFilter:
type: string
GroupDisplayNameAttribute:
type: string
GroupIdAttribute:
type: string
FirstNameAttribute:
type: string
LastNameAttribute:
type: string
EmailAttribute:
type: string
UsernameAttribute:
type: string
NicknameAttribute:
type: string
IdAttribute:
type: string
PositionAttribute:
type: string
LoginIdAttribute:
type: string
PictureAttribute:
type: string
SyncIntervalMinutes:
type: integer
SkipCertificateVerification:
type: boolean
PublicCertificateFile:
type: string
PrivateKeyFile:
type: string
QueryTimeout:
type: integer
MaxPageSize:
type: integer
LoginFieldName:
type: string
LoginButtonColor:
type: string
LoginButtonBorderColor:
type: string
LoginButtonTextColor:
type: string
LdapDiagnosticResult:
type: object
properties:
test_name:
type: string
description: Name/type of the diagnostic test being performed
test_value:
type: string
description: The actual test value (filter string or attribute name)
total_count:
type: integer
description: Number of entries found by the filter
message:
type: string
description: Optional success/info message
error:
type: string
description: Optional error message if test failed
sample_results:
type: array
description: Array of sample LDAP entries found
items:
type: object
properties:
dn:
type: string
description: Distinguished Name
username:
type: string
description: Username
email:
type: string
description: Email
first_name:
type: string
description: First name
last_name:
type: string
description: Last name
id:
type: string
description: ID attribute
display_name:
type: string
description: Display name for groups
available_attributes:
type: object
description: Map of all available LDAP attributes
additionalProperties:
type: string
Config:
type: object
properties:
ServiceSettings:
type: object
properties:
SiteURL:
type: string
ListenAddress:
type: string
ConnectionSecurity:
type: string
TLSCertFile:
type: string
TLSKeyFile:
type: string
UseLetsEncrypt:
type: boolean
LetsEncryptCertificateCacheFile:
type: string
Forward80To443:
type: boolean
ReadTimeout:
type: integer
WriteTimeout:
type: integer
MaximumLoginAttempts:
type: integer
SegmentDeveloperKey:
type: string
GoogleDeveloperKey:
type: string
EnableOAuthServiceProvider:
type: boolean
EnableIncomingWebhooks:
type: boolean
EnableOutgoingWebhooks:
type: boolean
EnableCommands:
type: boolean
EnableOnlyAdminIntegrations:
type: boolean
EnablePostUsernameOverride:
type: boolean
EnablePostIconOverride:
type: boolean
EnableTesting:
type: boolean
description: Intended only for isolated non-production environments and must never be enabled in production.
EnableDeveloper:
type: boolean
EnableSecurityFixAlert:
type: boolean
EnableInsecureOutgoingConnections:
type: boolean
EnableMultifactorAuthentication:
type: boolean
EnforceMultifactorAuthentication:
type: boolean
AllowCorsFrom:
type: string
SessionLengthWebInDays:
type: integer
SessionLengthMobileInDays:
type: integer
SessionLengthSSOInDays:
type: integer
SessionCacheInMinutes:
type: integer
WebsocketSecurePort:
type: integer
WebsocketPort:
type: integer
WebserverMode:
type: string
EnableCustomEmoji:
type: boolean
RestrictCustomEmojiCreation:
type: string
TeamSettings:
type: object
properties:
SiteName:
type: string
MaxUsersPerTeam:
type: integer
EnableTeamCreation:
type: boolean
EnableUserCreation:
type: boolean
EnableOpenServer:
type: boolean
RestrictCreationToDomains:
type: string
EnableCustomBrand:
type: boolean
CustomBrandText:
type: string
CustomDescriptionText:
type: string
RestrictDirectMessage:
type: string
RestrictTeamInvite:
type: string
RestrictPublicChannelManagement:
type: string
RestrictPrivateChannelManagement:
type: string
RestrictPublicChannelCreation:
type: string
RestrictPrivateChannelCreation:
type: string
RestrictPublicChannelDeletion:
type: string
RestrictPrivateChannelDeletion:
type: string
UserStatusAwayTimeout:
type: integer
MaxChannelsPerTeam:
type: integer
MaxNotificationsPerChannel:
type: integer
SqlSettings:
type: object
properties:
DriverName:
type: string
DataSource:
type: string
DataSourceReplicas:
type: array
items:
type: string
MaxIdleConns:
type: integer
MaxOpenConns:
type: integer
Trace:
type: boolean
AtRestEncryptKey:
type: string
LogSettings:
type: object
properties:
EnableConsole:
type: boolean
ConsoleLevel:
type: string
EnableFile:
type: boolean
FileLevel:
type: string
FileLocation:
type: string
EnableWebhookDebugging:
type: boolean
EnableDiagnostics:
type: boolean
PasswordSettings:
type: object
properties:
MinimumLength:
type: integer
Lowercase:
type: boolean
Number:
type: boolean
Uppercase:
type: boolean
Symbol:
type: boolean
FileSettings:
type: object
properties:
MaxFileSize:
type: integer
DriverName:
type: string
Directory:
type: string
EnablePublicLink:
type: boolean
PublicLinkSalt:
type: string
ThumbnailWidth:
type: integer
ThumbnailHeight:
type: integer
PreviewWidth:
type: integer
PreviewHeight:
type: integer
ProfileWidth:
type: integer
ProfileHeight:
type: integer
InitialFont:
type: string
AmazonS3AccessKeyId:
type: string
AmazonS3SecretAccessKey:
type: string
AmazonS3Bucket:
type: string
AmazonS3Region:
type: string
AmazonS3Endpoint:
type: string
AmazonS3SSL:
type: boolean
AmazonS3StorageClass:
type: string
EmailSettings:
type: object
properties:
EnableSignUpWithEmail:
type: boolean
EnableSignInWithEmail:
type: boolean
EnableSignInWithUsername:
type: boolean
SendEmailNotifications:
type: boolean
RequireEmailVerification:
type: boolean
FeedbackName:
type: string
FeedbackEmail:
type: string
FeedbackOrganization:
type: string
SMTPUsername:
type: string
SMTPPassword:
type: string
SMTPServer:
type: string
SMTPPort:
type: string
ConnectionSecurity:
type: string
InviteSalt:
type: string
PasswordResetSalt:
type: string
SendPushNotifications:
type: boolean
PushNotificationServer:
type: string
PushNotificationContents:
type: string
EnableEmailBatching:
type: boolean
EmailBatchingBufferSize:
type: integer
EmailBatchingInterval:
type: integer
RateLimitSettings:
type: object
properties:
Enable:
type: boolean
PerSec:
type: integer
MaxBurst:
type: integer
MemoryStoreSize:
type: integer
VaryByRemoteAddr:
type: boolean
VaryByHeader:
type: string
PrivacySettings:
type: object
properties:
ShowEmailAddress:
type: boolean
ShowFullName:
type: boolean
SupportSettings:
type: object
properties:
TermsOfServiceLink:
type: string
PrivacyPolicyLink:
type: string
AboutLink:
type: string
HelpLink:
type: string
ReportAProblemLink:
type: string
ReportAProblemType:
type: string
ReportAProblemMail:
type: string
AllowDownloadLogs:
type: boolean
SupportEmail:
type: string
GitLabSettings:
type: object
properties:
Enable:
type: boolean
Secret:
type: string
Id:
type: string
Scope:
type: string
AuthEndpoint:
type: string
TokenEndpoint:
type: string
UserApiEndpoint:
type: string
GoogleSettings:
type: object
properties:
Enable:
type: boolean
Secret:
type: string
Id:
type: string
Scope:
type: string
AuthEndpoint:
type: string
TokenEndpoint:
type: string
UserApiEndpoint:
type: string
Office365Settings:
type: object
properties:
Enable:
type: boolean
Secret:
type: string
Id:
type: string
Scope:
type: string
AuthEndpoint:
type: string
TokenEndpoint:
type: string
UserApiEndpoint:
type: string
LdapSettings:
type: object
properties:
Enable:
type: boolean
LdapServer:
type: string
LdapPort:
type: integer
ConnectionSecurity:
type: string
BaseDN:
type: string
BindUsername:
type: string
BindPassword:
type: string
UserFilter:
type: string
FirstNameAttribute:
type: string
LastNameAttribute:
type: string
EmailAttribute:
type: string
UsernameAttribute:
type: string
NicknameAttribute:
type: string
IdAttribute:
type: string
PositionAttribute:
type: string
SyncIntervalMinutes:
type: integer
SkipCertificateVerification:
type: boolean
QueryTimeout:
type: integer
MaxPageSize:
type: integer
LoginFieldName:
type: string
ComplianceSettings:
type: object
properties:
Enable:
type: boolean
Directory:
type: string
EnableDaily:
type: boolean
LocalizationSettings:
type: object
properties:
DefaultServerLocale:
type: string
DefaultClientLocale:
type: string
AvailableLocales:
type: string
SamlSettings:
type: object
properties:
Enable:
type: boolean
Verify:
type: boolean
Encrypt:
type: boolean
IdpUrl:
type: string
IdpDescriptorUrl:
type: string
AssertionConsumerServiceURL:
type: string
IdpCertificateFile:
type: string
PublicCertificateFile:
type: string
PrivateKeyFile:
type: string
FirstNameAttribute:
type: string
LastNameAttribute:
type: string
EmailAttribute:
type: string
UsernameAttribute:
type: string
NicknameAttribute:
type: string
LocaleAttribute:
type: string
PositionAttribute:
type: string
LoginButtonText:
type: string
NativeAppSettings:
type: object
properties:
AppDownloadLink:
type: string
AndroidAppDownloadLink:
type: string
IosAppDownloadLink:
type: string
ClusterSettings:
type: object
properties:
Enable:
type: boolean
InterNodeListenAddress:
type: string
InterNodeUrls:
type: array
items:
type: string
MetricsSettings:
type: object
properties:
Enable:
type: boolean
BlockProfileRate:
type: integer
ListenAddress:
type: string
AnalyticsSettings:
type: object
properties:
MaxUsersForStatistics:
type: integer
EnvironmentConfig:
type: object
properties:
ServiceSettings:
type: object
properties:
SiteURL:
type: boolean
ListenAddress:
type: boolean
ConnectionSecurity:
type: boolean
TLSCertFile:
type: boolean
TLSKeyFile:
type: boolean
UseLetsEncrypt:
type: boolean
LetsEncryptCertificateCacheFile:
type: boolean
Forward80To443:
type: boolean
ReadTimeout:
type: boolean
WriteTimeout:
type: boolean
MaximumLoginAttempts:
type: boolean
SegmentDeveloperKey:
type: boolean
GoogleDeveloperKey:
type: boolean
EnableOAuthServiceProvider:
type: boolean
EnableIncomingWebhooks:
type: boolean
EnableOutgoingWebhooks:
type: boolean
EnableCommands:
type: boolean
EnableOnlyAdminIntegrations:
type: boolean
EnablePostUsernameOverride:
type: boolean
EnablePostIconOverride:
type: boolean
EnableTesting:
type: boolean
description: Intended only for isolated non-production environments and must never be enabled in production.
EnableDeveloper:
type: boolean
EnableSecurityFixAlert:
type: boolean
EnableInsecureOutgoingConnections:
type: boolean
EnableMultifactorAuthentication:
type: boolean
EnforceMultifactorAuthentication:
type: boolean
AllowCorsFrom:
type: boolean
SessionLengthWebInDays:
type: boolean
SessionLengthMobileInDays:
type: boolean
SessionLengthSSOInDays:
type: boolean
SessionCacheInMinutes:
type: boolean
WebsocketSecurePort:
type: boolean
WebsocketPort:
type: boolean
WebserverMode:
type: boolean
EnableCustomEmoji:
type: boolean
RestrictCustomEmojiCreation:
type: boolean
TeamSettings:
type: object
properties:
SiteName:
type: boolean
MaxUsersPerTeam:
type: boolean
EnableTeamCreation:
type: boolean
EnableUserCreation:
type: boolean
EnableOpenServer:
type: boolean
RestrictCreationToDomains:
type: boolean
EnableCustomBrand:
type: boolean
CustomBrandText:
type: boolean
CustomDescriptionText:
type: boolean
RestrictDirectMessage:
type: boolean
RestrictTeamInvite:
type: boolean
RestrictPublicChannelManagement:
type: boolean
RestrictPrivateChannelManagement:
type: boolean
RestrictPublicChannelCreation:
type: boolean
RestrictPrivateChannelCreation:
type: boolean
RestrictPublicChannelDeletion:
type: boolean
RestrictPrivateChannelDeletion:
type: boolean
UserStatusAwayTimeout:
type: boolean
MaxChannelsPerTeam:
type: boolean
MaxNotificationsPerChannel:
type: boolean
SqlSettings:
type: object
properties:
DriverName:
type: boolean
DataSource:
type: boolean
DataSourceReplicas:
type: boolean
MaxIdleConns:
type: boolean
MaxOpenConns:
type: boolean
Trace:
type: boolean
AtRestEncryptKey:
type: boolean
LogSettings:
type: object
properties:
EnableConsole:
type: boolean
ConsoleLevel:
type: boolean
EnableFile:
type: boolean
FileLevel:
type: boolean
FileLocation:
type: boolean
EnableWebhookDebugging:
type: boolean
EnableDiagnostics:
type: boolean
PasswordSettings:
type: object
properties:
MinimumLength:
type: boolean
Lowercase:
type: boolean
Number:
type: boolean
Uppercase:
type: boolean
Symbol:
type: boolean
FileSettings:
type: object
properties:
MaxFileSize:
type: boolean
DriverName:
type: boolean
Directory:
type: boolean
EnablePublicLink:
type: boolean
PublicLinkSalt:
type: boolean
ThumbnailWidth:
type: boolean
ThumbnailHeight:
type: boolean
PreviewWidth:
type: boolean
PreviewHeight:
type: boolean
ProfileWidth:
type: boolean
ProfileHeight:
type: boolean
InitialFont:
type: boolean
AmazonS3AccessKeyId:
type: boolean
AmazonS3SecretAccessKey:
type: boolean
AmazonS3Bucket:
type: boolean
AmazonS3Region:
type: boolean
AmazonS3Endpoint:
type: boolean
AmazonS3SSL:
type: boolean
AmazonS3StorageClass:
type: string
EmailSettings:
type: object
properties:
EnableSignUpWithEmail:
type: boolean
EnableSignInWithEmail:
type: boolean
EnableSignInWithUsername:
type: boolean
SendEmailNotifications:
type: boolean
RequireEmailVerification:
type: boolean
FeedbackName:
type: boolean
FeedbackEmail:
type: boolean
FeedbackOrganization:
type: boolean
SMTPUsername:
type: boolean
SMTPPassword:
type: boolean
SMTPServer:
type: boolean
SMTPPort:
type: boolean
ConnectionSecurity:
type: boolean
InviteSalt:
type: boolean
PasswordResetSalt:
type: boolean
SendPushNotifications:
type: boolean
PushNotificationServer:
type: boolean
PushNotificationContents:
type: boolean
EnableEmailBatching:
type: boolean
EmailBatchingBufferSize:
type: boolean
EmailBatchingInterval:
type: boolean
RateLimitSettings:
type: object
properties:
Enable:
type: boolean
PerSec:
type: boolean
MaxBurst:
type: boolean
MemoryStoreSize:
type: boolean
VaryByRemoteAddr:
type: boolean
VaryByHeader:
type: boolean
PrivacySettings:
type: object
properties:
ShowEmailAddress:
type: boolean
ShowFullName:
type: boolean
SupportSettings:
type: object
properties:
TermsOfServiceLink:
type: boolean
PrivacyPolicyLink:
type: boolean
AboutLink:
type: boolean
HelpLink:
type: boolean
ReportAProblemLink:
type: boolean
ReportAProblemType:
type: boolean
ReportAProblemMail:
type: boolean
AllowDownloadLogs:
type: boolean
SupportEmail:
type: boolean
GitLabSettings:
type: object
properties:
Enable:
type: boolean
Secret:
type: boolean
Id:
type: boolean
Scope:
type: boolean
AuthEndpoint:
type: boolean
TokenEndpoint:
type: boolean
UserApiEndpoint:
type: boolean
GoogleSettings:
type: object
properties:
Enable:
type: boolean
Secret:
type: boolean
Id:
type: boolean
Scope:
type: boolean
AuthEndpoint:
type: boolean
TokenEndpoint:
type: boolean
UserApiEndpoint:
type: boolean
Office365Settings:
type: object
properties:
Enable:
type: boolean
Secret:
type: boolean
Id:
type: boolean
Scope:
type: boolean
AuthEndpoint:
type: boolean
TokenEndpoint:
type: boolean
UserApiEndpoint:
type: boolean
LdapSettings:
type: object
properties:
Enable:
type: boolean
LdapServer:
type: boolean
LdapPort:
type: boolean
ConnectionSecurity:
type: boolean
BaseDN:
type: boolean
BindUsername:
type: boolean
BindPassword:
type: boolean
UserFilter:
type: boolean
FirstNameAttribute:
type: boolean
LastNameAttribute:
type: boolean
EmailAttribute:
type: boolean
UsernameAttribute:
type: boolean
NicknameAttribute:
type: boolean
IdAttribute:
type: boolean
PositionAttribute:
type: boolean
SyncIntervalMinutes:
type: boolean
SkipCertificateVerification:
type: boolean
QueryTimeout:
type: boolean
MaxPageSize:
type: boolean
LoginFieldName:
type: boolean
ComplianceSettings:
type: object
properties:
Enable:
type: boolean
Directory:
type: boolean
EnableDaily:
type: boolean
LocalizationSettings:
type: object
properties:
DefaultServerLocale:
type: boolean
DefaultClientLocale:
type: boolean
AvailableLocales:
type: boolean
SamlSettings:
type: object
properties:
Enable:
type: boolean
Verify:
type: boolean
Encrypt:
type: boolean
IdpUrl:
type: boolean
IdpDescriptorUrl:
type: boolean
AssertionConsumerServiceURL:
type: boolean
IdpCertificateFile:
type: boolean
PublicCertificateFile:
type: boolean
PrivateKeyFile:
type: boolean
FirstNameAttribute:
type: boolean
LastNameAttribute:
type: boolean
EmailAttribute:
type: boolean
UsernameAttribute:
type: boolean
NicknameAttribute:
type: boolean
LocaleAttribute:
type: boolean
PositionAttribute:
type: boolean
LoginButtonText:
type: boolean
NativeAppSettings:
type: object
properties:
AppDownloadLink:
type: boolean
AndroidAppDownloadLink:
type: boolean
IosAppDownloadLink:
type: boolean
ClusterSettings:
type: object
properties:
Enable:
type: boolean
InterNodeListenAddress:
type: boolean
InterNodeUrls:
type: boolean
MetricsSettings:
type: object
properties:
Enable:
type: boolean
BlockProfileRate:
type: boolean
ListenAddress:
type: boolean
AnalyticsSettings:
type: object
properties:
MaxUsersForStatistics:
type: boolean
SamlCertificateStatus:
type: object
properties:
idp_certificate_file:
description: Status is good when `true`
type: boolean
public_certificate_file:
description: Status is good when `true`
type: boolean
private_key_file:
description: Status is good when `true`
type: boolean
IntuneLoginRequest:
type: object
description: Request body for Microsoft Intune MAM authentication using Azure AD/Entra ID access token
required:
- access_token
properties:
access_token:
type: string
description: Microsoft Entra ID access token obtained via MSAL (Microsoft Authentication Library). This token must be scoped to the Intune MAM app registration and will be validated against the configured tenant.
device_id:
type: string
description: Optional mobile device identifier used for push notifications. If provided, the device will be registered for receiving push notifications.
voip_device_id:
type: string
description: Optional VoIP push token. Same prefix shape as device_id. When provided, enables ring-style call push notifications.
Compliance:
type: object
properties:
id:
type: string
create_at:
type: integer
format: int64
user_id:
type: string
status:
type: string
count:
type: integer
desc:
type: string
type:
type: string
start_at:
type: integer
format: int64
end_at:
type: integer
format: int64
keywords:
type: string
emails:
type: string
ClusterInfo:
type: array
properties:
items:
type: object
properties:
id:
description: The unique ID for the node
type: string
version:
description: The server version the node is on
type: string
schema_version:
description: The number of the latest DB migration successfully executed for the node
type: string
config_hash:
description: The hash of the configuration file the node is using
type: string
ipaddress:
description: The IP address of the node
type: string
hostname:
description: The hostname for this node
type: string
AppError:
type: object
properties:
status_code:
type: integer
id:
type: string
message:
type: string
request_id:
type: string
Status:
type: object
properties:
user_id:
type: string
status:
type: string
manual:
type: boolean
last_activity_at:
type: integer
format: int64
OAuthApp:
type: object
properties:
id:
type: string
description: The client id of the application
client_secret:
type: string
description: The client secret of the application
name:
type: string
description: The name of the client application
description:
type: string
description: A short description of the application
icon_url:
type: string
description: A URL to an icon to display with the application
callback_urls:
type: array
items:
type: string
description: A list of callback URLs for the appliation
homepage:
type: string
description: A link to the website of the application
is_trusted:
type: boolean
description: Set this to `true` to skip asking users for permission
create_at:
type: integer
description: The time of registration for the application
format: int64
update_at:
type: integer
description: The last time of update for the application
format: int64
ClientRegistrationRequest:
type: object
description: OAuth 2.0 Dynamic Client Registration request as defined in RFC 7591
required:
- redirect_uris
properties:
redirect_uris:
type: array
items:
type: string
description: Array of redirection URI strings for use in redirect-based flows such as the authorization code and implicit flows
minItems: 1
client_name:
type: string
description: Human-readable string name of the client to be presented to the end-user during authorization
maxLength: 64
client_uri:
type: string
description: URL string of a web page providing information about the client
maxLength: 256
format: uri
ClientRegistrationResponse:
type: object
description: OAuth 2.0 Dynamic Client Registration response as defined in RFC 7591
properties:
client_id:
type: string
description: OAuth 2.0 client identifier string
client_secret:
type: string
description: OAuth 2.0 client secret string
redirect_uris:
type: array
items:
type: string
description: Array of the registered redirection URI strings
token_endpoint_auth_method:
type: string
description: String indicator of the requested authentication method for the token endpoint
enum:
- client_secret_post
- none
grant_types:
type: array
items:
type: string
description: Array of OAuth 2.0 grant type strings that the client can use at the token endpoint
response_types:
type: array
items:
type: string
description: Array of the OAuth 2.0 response type strings that the client can use at the authorization endpoint
scope:
type: string
description: Space-separated list of scope values that the client can use when requesting access tokens
client_name:
type: string
description: Human-readable string name of the client to be presented to the end-user during authorization
client_uri:
type: string
description: URL string of a web page providing information about the client
format: uri
AuthorizationServerMetadata:
type: object
description: OAuth 2.0 Authorization Server Metadata as defined in RFC 8414
properties:
issuer:
type: string
description: The authorization server's issuer identifier, which is a URL that uses the "https" scheme
authorization_endpoint:
type: string
description: URL of the authorization server's authorization endpoint
token_endpoint:
type: string
description: URL of the authorization server's token endpoint
response_types_supported:
type: array
items:
type: string
description: JSON array containing a list of the OAuth 2.0 response_type values that this authorization server supports
registration_endpoint:
type: string
description: URL of the authorization server's OAuth 2.0 Dynamic Client Registration endpoint
scopes_supported:
type: array
items:
type: string
description: JSON array containing a list of the OAuth 2.0 scope values that this authorization server supports
grant_types_supported:
type: array
items:
type: string
description: JSON array containing a list of the OAuth 2.0 grant type values that this authorization server supports
token_endpoint_auth_methods_supported:
type: array
items:
type: string
description: JSON array containing a list of client authentication methods supported by the token endpoint
code_challenge_methods_supported:
type: array
items:
type: string
description: JSON array containing a list of PKCE code challenge methods supported by this authorization server
required:
- issuer
- response_types_supported
Job:
type: object
properties:
id:
type: string
description: The unique id of the job
type:
type: string
description: The type of job
create_at:
type: integer
description: The time at which the job was created
format: int64
start_at:
type: integer
description: The time at which the job was started
format: int64
last_activity_at:
type: integer
description: The last time at which the job had activity
format: int64
status:
type: string
description: The status of the job
progress:
type: integer
description: The progress (as a percentage) of the job
data:
type: object
description: A freeform data field containing additional information about the job
UserAccessToken:
type: object
properties:
id:
type: string
description: Unique identifier for the token
token:
type: string
description: The token used for authentication
user_id:
type: string
description: The user the token authenticates for
description:
type: string
description: A description of the token usage
UserAccessTokenSanitized:
type: object
properties:
id:
type: string
description: Unique identifier for the token
user_id:
type: string
description: The user the token authenticates for
description:
type: string
description: A description of the token usage
is_active:
type: boolean
description: Indicates whether the token is active
GlobalDataRetentionPolicy:
type: object
properties:
message_deletion_enabled:
type: boolean
description: Indicates whether data retention policy deletion of messages is
enabled globally.
file_deletion_enabled:
type: boolean
description: Indicates whether data retention policy deletion of file attachments
is enabled globally.
message_retention_cutoff:
type: integer
description: The current server timestamp before which messages should be deleted.
file_retention_cutoff:
type: integer
description: The current server timestamp before which files should be deleted.
DataRetentionPolicyWithoutId:
type: object
properties:
display_name:
type: string
description: The display name for this retention policy.
post_duration:
type: integer
description: >
The number of days a message will be retained before being deleted by this policy.
If this value is less than 0, the policy has infinite retention (i.e. messages
are never deleted).
DataRetentionPolicy:
allOf:
- $ref: "#/components/schemas/DataRetentionPolicyWithoutId"
- type: object
properties:
id:
type: string
description: The ID of this retention policy.
DataRetentionPolicyWithTeamAndChannelCounts:
allOf:
- $ref: "#/components/schemas/DataRetentionPolicy"
- type: object
properties:
team_count:
type: integer
description: The number of teams to which this policy is applied.
channel_count:
type: integer
description: The number of channels to which this policy is applied.
DataRetentionPolicyWithTeamAndChannelIds:
allOf:
- $ref: "#/components/schemas/DataRetentionPolicyWithoutId"
- type: object
properties:
team_ids:
type: array
items:
type: string
description: The IDs of the teams to which this policy should be applied.
channel_ids:
type: array
items:
type: string
description: The IDs of the channels to which this policy should be applied.
DataRetentionPolicyCreate:
allOf:
- $ref: "#/components/schemas/DataRetentionPolicyWithTeamAndChannelIds"
required:
- display_name
- post_duration
DataRetentionPolicyForTeam:
type: object
properties:
team_id:
type: string
description: The team ID.
post_duration:
type: integer
description: The number of days a message will be retained before being deleted by this policy.
RetentionPolicyForTeamList:
type: object
properties:
policies:
type: array
items:
$ref: "#/components/schemas/DataRetentionPolicyForTeam"
description: The list of team policies.
total_count:
type: integer
description: The total number of team policies.
DataRetentionPolicyForChannel:
type: object
properties:
channel_id:
type: string
description: The channel ID.
post_duration:
type: integer
description: The number of days a message will be retained before being deleted by this policy.
RetentionPolicyForChannelList:
type: object
properties:
policies:
type: array
items:
$ref: "#/components/schemas/DataRetentionPolicyForChannel"
description: The list of channel policies.
total_count:
type: integer
description: The total number of channel policies.
UserNotifyProps:
type: object
properties:
email:
type: string
description: Set to "true" to enable email notifications, "false" to disable.
Defaults to "true".
push:
type: string
description: Set to "all" to receive push notifications for all activity,
"mention" for mentions and direct messages only, and "none" to
disable. Defaults to "mention".
desktop:
type: string
description: Set to "all" to receive desktop notifications for all activity,
"mention" for mentions and direct messages only, and "none" to
disable. Defaults to "all".
desktop_sound:
type: string
description: Set to "true" to enable sound on desktop notifications, "false" to
disable. Defaults to "true".
mention_keys:
type: string
description: A comma-separated list of words to count as mentions. Defaults to
username and @username.
channel:
type: string
description: Set to "true" to enable channel-wide notifications (@channel, @all,
etc.), "false" to disable. Defaults to "true".
first_name:
type: string
description: Set to "true" to enable mentions for first name. Defaults to "true"
if a first name is set, "false" otherwise.
auto_responder_message:
type: string
description: The message sent to users when they are auto-responded to.
Defaults to "".
push_threads:
type: string
description: Set to "all" to enable mobile push notifications for followed threads and "none" to disable.
Defaults to "all".
comments:
type: string
description: Set to "any" to enable notifications for comments to any post you have
replied to, "root" for comments on your posts, and "never" to disable. Only
affects users with collapsed reply threads disabled.
Defaults to "never".
desktop_threads:
type: string
description: Set to "all" to enable desktop notifications for followed threads and "none" to disable.
Defaults to "all".
email_threads:
type: string
description: Set to "all" to enable email notifications for followed threads and "none" to disable.
Defaults to "all".
Timezone:
type: object
properties:
useAutomaticTimezone:
type: string
description: Set to "true" to use the browser/system timezone, "false" to set
manually. Defaults to "true".
manualTimezone:
type: string
description: Value when setting manually the timezone, i.e. "Europe/Berlin".
automaticTimezone:
type: string
description: This value is set automatically when the "useAutomaticTimezone" is
set to "true".
ChannelNotifyProps:
type: object
properties:
email:
type: string
description: Set to "true" to enable email notifications, "false" to disable, or
"default" to use the global user notification setting.
push:
type: string
description: Set to "all" to receive push notifications for all activity,
"mention" for mentions and direct messages only, "none" to disable,
or "default" to use the global user notification setting.
desktop:
type: string
description: Set to "all" to receive desktop notifications for all activity,
"mention" for mentions and direct messages only, "none" to disable,
or "default" to use the global user notification setting.
mark_unread:
type: string
description: Set to "all" to mark the channel unread for any new message,
"mention" to mark unread for new mentions only. Defaults to "all".
PluginManifest:
type: object
properties:
id:
type: string
description: Globally unique identifier that represents the plugin.
name:
type: string
description: Name of the plugin.
description:
type: string
description: Description of what the plugin is and does.
version:
type: string
description: Version number of the plugin.
min_server_version:
type: string
description: |
The minimum Mattermost server version required for the plugin.
Available as server version 5.6.
backend:
type: object
description: Deprecated in Mattermost 5.2 release.
properties:
executable:
type: string
description: Path to the executable binary.
server:
type: object
properties:
executables:
type: object
description: Paths to executable binaries, specifying multiple entry points
for different platforms when bundled together in a single
plugin.
properties:
linux-amd64:
type: string
darwin-amd64:
type: string
windows-amd64:
type: string
executable:
type: string
description: Path to the executable binary.
webapp:
type: object
properties:
bundle_path:
type: string
description: Path to the webapp JavaScript bundle.
settings_schema:
type: object
description: Settings schema used to define the System Console UI for the plugin.
MarketplacePlugin:
type: object
properties:
homepage_url:
type: string
description: URL that leads to the homepage of the plugin.
icon_data:
type: string
description: Base64 encoding of a plugin icon SVG.
download_url:
type: string
description: URL to download the plugin.
release_notes_url:
type: string
description: URL that leads to the release notes of the plugin.
labels:
type: array
items:
type: string
description: A list of the plugin labels.
signature:
type: string
description: Base64 encoded signature of the plugin.
manifest:
$ref: "#/components/schemas/PluginManifest"
installed_version:
type: string
description: Version number of the already installed plugin, if any.
PushNotification:
type: object
properties:
ack_id:
type: string
platform:
type: string
server_id:
type: string
device_id:
type: string
post_id:
type: string
category:
type: string
sound:
type: string
message:
type: string
badge:
type: number
cont_ava:
type: number
team_id:
type: string
channel_id:
type: string
root_id:
type: string
channel_name:
type: string
type:
type: string
sub_type:
type: string
description: Additional message type information for mobile clients. Use "calls" for Calls plugin notifications.
transport:
type: string
description: Delivery path for the push proxy. Use "voip" for VoIP (CallKit) notifications; omit for standard delivery.
enum:
- ""
- voip
sender_id:
type: string
sender_name:
type: string
override_username:
type: string
override_icon_url:
type: string
from_webhook:
type: string
version:
type: string
is_crt_enabled:
type: boolean
description: Whether Collapsed Reply Threads is enabled for the recipient.
is_id_loaded:
type: boolean
signature:
type: string
PluginStatus:
type: object
properties:
plugin_id:
type: string
description: Globally unique identifier that represents the plugin.
name:
type: string
description: Name of the plugin.
description:
type: string
description: Description of what the plugin is and does.
version:
type: string
description: Version number of the plugin.
cluster_id:
type: string
description: ID of the cluster in which plugin is running
plugin_path:
type: string
description: Path to the plugin on the server
state:
type: number
description: State of the plugin
enum:
- NotRunning
- Starting
- Running
- FailedToStart
- FailedToStayRunning
- Stopping
PluginManifestWebapp:
type: object
properties:
id:
type: string
description: Globally unique identifier that represents the plugin.
version:
type: string
description: Version number of the plugin.
webapp:
type: object
properties:
bundle_path:
type: string
description: Path to the webapp JavaScript bundle.
Role:
type: object
properties:
id:
type: string
description: The unique identifier of the role.
name:
type: string
description: The unique name of the role, used when assigning roles to
users/groups in contexts.
display_name:
type: string
description: The human readable name for the role.
description:
type: string
description: A human readable description of the role.
permissions:
type: array
items:
type: string
description: A list of the unique names of the permissions this role grants.
scheme_managed:
type: boolean
description: indicates if this role is managed by a scheme (true), or is a custom
stand-alone role (false).
Scheme:
type: object
properties:
id:
type: string
description: The unique identifier of the scheme.
name:
type: string
description: The human readable name for the scheme.
description:
type: string
description: A human readable description of the scheme.
create_at:
type: integer
format: int64
description: The time at which the scheme was created.
update_at:
type: integer
format: int64
description: The time at which the scheme was last updated.
delete_at:
type: integer
format: int64
description: The time at which the scheme was deleted.
scope:
type: string
description: The scope to which this scheme can be applied, either "team" or
"channel".
default_team_admin_role:
type: string
description: The id of the default team admin role for this scheme.
default_team_user_role:
type: string
description: The id of the default team user role for this scheme.
default_channel_admin_role:
type: string
description: The id of the default channel admin role for this scheme.
default_channel_user_role:
type: string
description: The id of the default channel user role for this scheme.
TermsOfService:
type: object
properties:
id:
type: string
description: The unique identifier of the terms of service.
create_at:
type: integer
format: int64
description: The time at which the terms of service was created.
user_id:
type: string
description: The unique identifier of the user who created these terms of service.
text:
type: string
description: The text of terms of service. Supports Markdown.
UserTermsOfService:
type: object
properties:
user_id:
type: string
description: The unique identifier of the user who performed this terms of
service action.
terms_of_service_id:
type: string
description: The unique identifier of the terms of service the action was
performed on.
create_at:
description: The time in milliseconds that this action was performed.
type: integer
format: int64
PostIdToReactionsMap:
type: object
additionalProperties:
type: array
items:
$ref: "#/components/schemas/Reaction"
Product:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
price_per_seat:
type: string
add_ons:
type: array
items:
$ref: "#/components/schemas/AddOn"
AddOn:
type: object
properties:
id:
type: string
name:
type: string
display_name:
type: string
price_per_seat:
type: string
ProductLimits:
type: object
properties:
boards:
$ref: "#/components/schemas/BoardsLimits"
nullable: true
files:
$ref: "#/components/schemas/FilesLimits"
nullable: true
integrations:
$ref: "#/components/schemas/IntegrationsLimits"
nullable: true
messages:
$ref: "#/components/schemas/MessagesLimits"
nullable: true
teams:
$ref: "#/components/schemas/TeamsLimits"
nullable: true
BoardsLimits:
type: object
properties:
cards:
type: integer
nullable: true
views:
type: integer
nullable: true
FilesLimits:
type: object
properties:
total_storage:
type: integer
format: int64
nullable: true
IntegrationsLimits:
type: object
properties:
enabled:
type: integer
nullable: true
MessagesLimits:
type: object
properties:
history:
type: integer
nullable: true
TeamsLimits:
type: object
properties:
active:
type: integer
nullable: true
PaymentMethod:
type: object
properties:
type:
type: string
last_four:
type: integer
exp_month:
type: integer
exp_year:
type: integer
card_brand:
type: string
name:
type: string
Address:
type: object
properties:
city:
type: string
country:
type: string
line1:
type: string
line2:
type: string
postal_code:
type: string
state:
type: string
CloudCustomer:
type: object
properties:
id:
type: string
creator_id:
type: string
create_at:
type: integer
format: int64
email:
type: string
name:
type: string
num_employees:
type: string
contact_first_name:
type: string
contact_last_name:
type: string
billing_address:
$ref: "#/components/schemas/Address"
company_address:
$ref: "#/components/schemas/Address"
payment_method:
$ref: "#/components/schemas/PaymentMethod"
Subscription:
type: object
properties:
id:
type: string
customer_id:
type: string
product_id:
type: string
add_ons:
type: array
items:
type: string
start_at:
type: integer
format: int64
end_at:
type: integer
format: int64
create_at:
type: integer
format: int64
seats:
type: integer
dns:
type: string
SubscriptionStats:
type: object
properties:
remaining_seats:
type: integer
is_paid_tier:
type: string
Invoice:
type: object
properties:
id:
type: string
number:
type: string
create_at:
type: integer
format: int64
total:
type: integer
format: int64
tax:
type: integer
format: int64
status:
type: string
period_start:
type: integer
format: int64
period_end:
type: integer
format: int64
subscription_id:
type: string
item:
type: array
items:
$ref: "#/components/schemas/InvoiceLineItem"
InvoiceLineItem:
type: object
properties:
price_id:
type: string
total:
type: integer
format: int64
quantity:
type: integer
format: int64
price_per_unit:
type: integer
format: int64
description:
type: string
metadata:
type: array
items:
type: string
Group:
type: object
properties:
id:
type: string
name:
type: string
display_name:
type: string
description:
type: string
source:
type: string
remote_id:
type: string
create_at:
type: integer
format: int64
update_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
has_syncables:
type: boolean
GroupMember:
type: object
properties:
group_id:
type: string
user_id:
type: string
create_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
GroupSyncableTeam:
type: object
properties:
team_id:
type: string
group_id:
type: string
auto_add:
type: boolean
create_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
update_at:
type: integer
format: int64
GroupSyncableChannel:
type: object
properties:
channel_id:
type: string
group_id:
type: string
auto_add:
type: boolean
create_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
update_at:
type: integer
format: int64
GroupSyncableTeams:
type: object
properties:
team_id:
type: string
team_display_name:
type: string
team_type:
type: string
group_id:
type: string
auto_add:
type: boolean
create_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
update_at:
type: integer
format: int64
GroupSyncableChannels:
type: object
properties:
channel_id:
type: string
channel_display_name:
type: string
channel_type:
type: string
team_id:
type: string
team_display_name:
type: string
team_type:
type: string
group_id:
type: string
auto_add:
type: boolean
create_at:
type: integer
format: int64
delete_at:
type: integer
format: int64
update_at:
type: integer
format: int64
ChannelModeration:
type: object
properties:
name:
type: string
roles:
$ref: "#/components/schemas/ChannelModeratedRoles"
ChannelModeratedRoles:
type: object
properties:
guests:
$ref: "#/components/schemas/ChannelModeratedRole"
members:
$ref: "#/components/schemas/ChannelModeratedRole"
ChannelModeratedRole:
type: object
properties:
value:
type: boolean
enabled:
type: boolean
ChannelModeratedRolesPatch:
type: object
properties:
guests:
type: boolean
members:
type: boolean
ChannelModerationPatch:
type: object
properties:
name:
type: string
roles:
$ref: "#/components/schemas/ChannelModeratedRolesPatch"
ChannelMemberCountByGroup:
description: An object describing group member information in a channel
type: object
properties:
group_id:
type: string
description: ID of the group
channel_member_count:
type: number
description: Total number of group members in the channel
channel_member_timezones_count:
type: number
description: Total number of unique timezones for the group members in the channel
LDAPGroupsPaged:
description: A paged list of LDAP groups
type: object
properties:
count:
type: number
description: Total number of groups
groups:
type: array
items:
$ref: "#/components/schemas/LDAPGroup"
LDAPGroup:
description: A LDAP group
type: object
properties:
has_syncables:
type: boolean
mattermost_group_id:
type: string
primary_key:
type: string
name:
type: string
SidebarCategory:
description: User's sidebar category
type: object
properties:
id:
type: string
user_id:
type: string
team_id:
type: string
display_name:
type: string
type:
type: string
enum:
- channels
- custom
- direct_messages
- favorites
SidebarCategoryWithChannels:
description: User's sidebar category with it's channels
type: object
properties:
id:
type: string
user_id:
type: string
team_id:
type: string
display_name:
type: string
type:
type: string
enum:
- channels
- custom
- direct_messages
- favorites
channel_ids:
type: array
items:
type: string
OrderedSidebarCategories:
description: List of user's categories with their channels
type: object
properties:
order:
type: array
items:
type: string
categories:
type: array
items:
$ref: "#/components/schemas/SidebarCategoryWithChannels"
Bot:
description: A bot account
type: object
properties:
user_id:
description: The user id of the associated user entry.
type: string
create_at:
description: The time in milliseconds a bot was created
type: integer
format: int64
update_at:
description: The time in milliseconds a bot was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a bot was deleted
type: integer
format: int64
username:
type: string
display_name:
type: string
description:
type: string
owner_id:
description: The user id of the user that currently owns this bot.
type: string
Server_Busy:
type: object
properties:
busy:
description: True if the server is marked as busy (under high load)
type: boolean
expires:
description: timestamp - number of seconds since Jan 1, 1970 UTC.
type: integer
format: int64
GroupWithSchemeAdmin:
description: group augmented with scheme admin information
type: object
properties:
group:
$ref: "#/components/schemas/Group"
scheme_admin:
type: boolean
GroupsAssociatedToChannels:
description: a map of channel id(s) to the set of groups that constrain the corresponding channel in a team
type: object
additionalProperties:
type: array
items:
$ref: "#/components/schemas/GroupWithSchemeAdmin"
OrphanedRecord:
description: an object containing information about an orphaned record.
type: object
properties:
parent_id:
type: string
description: the id of the parent relation (table) entry.
child_id:
type: string
description: the id of the child relation (table) entry.
UserThread:
description: a thread that user is following
type: object
properties:
id:
type: string
description: ID of the post that is this thread's root
reply_count:
type: integer
description: number of replies in this thread
last_reply_at:
type: integer
format: int64
description: timestamp of the last post to this thread
last_viewed_at:
type: integer
format: int64
description: timestamp of the last time the user viewed this thread
participants:
type: array
description: list of users participating in this thread. only includes IDs unless 'extended' was set to 'true'
items:
$ref: "#/components/schemas/User"
post:
$ref: "#/components/schemas/Post"
RelationalIntegrityCheckData:
description: an object containing the results of a relational integrity check.
type: object
properties:
parent_name:
type: string
description: the name of the parent relation (table).
child_name:
type: string
description: the name of the child relation (table).
parent_id_attr:
type: string
description: the name of the attribute (column) containing the parent id.
child_id_attr:
type: string
description: the name of the attribute (column) containing the child id.
records:
description: the list of orphaned records found.
type: array
items:
$ref: "#/components/schemas/OrphanedRecord"
IntegrityCheckResult:
description: an object with the result of the integrity check.
type: object
properties:
data:
$ref: "#/components/schemas/RelationalIntegrityCheckData"
err:
type: string
description: a string value set in case of error.
UploadSession:
description: an object containing information used to keep track of a file upload.
type: object
properties:
id:
description: The unique identifier for the upload.
type: string
type:
description: The type of the upload.
type: string
enum:
- attachment
- import
create_at:
description: The time the upload was created in milliseconds.
type: integer
format: int64
user_id:
description: The ID of the user performing the upload.
type: string
channel_id:
description: The ID of the channel to upload to.
type: string
filename:
description: The name of the file to upload.
type: string
file_size:
description: The size of the file to upload in bytes.
type: integer
format: int64
file_offset:
description: The amount of data uploaded in bytes.
type: integer
format: int64
Notice:
type: object
properties:
id:
description: Notice ID
type: string
sysAdminOnly:
description: Does this notice apply only to sysadmins
type: boolean
teamAdminOnly:
description: Does this notice apply only to team admins
type: boolean
action:
description: "Optional action to perform on action button click. (defaults to closing the notice)"
type: string
actionParam:
description: "Optional action parameter. \nExample: {\"action\": \"url\", actionParam: \"/console/some-page\"}"
type: string
actionText:
description: Optional override for the action button text (defaults to OK)
type: string
description:
description: "Notice content. Use {{Mattermost}} instead of plain text to support white-labeling. Text supports Markdown."
type: string
image:
description: URL of image to display
type: string
title:
description: "Notice title. Use {{Mattermost}} instead of plain text to support white-labeling. Text supports Markdown."
type: string
SharedChannel:
type: object
properties:
id:
description: Channel id of the shared channel
type: string
team_id:
type: string
home:
description: Is this the home cluster for the shared channel
type: boolean
readonly:
description: Is this shared channel shared as read only
type: boolean
name:
description: Channel name as it is shared (may be different than original channel name)
type: string
display_name:
description: Channel display name as it appears locally
type: string
purpose:
type: string
header:
type: string
creator_id:
description: Id of the user that shared the channel
type: string
create_at:
description: Time in milliseconds that the channel was shared
type: integer
update_at:
description: Time in milliseconds that the shared channel record was last updated
type: integer
remote_id:
description: Id of the remote cluster where the shared channel is homed
type: string
RemoteCluster:
type: object
properties:
remote_id:
type: string
remote_team_id:
type: string
name:
type: string
display_name:
type: string
site_url:
description: URL of the remote cluster
type: string
default_team_id:
description: The team where channels from invites are created
type: string
create_at:
description: Time in milliseconds that the remote cluster was created
type: integer
delete_at:
description: Time in milliseconds that the remote cluster record was deleted
type: integer
last_ping_at:
description: Time in milliseconds when the last ping to the remote cluster was run
type: integer
token:
type: string
remote_token:
type: string
topics:
type: string
creator_id:
type: string
plugin_id:
type: string
options:
description: A bitmask with a set of option flags
type: integer
RemoteClusterInfo:
type: object
properties:
display_name:
description: The display name for the remote cluster
type: string
create_at:
description: The time in milliseconds a remote cluster was created
type: integer
format: int64
last_ping_at:
description: The time in milliseconds a remote cluster was last pinged successfully
type: integer
format: int64
SharedChannelRemote:
type: object
properties:
id:
description: The id of the shared channel remote
type: string
channel_id:
description: The id of the channel
type: string
creator_id:
description: Id of the user that invited the remote to share the channel
type: string
create_at:
description: Time in milliseconds that the remote was invited to the channel
type: integer
update_at:
description: Time in milliseconds that the shared channel remote record was last updated
type: integer
delete_at:
description: Time in milliseconds that the shared chanenl remote record was deleted
type: integer
is_invite_accepted:
description: Indicates if the invite has been accepted by the remote
type: boolean
is_invite_confirmed:
description: Indicates if the invite has been confirmed by the remote
type: boolean
remote_id:
description: Id of the remote cluster that the channel is shared with
type: string
last_post_update_at:
description: Time in milliseconds of the last post in the channel that was synchronized with the remote update_at
type: integer
last_post_id:
description: Id of the last post in the channel that was synchronized with the remote
type: string
last_post_create_at:
description: Time in milliseconds of the last post in the channel that was synchronized with the remote create_at
type: string
last_post_create_id:
type: string
SystemStatusResponse:
type: object
properties:
AndroidLatestVersion:
description: Latest Android version supported
type: string
AndroidMinVersion:
description: Minimum Android version supported
type: string
DesktopLatestVersion:
description: Latest desktop version supported
type: string
DesktopMinVersion:
description: Minimum desktop version supported
type: string
IosLatestVersion:
description: Latest iOS version supported
type: string
IosMinVersion:
description: Minimum iOS version supported
type: string
database_status:
description: Status of database ("OK" or "UNHEALTHY"). Included when get_server_status parameter set.
type: string
filestore_status:
description: Status of filestore ("OK" or "UNHEALTHY"). Included when get_server_status parameter set.
type: string
status:
description: Status of server ("OK" or "UNHEALTHY"). Included when get_server_status parameter set.
type: string
CanReceiveNotifications:
description: Whether the device id provided can receive notifications ("true", "false" or "unknown"). Included when device_id parameter set.
type: string
UserThreads:
type: object
properties:
total:
description: Total number of threads (used for paging)
type: integer
threads:
description: Array of threads
type: array
items:
$ref: "#/components/schemas/UserThread"
System:
type: object
properties:
name:
description: System property name
type: string
value:
description: System property value
type: string
PostsUsage:
type: object
properties:
count:
type: number
description: Total no. of posts
StorageUsage:
type: object
properties:
bytes:
type: number
description: Total file storage usage for the instance in bytes rounded down to the most significant digit
BridgeAgentInfo:
type: object
properties:
id:
type: string
description: Unique identifier for the agent
displayName:
type: string
description: Human-readable name for the agent
username:
type: string
description: Username associated with the agent bot
service_id:
type: string
description: ID of the service providing this agent
service_type:
type: string
description: Type of the service (e.g., openai, anthropic)
BridgeServiceInfo:
type: object
properties:
id:
type: string
description: Unique identifier for the LLM service
name:
type: string
description: Name of the LLM service
type:
type: string
description: Type of the service (e.g., openai, anthropic, azure)
AgentsResponse:
type: object
properties:
agents:
type: array
items:
$ref: "#/components/schemas/BridgeAgentInfo"
description: List of available agents
ServicesResponse:
type: object
properties:
services:
type: array
items:
$ref: "#/components/schemas/BridgeServiceInfo"
description: List of available LLM services
AgentsIntegrityResponse:
type: object
properties:
available:
type: boolean
description: Whether the AI plugin bridge is available
reason:
type: string
description: Reason code if not available (translation ID)
AIBridgeTestHelperStatus:
type: object
properties:
available:
type: boolean
description: Whether the mocked AI bridge should be reported as available
reason:
type: string
description: Optional reason code when the mocked AI bridge is unavailable
AIBridgeTestHelperFeatureFlags:
type: object
properties:
enable_ai_plugin_bridge:
type: boolean
description: Override for the EnableAIPluginBridge feature flag in test mode
enable_ai_recaps:
type: boolean
description: Override for the EnableAIRecaps feature flag in test mode
AIBridgeTestHelperCompletion:
type: object
properties:
completion:
type: string
description: Mocked completion payload returned for a queued bridge operation
error:
type: string
description: Mocked error message returned for a queued bridge operation
status_code:
type: integer
description: Optional HTTP-style status code associated with a mocked error
AIBridgeTestHelperMessage:
type: object
properties:
role:
type: string
description: Role associated with the message payload
message:
type: string
description: Message content sent through the AI bridge
file_ids:
type: array
description: Optional file IDs attached to the bridge message
items:
type: string
AIBridgeTestHelperConfig:
type: object
properties:
status:
$ref: "#/components/schemas/AIBridgeTestHelperStatus"
agents:
type: array
items:
$ref: "#/components/schemas/BridgeAgentInfo"
description: Mock agent list returned from the bridge
services:
type: array
items:
$ref: "#/components/schemas/BridgeServiceInfo"
description: Mock service list returned from the bridge
agent_completions:
type: object
description: Queued mocked completion responses keyed by explicit bridge operation name
additionalProperties:
type: array
items:
$ref: "#/components/schemas/AIBridgeTestHelperCompletion"
feature_flags:
$ref: "#/components/schemas/AIBridgeTestHelperFeatureFlags"
record_requests:
type: boolean
description: Whether bridge requests should be recorded for later inspection
AIBridgeTestHelperRecordedRequest:
type: object
properties:
operation:
type: string
description: Explicit bridge operation key such as recap_summary or rewrite
client_operation:
type: string
description: Client-facing operation routed through the bridge client
operation_sub_type:
type: string
description: Optional subtype used to disambiguate bridge requests
session_user_id:
type: string
description: Session user ID used when invoking the bridge
user_id:
type: string
description: Optional effective user ID passed through the bridge request
channel_id:
type: string
description: Optional channel context passed through the bridge request
agent_id:
type: string
description: Agent ID targeted by the bridge completion request
service_id:
type: string
description: Service ID targeted by the bridge completion request
messages:
type: array
items:
$ref: "#/components/schemas/AIBridgeTestHelperMessage"
description: Bridge messages sent for the recorded request
json_output_format:
type: object
description: Optional JSON schema requested for structured bridge output
additionalProperties: true
AIBridgeTestHelperState:
type: object
properties:
status:
$ref: "#/components/schemas/AIBridgeTestHelperStatus"
agents:
type: array
items:
$ref: "#/components/schemas/BridgeAgentInfo"
description: Current mocked agent list
services:
type: array
items:
$ref: "#/components/schemas/BridgeServiceInfo"
description: Current mocked service list
agent_completions:
type: object
description: Remaining queued mocked completions keyed by bridge operation
additionalProperties:
type: array
items:
$ref: "#/components/schemas/AIBridgeTestHelperCompletion"
feature_flags:
$ref: "#/components/schemas/AIBridgeTestHelperFeatureFlags"
record_requests:
type: boolean
description: Whether bridge request recording is currently enabled
recorded_requests:
type: array
description: Recorded bridge requests captured while record_requests was enabled
items:
$ref: "#/components/schemas/AIBridgeTestHelperRecordedRequest"
PostAcknowledgement:
type: object
properties:
user_id:
description: The ID of the user that made this acknowledgement.
type: string
post_id:
description: The ID of the post to which this acknowledgement was made.
type: string
acknowledged_at:
description: The time in milliseconds in which this acknowledgement was made.
type: integer
format: int64
AllowedIPRange:
type: object
properties:
CIDRBlock:
description: An IP address range in CIDR notation
type: string
Description:
description: A description for the CIDRBlock
type: string
UserReport:
type: object
properties:
id:
type: string
create_at:
description: The time in milliseconds a user was created
type: integer
format: int64
update_at:
description: The time in milliseconds a user was last updated
type: integer
format: int64
delete_at:
description: The time in milliseconds a user was deleted
type: integer
format: int64
username:
type: string
auth_data:
type: string
auth_service:
type: string
email:
type: string
nickname:
type: string
first_name:
type: string
last_name:
type: string
position:
type: string
roles:
type: string
locale:
type: string
timezone:
$ref: "#/components/schemas/Timezone"
disable_welcome_email:
type: boolean
last_login:
description: Last time the user was logged in
type: integer
format: int64
last_status_at:
description: Last time the user's status was updated
type: integer
format: int64
last_post_date:
description: Last time the user made a post within the given date range
type: integer
format: int64
days_active:
description: Total number of days a user posted within the given date range
type: integer
total_posts:
description: Total number of posts made by a user within the given date range
type: integer
Installation:
type: object
properties:
id:
description: A unique identifier
type: string
allowed_ip_ranges:
$ref: "#/components/schemas/AllowedIPRange"
state:
description: The current state of the installation
type: string
MessageDescriptor:
type: object
properties:
id:
description: The i18n message ID
type: string
defaultMessage:
description: The default message text
type: string
values:
description: Optional values for message interpolation
type: object
additionalProperties: true
PreviewModalContentData:
type: object
properties:
skuLabel:
$ref: "#/components/schemas/MessageDescriptor"
title:
$ref: "#/components/schemas/MessageDescriptor"
subtitle:
$ref: "#/components/schemas/MessageDescriptor"
videoUrl:
description: URL of the video content
type: string
videoPoster:
description: URL of the video poster/thumbnail image
type: string
useCase:
description: The use case category for this content
type: string
ServerLimits:
type: object
properties:
maxUsersLimit:
description: The maximum number of users allowed on server
type: integer
format: int64
activeUserCount:
description: The number of active users in the server
type: integer
format: int64
# Outgoing OAuth Connections
OutgoingOAuthConnectionGetItem:
type: object
properties:
id:
description: The unique identifier for the outgoing OAuth connection.
type: string
name:
description: The name of the outgoing OAuth connection.
type: string
create_at:
description: The time in milliseconds the outgoing OAuth connection was created.
type: integer
format: int64
update_at:
description: The time in milliseconds the outgoing OAuth connection was last updated.
type: integer
format: int64
grant_type:
description: The grant type of the outgoing OAuth connection.
type: string
audiences:
description: The audiences of the outgoing OAuth connection.
type: string
OutgoingOAuthConnectionPostItem:
type: object
properties:
name:
description: The name of the outgoing OAuth connection.
type: string
client_id:
description: The client ID of the outgoing OAuth connection.
type: string
client_secret:
description: The client secret of the outgoing OAuth connection.
type: string
credentials_username:
description: The username of the credentials of the outgoing OAuth connection.
type: string
credentials_password:
description: The password of the credentials of the outgoing OAuth connection.
type: string
oauth_token_url:
description: The OAuth token URL of the outgoing OAuth connection.
type: string
grant_type:
description: The grant type of the outgoing OAuth connection.
type: string
audiences:
description: The audiences of the outgoing OAuth connection.
type: string
ScheduledPost:
type: object
properties:
id:
type: string
create_at:
description: The time in milliseconds a scheduled post was created
type: integer
format: int64
update_at:
description: The time in milliseconds a scheduled post was last updated
type: integer
format: int64
user_id:
type: string
channel_id:
type: string
root_id:
type: string
message:
type: string
props:
type: object
file_ids:
type: array
items:
type: string
scheduled_at:
description: The time in milliseconds a scheduled post is scheduled to be sent at
type: integer
format: int64
processed_at:
description: The time in milliseconds a scheduled post was processed at
type: integer
format: int64
error_code:
type: string
description: Explains the error behind why a scheduled post could not have been sent
metadata:
$ref: "#/components/schemas/PostMetadata"
AccessControlFieldsAutocompleteResponse:
type: object
properties:
fields:
type: array
items:
type: object
properties:
name:
type: string
description: The name of the field.
description:
type: string
description: A description of the field.
AccessControlPoliciesWithCount:
type: object
properties:
policies:
type: array
items:
$ref: "#/components/schemas/AccessControlPolicy"
total_count:
type: integer
description: The total number of policies.
AccessControlPolicy:
type: object
properties:
id:
type: string
description: The unique identifier of the policy.
name:
type: string
description: The unique name for the policy.
display_name:
type: string
description: The human-readable name for the policy.
description:
type: string
description: A description of the policy.
expression:
type: string
description: The CEL expression defining the policy rules.
is_active:
type: boolean
description: Whether the policy is currently active and enforced.
create_at:
type: integer
format: int64
description: The time in milliseconds the policy was created.
update_at:
type: integer
format: int64
description: The time in milliseconds the policy was last updated.
delete_at:
type: integer
format: int64
description: The time in milliseconds the policy was deleted.
AccessControlPolicySearch:
type: object
properties:
term:
type: string
description: The search term to match against policy names or display names.
type:
type: string
description: The type of policy (e.g., 'parent' or 'channel').
parent_id:
type: string
description: The ID of the parent policy to search within.
ids:
type: array
items:
type: string
description: List of policy IDs to filter by.
active:
type: boolean
description: Filter policies by active status.
include_children:
type: boolean
description: Whether to include child policies in the result.
cursor:
$ref: "#/components/schemas/AccessControlPolicyCursor"
limit:
type: integer
description: The maximum number of policies to return.
AccessControlPolicyCursor:
type: object
properties:
id:
type: string
description: The ID of the policy to start searching after.
AccessControlPolicyTestResponse:
type: object
properties:
users:
type: array
items:
$ref: "#/components/schemas/User"
description: A list of users affected by the policy expression.
total_count:
type: integer
description: The total number of users affected.
PolicySimulationUserOverride:
type: object
description: |
Per-user payload for the picker-driven `/cel/simulate_users` endpoint.
The simulator resolves each user's profile attributes from CPA storage
and then layers session context on top: first the requesting admin's
active-session snapshot (when `use_active_session` is true), then the
explicit `session_overrides` map.
required:
- user_id
properties:
user_id:
type: string
description: ID of the user to evaluate the draft policy against.
use_active_session:
type: boolean
description: |
When true, inject the requesting admin's `session.*` attributes
(network_status, device_managed, ip_range, etc.) into this user's
evaluation context. Forward-compatible with future PDP work that
populates session attributes on the request context.
session_overrides:
type: object
additionalProperties:
type: string
description: |
Replaces individual `session.*` attributes for this user only.
Applied on top of the active-session snapshot when both are set,
so a "configure session" panel can shadow specific values without
discarding the rest of the active session.
PolicySimulationByUsersParams:
type: object
description: |
Request body for `/access_control_policies/cel/simulate_users`. The
draft policy is compiled in-memory only — nothing is persisted.
required:
- policy
- actions
- users
properties:
policy:
$ref: "#/components/schemas/AccessControlPolicy"
actions:
type: array
minItems: 1
items:
type: string
description: |
Permission actions to simulate (e.g. `upload_file_attachment`,
`download_file_attachment`). At least one action is required —
the picker UX only makes sense once an action is in scope. The
backend rejects empty arrays with `app.pap.simulate.missing_actions`
(HTTP 400); `minItems` lets OpenAPI tooling catch that earlier
on the client.
rule_name:
type: string
description: |
Identifies which rule in `policy.rules` the author is editing
(used for blame attribution). When set, denies originating from
this rule are tagged `source=this_rule`; other denies in the same
draft are tagged `source=sibling_rule`.
channel_id:
type: string
description: |
Provides resource context for delegated channel admins and for
resource-lane evaluation when `policy.type == "channel"`.
team_id:
type: string
description: Provides team context for team-level delegated admins.
users:
type: array
minItems: 1
items:
$ref: "#/components/schemas/PolicySimulationUserOverride"
description: |
Explicit user list to evaluate, with per-user session-attribute
overrides. At least one user is required (the backend rejects
empty arrays with `app.pap.simulate.missing_users`).
evaluation_scope:
type: string
enum: [all, this_rule]
description: |
Selects whether the simulator considers only the rule under
simulation (`this_rule`) or co-evaluates every contributing
program (`all`). Empty defaults to `this_rule` on the server.
`this_rule` is the authoring-time "what does this rule alone
do?" view: useful for iterating on a single rule without
sibling rules shadowing or compensating for it. `all` mirrors
the live PDP at request time.
PolicySimulationBlame:
type: object
description: |
Attributes a deny decision back to the rule or policy that caused it.
properties:
source:
type: string
enum:
- this_rule
- sibling_rule
- sibling_saved
- peer_policy
- system_permission
- channel_policy
- no_applicable_policy
description: |
Origin of the blamed contribution.
* `this_rule` — the rule the author is currently editing.
* `sibling_rule` — another rule in the same draft policy.
* `sibling_saved` — recorded on ALLOW decisions where the
author's own rule alone would have denied; a sibling rule
flipped the verdict.
* `peer_policy` — a different policy at the SAME scope as the
draft. Carries `expression` / `evaluation_tree`.
* `system_permission` — a higher-scoped system permission policy.
Expression / tree are stripped to avoid leaking the contents
of policies outside the editing scope.
* `channel_policy` — a higher-scoped channel policy. Same
privacy stripping as `system_permission`.
* `no_applicable_policy` — no policy at any scope contributed a
decision (vacuous allow).
outcome:
type: string
enum:
- deny
- allow
description: |
Per-blame verdict. Most blame entries describe the deny that
produced the overall decision (`deny`); the simulator also
emits informational `allow` entries so the picker can show
"your draft rule allowed this user" alongside any peer
policies that actually caused the deny. Consumers that only
care about deny attribution should filter to `deny`. Empty
(omitted) is treated as `deny` for backward compatibility
with simulator builds that pre-date this field.
policy_id:
type: string
description: |
ID of the contributing policy. Empty when the deny originated
from the draft itself (no persisted ID exists yet).
policy_name:
type: string
description: Human-readable name of the contributing policy.
rule_name:
type: string
description: Name of the contributing rule.
role:
type: string
description: |
Scoped role (`system_admin` / `system_user` / `channel_admin` /
…) the contributing rule targets. Useful for explaining
role-chain fallbacks.
expression:
type: string
description: |
CEL text of the contributing rule. Only populated for blame
entries at the draft's own scope (`this_rule`, `sibling_rule`,
`sibling_saved`, `peer_policy`).
evaluation_tree:
type: object
description: |
Recursive per-node breakdown of the contributing rule, mirroring
the boolean shape of the CEL expression's AST. Same scope-privacy
rule as `expression`. The picker renders it as a structured
AND/OR/NOT tree highlighting which sub-expression(s) drove the
deny.
PolicySimulationActionDecision:
type: object
description: Per-action verdict for one user (or one session).
properties:
decision:
type: boolean
description: |
`true` means ALLOW, `false` means DENY. Pending evaluations
(rare) surface as `false` paired with an empty `blame` array.
blame:
type: array
items:
$ref: "#/components/schemas/PolicySimulationBlame"
description: |
Ordered blame entries for the decision. The first entry is the
primary blame (what the picker renders on the chip); subsequent
entries describe other contributing policies the user can drill
into via the "Decision details" view.
PolicySimulationSession:
type: object
description: Per-session verdict for one user.
properties:
device:
type: string
network:
type: string
last_active_at:
type: integer
format: int64
description: Last-active timestamp in milliseconds since epoch.
decisions:
type: object
additionalProperties:
$ref: "#/components/schemas/PolicySimulationActionDecision"
description: Per-action verdicts for this specific session.
attributes:
type: object
additionalProperties:
type: string
description: |
Session-attribute snapshot used when evaluating this session
(network_status, device_managed, ip_range, etc.). Surfaced in
the per-row "Decision details" view.
PolicySimulationUserResult:
type: object
properties:
user:
$ref: "#/components/schemas/User"
decisions:
type: object
additionalProperties:
$ref: "#/components/schemas/PolicySimulationActionDecision"
description: |
Per-action verdicts for the user. When `sessions` is populated
this represents the "headline" decision (e.g. from the
most-recently-active session) so the picker can render a
single chip without consulting `sessions`.
sessions:
type: array
items:
$ref: "#/components/schemas/PolicySimulationSession"
description: |
Optional per-session breakdown. When populated the picker
renders a Recent activity expand row revealing one decision
chip per session. Empty/undefined falls back to a single
user-level chip.
attributes:
type: object
additionalProperties:
type: string
description: |
User profile attribute snapshot used when evaluating this user
(department, region, clearance, etc.).
PolicySimulationResponse:
type: object
description: |
Body returned by `/cel/simulate_users`. Per-user, per-action
verdicts plus blame attribution for any deny.
properties:
results:
type: array
items:
$ref: "#/components/schemas/PolicySimulationUserResult"
total:
type: integer
format: int64
description: |
Total number of users evaluated (matches `results.length` for
the picker endpoint since the caller supplies the user list
explicitly).
ChannelSearch: # Added based on dataretention.yaml and access_control.go usage
type: object
properties:
term:
type: string
description: The string to search in the channel name, display name, and purpose.
team_ids:
type: array
items:
type: string
description: Filters results to channels belonging to the given team ids.
public:
type: boolean
description: Filters results to only return Public / Open channels.
private:
type: boolean
description: Filters results to only return Private channels.
deleted:
type: boolean
description: Filters results to only return deleted / archived channels.
include_deleted:
type: boolean
description: Whether to include deleted channels in the search results.
# Add other potential search fields like not_associated_to_group, exclude_default_channels etc.
ChannelsWithCount: # Added based on access_control.go usage
type: object
properties:
channels:
$ref: "#/components/schemas/ChannelListWithTeamData" # Referencing existing type used in similar contexts
total_count:
type: integer
description: The total number of channels.
ExpressionError:
type: object
properties:
message:
type: string
description: The error message.
field:
type: string
description: The field related to the error, if applicable.
line:
type: integer
description: The line number where the error occurred in the expression.
column:
type: integer
description: The column number where the error occurred in the expression.
QueryExpressionParams:
type: object
properties:
expression:
type: string
description: The policy expression to test.
term:
type: string
description: A search term to filter users against whom the expression is tested.
limit:
type: integer
description: The maximum number of users to return.
after:
type: string
description: The ID of the user to start the test after (for pagination).
channelId:
type: string
description: The channel ID to contextually test the expression against (required for channel admins).
CELExpression:
type: object
properties:
expression:
type: string
description: The CEL expression to visualize.
channelId:
type: string
description: The channel ID to contextually test the expression against (required for channel admins).
VisualExpression:
type: object
properties:
conditions:
type: array
items:
$ref: "#/components/schemas/Condition"
description: The visual AST for the CEL expression
Condition:
type: object
properties:
attribute:
type: string
description: The attribute name.
operator:
type: string
description: The operator of a single condition.
value:
type: string
description: The value.
value_type:
type: string
description: The value type.
ChannelBanner:
type: object
properties:
enabled:
type: boolean
description: enabled indicates whether the channel banner is enabled or not
text:
type: string
description: text is the actual text that renders in the channel banner. Markdown is supported.
background_color:
type: string
description: background_color is the HEX color code for the banner's background
ContentFlaggingConfig:
type: object
properties:
EnableContentFlagging:
type: boolean
description: Flag to enable or disable content flagging feature
example: true
NotificationSettings:
$ref: '#/components/schemas/NotificationSettings'
AdditionalSettings:
$ref: '#/components/schemas/AdditionalSettings'
ReviewerSettings:
$ref: '#/components/schemas/ReviewerSettings'
NotificationSettings:
type: object
properties:
EventTargetMapping:
$ref: '#/components/schemas/EventTargetMapping'
required:
- EventTargetMapping
EventTargetMapping:
type: object
properties:
assigned:
type: array
items:
type: string
description: List of targets to notify when content is assigned
example: [ ]
dismissed:
type: array
items:
type: string
description: List of targets to notify when content is dismissed
example: [ ]
flagged:
type: array
items:
type: string
description: List of targets to notify when content is flagged
example: [ "reviewers" ]
removed:
type: array
items:
type: string
description: List of targets to notify when content is removed
example: [ ]
required:
- assigned
- dismissed
- flagged
- removed
AdditionalSettings:
type: object
properties:
Reasons:
type: array
items:
type: string
description: Predefined reasons for flagging content
example: [ "reason 1", "reason 2", "reason 3" ]
ReporterCommentRequired:
type: boolean
description: Whether a comment is required from the reporter
example: false
ReviewerCommentRequired:
type: boolean
description: Whether a comment is required from the reviewer
example: false
HideFlaggedContent:
type: boolean
description: Whether to hide flagged content from general view
example: true
required:
- Reasons
- ReporterCommentRequired
- ReviewerCommentRequired
- HideFlaggedContent
ReviewerSettings:
type: object
properties:
CommonReviewers:
type: boolean
description: Whether to use common reviewers across all teams
example: true
SystemAdminsAsReviewers:
type: boolean
description: Whether system administrators can act as reviewers
example: false
TeamAdminsAsReviewers:
type: boolean
description: Whether team administrators can act as reviewers
example: true
CommonReviewerIds:
type: array
items:
type: string
description: List of user IDs designated as common reviewers
example: [ "onymzj7qcjnz7dcnhtjp1noc3w" ]
TeamReviewersSetting:
type: object
additionalProperties:
$ref: '#/components/schemas/TeamReviewerConfig'
description: Team-specific reviewer configuration, keyed by team ID
example:
"8guxic3sg7nijeu5dgxt1fh4ia":
Enabled: true
ReviewerIds: [ ]
"u1ujk34a47gfxp856pdczs9gey":
Enabled: false
ReviewerIds: [ ]
required:
- CommonReviewers
- SystemAdminsAsReviewers
- TeamAdminsAsReviewers
- CommonReviewerIds
- TeamReviewersSetting
TeamReviewerConfig:
type: object
properties:
Enabled:
type: boolean
description: Whether team-specific reviewers are enabled for this team
example: true
ReviewerIds:
type: array
items:
type: string
description: List of user IDs designated as reviewers for this specific team
example: [ ]
required:
- Enabled
- ReviewerIds
AccessControlPolicyActiveUpdateRequest:
type: object
properties:
entries:
type: array
items:
$ref: "#/components/schemas/AccessControlPolicyActiveUpdate"
AccessControlPolicyActiveUpdate:
type: object
properties:
id:
type: string
description: The ID of the policy.
active:
type: boolean
description: The active status of the policy.
Recap:
type: object
properties:
id:
type: string
description: Unique identifier for the recap
user_id:
type: string
description: ID of the user who created the recap
title:
type: string
description: AI-generated title for the recap (max 5 words)
create_at:
type: integer
format: int64
description: The time in milliseconds the recap was created
update_at:
type: integer
format: int64
description: The time in milliseconds the recap was last updated
delete_at:
type: integer
format: int64
description: The time in milliseconds the recap was deleted
read_at:
type: integer
format: int64
description: The time in milliseconds the recap was marked as read
viewed_at:
type: integer
format: int64
description: The time in milliseconds the recap was marked as viewed (set in bulk when the recaps page is opened)
total_message_count:
type: integer
description: Total number of messages summarized across all channels
status:
type: string
enum: [pending, processing, completed, failed]
description: Current status of the recap job
bot_id:
type: string
description: ID of the AI agent/bot used to generate this recap
channels:
type: array
items:
$ref: "#/components/schemas/RecapChannel"
description: List of channel summaries included in this recap
RecapChannel:
type: object
properties:
id:
type: string
description: Unique identifier for the recap channel
recap_id:
type: string
description: ID of the parent recap
channel_id:
type: string
description: ID of the channel that was summarized
channel_name:
type: string
description: Display name of the channel
highlights:
type: array
items:
type: string
description: Key discussion points and important information from the channel
action_items:
type: array
items:
type: string
description: Tasks, todos, and action items mentioned in the channel
source_post_ids:
type: array
items:
type: string
description: IDs of the posts used to generate this summary
create_at:
type: integer
format: int64
description: The time in milliseconds the recap channel was created
RecapLimitStatus:
type: object
description: The current user's recap limit status including usage and cooldown information
properties:
effective_limits:
$ref: "#/components/schemas/EffectiveRecapLimits"
daily:
$ref: "#/components/schemas/DailyUsageStatus"
cooldown:
$ref: "#/components/schemas/CooldownStatus"
EffectiveRecapLimits:
type: object
description: Resolved recap limit values for a user. A value of -1 means the limit is disabled/unlimited.
properties:
max_recaps_per_day:
type: integer
description: Maximum number of recaps the user can create per day (-1 = unlimited)
max_scheduled_recaps:
type: integer
description: Maximum number of scheduled recaps (-1 = unlimited)
max_channels_per_recap:
type: integer
description: Maximum number of channels per recap (-1 = unlimited)
max_posts_per_recap:
type: integer
description: Maximum number of posts per recap (-1 = unlimited)
max_tokens_per_recap:
type: integer
description: Maximum number of tokens per recap (-1 = unlimited)
max_posts_per_day:
type: integer
description: Maximum number of posts that can be processed per day (-1 = unlimited)
cooldown_minutes:
type: integer
description: Cooldown period in minutes between recap creations (-1 = no cooldown)
source:
type: string
enum: [system, group, user]
description: Where the effective limits originated from
source_id:
type: string
description: Group ID or User ID if overridden, empty for system defaults
DailyUsageStatus:
type: object
description: Daily recap usage tracking
properties:
used:
type: integer
description: Number of recaps used today
limit:
type: integer
description: Maximum recaps allowed per day
reset_at:
type: integer
format: int64
description: Unix timestamp in milliseconds when daily usage resets
CooldownStatus:
type: object
description: Cooldown state for recap creation
properties:
is_active:
type: boolean
description: Whether the cooldown is currently active
available_at:
type: integer
format: int64
description: Unix timestamp in milliseconds when cooldown ends
retry_after_seconds:
type: integer
description: Seconds until recap creation is available again
ScheduledRecap:
type: object
properties:
id:
type: string
description: Unique identifier for the scheduled recap
user_id:
type: string
description: The ID of the user who owns this scheduled recap
title:
type: string
description: Title for the scheduled recap
maxLength: 255
days_of_week:
type: integer
description: >
Bitmask for days of the week the recap should run.
Sun=1, Mon=2, Tue=4, Wed=8, Thu=16, Fri=32, Sat=64.
minimum: 1
maximum: 127
time_of_day:
type: string
description: Time of day in HH:MM format (e.g., "09:00")
timezone:
type: string
description: IANA timezone (e.g., "America/New_York")
time_period:
type: string
description: The lookback period for the recap content
enum:
- last_24h
- last_week
- since_last_read
next_run_at:
type: integer
format: int64
description: The next scheduled execution time in UTC milliseconds
last_run_at:
type: integer
format: int64
description: The last execution time in UTC milliseconds
run_count:
type: integer
description: Number of times this schedule has executed
channel_mode:
type: string
description: How channels are selected for the recap
enum:
- specific
- all_unreads
channel_ids:
type: array
items:
type: string
description: List of channel IDs to include (when channel_mode is "specific")
custom_instructions:
type: string
description: Custom AI instructions for the recap
agent_id:
type: string
description: ID of the AI agent to use for generating the recap
is_recurring:
type: boolean
description: Whether the recap runs on a recurring schedule or just once
enabled:
type: boolean
description: Whether the scheduled recap is active (false when paused)
create_at:
type: integer
format: int64
description: The time in milliseconds the scheduled recap was created
update_at:
type: integer
format: int64
description: The time in milliseconds the scheduled recap was last updated
delete_at:
type: integer
format: int64
description: The time in milliseconds the scheduled recap was soft-deleted (0 if not deleted)
externalDocs:
description: Find out more about Mattermost
url: 'https://about.mattermost.com'
security:
- bearerAuth: []