KosmoKrator

analytics

Google Analytics Lua API for KosmoKrator Agents

Agent-facing Lua documentation and function reference for the Google Analytics KosmoKrator integration.

Lua Namespace

Agents call this integration through app.integrations.google_analytics.*. Use lua_read_doc("integrations.google-analytics") inside KosmoKrator to discover the same reference at runtime.

Call Lua from the Headless CLI

Use kosmo integrations:lua when a shell script, CI job, cron job, or another coding CLI should run a deterministic Google Analytics workflow without starting an interactive agent session.

Inline Lua call
kosmo integrations:lua --eval 'dump(app.integrations.google_analytics.list_properties({}))' --json
Read Lua docs headlessly
kosmo integrations:lua --eval 'print(docs.read("google-analytics"))' --json
kosmo integrations:lua --eval 'print(docs.read("google-analytics.list_properties"))' --json

Workflow file

Put repeatable logic in a Lua file, then execute it with JSON output for the calling process.

workflow.lua
local google_analytics = app.integrations.google_analytics
local result = google_analytics.list_properties({})

dump(result)
Run the workflow
kosmo integrations:lua workflow.lua --json
kosmo integrations:lua workflow.lua --force --json
Namespace note. integrations:lua exposes app.integrations.google_analytics, app.mcp.*, docs.*, json.*, and regex.*. Use app.integrations.google_analytics.default.* or app.integrations.google_analytics.work.* when you configured named credential accounts.

MCP-only Lua

If the script only needs configured MCP servers and does not need Google Analytics, use the narrower mcp:lua command.

MCP Lua command
# Use mcp:lua for MCP-only scripts; use integrations:lua for this integration namespace.
kosmo mcp:lua --eval 'dump(mcp.servers())' --json

Agent-Facing Lua Docs

This is the rendered version of the full Lua documentation exposed to agents when they inspect the integration namespace.

Google Integration — Lua API Supplement

Google services are registered as separate namespaces: integrations.gmail, integrations["google-sheets"], integrations["google-calendar"], integrations["google-drive"], etc. All share the same OAuth credentials.

Gmail

Send email with CC/BCC:

app.integrations.gmail.gmail_send_email({
    to = "alice@example.com",
    subject = "Q1 Report",
    body = "Please find the report attached.",
    cc = "bob@example.com, carol@example.com",
    bcc = "manager@example.com",
})

Search, read, then reply workflow:

-- Step 1: Search for messages
local results = app.integrations.gmail.gmail_search_emails({
    query = "from:alice subject:meeting is:unread",
    max_results = 5,
})

-- Step 2: Read the full message
local msg = app.integrations.gmail.gmail_read({ message_id = results.messages[1].id })

-- Step 3: Reply in the same thread
app.integrations.gmail.gmail_reply({
    message_id = msg.id,
    thread_id = msg.threadId,
    body = "Thanks, I'll be there.",
    cc = "team@example.com",
})

Draft vs direct send — use create_draft to stage an email without sending, then send_draft to send it later:

-- Create a draft (not sent)
local draft = app.integrations.gmail.gmail_create_draft({
    to = "client@example.com",
    subject = "Proposal",
    body = "Draft content here...",
})

-- Send it later using the draft ID
app.integrations.gmail.gmail_send_draft({ draft_id = draft.draftId })

Google Sheets

Values use 2D Lua tables — each inner table is one row:

local values = {
    {"Name", "Age", "City"},
    {"Alice", 30, "NYC"},
    {"Bob", 25, "LA"},
}

A1 notation examples:

  • "Sheet1!A1:D10" — specific range
  • "Sheet1!A:A" — entire column
  • "Sheet1" — entire sheet
  • "'My Sheet'!A1:B2" — sheet names with spaces need quotes

Input modes: "user_entered" (default) parses formulas and dates, "raw" stores literal strings.

Create a spreadsheet, add a sheet, write data:

-- Create a new spreadsheet
local ss = app.integrations["google-sheets"].google_sheets_create({ title = "Q1 Sales" })
local id = ss.spreadsheetId

-- Add a second sheet/tab
app.integrations["google-sheets"].google_sheets_add_sheet({
    spreadsheet_id = id,
    title = "By Region",
})

-- Write data with headers
app.integrations["google-sheets"].google_sheets_write_range({
    spreadsheet_id = id,
    range = "Sheet1!A1:C3",
    values = {
        {"Region", "Revenue", "Growth"},
        {"North", 50000, "=B2/50000-1"},
        {"South", 42000, "=B3/42000-1"},
    },
    input = "user_entered",  -- parses the formulas
})

Read data back:

local data = app.integrations["google-sheets"].google_sheets_read_range({
    spreadsheet_id = id,
    range = "Sheet1!A1:C3",
    render = "formatted",  -- "formatted" (default), "unformatted", or "formula"
})
-- data.values is a 2D table: {{"Region","Revenue","Growth"}, {"North","50000","0%"}, ...}

Append vs write — append_rows auto-detects the last row and adds below it:

app.integrations["google-sheets"].google_sheets_append({
    spreadsheet_id = id,
    range = "Sheet1",
    values = {
        {"East", 38000, "=B4/38000-1"},
    },
    input = "user_entered",
})

Google Calendar

Create a timed event with attendees:

app.integrations["google-calendar"].google_calendar_create_event({
    summary = "Sprint Planning",
    description = "Bi-weekly sprint planning session",
    location = "Conference Room B",
    start_date_time = "2026-04-01T10:00:00-05:00",
    end_date_time = "2026-04-01T11:00:00-05:00",
    time_zone = "America/New_York",
    attendees = "alice@example.com, bob@example.com",
    recurrence = "RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=10",
})

Create an all-day event:

app.integrations["google-calendar"].google_calendar_create_event({
    summary = "Company Holiday",
    start_date = "2026-07-04",
    end_date = "2026-07-05",
})

Date/time format: ISO 8601 with timezone offset for timed events (2026-04-01T10:00:00-05:00), plain YYYY-MM-DD for all-day events. Use time_zone for IANA names like "America/New_York".

Google Drive

Search for files, then get details:

-- Search by name and type
local results = app.integrations["google-drive"].google_drive_search_files({
    query = "name contains 'report' and mimeType = 'application/vnd.google-apps.spreadsheet'",
    max_results = 10,
    order_by = "modifiedTime desc",
})

-- Get full file info (and optionally export content)
local file = app.integrations["google-drive"].google_drive_get_file({
    file_id = results.files[1].id,
    export_as = "csv",  -- "text", "csv", or "markdown" (Google Workspace files only)
})

Common Drive query patterns:

  • "name contains 'budget'" — by name
  • "mimeType = 'application/vnd.google-apps.spreadsheet'" — Sheets
  • "mimeType = 'application/vnd.google-apps.document'" — Docs
  • "mimeType = 'application/vnd.google-apps.folder'" — folders
  • "modifiedTime > '2026-01-01'" — recently modified
  • "sharedWithMe = true" — shared files
  • "'FOLDER_ID' in parents" — files in a folder

Share a file:

-- Share with a specific user
app.integrations["google-drive"].google_drive_share_file({
    file_id = "abc123",
    role = "writer",       -- "reader", "writer", or "commenter"
    email = "alice@example.com",
    notify = "true",
})

-- Share with anyone via link
app.integrations["google-drive"].google_drive_share_file({
    file_id = "abc123",
    role = "reader",
    type = "anyone",
})

Google Analytics

The GA4 namespace is app.integrations["google-analytics"]. Start with property discovery, then run metadata or report tools against the numeric property ID.

local properties = app.integrations["google-analytics"].google_analytics_list_properties({})

Run a standard report:

local report = app.integrations["google-analytics"].google_analytics_report({
    property_id = "123456789",
    metrics = {"sessions", "totalUsers"},
    dimensions = {"sessionDefaultChannelGroup"},
    start_date = "28daysAgo",
    end_date = "yesterday",
    order_by = "sessions",
    order_direction = "desc",
    limit = 20,
})

Check compatibility before combining unfamiliar dimensions and metrics:

local compatibility = app.integrations["google-analytics"].google_analytics_check_compatibility({
    property_id = "123456789",
    metrics = {"sessions"},
    dimensions = {"country", "deviceCategory"},
})

Run pivot and batch reports when you need the exact Google Analytics Data API response shape:

local pivot = app.integrations["google-analytics"].google_analytics_pivot_report({
    property_id = "123456789",
    metrics = {"sessions"},
    dimensions = {"country", "deviceCategory"},
    pivots = {
        { fieldNames = {"country"}, limit = 10 },
        { fieldNames = {"deviceCategory"}, limit = 5 },
    },
})

local batch = app.integrations["google-analytics"].google_analytics_batch_run_reports({
    property_id = "123456789",
    requests = {
        {
            metrics = {{ name = "sessions" }},
            dimensions = {{ name = "country" }},
            dateRanges = {{ startDate = "7daysAgo", endDate = "yesterday" }},
        },
    },
})

Tips

  • All Google APIs share the same OAuth token — if Gmail is connected, the same credentials work for Sheets, Drive, Calendar, etc.
  • Use input = "user_entered" when writing Sheets data that contains formulas (e.g., "=SUM(A1:A10)") or dates. Use "raw" for literal strings.
  • Sheet names with spaces must be quoted in A1 notation: "'My Sheet'!A1:B2".
  • append_rows is better than write_range when adding rows to an existing table — it auto-detects where the data ends.
  • Calendar event times use ISO 8601 with timezone offset. Always include the offset or set time_zone explicitly.
  • Drive search excludes trashed files by default.

Multi-Account Usage

If you have multiple Google service accounts configured, use account-specific namespaces:

-- Default account (always works)
app.integrations["google-sheets"].function_name({...})

-- Explicit default (portable across setups)
app.integrations["google-sheets"].default.function_name({...})

-- Named accounts
app.integrations["google-sheets"].work.function_name({...})
app.integrations["google-sheets"].personal.function_name({...})

All functions are identical across accounts — only the credentials differ.

Raw agent markdown
# Google Integration — Lua API Supplement

Google services are registered as separate namespaces: `integrations.gmail`, `integrations["google-sheets"]`, `integrations["google-calendar"]`, `integrations["google-drive"]`, etc. All share the same OAuth credentials.

## Gmail

Send email with CC/BCC:

```lua
app.integrations.gmail.gmail_send_email({
    to = "alice@example.com",
    subject = "Q1 Report",
    body = "Please find the report attached.",
    cc = "bob@example.com, carol@example.com",
    bcc = "manager@example.com",
})
```

Search, read, then reply workflow:

```lua
-- Step 1: Search for messages
local results = app.integrations.gmail.gmail_search_emails({
    query = "from:alice subject:meeting is:unread",
    max_results = 5,
})

-- Step 2: Read the full message
local msg = app.integrations.gmail.gmail_read({ message_id = results.messages[1].id })

-- Step 3: Reply in the same thread
app.integrations.gmail.gmail_reply({
    message_id = msg.id,
    thread_id = msg.threadId,
    body = "Thanks, I'll be there.",
    cc = "team@example.com",
})
```

Draft vs direct send -- use `create_draft` to stage an email without sending, then `send_draft` to send it later:

```lua
-- Create a draft (not sent)
local draft = app.integrations.gmail.gmail_create_draft({
    to = "client@example.com",
    subject = "Proposal",
    body = "Draft content here...",
})

-- Send it later using the draft ID
app.integrations.gmail.gmail_send_draft({ draft_id = draft.draftId })
```

## Google Sheets

Values use 2D Lua tables -- each inner table is one row:

```lua
local values = {
    {"Name", "Age", "City"},
    {"Alice", 30, "NYC"},
    {"Bob", 25, "LA"},
}
```

A1 notation examples:

- `"Sheet1!A1:D10"` -- specific range
- `"Sheet1!A:A"` -- entire column
- `"Sheet1"` -- entire sheet
- `"'My Sheet'!A1:B2"` -- sheet names with spaces need quotes

Input modes: `"user_entered"` (default) parses formulas and dates, `"raw"` stores literal strings.

Create a spreadsheet, add a sheet, write data:

```lua
-- Create a new spreadsheet
local ss = app.integrations["google-sheets"].google_sheets_create({ title = "Q1 Sales" })
local id = ss.spreadsheetId

-- Add a second sheet/tab
app.integrations["google-sheets"].google_sheets_add_sheet({
    spreadsheet_id = id,
    title = "By Region",
})

-- Write data with headers
app.integrations["google-sheets"].google_sheets_write_range({
    spreadsheet_id = id,
    range = "Sheet1!A1:C3",
    values = {
        {"Region", "Revenue", "Growth"},
        {"North", 50000, "=B2/50000-1"},
        {"South", 42000, "=B3/42000-1"},
    },
    input = "user_entered",  -- parses the formulas
})
```

Read data back:

```lua
local data = app.integrations["google-sheets"].google_sheets_read_range({
    spreadsheet_id = id,
    range = "Sheet1!A1:C3",
    render = "formatted",  -- "formatted" (default), "unformatted", or "formula"
})
-- data.values is a 2D table: {{"Region","Revenue","Growth"}, {"North","50000","0%"}, ...}
```

Append vs write -- `append_rows` auto-detects the last row and adds below it:

```lua
app.integrations["google-sheets"].google_sheets_append({
    spreadsheet_id = id,
    range = "Sheet1",
    values = {
        {"East", 38000, "=B4/38000-1"},
    },
    input = "user_entered",
})
```

## Google Calendar

Create a timed event with attendees:

```lua
app.integrations["google-calendar"].google_calendar_create_event({
    summary = "Sprint Planning",
    description = "Bi-weekly sprint planning session",
    location = "Conference Room B",
    start_date_time = "2026-04-01T10:00:00-05:00",
    end_date_time = "2026-04-01T11:00:00-05:00",
    time_zone = "America/New_York",
    attendees = "alice@example.com, bob@example.com",
    recurrence = "RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=10",
})
```

Create an all-day event:

```lua
app.integrations["google-calendar"].google_calendar_create_event({
    summary = "Company Holiday",
    start_date = "2026-07-04",
    end_date = "2026-07-05",
})
```

Date/time format: ISO 8601 with timezone offset for timed events (`2026-04-01T10:00:00-05:00`), plain `YYYY-MM-DD` for all-day events. Use `time_zone` for IANA names like `"America/New_York"`.

## Google Drive

Search for files, then get details:

```lua
-- Search by name and type
local results = app.integrations["google-drive"].google_drive_search_files({
    query = "name contains 'report' and mimeType = 'application/vnd.google-apps.spreadsheet'",
    max_results = 10,
    order_by = "modifiedTime desc",
})

-- Get full file info (and optionally export content)
local file = app.integrations["google-drive"].google_drive_get_file({
    file_id = results.files[1].id,
    export_as = "csv",  -- "text", "csv", or "markdown" (Google Workspace files only)
})
```

Common Drive query patterns:

- `"name contains 'budget'"` -- by name
- `"mimeType = 'application/vnd.google-apps.spreadsheet'"` -- Sheets
- `"mimeType = 'application/vnd.google-apps.document'"` -- Docs
- `"mimeType = 'application/vnd.google-apps.folder'"` -- folders
- `"modifiedTime > '2026-01-01'"` -- recently modified
- `"sharedWithMe = true"` -- shared files
- `"'FOLDER_ID' in parents"` -- files in a folder

Share a file:

```lua
-- Share with a specific user
app.integrations["google-drive"].google_drive_share_file({
    file_id = "abc123",
    role = "writer",       -- "reader", "writer", or "commenter"
    email = "alice@example.com",
    notify = "true",
})

-- Share with anyone via link
app.integrations["google-drive"].google_drive_share_file({
    file_id = "abc123",
    role = "reader",
    type = "anyone",
})
```

## Google Analytics

The GA4 namespace is `app.integrations["google-analytics"]`. Start with property discovery, then run metadata or report tools against the numeric property ID.

```lua
local properties = app.integrations["google-analytics"].google_analytics_list_properties({})
```

Run a standard report:

```lua
local report = app.integrations["google-analytics"].google_analytics_report({
    property_id = "123456789",
    metrics = {"sessions", "totalUsers"},
    dimensions = {"sessionDefaultChannelGroup"},
    start_date = "28daysAgo",
    end_date = "yesterday",
    order_by = "sessions",
    order_direction = "desc",
    limit = 20,
})
```

Check compatibility before combining unfamiliar dimensions and metrics:

```lua
local compatibility = app.integrations["google-analytics"].google_analytics_check_compatibility({
    property_id = "123456789",
    metrics = {"sessions"},
    dimensions = {"country", "deviceCategory"},
})
```

Run pivot and batch reports when you need the exact Google Analytics Data API response shape:

```lua
local pivot = app.integrations["google-analytics"].google_analytics_pivot_report({
    property_id = "123456789",
    metrics = {"sessions"},
    dimensions = {"country", "deviceCategory"},
    pivots = {
        { fieldNames = {"country"}, limit = 10 },
        { fieldNames = {"deviceCategory"}, limit = 5 },
    },
})

local batch = app.integrations["google-analytics"].google_analytics_batch_run_reports({
    property_id = "123456789",
    requests = {
        {
            metrics = {{ name = "sessions" }},
            dimensions = {{ name = "country" }},
            dateRanges = {{ startDate = "7daysAgo", endDate = "yesterday" }},
        },
    },
})
```

## Tips

- All Google APIs share the same OAuth token -- if Gmail is connected, the same credentials work for Sheets, Drive, Calendar, etc.
- Use `input = "user_entered"` when writing Sheets data that contains formulas (e.g., `"=SUM(A1:A10)"`) or dates. Use `"raw"` for literal strings.
- Sheet names with spaces must be quoted in A1 notation: `"'My Sheet'!A1:B2"`.
- `append_rows` is better than `write_range` when adding rows to an existing table -- it auto-detects where the data ends.
- Calendar event times use ISO 8601 with timezone offset. Always include the offset or set `time_zone` explicitly.
- Drive search excludes trashed files by default.

---

## Multi-Account Usage

If you have multiple Google service accounts configured, use account-specific namespaces:

```lua
-- Default account (always works)
app.integrations["google-sheets"].function_name({...})

-- Explicit default (portable across setups)
app.integrations["google-sheets"].default.function_name({...})

-- Named accounts
app.integrations["google-sheets"].work.function_name({...})
app.integrations["google-sheets"].personal.function_name({...})
```

All functions are identical across accounts — only the credentials differ.
Metadata-derived Lua example
local result = app.integrations.google_analytics.list_properties({})
print(result)

Functions

list_properties Read

List all accessible GA4 properties with their IDs and names. Use this first to discover the propertyId needed for other Analytics tools.

Lua path
app.integrations.google_analytics.list_properties
Full name
google-analytics.google_analytics_list_properties
ParameterTypeRequiredDescription
No parameters.
metadata Read

List all available dimensions and metrics for a GA4 property, including custom ones. Use this to discover what data can be queried in reports.

Lua path
app.integrations.google_analytics.metadata
Full name
google-analytics.google_analytics_metadata
ParameterTypeRequiredDescription
property_id string yes GA4 property ID (numeric, e.g., "123456789"). Use google_analytics_list_properties to find it.
realtime Read

Run a GA4 realtime report showing activity in the last 30 minutes. Common dimensions: country, city, deviceCategory, unifiedScreenName (page/screen), platform. Common metrics: activeUsers, screenPageViews, eventCount, conversions.

Lua path
app.integrations.google_analytics.realtime
Full name
google-analytics.google_analytics_realtime
ParameterTypeRequiredDescription
property_id string yes GA4 property ID (numeric, e.g., "123456789"). Use google_analytics_list_properties to find it.
metrics array no Metric names (default: ["activeUsers"]). Common: activeUsers, screenPageViews, eventCount, conversions.
dimensions array no Dimension names to group by (e.g., ["country", "unifiedScreenName"]). Optional — omit for aggregate totals.
limit integer no Max rows to return (default 10).
report Read

Run a GA4 analytics report. Returns rows of dimension/metric data for the specified date range. Common dimensions: sessionSource, sessionMedium, sessionDefaultChannelGroup (traffic source); pagePath, pageTitle, landingPage (pages); country, city (geo); deviceCategory, browser, operatingSystem (device); date, dateHour, month (time); newVsReturning (user); eventName (events). Common metrics: sessions, totalUsers, newUsers, activeUsers (traffic); screenPageViews, bounceRate, averageSessionDuration, engagementRate, sessionsPerUser (engagement); eventCount, conversions (events); purchaseRevenue, totalRevenue (e-commerce). Dates: YYYY-MM-DD or relative: "today", "yesterday", "7daysAgo", "28daysAgo", "30daysAgo", "90daysAgo", "365daysAgo". Filter operators: exact, contains, begins_with, ends_with, regex, in_list. Metric filter operators: equal, less_than, greater_than, less_than_or_equal, greater_than_or_equal.

Lua path
app.integrations.google_analytics.report
Full name
google-analytics.google_analytics_report
ParameterTypeRequiredDescription
property_id string yes GA4 property ID (numeric, e.g., "123456789"). Use google_analytics_list_properties to find it.
metrics array yes Metric names to measure (e.g., ["sessions", "totalUsers"]).
dimensions array no Dimension names to group by (e.g., ["country", "pagePath"]). Optional — omit for aggregate totals.
start_date string no Start date: YYYY-MM-DD or relative ("7daysAgo", "28daysAgo", "yesterday", "today"). Default: "28daysAgo".
end_date string no End date: YYYY-MM-DD or relative. Default: "yesterday".
compare_start_date string no Comparison period start date (for period-over-period).
compare_end_date string no Comparison period end date.
filters array no Dimension filters: [{dimension, operator, value}]. Operators: exact, contains, begins_with, ends_with, regex, in_list.
metric_filters array no Metric filters: [{metric, operator, value}]. Operators: equal, less_than, greater_than, less_than_or_equal, greater_than_or_equal.
order_by string no Dimension or metric name to sort by.
order_direction string no "asc" or "desc" (default "desc").
limit integer no Max rows to return (default 10).
offset integer no Pagination offset (default 0).
check_compatibility Read

Check whether GA4 dimensions and metrics can be combined in a report request.

Lua path
app.integrations.google_analytics.check_compatibility
Full name
google-analytics.google_analytics_check_compatibility
ParameterTypeRequiredDescription
property_id string yes GA4 property ID.
metrics array no Metric names to check.
dimensions array no Dimension names to check.
filters array no Dimension filters matching the report request.
metric_filters array no Metric filters matching the report request.
compatibility_filter string no Optional compatibility filter accepted by the Data API.
pivot_report Read

Run a GA4 pivot report for advanced cross-tabbed dimension and metric analysis.

Lua path
app.integrations.google_analytics.pivot_report
Full name
google-analytics.google_analytics_pivot_report
ParameterTypeRequiredDescription
property_id string yes GA4 property ID.
metrics array yes Metric names to measure.
dimensions array no Dimension names used by pivots.
pivots array no Data API pivot definitions. If omitted, one pivot is built from dimensions.
start_date string no Start date. Default: 28daysAgo.
end_date string no End date. Default: yesterday.
filters array no Dimension filters.
metric_filters array no Metric filters.
limit integer no Default pivot limit when pivots are omitted.
batch_run_reports Read

Run multiple GA4 standard report requests in one batchRunReports call.

Lua path
app.integrations.google_analytics.batch_run_reports
Full name
google-analytics.google_analytics_batch_run_reports
ParameterTypeRequiredDescription
property_id string yes GA4 property ID.
requests array yes Array of Data API RunReportRequest bodies.
batch_run_pivot_reports Read

Run multiple GA4 pivot report requests in one batchRunPivotReports call.

Lua path
app.integrations.google_analytics.batch_run_pivot_reports
Full name
google-analytics.google_analytics_batch_run_pivot_reports
ParameterTypeRequiredDescription
property_id string yes GA4 property ID.
requests array yes Array of Data API RunPivotReportRequest bodies.