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.
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 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.
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) kosmo integrations:lua workflow.lua --json
kosmo integrations:lua workflow.lua --force --json 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.
# 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({...})
``` 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
| Parameter | Type | Required | Description |
|---|---|---|---|
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
| Parameter | Type | Required | Description |
|---|---|---|---|
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
| Parameter | Type | Required | Description |
|---|---|---|---|
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
| Parameter | Type | Required | Description |
|---|---|---|---|
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
| Parameter | Type | Required | Description |
|---|---|---|---|
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
| Parameter | Type | Required | Description |
|---|---|---|---|
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
| Parameter | Type | Required | Description |
|---|---|---|---|
| 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
| Parameter | Type | Required | Description |
|---|---|---|---|
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
| Parameter | Type | Required | Description |
|---|---|---|---|
| No parameters. | |||