{
  "generatedFor": "https://getmarula.com",
  "products": [
    {
      "product": "psa",
      "label": "Marula PSA",
      "repo": "marulahq/marula-core",
      "path": "docs/site",
      "license": "CC-BY-4.0",
      "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
      "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site",
      "versions": [
        {
          "slug": "v0.3",
          "label": "v0.3",
          "ref": "v0.3.1",
          "commit": "146720475bd91738105c2e3454844cdd7b9eb05a",
          "channel": "current",
          "route": "/docs/psa/v0.3",
          "llms": "/docs/psa/v0.3/llms.txt",
          "llmsFull": "/docs/psa/v0.3/llms-full.txt",
          "openapi": "/docs/psa/v0.3/openapi.json"
        },
        {
          "slug": "v0.2",
          "label": "v0.2",
          "ref": "v0.2.0",
          "commit": "ee7dfd3e239fc48aa2d1c3874dd8e41059305037",
          "channel": "archived",
          "route": "/docs/psa/v0.2",
          "llms": "/docs/psa/v0.2/llms.txt",
          "llmsFull": "/docs/psa/v0.2/llms-full.txt",
          "openapi": "/docs/psa/v0.2/openapi.json"
        },
        {
          "slug": "next",
          "label": "Next",
          "ref": "main",
          "commit": "ebe78dc92d2b4e5f75bfd6f5cfdd37f469bd6dea",
          "channel": "next",
          "route": "/docs/psa/next",
          "llms": "/docs/psa/next/llms.txt",
          "llmsFull": "/docs/psa/next/llms-full.txt",
          "openapi": "/docs/psa/next/openapi.json"
        }
      ],
      "pages": [
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3",
          "file": "psa/v0.3.md",
          "sourcePath": "index.md",
          "title": "Marula documentation",
          "description": "Marula is an open-source PSA (professional services automation) platform for IT service teams and MSPs.",
          "section": "Home",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/index.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/start",
          "file": "psa/v0.3/start.md",
          "sourcePath": "start/index.md",
          "title": "Start here",
          "description": "Pick the row that matches your job. Each page lists tasks in the words people actually use (\"a customer cannot log in\", \"I need to close the month\") and…",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/index.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/start/owners",
          "file": "psa/v0.3/start/owners.md",
          "sourcePath": "start/owners.md",
          "title": "Owner tasks",
          "description": "You are accountable for the numbers and for who can see what. These are the jobs that land on your desk, in the order they usually arrive.",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/owners.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/start/admins",
          "file": "psa/v0.3/start/admins.md",
          "sourcePath": "start/admins.md",
          "title": "Admin tasks",
          "description": "Most of this work happens once, at the start, and then twice a year. The list is grouped by the job rather than by the settings menu, because the menu moves…",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/admins.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/start/technicians",
          "file": "psa/v0.3/start/technicians.md",
          "sourcePath": "start/technicians.md",
          "title": "Technician tasks",
          "description": "The technician's path through Marula: work the queue, run a service day, log billable time and answer the customer.",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/technicians.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/start/operators",
          "file": "psa/v0.3/start/operators.md",
          "sourcePath": "start/operators.md",
          "title": "Operator tasks",
          "description": "You are not the workspace admin. Admins configure boards, email routing and people.",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/operators.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/start/agents",
          "file": "psa/v0.3/start/agents.md",
          "sourcePath": "start/agents.md",
          "title": "Agent and automation tasks",
          "description": "Marula separates three things that are easy to blur: what an agent may do (grants), what it did (provenance and audit), and what the platform exposes (API…",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/agents.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to",
          "file": "psa/v0.3/how-to.md",
          "sourcePath": "how-to/index.md",
          "title": "Admin how-to guides",
          "description": "Each how-to guide gives you a direct checklist for one specific job in Marula. If you are brand new and want a guided walkthrough from start to finish…",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/index.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/tutorials",
          "file": "psa/v0.3/tutorials.md",
          "sourcePath": "tutorials/index.md",
          "title": "Tutorials",
          "description": "Each tutorial walks you through one real job from start to finish using the sample organization that ships with Marula.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/index.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/tutorials/first-ticket",
          "file": "psa/v0.3/tutorials/first-ticket.md",
          "sourcePath": "tutorials/first-ticket.md",
          "title": "Tutorial: your first ticket (in the UI)",
          "description": "When a client calls or emails with a problem, you shouldn't have to bounce between a ticket tab, a separate stopwatch popup, and a timecard sheet at 5 PM.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-ticket.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/tutorials/first-invoice",
          "file": "psa/v0.3/tutorials/first-invoice.md",
          "sourcePath": "tutorials/first-invoice.md",
          "title": "Tutorial: your first invoice",
          "description": "Walk the invoice cycle end to end in the demo organization, from billable time to a sent invoice.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-invoice.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/tutorials/first-inventory-sync",
          "file": "psa/v0.3/tutorials/first-inventory-sync.md",
          "sourcePath": "tutorials/first-inventory-sync.md",
          "title": "Tutorial: your first inventory sync",
          "description": "When you pull computers and network gear from an RMM tool, an MDM, and a spreadsheet, most PSAs dump duplicate rows into your asset list and leave techs…",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-inventory-sync.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/tutorials/first-agent-run",
          "file": "psa/v0.3/tutorials/first-agent-run.md",
          "sourcePath": "tutorials/first-agent-run.md",
          "title": "Tutorial: your first agent run",
          "description": "In many tools, turning on AI means letting a bot rewrite tickets or email clients behind your back.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-agent-run.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/tutorials/portal-onboarding",
          "file": "psa/v0.3/tutorials/portal-onboarding.md",
          "sourcePath": "tutorials/portal-onboarding.md",
          "title": "Tutorial: portal onboarding",
          "description": "Your clients shouldn't have to email your helpdesk just to check if a ticket is being worked on, download last month's invoice, or approve a hardware quote.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/portal-onboarding.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/tutorials/first-ticket-api",
          "file": "psa/v0.3/tutorials/first-ticket-api.md",
          "sourcePath": "tutorials/first-ticket-api.md",
          "title": "Tutorial: your first ticket",
          "description": "If you prefer exploring a system from the terminal or want to build an integration script, this tutorial walks through the exact same workflow as Your first…",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-ticket-api.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-org-bootstrap",
          "file": "psa/v0.3/how-to/admin-org-bootstrap.md",
          "sourcePath": "how-to/admin-org-bootstrap.md",
          "title": "How to bootstrap your first organization",
          "description": "When you launch a fresh Marula install, you create your organization and first administrator account right from the sign-in screen.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-org-bootstrap.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-users-invites",
          "file": "psa/v0.3/how-to/admin-users-invites.md",
          "sourcePath": "how-to/admin-users-invites.md",
          "title": "How to manage users and invites",
          "description": "Instead of creating temporary passwords and reading them over the phone, you invite teammates from Settings → Team.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-users-invites.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-sso",
          "file": "psa/v0.3/how-to/admin-sso.md",
          "sourcePath": "how-to/admin-sso.md",
          "title": "How to connect an IdP (SSO)",
          "description": "Single Sign-On (SSO) lets your staff sign in to Marula through your company's identity provider (such as Google Workspace, Microsoft Entra ID, Okta, or…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-sso.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-email",
          "file": "psa/v0.3/how-to/admin-email.md",
          "sourcePath": "how-to/admin-email.md",
          "title": "How to configure email",
          "description": "This page covers three jobs in order: routing inbound mail to boards, proving your domain with DNS, and choosing how outbound mail leaves.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-email.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-sla-calendars",
          "file": "psa/v0.3/how-to/admin-sla-calendars.md",
          "sourcePath": "how-to/admin-sla-calendars.md",
          "title": "How to configure SLA calendars & escalation ladders",
          "description": "When a client has an agreement for a 2-hour response on urgent tickets, you don't want the SLA clock ticking at 3 AM on a Sunday unless they pay for 24/7…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-sla-calendars.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-workflow-categories",
          "file": "psa/v0.3/how-to/admin-workflow-categories.md",
          "sourcePath": "how-to/admin-workflow-categories.md",
          "title": "How to set workflow categories",
          "description": "In many ticketing tools, renaming a board column from \"Waiting on Vendor\" to \"Parts Ordered\" breaks every SLA rule, report filter, and billing script that…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-workflow-categories.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-automation-rules",
          "file": "psa/v0.3/how-to/admin-automation-rules.md",
          "sourcePath": "how-to/admin-automation-rules.md",
          "title": "How to author automation rules",
          "description": "Automation rules let your service desk handle repetitive routing and follow-ups automatically: for example, alerting a manager when a P1 ticket arrives…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-automation-rules.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-labels",
          "file": "psa/v0.3/how-to/admin-labels.md",
          "sourcePath": "how-to/admin-labels.md",
          "title": "How to set up labels and label templates",
          "description": "A template is typed by PURPOSE, and the purpose decides which fields it can print and what its QR code points at. Four purposes ship:",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-labels.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-imports",
          "file": "psa/v0.3/how-to/admin-imports.md",
          "sourcePath": "how-to/admin-imports.md",
          "title": "How to run a dry-run import",
          "description": "Moving clients, contacts, tickets, or hardware assets from a legacy PSA or spreadsheet shouldn't be a blind leap of faith.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-imports.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-dashboards-reports",
          "file": "psa/v0.3/how-to/admin-dashboards-reports.md",
          "sourcePath": "how-to/admin-dashboards-reports.md",
          "title": "How to manage dashboards & report schedules",
          "description": "Marula gives service leads and owners three ways to track how the shop is running: live Dashboards (/reports/dashboards), a custom Report Builder…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-dashboards-reports.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-csat-surveys",
          "file": "psa/v0.3/how-to/admin-csat-surveys.md",
          "sourcePath": "how-to/admin-csat-surveys.md",
          "title": "How to set up CSAT surveys on resolution",
          "description": "Set up satisfaction surveys on ticket resolution, with intervals, link validity and quiet hours.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-csat-surveys.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-toolboxes",
          "file": "psa/v0.3/how-to/admin-toolboxes.md",
          "sourcePath": "how-to/admin-toolboxes.md",
          "title": "How to set up toolboxes and dispatch defaults",
          "description": "Settings → Toolboxes & day pack is the config home for toolboxes. It holds the kits themselves, the tools inside them, the mappings the day pack reads, and…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-toolboxes.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-reply-snippets",
          "file": "psa/v0.3/how-to/admin-reply-snippets.md",
          "sourcePath": "how-to/admin-reply-snippets.md",
          "title": "How to use reply snippets",
          "description": "A reply snippet is a canned reply your team writes once and inserts everywhere. Open the composer on any ticket, press Snippets, and pick one.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-reply-snippets.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-purchasing",
          "file": "psa/v0.3/how-to/admin-purchasing.md",
          "sourcePath": "how-to/admin-purchasing.md",
          "title": "How to buy: vendors, purchase orders, receiving, bills",
          "description": "Purchasing lives at Purchasing (/purchasing). A purchase order is the paper trail from \"we need this\" to \"it is on the shelf and the bill is posted\"…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-purchasing.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-work-a-ticket",
          "file": "psa/v0.3/how-to/staff-work-a-ticket.md",
          "sourcePath": "how-to/staff-work-a-ticket.md",
          "title": "How to work a ticket",
          "description": "Working a ticket in Marula happens on one screen so you don't lose your place switching between notes, your stopwatch, and client documentation.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-work-a-ticket.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-time-categories",
          "file": "psa/v0.3/how-to/staff-time-categories.md",
          "sourcePath": "how-to/staff-time-categories.md",
          "title": "How to log billable time with categories",
          "description": "How work categories decide what a time entry bills, where it lands and why the category matters.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-time-categories.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-day-pack",
          "file": "psa/v0.3/how-to/staff-day-pack.md",
          "sourcePath": "how-to/staff-day-pack.md",
          "title": "How to work a day pack",
          "description": "The day pack is the trip preparation panel at the top of Today. It answers three questions before you leave.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-day-pack.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-multi-window",
          "file": "psa/v0.3/how-to/staff-multi-window.md",
          "sourcePath": "how-to/staff-multi-window.md",
          "title": "How to use multiple windows",
          "description": "How to open a second window on the same work, with a compact shell and the workbar.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-multi-window.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-keyboard-shortcuts",
          "file": "psa/v0.3/how-to/staff-keyboard-shortcuts.md",
          "sourcePath": "how-to/staff-keyboard-shortcuts.md",
          "title": "How to use the keyboard shortcuts",
          "description": "You can navigate boards, create tickets, copy record links, and search across Marula without taking your hands off the keyboard.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-keyboard-shortcuts.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-accessibility",
          "file": "psa/v0.3/how-to/staff-accessibility.md",
          "sourcePath": "how-to/staff-accessibility.md",
          "title": "How to use Marula with a keyboard, a screen reader, and themes",
          "description": "Marula is built to be usable without a mouse. You can run a ticket from the keyboard end to end, hear what changes through a screen reader, and pick a theme…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-accessibility.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-email-signature",
          "file": "psa/v0.3/how-to/staff-email-signature.md",
          "sourcePath": "how-to/staff-email-signature.md",
          "title": "How to sign your own email",
          "description": "Every message you send to a client can close with your own details: your name, your address, the workspace name.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-email-signature.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-scanning",
          "file": "psa/v0.3/how-to/staff-scanning.md",
          "sourcePath": "how-to/staff-scanning.md",
          "title": "How to scan barcodes and QR codes",
          "description": "How a scan resolves to one typed record — ticket, asset or stock item — before Marula acts on it.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-scanning.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-stock-and-parts",
          "file": "psa/v0.3/how-to/staff-stock-and-parts.md",
          "sourcePath": "how-to/staff-stock-and-parts.md",
          "title": "How to run stock and use parts",
          "description": "Stock lives at Stock (/stock). The board reads the same on-hand rows the low-stock alerts use, so the numbers you see here are the numbers automations act on.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-stock-and-parts.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-tools-and-loans",
          "file": "psa/v0.3/how-to/staff-tools-and-loans.md",
          "sourcePath": "how-to/staff-tools-and-loans.md",
          "title": "How to check tools out, and how to run client loans",
          "description": "Tools are stock items flagged as tools: serialized, individually tracked, and always answerable to \"who has this unit right now\".",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-tools-and-loans.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/staff-dispatch",
          "file": "psa/v0.3/how-to/staff-dispatch.md",
          "sourcePath": "how-to/staff-dispatch.md",
          "title": "How to dispatch from the board",
          "description": "The Dispatch board (/dispatch) gives dispatchers and technicians a single view of who is booked where, which tickets are waiting for an owner, and how much…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-dispatch.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-routing-travel",
          "file": "psa/v0.3/how-to/admin-routing-travel.md",
          "sourcePath": "how-to/admin-routing-travel.md",
          "title": "Turn on travel time and mileage reconciliation",
          "description": "This guide configures a routing provider, sets a technician's day start, reads the travel warnings the dispatcher sees, and reconciles logged mileage into…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-routing-travel.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/technician-service-day",
          "file": "psa/v0.3/how-to/technician-service-day.md",
          "sourcePath": "how-to/technician-service-day.md",
          "title": "How to run a service day from the phone",
          "description": "Today is the first screen after sign-in. It reads the same dispatch board the office sees, narrowed to your bookings:",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/technician-service-day.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/technician-field-ops",
          "file": "psa/v0.3/how-to/technician-field-ops.md",
          "sourcePath": "how-to/technician-field-ops.md",
          "title": "How to move stock and check out tools in the field",
          "description": "The phone moves stock through the same ledger as the web app. A transfer you make in a basement and a transfer the stockroom makes at the desk are the same…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/technician-field-ops.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/technician-mobile-app",
          "file": "psa/v0.3/how-to/technician-mobile-app.md",
          "sourcePath": "how-to/technician-mobile-app.md",
          "title": "How to use the Marula mobile app",
          "description": "The mobile app is the same product as the web app against the same API. A note you write on the phone lands on the ticket everyone else is looking at, and a…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/technician-mobile-app.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/technician-tools-and-parts",
          "file": "psa/v0.3/how-to/technician-tools-and-parts.md",
          "sourcePath": "how-to/technician-tools-and-parts.md",
          "title": "How to check out tools and use parts on site",
          "description": "Your day pack lists what the jobs need: the tools, the consumables, and the parts already reserved against the tickets. It lives on Today under the schedule.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/technician-tools-and-parts.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/project-billing",
          "file": "psa/v0.3/how-to/project-billing.md",
          "sourcePath": "how-to/project-billing.md",
          "title": "How to bill project work — contracts, milestones, fees",
          "description": "A ticket traces work to a client. But rollout projects and migrations live in Projects — and until now, project work that skipped tickets had no path to an…",
          "section": "Billing and contracts",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/project-billing.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-billing-verification",
          "file": "psa/v0.3/how-to/admin-billing-verification.md",
          "sourcePath": "how-to/admin-billing-verification.md",
          "title": "How to verify a billing period before you invoice it",
          "description": "An invoice run prices what it finds. Verification is where a human reads that same window first, decides what each entry really is, lowers the ones that…",
          "section": "Billing and contracts",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-billing-verification.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-contract-types",
          "file": "psa/v0.3/how-to/admin-contract-types.md",
          "sourcePath": "how-to/admin-contract-types.md",
          "title": "How to price a service contract",
          "description": "A contract is one client's answer to how do we get paid for this work? The type you pick decides what the engine evaluates.",
          "section": "Billing and contracts",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-contract-types.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-fx-rates",
          "file": "psa/v0.3/how-to/admin-fx-rates.md",
          "sourcePath": "how-to/admin-fx-rates.md",
          "title": "How to record FX rates & read reconciliation",
          "description": "If your MSP bills a client in EUR or CAD while reporting company financials in USD, you need historical invoices and inventory receipts to keep the exact…",
          "section": "Billing and contracts",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-fx-rates.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-portal-setup",
          "file": "psa/v0.3/how-to/admin-portal-setup.md",
          "sourcePath": "how-to/admin-portal-setup.md",
          "title": "How to set up the portal",
          "description": "The Client Portal lets your customers submit support requests, view their invoices, read client-facing help articles, and book appointment slots without…",
          "section": "Client portal",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-portal-setup.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/client-portal-tasks",
          "file": "psa/v0.3/how-to/client-portal-tasks.md",
          "sourcePath": "how-to/client-portal-tasks.md",
          "title": "How to use the portal (client-side tasks)",
          "description": "The Client Portal gives you a single place to open support requests, check the status of ongoing work, review invoices, read help guides written for your…",
          "section": "Client portal",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/client-portal-tasks.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/client-quote-approval",
          "file": "psa/v0.3/how-to/client-quote-approval.md",
          "sourcePath": "how-to/client-quote-approval.md",
          "title": "How to approve or decline a quote",
          "description": "How a client reads, accepts or declines a quote in the portal, and what changes after acceptance.",
          "section": "Client portal",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/client-quote-approval.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/call-the-api",
          "file": "psa/v0.3/how-to/call-the-api.md",
          "sourcePath": "how-to/call-the-api.md",
          "title": "How to call the API",
          "description": "Every action in the Marula web app, desktop app, and mobile app goes through the same /api/v1/… REST API.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/call-the-api.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/read-model",
          "file": "psa/v0.3/how-to/read-model.md",
          "sourcePath": "how-to/read-model.md",
          "title": "How to report against the read model",
          "description": "Because you own your PostgreSQL database, you can connect Metabase, Grafana, Power BI, or psql directly to Marula for custom reporting.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/read-model.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-api-keys",
          "file": "psa/v0.3/how-to/admin-api-keys.md",
          "sourcePath": "how-to/admin-api-keys.md",
          "title": "How to manage API keys",
          "description": "When an external script, monitoring tool, or custom integration needs to call Marula's API without a human signing in, you issue a scoped API key under…",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-api-keys.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-ai-bringup",
          "file": "psa/v0.3/how-to/admin-ai-bringup.md",
          "sourcePath": "how-to/admin-ai-bringup.md",
          "title": "How to bring up AI with your own API keys",
          "description": "Six settings decisions, in a fixed order, all on Settings → AI. The cards on that page sit in the order of the steps below.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-ai-bringup.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-ai-access",
          "file": "psa/v0.3/how-to/admin-ai-access.md",
          "sourcePath": "how-to/admin-ai-access.md",
          "title": "How to manage AI access",
          "description": "Marula treats AI as an optional tool that you control down to each role and screen.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-ai-access.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-local-ai-models",
          "file": "psa/v0.3/how-to/admin-local-ai-models.md",
          "sourcePath": "how-to/admin-local-ai-models.md",
          "title": "How to run transcription and embeddings on your own hardware",
          "description": "Marula will call a model runtime you run. The image you already deploy carries no model weights, so the models are a separate opt-in step: start the local…",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-local-ai-models.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-plugin-surfaces",
          "file": "psa/v0.3/how-to/admin-plugin-surfaces.md",
          "sourcePath": "how-to/admin-plugin-surfaces.md",
          "title": "How to extend Marula with plugin surfaces",
          "description": "The \"Connector?\" column is ADR 0017 decision 3, and the split is by KIND, not by who wrote the plugin.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-plugin-surfaces.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/write-a-plugin",
          "file": "psa/v0.3/how-to/write-a-plugin.md",
          "sourcePath": "how-to/write-a-plugin.md",
          "title": "How to write and build a plugin",
          "description": "A plugin is a signed WebAssembly module with no WASI and three exports. This walkthrough takes a handler from an empty crate to an installable bundle.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/write-a-plugin.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-plugin-consent",
          "file": "psa/v0.3/how-to/admin-plugin-consent.md",
          "sourcePath": "how-to/admin-plugin-consent.md",
          "title": "How to configure the plugin consent flow",
          "description": "Installing a plugin or external connector in an MSP platform is a high-trust security decision.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-plugin-consent.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/customize",
          "file": "psa/v0.3/how-to/customize.md",
          "sourcePath": "how-to/customize.md",
          "title": "How to customize without code",
          "description": "Every MSP names its ticket columns, client fields, and routing rules a little differently.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/customize.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/upgrade",
          "file": "psa/v0.3/how-to/upgrade.md",
          "sourcePath": "how-to/upgrade.md",
          "title": "How to upgrade to the latest release",
          "description": "Marula guarantees you can always upgrade from either of the two previous tagged releases (the N−2 rule, policy §1/§3). This guide gets you there safely.",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/upgrade.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/export-data",
          "file": "psa/v0.3/how-to/export-data.md",
          "sourcePath": "how-to/export-data.md",
          "title": "How to export your data",
          "description": "Marula keeps your organization's records in its own database. When you need a copy outside the app, for a migration, a compliance request, or a look at the…",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/export-data.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/local-demo-stack",
          "file": "psa/v0.3/how-to/local-demo-stack.md",
          "sourcePath": "how-to/local-demo-stack.md",
          "title": "How to run the local demo stack",
          "description": "Take a fresh clone to a booted, seeded demo with Postgres, Valkey and the sample organization.",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/local-demo-stack.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/operator-embedding-model",
          "file": "psa/v0.3/how-to/operator-embedding-model.md",
          "sourcePath": "how-to/operator-embedding-model.md",
          "title": "How to change the embedding model",
          "description": "The embedding model decides what search can match on meaning. It serves the whole install, so a change is a deployment decision, not an organization setting.",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/operator-embedding-model.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/operator-retrieval-mode",
          "file": "psa/v0.3/how-to/operator-retrieval-mode.md",
          "sourcePath": "how-to/operator-retrieval-mode.md",
          "title": "How to choose the retrieval mode",
          "description": "The search vector leg has one exact answer and two indexed shortcuts. Which one fits depends on the shape of the install, and the shapes pull in opposite…",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/operator-retrieval-mode.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/admin-self-host-services",
          "file": "psa/v0.3/how-to/admin-self-host-services.md",
          "sourcePath": "how-to/admin-self-host-services.md",
          "title": "How to watch your self-hosted services",
          "description": "The Settings → Self-host services pane answers two operator questions in one place: is the stack running, and where do I look when it is not.",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-self-host-services.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference",
          "file": "psa/v0.3/reference.md",
          "sourcePath": "reference/index.md",
          "title": "Reference",
          "description": "Reference pages give you exact endpoints, database view columns, environment variables, and operator runbooks for lookup.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/index.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/api",
          "file": "psa/v0.3/reference/api.md",
          "sourcePath": "reference/api.md",
          "title": "API reference",
          "description": "Marula Core API reference: endpoints, operations, request bodies and schemas from the committed OpenAPI pin.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/api.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/openapi",
          "file": "psa/v0.3/reference/openapi.md",
          "sourcePath": "reference/openapi.md",
          "title": "The OpenAPI pin",
          "description": "The API contract is pinned twice, and CI enforces that the two are a byte-identical pair:",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/openapi.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/glossary",
          "file": "psa/v0.3/reference/glossary.md",
          "sourcePath": "reference/glossary.md",
          "title": "Glossary",
          "description": "The words this documentation assumes. Terms are grouped by where you meet them, not alphabetically, because \"what is a board\" and \"what is an optimistic…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/glossary.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/billing-schemas",
          "file": "psa/v0.3/reference/billing-schemas.md",
          "sourcePath": "reference/billing-schemas.md",
          "title": "Billing schema reference",
          "description": "The tables behind work-type categories, billing verification, contract pricing and project milestone billing, and the rules an integrator has to know before…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/billing-schemas.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/read-model",
          "file": "psa/v0.3/reference/read-model.md",
          "sourcePath": "reference/read-model.md",
          "title": "Read model view catalog",
          "description": "The documented read model is a stable, versioned set of SQL views over operational data — the supported interface for direct SQL access and external…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/read-model.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/routing",
          "file": "psa/v0.3/reference/routing.md",
          "sourcePath": "reference/routing.md",
          "title": "Routing and travel reference",
          "description": "System facts about the routing provider seam, its endpoints, its settings, and the reconciliation surface.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/routing.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/backup-restore",
          "file": "psa/v0.3/reference/backup-restore.md",
          "sourcePath": "reference/backup-restore.md",
          "title": "Runbook: backup and restore",
          "description": "Everything in Marula lives in the Postgres database, and once S3 object storage is enabled also the object-storage (Garage/S3) bucket.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/backup-restore.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/self-host-local-stack",
          "file": "psa/v0.3/reference/self-host-local-stack.md",
          "sourcePath": "reference/self-host-local-stack.md",
          "title": "Self-host reference: the local stack",
          "description": "The canonical local stack: Postgres, Redis, schema migration, core API, worker and web console.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/self-host-local-stack.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/self-host-local-ai",
          "file": "psa/v0.3/reference/self-host-local-ai.md",
          "sourcePath": "reference/self-host-local-ai.md",
          "title": "Local AI: transcription and embeddings on your own hardware",
          "description": "Marula's AI features talk to a model runtime you choose. The core ships no model weights, in no image, under no profile.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/self-host-local-ai.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/self-host-observability",
          "file": "psa/v0.3/reference/self-host-observability.md",
          "sourcePath": "reference/self-host-observability.md",
          "title": "Observability: distributed traces, logs, metrics",
          "description": "Marula's telemetry is off by default. With OTELEXPORTEROTLPENDPOINT unset, core-api and the worker run exactly as they did before the observability work…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/self-host-observability.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/reverse-proxy-tls",
          "file": "psa/v0.3/reference/reverse-proxy-tls.md",
          "sourcePath": "reference/reverse-proxy-tls.md",
          "title": "Runbook: reverse proxy and TLS",
          "description": "This runbook is the front door. It covers what the proxy must serve, the two TLS modes a real deployment runs, the two ways to run the edge one, the…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/reverse-proxy-tls.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/db-observability",
          "file": "psa/v0.3/reference/db-observability.md",
          "sourcePath": "reference/db-observability.md",
          "title": "Database observability",
          "description": "Marula measures performance one endpoint at a time. That leaves the real query mix unseen and the slow tail unmeasured, so the database now records both.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/db-observability.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/pg18-upgrade",
          "file": "psa/v0.3/reference/pg18-upgrade.md",
          "sourcePath": "reference/pg18-upgrade.md",
          "title": "Upgrading Postgres 17 to 18",
          "description": "Marula runs Postgres 18 + pgvector everywhere since the 2026-09 transition (deploy/docker-compose.yml, the Helm chart, and the desktop test app all pin…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/pg18-upgrade.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/upgrade-matrix",
          "file": "psa/v0.3/reference/upgrade-matrix.md",
          "sourcePath": "reference/upgrade-matrix.md",
          "title": "Upgrade matrix",
          "description": "Every tagged Marula release and the N−2 upgrade paths proven in CI, with the fixture anchors and covered surfaces.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/upgrade-matrix.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/reference/embedding-model-catalogue",
          "file": "psa/v0.3/reference/embedding-model-catalogue.md",
          "sourcePath": "reference/embedding-model-catalogue.md",
          "title": "Embedding model catalogue",
          "description": "Marula turns tickets, comments, clients and knowledge articles into vectors so search can match on meaning as well as words.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/embedding-model-catalogue.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation",
          "file": "psa/v0.3/explanation.md",
          "sourcePath": "explanation/index.md",
          "title": "Explanation",
          "description": "These pages explain why Marula works the way it does: why renaming a board column never breaks an SLA timer, why billing corrections create credit notes…",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/index.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/why-marula",
          "file": "psa/v0.3/explanation/why-marula.md",
          "sourcePath": "explanation/why-marula.md",
          "title": "Why we're building Marula",
          "description": "Marula's positioning narrative, quoted verbatim: why the PSA was built and what it refuses to repeat.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/why-marula.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/instant-first",
          "file": "psa/v0.3/explanation/instant-first.md",
          "sourcePath": "explanation/instant-first.md",
          "title": "Instant-first interaction",
          "description": "When you are on the phone with a customer and updating a ticket's priority or assignee, you shouldn't have to hunt for a Save button at the bottom of a form…",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/instant-first.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/ai-deny-by-default",
          "file": "psa/v0.3/explanation/ai-deny-by-default.md",
          "sourcePath": "explanation/ai-deny-by-default.md",
          "title": "AI: deny-by-default and the decision harness",
          "description": "Marula ships AI deny-by-default: the org switch stays off until grants, caps and credentials make a surface audible.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/ai-deny-by-default.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/customizations-are-data",
          "file": "psa/v0.3/explanation/customizations-are-data.md",
          "sourcePath": "explanation/customizations-are-data.md",
          "title": "Customizations are data, not code",
          "description": "Every MSP runs its service desk a little differently: you have your own board column names, custom client fields, SLA rules, and ticket automations.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/customizations-are-data.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/provenance-vs-audit",
          "file": "psa/v0.3/explanation/provenance-vs-audit.md",
          "sourcePath": "explanation/provenance-vs-audit.md",
          "title": "Provenance vs audit: two append-only ledgers, different granularity",
          "description": "When an owner or service lead asks \"Who changed this client's billing rate?\" or \"Who viewed that domain admin password yesterday?\", you need a straight…",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/provenance-vs-audit.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/billing-corrections",
          "file": "psa/v0.3/explanation/billing-corrections.md",
          "sourcePath": "explanation/billing-corrections.md",
          "title": "Billing corrections, and where tax lives",
          "description": "An issued invoice is a record of what happened, not a draft that can be tidied up later.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/billing-corrections.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/contract-relationship-types",
          "file": "psa/v0.3/explanation/contract-relationship-types.md",
          "sourcePath": "explanation/contract-relationship-types.md",
          "title": "Contracts: one shape per client relationship",
          "description": "A Marula contract is the commercial answer to one question: how does this client pay for this work?",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/contract-relationship-types.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/fx-additivity",
          "file": "psa/v0.3/explanation/fx-additivity.md",
          "sourcePath": "explanation/fx-additivity.md",
          "title": "FX additivity and the append-only rate book",
          "description": "Two contracts govern money in multi-currency stacks, and they travel together. The command-side procedure is the FX how-to; this page explains the why they…",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/fx-additivity.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/kb-class-categories",
          "file": "psa/v0.3/explanation/kb-class-categories.md",
          "sourcePath": "explanation/kb-class-categories.md",
          "title": "Knowledge-base categories and the secret vault share one grant model",
          "description": "Your runbooks in the Knowledge Base (/kb) and your stored credentials in the Secret Vault (/passwords) use the exact same folder permission model (ADR 0006).",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/kb-class-categories.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/portal-isolation",
          "file": "psa/v0.3/explanation/portal-isolation.md",
          "sourcePath": "explanation/portal-isolation.md",
          "title": "The portal isolation model",
          "description": "The portal is not a theme on the staff product. It is a separate trust zone with its own principals, its own sign-in shell, and its own knowledge gate.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/portal-isolation.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/explanation/upgrade-policy",
          "file": "psa/v0.3/explanation/upgrade-policy.md",
          "sourcePath": "explanation/upgrade-policy.md",
          "title": "The upgrade compatibility policy",
          "description": "Marula asks organizations to bet their operating system on it. That bet is only rational if upgrades are boring. Two commitments define the whole document:",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/upgrade-policy.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/troubleshooting",
          "file": "psa/v0.3/troubleshooting.md",
          "sourcePath": "troubleshooting.md",
          "title": "Troubleshooting",
          "description": "Start from what you see. Each entry below names a symptom in plain words, the checks in the order they usually find it, and the page that explains the part…",
          "section": "Troubleshooting",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/troubleshooting.md"
        },
        {
          "product": "psa",
          "version": "v0.3",
          "channel": "current",
          "route": "/docs/psa/v0.3/how-to/get-help",
          "file": "psa/v0.3/how-to/get-help.md",
          "sourcePath": "how-to/get-help.md",
          "title": "How to get help inside Marula",
          "description": "Every entry is a page from the public docs site — the same markdown that lives at getmarula.com/docs.",
          "section": "Get help",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/get-help.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next",
          "file": "psa/next.md",
          "sourcePath": "index.md",
          "title": "Marula documentation",
          "description": "Marula is an open-source PSA (professional services automation) platform for IT service teams and MSPs.",
          "section": "Home",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/index.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/start",
          "file": "psa/next/start.md",
          "sourcePath": "start/index.md",
          "title": "Start here",
          "description": "Pick the row that matches your job. Each page lists tasks in the words people actually use (\"a customer cannot log in\", \"I need to close the month\") and…",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/index.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/start/owners",
          "file": "psa/next/start/owners.md",
          "sourcePath": "start/owners.md",
          "title": "Owner tasks",
          "description": "You are accountable for the numbers and for who can see what. These are the jobs that land on your desk, in the order they usually arrive.",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/owners.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/start/admins",
          "file": "psa/next/start/admins.md",
          "sourcePath": "start/admins.md",
          "title": "Admin tasks",
          "description": "Most of this work happens once, at the start, and then twice a year. The list is grouped by the job rather than by the settings menu, because the menu moves…",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/admins.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/start/technicians",
          "file": "psa/next/start/technicians.md",
          "sourcePath": "start/technicians.md",
          "title": "Technician tasks",
          "description": "The technician's path through Marula: work the queue, run a service day, log billable time and answer the customer.",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/technicians.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/start/operators",
          "file": "psa/next/start/operators.md",
          "sourcePath": "start/operators.md",
          "title": "Operator tasks",
          "description": "You are not the workspace admin. Admins configure boards, email routing and people.",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/operators.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/start/agents",
          "file": "psa/next/start/agents.md",
          "sourcePath": "start/agents.md",
          "title": "Agent and automation tasks",
          "description": "Marula separates three things that are easy to blur: what an agent may do (grants), what it did (provenance and audit), and what the platform exposes (API…",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/start/agents.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to",
          "file": "psa/next/how-to.md",
          "sourcePath": "how-to/index.md",
          "title": "Admin how-to guides",
          "description": "Each how-to guide gives you a direct checklist for one specific job in Marula. If you are brand new and want a guided walkthrough from start to finish…",
          "section": "Start here",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/index.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/tutorials",
          "file": "psa/next/tutorials.md",
          "sourcePath": "tutorials/index.md",
          "title": "Tutorials",
          "description": "Each tutorial walks you through one real job from start to finish using the sample organization that ships with Marula.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/index.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/tutorials/first-ticket",
          "file": "psa/next/tutorials/first-ticket.md",
          "sourcePath": "tutorials/first-ticket.md",
          "title": "Tutorial: your first ticket (in the UI)",
          "description": "When a client calls or emails with a problem, you shouldn't have to bounce between a ticket tab, a separate stopwatch popup, and a timecard sheet at 5 PM.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-ticket.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/tutorials/first-invoice",
          "file": "psa/next/tutorials/first-invoice.md",
          "sourcePath": "tutorials/first-invoice.md",
          "title": "Tutorial: your first invoice",
          "description": "Walk the invoice cycle end to end in the demo organization, from billable time to a sent invoice.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-invoice.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/tutorials/first-inventory-sync",
          "file": "psa/next/tutorials/first-inventory-sync.md",
          "sourcePath": "tutorials/first-inventory-sync.md",
          "title": "Tutorial: your first inventory sync",
          "description": "When you pull computers and network gear from an RMM tool, an MDM, and a spreadsheet, most PSAs dump duplicate rows into your asset list and leave techs…",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-inventory-sync.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/tutorials/first-agent-run",
          "file": "psa/next/tutorials/first-agent-run.md",
          "sourcePath": "tutorials/first-agent-run.md",
          "title": "Tutorial: your first agent run",
          "description": "In many tools, turning on AI means letting a bot rewrite tickets or email clients behind your back.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-agent-run.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/tutorials/portal-onboarding",
          "file": "psa/next/tutorials/portal-onboarding.md",
          "sourcePath": "tutorials/portal-onboarding.md",
          "title": "Tutorial: portal onboarding",
          "description": "Your clients shouldn't have to email your helpdesk just to check if a ticket is being worked on, download last month's invoice, or approve a hardware quote.",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/portal-onboarding.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/tutorials/first-ticket-api",
          "file": "psa/next/tutorials/first-ticket-api.md",
          "sourcePath": "tutorials/first-ticket-api.md",
          "title": "Tutorial: your first ticket",
          "description": "If you prefer exploring a system from the terminal or want to build an integration script, this tutorial walks through the exact same workflow as Your first…",
          "section": "Tutorials",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/tutorials/first-ticket-api.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-org-bootstrap",
          "file": "psa/next/how-to/admin-org-bootstrap.md",
          "sourcePath": "how-to/admin-org-bootstrap.md",
          "title": "How to bootstrap your first organization",
          "description": "When you launch a fresh Marula install, you create your organization and first administrator account right from the sign-in screen.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-org-bootstrap.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-users-invites",
          "file": "psa/next/how-to/admin-users-invites.md",
          "sourcePath": "how-to/admin-users-invites.md",
          "title": "How to manage users and invites",
          "description": "Instead of creating temporary passwords and reading them over the phone, you invite teammates from Settings → Team.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-users-invites.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-sso",
          "file": "psa/next/how-to/admin-sso.md",
          "sourcePath": "how-to/admin-sso.md",
          "title": "How to connect an IdP (SSO)",
          "description": "Single Sign-On (SSO) lets your staff sign in to Marula through your company's identity provider (such as Google Workspace, Microsoft Entra ID, Okta, or…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-sso.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-email",
          "file": "psa/next/how-to/admin-email.md",
          "sourcePath": "how-to/admin-email.md",
          "title": "How to configure email",
          "description": "This page covers three jobs in order: routing inbound mail to boards, proving your domain with DNS, and choosing how outbound mail leaves.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-email.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-sla-calendars",
          "file": "psa/next/how-to/admin-sla-calendars.md",
          "sourcePath": "how-to/admin-sla-calendars.md",
          "title": "How to configure SLA calendars & escalation ladders",
          "description": "When a client has an agreement for a 2-hour response on urgent tickets, you don't want the SLA clock ticking at 3 AM on a Sunday unless they pay for 24/7…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-sla-calendars.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-workflow-categories",
          "file": "psa/next/how-to/admin-workflow-categories.md",
          "sourcePath": "how-to/admin-workflow-categories.md",
          "title": "How to set workflow categories",
          "description": "In many ticketing tools, renaming a board column from \"Waiting on Vendor\" to \"Parts Ordered\" breaks every SLA rule, report filter, and billing script that…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-workflow-categories.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-automation-rules",
          "file": "psa/next/how-to/admin-automation-rules.md",
          "sourcePath": "how-to/admin-automation-rules.md",
          "title": "How to author automation rules",
          "description": "Automation rules let your service desk handle repetitive routing and follow-ups automatically: for example, alerting a manager when a P1 ticket arrives…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-automation-rules.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-labels",
          "file": "psa/next/how-to/admin-labels.md",
          "sourcePath": "how-to/admin-labels.md",
          "title": "How to set up labels and label templates",
          "description": "A template is typed by PURPOSE, and the purpose decides which fields it can print and what its QR code points at. Four purposes ship:",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-labels.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-imports",
          "file": "psa/next/how-to/admin-imports.md",
          "sourcePath": "how-to/admin-imports.md",
          "title": "How to run a dry-run import",
          "description": "Moving clients, contacts, tickets, or hardware assets from a legacy PSA or spreadsheet shouldn't be a blind leap of faith.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-imports.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-dashboards-reports",
          "file": "psa/next/how-to/admin-dashboards-reports.md",
          "sourcePath": "how-to/admin-dashboards-reports.md",
          "title": "How to manage dashboards & report schedules",
          "description": "Marula gives service leads and owners three ways to track how the shop is running: live Dashboards (/reports/dashboards), a custom Report Builder…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-dashboards-reports.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-csat-surveys",
          "file": "psa/next/how-to/admin-csat-surveys.md",
          "sourcePath": "how-to/admin-csat-surveys.md",
          "title": "How to set up CSAT surveys on resolution",
          "description": "Set up satisfaction surveys on ticket resolution, with intervals, link validity and quiet hours.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-csat-surveys.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-toolboxes",
          "file": "psa/next/how-to/admin-toolboxes.md",
          "sourcePath": "how-to/admin-toolboxes.md",
          "title": "How to set up toolboxes and dispatch defaults",
          "description": "Settings → Toolboxes & day pack is the config home for toolboxes. It holds the kits themselves, the tools inside them, the mappings the day pack reads, and…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-toolboxes.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-reply-snippets",
          "file": "psa/next/how-to/admin-reply-snippets.md",
          "sourcePath": "how-to/admin-reply-snippets.md",
          "title": "How to use reply snippets",
          "description": "A reply snippet is a canned reply your team writes once and inserts everywhere. Open the composer on any ticket, press Snippets, and pick one.",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-reply-snippets.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-purchasing",
          "file": "psa/next/how-to/admin-purchasing.md",
          "sourcePath": "how-to/admin-purchasing.md",
          "title": "How to buy: vendors, purchase orders, receiving, bills",
          "description": "Purchasing lives at Purchasing (/purchasing). A purchase order is the paper trail from \"we need this\" to \"it is on the shelf and the bill is posted\"…",
          "section": "Set up and administer",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-purchasing.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-work-a-ticket",
          "file": "psa/next/how-to/staff-work-a-ticket.md",
          "sourcePath": "how-to/staff-work-a-ticket.md",
          "title": "How to work a ticket",
          "description": "Working a ticket in Marula happens on one screen so you don't lose your place switching between notes, your stopwatch, and client documentation.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-work-a-ticket.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-time-categories",
          "file": "psa/next/how-to/staff-time-categories.md",
          "sourcePath": "how-to/staff-time-categories.md",
          "title": "How to log billable time with categories",
          "description": "How work categories decide what a time entry bills, where it lands and why the category matters.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-time-categories.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-day-pack",
          "file": "psa/next/how-to/staff-day-pack.md",
          "sourcePath": "how-to/staff-day-pack.md",
          "title": "How to work a day pack",
          "description": "The day pack is the trip preparation panel at the top of Today. It answers three questions before you leave.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-day-pack.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-multi-window",
          "file": "psa/next/how-to/staff-multi-window.md",
          "sourcePath": "how-to/staff-multi-window.md",
          "title": "How to use multiple windows",
          "description": "How to open a second window on the same work, with a compact shell and the workbar.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-multi-window.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-keyboard-shortcuts",
          "file": "psa/next/how-to/staff-keyboard-shortcuts.md",
          "sourcePath": "how-to/staff-keyboard-shortcuts.md",
          "title": "How to use the keyboard shortcuts",
          "description": "You can navigate boards, create tickets, copy record links, and search across Marula without taking your hands off the keyboard.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-keyboard-shortcuts.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-accessibility",
          "file": "psa/next/how-to/staff-accessibility.md",
          "sourcePath": "how-to/staff-accessibility.md",
          "title": "How to use Marula with a keyboard, a screen reader, and themes",
          "description": "Marula is built to be usable without a mouse. You can run a ticket from the keyboard end to end, hear what changes through a screen reader, and pick a theme…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-accessibility.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-email-signature",
          "file": "psa/next/how-to/staff-email-signature.md",
          "sourcePath": "how-to/staff-email-signature.md",
          "title": "How to sign your own email",
          "description": "Every message you send to a client can close with your own details: your name, your address, the workspace name.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-email-signature.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-scanning",
          "file": "psa/next/how-to/staff-scanning.md",
          "sourcePath": "how-to/staff-scanning.md",
          "title": "How to scan barcodes and QR codes",
          "description": "How a scan resolves to one typed record — ticket, asset or stock item — before Marula acts on it.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-scanning.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-stock-and-parts",
          "file": "psa/next/how-to/staff-stock-and-parts.md",
          "sourcePath": "how-to/staff-stock-and-parts.md",
          "title": "How to run stock and use parts",
          "description": "Stock lives at Stock (/stock). The board reads the same on-hand rows the low-stock alerts use, so the numbers you see here are the numbers automations act on.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-stock-and-parts.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-tools-and-loans",
          "file": "psa/next/how-to/staff-tools-and-loans.md",
          "sourcePath": "how-to/staff-tools-and-loans.md",
          "title": "How to check tools out, and how to run client loans",
          "description": "Tools are stock items flagged as tools: serialized, individually tracked, and always answerable to \"who has this unit right now\".",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-tools-and-loans.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/staff-dispatch",
          "file": "psa/next/how-to/staff-dispatch.md",
          "sourcePath": "how-to/staff-dispatch.md",
          "title": "How to dispatch from the board",
          "description": "The Dispatch board (/dispatch) gives dispatchers and technicians a single view of who is booked where, which tickets are waiting for an owner, and how much…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/staff-dispatch.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-routing-travel",
          "file": "psa/next/how-to/admin-routing-travel.md",
          "sourcePath": "how-to/admin-routing-travel.md",
          "title": "Turn on travel time and mileage reconciliation",
          "description": "This guide configures a routing provider, sets a technician's day start, reads the travel warnings the dispatcher sees, and reconciles logged mileage into…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-routing-travel.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/technician-service-day",
          "file": "psa/next/how-to/technician-service-day.md",
          "sourcePath": "how-to/technician-service-day.md",
          "title": "How to run a service day from the phone",
          "description": "Today is the first screen after sign-in. It reads the same dispatch board the office sees, narrowed to your bookings:",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/technician-service-day.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/technician-field-ops",
          "file": "psa/next/how-to/technician-field-ops.md",
          "sourcePath": "how-to/technician-field-ops.md",
          "title": "How to move stock and check out tools in the field",
          "description": "The phone moves stock through the same ledger as the web app. A transfer you make in a basement and a transfer the stockroom makes at the desk are the same…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/technician-field-ops.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/technician-mobile-app",
          "file": "psa/next/how-to/technician-mobile-app.md",
          "sourcePath": "how-to/technician-mobile-app.md",
          "title": "How to use the Marula mobile app",
          "description": "The mobile app is the same product as the web app against the same API. A note you write on the phone lands on the ticket everyone else is looking at, and a…",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/technician-mobile-app.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/technician-tools-and-parts",
          "file": "psa/next/how-to/technician-tools-and-parts.md",
          "sourcePath": "how-to/technician-tools-and-parts.md",
          "title": "How to check out tools and use parts on site",
          "description": "Your day pack lists what the jobs need: the tools, the consumables, and the parts already reserved against the tickets. It lives on Today under the schedule.",
          "section": "Tickets, time and field work",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/technician-tools-and-parts.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/project-billing",
          "file": "psa/next/how-to/project-billing.md",
          "sourcePath": "how-to/project-billing.md",
          "title": "How to bill project work — contracts, milestones, fees",
          "description": "A ticket traces work to a client. But rollout projects and migrations live in Projects — and until now, project work that skipped tickets had no path to an…",
          "section": "Billing and contracts",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/project-billing.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-billing-verification",
          "file": "psa/next/how-to/admin-billing-verification.md",
          "sourcePath": "how-to/admin-billing-verification.md",
          "title": "How to verify a billing period before you invoice it",
          "description": "An invoice run prices what it finds. Verification is where a human reads that same window first, decides what each entry really is, lowers the ones that…",
          "section": "Billing and contracts",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-billing-verification.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-contract-types",
          "file": "psa/next/how-to/admin-contract-types.md",
          "sourcePath": "how-to/admin-contract-types.md",
          "title": "How to price a service contract",
          "description": "A contract is one client's answer to how do we get paid for this work? The type you pick decides what the engine evaluates.",
          "section": "Billing and contracts",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-contract-types.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-fx-rates",
          "file": "psa/next/how-to/admin-fx-rates.md",
          "sourcePath": "how-to/admin-fx-rates.md",
          "title": "How to record FX rates & read reconciliation",
          "description": "If your MSP bills a client in EUR or CAD while reporting company financials in USD, you need historical invoices and inventory receipts to keep the exact…",
          "section": "Billing and contracts",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-fx-rates.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-portal-setup",
          "file": "psa/next/how-to/admin-portal-setup.md",
          "sourcePath": "how-to/admin-portal-setup.md",
          "title": "How to set up the portal",
          "description": "The Client Portal lets your customers submit support requests, view their invoices, read client-facing help articles, and book appointment slots without…",
          "section": "Client portal",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-portal-setup.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/client-portal-tasks",
          "file": "psa/next/how-to/client-portal-tasks.md",
          "sourcePath": "how-to/client-portal-tasks.md",
          "title": "How to use the portal (client-side tasks)",
          "description": "The Client Portal gives you a single place to open support requests, check the status of ongoing work, review invoices, read help guides written for your…",
          "section": "Client portal",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/client-portal-tasks.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/client-quote-approval",
          "file": "psa/next/how-to/client-quote-approval.md",
          "sourcePath": "how-to/client-quote-approval.md",
          "title": "How to approve or decline a quote",
          "description": "How a client reads, accepts or declines a quote in the portal, and what changes after acceptance.",
          "section": "Client portal",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/client-quote-approval.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/call-the-api",
          "file": "psa/next/how-to/call-the-api.md",
          "sourcePath": "how-to/call-the-api.md",
          "title": "How to call the API",
          "description": "Every action in the Marula web app, desktop app, and mobile app goes through the same /api/v1/… REST API.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/call-the-api.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/read-model",
          "file": "psa/next/how-to/read-model.md",
          "sourcePath": "how-to/read-model.md",
          "title": "How to report against the read model",
          "description": "Because you own your PostgreSQL database, you can connect Metabase, Grafana, Power BI, or psql directly to Marula for custom reporting.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/read-model.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-api-keys",
          "file": "psa/next/how-to/admin-api-keys.md",
          "sourcePath": "how-to/admin-api-keys.md",
          "title": "How to manage API keys",
          "description": "When an external script, monitoring tool, or custom integration needs to call Marula's API without a human signing in, you issue a scoped API key under…",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-api-keys.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-ai-bringup",
          "file": "psa/next/how-to/admin-ai-bringup.md",
          "sourcePath": "how-to/admin-ai-bringup.md",
          "title": "How to bring up AI with your own API keys",
          "description": "Six settings decisions, in a fixed order, all on Settings → AI. The cards on that page sit in the order of the steps below.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-ai-bringup.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-ai-access",
          "file": "psa/next/how-to/admin-ai-access.md",
          "sourcePath": "how-to/admin-ai-access.md",
          "title": "How to manage AI access",
          "description": "Marula treats AI as an optional tool that you control down to each role and screen.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-ai-access.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-local-ai-models",
          "file": "psa/next/how-to/admin-local-ai-models.md",
          "sourcePath": "how-to/admin-local-ai-models.md",
          "title": "How to run transcription and embeddings on your own hardware",
          "description": "Marula will call a model runtime you run. The image you already deploy carries no model weights, so the models are a separate opt-in step: start the local…",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-local-ai-models.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-plugin-surfaces",
          "file": "psa/next/how-to/admin-plugin-surfaces.md",
          "sourcePath": "how-to/admin-plugin-surfaces.md",
          "title": "How to extend Marula with plugin surfaces",
          "description": "The \"Connector?\" column is ADR 0017 decision 3, and the split is by KIND, not by who wrote the plugin.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-plugin-surfaces.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/write-a-plugin",
          "file": "psa/next/how-to/write-a-plugin.md",
          "sourcePath": "how-to/write-a-plugin.md",
          "title": "How to write and build a plugin",
          "description": "A plugin is a signed WebAssembly module with no WASI and three exports. This walkthrough takes a handler from an empty crate to an installable bundle.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/write-a-plugin.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-plugin-consent",
          "file": "psa/next/how-to/admin-plugin-consent.md",
          "sourcePath": "how-to/admin-plugin-consent.md",
          "title": "How to configure the plugin consent flow",
          "description": "Installing a plugin or external connector in an MSP platform is a high-trust security decision.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-plugin-consent.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/customize",
          "file": "psa/next/how-to/customize.md",
          "sourcePath": "how-to/customize.md",
          "title": "How to customize without code",
          "description": "Every MSP names its ticket columns, client fields, and routing rules a little differently.",
          "section": "Automation, API and agents",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/customize.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/upgrade",
          "file": "psa/next/how-to/upgrade.md",
          "sourcePath": "how-to/upgrade.md",
          "title": "How to upgrade to the latest release",
          "description": "Marula guarantees you can always upgrade from either of the two previous tagged releases (the N−2 rule, policy §1/§3). This guide gets you there safely.",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/upgrade.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/export-data",
          "file": "psa/next/how-to/export-data.md",
          "sourcePath": "how-to/export-data.md",
          "title": "How to export your data",
          "description": "Marula keeps your organization's records in its own database. When you need a copy outside the app, for a migration, a compliance request, or a look at the…",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/export-data.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/local-demo-stack",
          "file": "psa/next/how-to/local-demo-stack.md",
          "sourcePath": "how-to/local-demo-stack.md",
          "title": "How to run the local demo stack",
          "description": "Take a fresh clone to a booted, seeded demo with Postgres, Valkey and the sample organization.",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/local-demo-stack.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/operator-embedding-model",
          "file": "psa/next/how-to/operator-embedding-model.md",
          "sourcePath": "how-to/operator-embedding-model.md",
          "title": "How to change the embedding model",
          "description": "The embedding model decides what search can match on meaning. It serves the whole install, so a change is a deployment decision, not an organization setting.",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/operator-embedding-model.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/operator-retrieval-mode",
          "file": "psa/next/how-to/operator-retrieval-mode.md",
          "sourcePath": "how-to/operator-retrieval-mode.md",
          "title": "How to choose the retrieval mode",
          "description": "The search vector leg has one exact answer and two indexed shortcuts. Which one fits depends on the shape of the install, and the shapes pull in opposite…",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/operator-retrieval-mode.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/admin-self-host-services",
          "file": "psa/next/how-to/admin-self-host-services.md",
          "sourcePath": "how-to/admin-self-host-services.md",
          "title": "How to watch your self-hosted services",
          "description": "The Settings → Self-host services pane answers two operator questions in one place: is the stack running, and where do I look when it is not.",
          "section": "Self-host and operate",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/admin-self-host-services.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference",
          "file": "psa/next/reference.md",
          "sourcePath": "reference/index.md",
          "title": "Reference",
          "description": "Reference pages give you exact endpoints, database view columns, environment variables, and operator runbooks for lookup.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/index.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/api",
          "file": "psa/next/reference/api.md",
          "sourcePath": "reference/api.md",
          "title": "API reference",
          "description": "Marula Core API reference: endpoints, operations, request bodies and schemas from the committed OpenAPI pin.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/api.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/openapi",
          "file": "psa/next/reference/openapi.md",
          "sourcePath": "reference/openapi.md",
          "title": "The OpenAPI pin",
          "description": "The API contract is pinned twice, and CI enforces that the two are a byte-identical pair:",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/openapi.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/glossary",
          "file": "psa/next/reference/glossary.md",
          "sourcePath": "reference/glossary.md",
          "title": "Glossary",
          "description": "The words this documentation assumes. Terms are grouped by where you meet them, not alphabetically, because \"what is a board\" and \"what is an optimistic…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/glossary.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/billing-schemas",
          "file": "psa/next/reference/billing-schemas.md",
          "sourcePath": "reference/billing-schemas.md",
          "title": "Billing schema reference",
          "description": "The tables behind work-type categories, billing verification, contract pricing and project milestone billing, and the rules an integrator has to know before…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/billing-schemas.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/read-model",
          "file": "psa/next/reference/read-model.md",
          "sourcePath": "reference/read-model.md",
          "title": "Read model view catalog",
          "description": "The documented read model is a stable, versioned set of SQL views over operational data — the supported interface for direct SQL access and external…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/read-model.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/routing",
          "file": "psa/next/reference/routing.md",
          "sourcePath": "reference/routing.md",
          "title": "Routing and travel reference",
          "description": "System facts about the routing provider seam, its endpoints, its settings, and the reconciliation surface.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/routing.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/backup-restore",
          "file": "psa/next/reference/backup-restore.md",
          "sourcePath": "reference/backup-restore.md",
          "title": "Runbook: backup and restore",
          "description": "Everything in Marula lives in the Postgres database, and once S3 object storage is enabled also the object-storage (Garage/S3) bucket.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/backup-restore.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/self-host-local-stack",
          "file": "psa/next/reference/self-host-local-stack.md",
          "sourcePath": "reference/self-host-local-stack.md",
          "title": "Self-host reference: the local stack",
          "description": "The canonical local stack: Postgres, Redis, schema migration, core API, worker and web console.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/self-host-local-stack.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/self-host-local-ai",
          "file": "psa/next/reference/self-host-local-ai.md",
          "sourcePath": "reference/self-host-local-ai.md",
          "title": "Local AI: transcription and embeddings on your own hardware",
          "description": "Marula's AI features talk to a model runtime you choose. The core ships no model weights, in no image, under no profile.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/self-host-local-ai.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/self-host-observability",
          "file": "psa/next/reference/self-host-observability.md",
          "sourcePath": "reference/self-host-observability.md",
          "title": "Observability: distributed traces, logs, metrics",
          "description": "Marula's telemetry is off by default. With OTELEXPORTEROTLPENDPOINT unset, core-api and the worker run exactly as they did before the observability work…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/self-host-observability.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/reverse-proxy-tls",
          "file": "psa/next/reference/reverse-proxy-tls.md",
          "sourcePath": "reference/reverse-proxy-tls.md",
          "title": "Runbook: reverse proxy and TLS",
          "description": "This runbook is the front door. It covers what the proxy must serve, the two TLS modes a real deployment runs, the two ways to run the edge one, the…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/reverse-proxy-tls.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/db-observability",
          "file": "psa/next/reference/db-observability.md",
          "sourcePath": "reference/db-observability.md",
          "title": "Database observability",
          "description": "Marula measures performance one endpoint at a time. That leaves the real query mix unseen and the slow tail unmeasured, so the database now records both.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/db-observability.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/pg18-upgrade",
          "file": "psa/next/reference/pg18-upgrade.md",
          "sourcePath": "reference/pg18-upgrade.md",
          "title": "Upgrading Postgres 17 to 18",
          "description": "Marula runs Postgres 18 + pgvector everywhere since the 2026-09 transition (deploy/docker-compose.yml, the Helm chart, and the desktop test app all pin…",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/pg18-upgrade.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/upgrade-matrix",
          "file": "psa/next/reference/upgrade-matrix.md",
          "sourcePath": "reference/upgrade-matrix.md",
          "title": "Upgrade matrix",
          "description": "Every tagged Marula release and the N−2 upgrade paths proven in CI, with the fixture anchors and covered surfaces.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/upgrade-matrix.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/reference/embedding-model-catalogue",
          "file": "psa/next/reference/embedding-model-catalogue.md",
          "sourcePath": "reference/embedding-model-catalogue.md",
          "title": "Embedding model catalogue",
          "description": "Marula turns tickets, comments, clients and knowledge articles into vectors so search can match on meaning as well as words.",
          "section": "Reference",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/reference/embedding-model-catalogue.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation",
          "file": "psa/next/explanation.md",
          "sourcePath": "explanation/index.md",
          "title": "Explanation",
          "description": "These pages explain why Marula works the way it does: why renaming a board column never breaks an SLA timer, why billing corrections create credit notes…",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/index.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/why-marula",
          "file": "psa/next/explanation/why-marula.md",
          "sourcePath": "explanation/why-marula.md",
          "title": "Why we're building Marula",
          "description": "Marula's positioning narrative, quoted verbatim: why the PSA was built and what it refuses to repeat.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/why-marula.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/instant-first",
          "file": "psa/next/explanation/instant-first.md",
          "sourcePath": "explanation/instant-first.md",
          "title": "Instant-first interaction",
          "description": "When you are on the phone with a customer and updating a ticket's priority or assignee, you shouldn't have to hunt for a Save button at the bottom of a form…",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/instant-first.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/ai-deny-by-default",
          "file": "psa/next/explanation/ai-deny-by-default.md",
          "sourcePath": "explanation/ai-deny-by-default.md",
          "title": "AI: deny-by-default and the decision harness",
          "description": "Marula ships AI deny-by-default: the org switch stays off until grants, caps and credentials make a surface audible.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/ai-deny-by-default.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/customizations-are-data",
          "file": "psa/next/explanation/customizations-are-data.md",
          "sourcePath": "explanation/customizations-are-data.md",
          "title": "Customizations are data, not code",
          "description": "Every MSP runs its service desk a little differently: you have your own board column names, custom client fields, SLA rules, and ticket automations.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/customizations-are-data.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/provenance-vs-audit",
          "file": "psa/next/explanation/provenance-vs-audit.md",
          "sourcePath": "explanation/provenance-vs-audit.md",
          "title": "Provenance vs audit: two append-only ledgers, different granularity",
          "description": "When an owner or service lead asks \"Who changed this client's billing rate?\" or \"Who viewed that domain admin password yesterday?\", you need a straight…",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/provenance-vs-audit.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/billing-corrections",
          "file": "psa/next/explanation/billing-corrections.md",
          "sourcePath": "explanation/billing-corrections.md",
          "title": "Billing corrections, and where tax lives",
          "description": "An issued invoice is a record of what happened, not a draft that can be tidied up later.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/billing-corrections.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/contract-relationship-types",
          "file": "psa/next/explanation/contract-relationship-types.md",
          "sourcePath": "explanation/contract-relationship-types.md",
          "title": "Contracts: one shape per client relationship",
          "description": "A Marula contract is the commercial answer to one question: how does this client pay for this work?",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/contract-relationship-types.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/fx-additivity",
          "file": "psa/next/explanation/fx-additivity.md",
          "sourcePath": "explanation/fx-additivity.md",
          "title": "FX additivity and the append-only rate book",
          "description": "Two contracts govern money in multi-currency stacks, and they travel together. The command-side procedure is the FX how-to; this page explains the why they…",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/fx-additivity.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/kb-class-categories",
          "file": "psa/next/explanation/kb-class-categories.md",
          "sourcePath": "explanation/kb-class-categories.md",
          "title": "Knowledge-base categories and the secret vault share one grant model",
          "description": "Your runbooks in the Knowledge Base (/kb) and your stored credentials in the Secret Vault (/passwords) use the exact same folder permission model (ADR 0006).",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/kb-class-categories.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/portal-isolation",
          "file": "psa/next/explanation/portal-isolation.md",
          "sourcePath": "explanation/portal-isolation.md",
          "title": "The portal isolation model",
          "description": "The portal is not a theme on the staff product. It is a separate trust zone with its own principals, its own sign-in shell, and its own knowledge gate.",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/portal-isolation.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/explanation/upgrade-policy",
          "file": "psa/next/explanation/upgrade-policy.md",
          "sourcePath": "explanation/upgrade-policy.md",
          "title": "The upgrade compatibility policy",
          "description": "Marula asks organizations to bet their operating system on it. That bet is only rational if upgrades are boring. Two commitments define the whole document:",
          "section": "Explanation",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/explanation/upgrade-policy.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/troubleshooting",
          "file": "psa/next/troubleshooting.md",
          "sourcePath": "troubleshooting.md",
          "title": "Troubleshooting",
          "description": "Start from what you see. Each entry below names a symptom in plain words, the checks in the order they usually find it, and the page that explains the part…",
          "section": "Troubleshooting",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/troubleshooting.md"
        },
        {
          "product": "psa",
          "version": "next",
          "channel": "next",
          "route": "/docs/psa/next/how-to/get-help",
          "file": "psa/next/how-to/get-help.md",
          "sourcePath": "how-to/get-help.md",
          "title": "How to get help inside Marula",
          "description": "Every entry is a page from the public docs site — the same markdown that lives at getmarula.com/docs.",
          "section": "Get help",
          "license": "CC-BY-4.0",
          "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
          "sourceUrl": "https://github.com/marulahq/marula-core/tree/main/docs/site/how-to/get-help.md"
        }
      ]
    }
  ]
}
