KosmoKrator

productivity

Sendy Lua API for KosmoKrator Agents

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

Lua Namespace

Agents call this integration through app.integrations.sendy.*. Use lua_read_doc("integrations.sendy") 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 Sendy workflow without starting an interactive agent session.

Inline Lua call
kosmo integrations:lua --eval 'dump(app.integrations.sendy.subscribe({list = "example_list", email = "example_email", name = "example_name", country = "example_country", ipaddress = "example_ipaddress", referrer = "example_referrer", gdpr = "example_gdpr", silent = "example_silent"}))' --json
Read Lua docs headlessly
kosmo integrations:lua --eval 'print(docs.read("sendy"))' --json
kosmo integrations:lua --eval 'print(docs.read("sendy.subscribe"))' --json

Workflow file

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

workflow.lua
local sendy = app.integrations.sendy
local result = sendy.subscribe({list = "example_list", email = "example_email", name = "example_name", country = "example_country", ipaddress = "example_ipaddress", referrer = "example_referrer", gdpr = "example_gdpr", silent = "example_silent"})

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.sendy, app.mcp.*, docs.*, json.*, and regex.*. Use app.integrations.sendy.default.* or app.integrations.sendy.work.* when you configured named credential accounts.

MCP-only Lua

If the script only needs configured MCP servers and does not need Sendy, 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.

Sendy Lua Reference

Sendy is self-hosted, so every account needs both an API key and the installation hostname. The integration uses Sendy’s official form-post API and normalizes plain-text responses into small agent-friendly objects.

subscribe

Subscribe or update an email address on a list.

local result = app.integrations.sendy.subscribe({
  list = "list_abc",
  email = "reader@example.test",
  name = "Example Reader",
  country = "US",
  gdpr = "true",
  custom_fields = {
    Plan = "Pro"
  }
})

Optional fields include country, ipaddress, referrer, gdpr, silent, and custom_fields.

unsubscribe

Unsubscribe an email address from a list.

local result = app.integrations.sendy.unsubscribe({
  list = "list_abc",
  email = "reader@example.test"
})

delete_subscriber

Delete a subscriber from a list.

local result = app.integrations.sendy.delete_subscriber({
  list_id = "list_abc",
  email = "reader@example.test"
})

subscription_status

Get a subscriber’s status in a list. Sendy can return values such as Subscribed, Unsubscribed, Unconfirmed, Bounced, Soft bounced, or Complained.

local result = app.integrations.sendy.subscription_status({
  list_id = "list_abc",
  email = "reader@example.test"
})

print(result.status)

list_subscribers

Get the active subscriber count for a list. The tool name is historical; it maps to Sendy’s active-subscriber-count.php endpoint.

local result = app.integrations.sendy.list_subscribers({
  list_id = "list_abc"
})

print(result.subscribers)

get_lists

Get lists for a brand.

local lists = app.integrations.sendy.get_lists({
  brand_id = "1",
  include_hidden = true
})

get_brands

Get all brands visible to the API key.

local brands = app.integrations.sendy.get_brands({})

create_campaign

Create a draft, send immediately, or schedule a campaign. Sendy requires brand_id for drafts, and requires list_ids or segment_ids when send_campaign = 1.

local result = app.integrations.sendy.create_campaign({
  from_name = "Example Corp",
  from_email = "newsletter@example.test",
  reply_to = "support@example.test",
  title = "May Newsletter",
  subject = "What changed this month",
  html_text = "<h1>Hello</h1><p>Monthly update.</p>",
  plain_text = "Hello\n\nMonthly update.",
  list_ids = "list_abc",
  send_campaign = 1,
  track_opens = 1,
  track_clicks = 1
})

Scheduling options:

local result = app.integrations.sendy.create_campaign({
  from_name = "Example Corp",
  from_email = "newsletter@example.test",
  reply_to = "support@example.test",
  title = "Scheduled Newsletter",
  subject = "Scheduled update",
  html_text = "<h1>Scheduled</h1>",
  list_ids = "list_abc",
  send_campaign = 1,
  schedule_date_time = "June 15, 2026 6:05pm",
  schedule_timezone = "America/New_York"
})

get_current_user

Compatibility alias for get_brands.

local brands = app.integrations.sendy.get_current_user({})

Multi-Account Usage

app.integrations.sendy.subscribe({...})
app.integrations.sendy.default.subscribe({...})
app.integrations.sendy.marketing.subscribe({...})
Raw agent markdown
# Sendy Lua Reference

Sendy is self-hosted, so every account needs both an API key and the installation hostname. The integration uses Sendy's official form-post API and normalizes plain-text responses into small agent-friendly objects.

## subscribe

Subscribe or update an email address on a list.

```lua
local result = app.integrations.sendy.subscribe({
  list = "list_abc",
  email = "reader@example.test",
  name = "Example Reader",
  country = "US",
  gdpr = "true",
  custom_fields = {
    Plan = "Pro"
  }
})
```

Optional fields include `country`, `ipaddress`, `referrer`, `gdpr`, `silent`, and `custom_fields`.

## unsubscribe

Unsubscribe an email address from a list.

```lua
local result = app.integrations.sendy.unsubscribe({
  list = "list_abc",
  email = "reader@example.test"
})
```

## delete_subscriber

Delete a subscriber from a list.

```lua
local result = app.integrations.sendy.delete_subscriber({
  list_id = "list_abc",
  email = "reader@example.test"
})
```

## subscription_status

Get a subscriber's status in a list. Sendy can return values such as `Subscribed`, `Unsubscribed`, `Unconfirmed`, `Bounced`, `Soft bounced`, or `Complained`.

```lua
local result = app.integrations.sendy.subscription_status({
  list_id = "list_abc",
  email = "reader@example.test"
})

print(result.status)
```

## list_subscribers

Get the active subscriber count for a list. The tool name is historical; it maps to Sendy's `active-subscriber-count.php` endpoint.

```lua
local result = app.integrations.sendy.list_subscribers({
  list_id = "list_abc"
})

print(result.subscribers)
```

## get_lists

Get lists for a brand.

```lua
local lists = app.integrations.sendy.get_lists({
  brand_id = "1",
  include_hidden = true
})
```

## get_brands

Get all brands visible to the API key.

```lua
local brands = app.integrations.sendy.get_brands({})
```

## create_campaign

Create a draft, send immediately, or schedule a campaign. Sendy requires `brand_id` for drafts, and requires `list_ids` or `segment_ids` when `send_campaign = 1`.

```lua
local result = app.integrations.sendy.create_campaign({
  from_name = "Example Corp",
  from_email = "newsletter@example.test",
  reply_to = "support@example.test",
  title = "May Newsletter",
  subject = "What changed this month",
  html_text = "<h1>Hello</h1><p>Monthly update.</p>",
  plain_text = "Hello\n\nMonthly update.",
  list_ids = "list_abc",
  send_campaign = 1,
  track_opens = 1,
  track_clicks = 1
})
```

Scheduling options:

```lua
local result = app.integrations.sendy.create_campaign({
  from_name = "Example Corp",
  from_email = "newsletter@example.test",
  reply_to = "support@example.test",
  title = "Scheduled Newsletter",
  subject = "Scheduled update",
  html_text = "<h1>Scheduled</h1>",
  list_ids = "list_abc",
  send_campaign = 1,
  schedule_date_time = "June 15, 2026 6:05pm",
  schedule_timezone = "America/New_York"
})
```

## get_current_user

Compatibility alias for `get_brands`.

```lua
local brands = app.integrations.sendy.get_current_user({})
```

## Multi-Account Usage

```lua
app.integrations.sendy.subscribe({...})
app.integrations.sendy.default.subscribe({...})
app.integrations.sendy.marketing.subscribe({...})
```
Metadata-derived Lua example
local result = app.integrations.sendy.subscribe({list = "example_list", email = "example_email", name = "example_name", country = "example_country", ipaddress = "example_ipaddress", referrer = "example_referrer", gdpr = "example_gdpr", silent = "example_silent"})
print(result)

Functions

subscribe Write

Subscribe an email address to a Sendy mailing list. Optionally provide a name and custom fields.

Lua path
app.integrations.sendy.subscribe
Full name
sendy.sendy_subscribe
ParameterTypeRequiredDescription
list string yes The list ID to subscribe to.
email string yes The subscriber's email address.
name string no The subscriber's name (optional).
country string no Optional two-letter country code.
ipaddress string no Optional signup IP address.
referrer string no Optional signup referrer URL.
gdpr string no Set to "true" for GDPR-compliant signups.
silent string no Set to "true" to bypass double opt-in where appropriate.
custom_fields object no Additional custom field tag values, keyed by the Sendy personalization tag name.
unsubscribe Write

Unsubscribe an email address from a Sendy mailing list.

Lua path
app.integrations.sendy.unsubscribe
Full name
sendy.sendy_unsubscribe
ParameterTypeRequiredDescription
list string yes The list ID to unsubscribe from.
email string yes The subscriber's email address.
delete_subscriber Write

Delete a subscriber from a Sendy list by email address.

Lua path
app.integrations.sendy.delete_subscriber
Full name
sendy.sendy_delete_subscriber
ParameterTypeRequiredDescription
list_id string yes Encrypted list ID.
email string yes Subscriber email address to delete.
subscription_status Read

Get the current subscription status for an email address in a Sendy list.

Lua path
app.integrations.sendy.subscription_status
Full name
sendy.sendy_subscription_status
ParameterTypeRequiredDescription
list_id string yes Encrypted list ID.
email string yes Subscriber email address to check.
active_subscriber_count Read

Get the active subscriber count for a Sendy mailing list.

Lua path
app.integrations.sendy.active_subscriber_count
Full name
sendy.sendy_list_subscribers
ParameterTypeRequiredDescription
list_id string yes The list ID to query subscriber count for.
get_lists Read

Get all lists for a Sendy brand, optionally including hidden lists.

Lua path
app.integrations.sendy.get_lists
Full name
sendy.sendy_get_lists
ParameterTypeRequiredDescription
brand_id string yes Sendy brand ID.
include_hidden boolean no Include hidden lists when true. Defaults to false.
get_brands Read

Get all brands available in the Sendy installation.

Lua path
app.integrations.sendy.get_brands
Full name
sendy.sendy_get_brands
ParameterTypeRequiredDescription
No parameters.
create_campaign Write

Create a new email campaign in Sendy. You can create a draft or send immediately. Requires a list ID, subject, HTML content, and sender details.

Lua path
app.integrations.sendy.create_campaign
Full name
sendy.sendy_create_campaign
ParameterTypeRequiredDescription
from_name string yes Sender name (e.g., "Acme Corp").
from_email string yes Sender email address (e.g., "hello@acme.com").
reply_to string yes Reply-to email address.
title string yes Internal campaign title (for your reference).
subject string yes Email subject line.
html_text string yes HTML content of the email.
list_ids string no Comma-separated list IDs. Required when sending without segment_ids.
plain_text string no Plain text version of the email. Auto-generated if omitted.
segment_ids string no Comma-separated segment IDs to send to. Required when sending without list_ids.
exclude_list_ids string no Comma-separated list IDs to exclude.
exclude_segments_ids string no Comma-separated segment IDs to exclude.
send_campaign integer no Set to 1 to send immediately, 0 or omit to save as draft.
brand_id string no Brand ID (required for multi-brand setups).
query_string string no UTM query string appended to links (e.g., "utm_source=sendy&utm_medium=email").
track_opens integer no 0 disables, 1 enables, 2 enables anonymous open tracking.
track_clicks integer no 0 disables, 1 enables, 2 enables anonymous click tracking.
schedule_date_time string no Schedule time such as "June 15, 2026 6:05pm". Minutes must be increments of 5.
schedule_timezone string no PHP timezone name for scheduled campaigns, such as America/New_York.
get_current_user Read

Get Sendy brands for the configured API key. This keeps the historical get_current_user tool slug for compatibility.

Lua path
app.integrations.sendy.get_current_user
Full name
sendy.sendy_get_current_user
ParameterTypeRequiredDescription
No parameters.