COM1_
TERMINAL MODEGET STARTED →
BOT://INGEST

Send events into COM1

Setup and copy-pasteable cURL, Python and Node.js examples for the COM1 Bot Ingest API.

BOT API / RECEIVE EVENTS

This guide covers a server/script sending text, structured data and alerts to a COM1 bot inbox or other chosen standard conversation. Calls use HTTPS and a scoped token; they do not require a logged-in human app session.

Step 1 — Configure and copy a token

  1. In COM1, run /bot and create or select a bot.
  2. Select + TOKEN; name it for the integration and choose its target conversation.
  3. Enable send_text, send_structured and/or send_alert as needed.
  4. Copy the raw token once and store it in an environment variable or a secrets manager.
# Example in your own shell — substitute actual values.
export COM1_PROJECT_URL='https://YOUR_PROJECT.supabase.co'
export COM1_BOT_TOKEN='YOUR_ONE_TIME_BOT_TOKEN'

Do not use a Supabase anon key or service-role key as your bot token. The bot token is created inside COM1. Never place it in a client-side website, mobile APK, repository or public screenshot.

Step 2 — Send a simple text packet

curl --fail-with-body -sS -X POST \
  "$COM1_PROJECT_URL/functions/v1/com1-bot-ingest" \
  -H "Authorization: Bearer $COM1_BOT_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "event_id": "hello-001",
    "kind": "text",
    "message": "Hello from homelab01. All systems nominal."
  }'

Expected behavior: one incoming packet from your bot in the selected COM1 conversation. The HTTP response may include acceptance/deduplication metadata; check the response and chat, rather than assuming a request succeeded from its HTTP status alone.

Step 3 — Send an alert with useful fields

curl --fail-with-body -sS -X POST \
  "$COM1_PROJECT_URL/functions/v1/com1-bot-ingest" \
  -H "Authorization: Bearer $COM1_BOT_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "event_id": "disk-alert-20261010-01",
    "kind": "alert",
    "title": "DISK SPACE LOW",
    "message": "Root partition has reached 92% capacity.",
    "level": "warning",
    "fields": {"host": "homelab01", "disk": "/", "used_percent": 92}
  }'

Event body reference

FieldRules in supplied migration
kindtext, structured or alert; defaults to text.
messageRequired nonblank string, at most 4,000 characters.
event_idOptional, at most 128 characters; prevents duplicate accepted events for the same token when retried with the same payload.
titleOptional up to 100 characters; supported on structured/alert events.
levelinfo, success, warning, error, critical. Text events must use info.
fieldsUp to 20 scalar fields. Keys must match [A-Za-z0-9_.:-]{1,40}; scalar values max 256 characters.

Plain text events cannot carry a title or nonempty fields. For a card with fields, use structured or alert and grant the corresponding permission.

Tokens, idempotency and rate limits

Each token has a destination conversation, permissions, revocation state and per-minute/per-day limits. The supplied baseline quotas are 30/minute and 2,000/day for ordinary accounts, and 120/minute and 20,000/day for the higher feature tier, subject to actual deployed configuration. Reusing an accepted event_id with an identical payload is idempotent; reusing the same ID with different content is rejected.

Python example — server monitoring

import json
import os
import urllib.request

url = os.environ['COM1_PROJECT_URL'].rstrip('/') + '/functions/v1/com1-bot-ingest'
token = os.environ['COM1_BOT_TOKEN']
body = {
    'event_id': 'uptime-example-001',
    'kind': 'structured',
    'title': 'SYSTEM STATUS',
    'message': 'Heartbeat from my home server',
    'fields': {'host': 'homelab01', 'uptime_hours': 240, 'healthy': True},
}
req = urllib.request.Request(
    url,
    data=json.dumps(body).encode('utf-8'),
    headers={'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json'},
    method='POST',
)
with urllib.request.urlopen(req, timeout=15) as resp:
    print(resp.status, resp.read().decode('utf-8'))

Node.js example — CI/deployment notification

// Node.js 18+ — runs server-side, not inside a webpage.
const url = `${process.env.COM1_PROJECT_URL.replace(/\/$/, '')}/functions/v1/com1-bot-ingest`;
const res = await fetch(url, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.COM1_BOT_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    event_id: 'deploy-build-1024',
    kind: 'alert',
    title: 'DEPLOY SUCCESS',
    message: 'New release is live.',
    level: 'success',
    fields: { service: 'com1-web', build: '1024' },
  }),
});
console.log(res.status, await res.text());
if (!res.ok) process.exitCode = 1;

Before production

  • Store secrets outside source files and rotate tokens that leak.
  • Use stable but unique event IDs for each event; never reuse one for a different payload.
  • Retry transient failures with the same ID and exponential backoff; do not hammer a rate-limited endpoint.
  • Never send personal data or full logs by default. Redact credentials before posting.
  • Keep the relevant Supabase Edge Function and Bot API migrations deployed.

Next: Two-way command callbacks or Practical recipes.