Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt

Use this file to discover all available pages before exploring further.

These endpoints are system-only. They are authenticated with a shared secret (CRON_SECRET for maintenance jobs, CRON_TOKEN for /api/cron/tick) and are intended to be invoked exclusively by AWS EventBridge Scheduler or an equivalent external cron.During pilot / initial deployment, EventBridge is typically not wired. That means:
  • /api/cron/tick exists and is callable, but is effectively unused until a scheduler starts hitting it.
  • Alert rules and report schedules will not fire automatically until a caller invokes this endpoint.
  • Features like Run Now (reports) and on-demand alert evaluation work independently and do not require any cron wiring.
See EventBridge Setup for the setup path (marked optional on purpose).

GET /api/v1/cron/export-interactions

Exports new interaction history rows for all active tenants as Hive-partitioned NDJSON files. Uses checkpoint tracking to export only rows created since the last run. Intended to be called by a cron scheduler (e.g., Vercel Cron Jobs, Kubernetes CronJob). Processes up to 10,000 rows per tenant per invocation.

Authentication

Requires a CRON_SECRET token via either:
  • Authorization: Bearer <CRON_SECRET> header
  • X-Cron-Secret: <CRON_SECRET> header

File Layout

exports/{tenantId}/interaction_history/year=YYYY/month=MM/day=DD/batch-{timestamp}.json
Each file contains newline-delimited JSON (NDJSON), compatible with Hive, Spark, Athena, and other data lake tools.

Response

{
  "ok": true,
  "totalExported": 8500,
  "tenants": [
    {
      "tenantId": "tenant_001",
      "tenantName": "Acme Corp",
      "exported": 5200,
      "filePath": "exports/tenant_001/interaction_history/year=2026/month=03/day=30/batch-2026-03-30T02-00-00-000Z.json"
    },
    {
      "tenantId": "tenant_002",
      "tenantName": "Beta Inc",
      "exported": 3300,
      "filePath": "exports/tenant_002/interaction_history/year=2026/month=03/day=30/batch-2026-03-30T02-00-01-000Z.json"
    }
  ]
}

Error Handling

If export fails for one tenant, other tenants continue processing. Failed tenants include an error field and their checkpoint is marked as failed for retry on the next run.
In production, replace the local filesystem writes with S3 uploads via @aws-sdk/client-s3. The file paths follow the same Hive-style partitioning scheme.

GET /api/v1/cron/cleanup

Periodic data cleanup that removes expired suppressions, purges interaction history, interaction summaries, and decision traces according to each tenant’s retention configuration, and ensures future database partitions exist.

Authentication

Requires CRON_SECRET via Authorization: Bearer <secret> or X-Cron-Secret header. If CRON_SECRET is not set in the environment, the endpoint is fail-closed and rejects every request with 401.

Cleanup Operations

OperationDescription
Expired suppressionsDeletes any suppression entry whose expiry timestamp is in the past. Event-driven; does not consult per-tenant retention settings.
Per-tenant history purgeFor every tenant, applies that tenant’s retention settings — history days, summary days, decision-trace days — together with the legalHold flag. Purges interaction history, interaction summary rows (all four period types — daily, weekly, monthly, all-time), and decision-trace rows. A tenant with legalHold = true is skipped per-table and surfaced in legalHoldSkips.
Partition maintenanceCreates database partitions for the next 3 months (non-fatal if partitions are not configured).
A failure inside one tenant’s purge is captured in perTenantErrors and does not abort the run — the cron will continue with the remaining tenants and still emit a 200 response.

Response

{
  "status": "ok",
  "cleaned": {
    "expiredSuppressions": 45,
    "tenantsProcessed": 12,
    "totalHistoryPurged": 8400,
    "totalSummariesPurged": 1200,
    "totalDecisionsPurged": 600,
    "legalHoldSkips": {
      "tenant-uuid-1": ["interactions", "decisions"]
    },
    "partitionsEnsured": 1,
    "perTenantErrors": []
  },
  "timestamp": "2026-04-27T02:00:00.000Z"
}

Error Codes

CodeReason
401Invalid or missing CRON_SECRET
500Cleanup operation failed

GET /api/v1/cron/approvals-expire

Sweeps every pending approval request and flips any that has aged past APPROVAL_MAX_AGE_HOURS (default 168 hours = 7 days) to status = "expired". The operation is a single bulk database write and is fully idempotent — running it again immediately is a no-op because no rows match the cutoff anymore.

Authentication

Same CRON_SECRET shared-header pattern as /api/v1/cron/cleanup:
  • Authorization: Bearer <CRON_SECRET> header
  • X-Cron-Secret: <CRON_SECRET> header
Unset CRON_SECRET → the endpoint rejects all requests with 401 (fail-closed).

Configuration

Env varRequiredDescription
CRON_SECRETYesShared secret. Fail-closed when unset.
APPROVAL_MAX_AGE_HOURSNoMaximum age in hours before a pending approval auto-expires. Default 168 (7 days). Invalid values fall back to the default.
Every 15 minutes is plenty — the operation is O(rows-to-expire) at the database with zero per-row work in Node. Once nothing is left to expire, each invocation is essentially free.

Response

{
  "status": "ok",
  "maxAgeHours": 168,
  "cutoff": "2026-04-16T17:00:00.000Z",
  "expired": 7,
  "durationMs": 23,
  "timestamp": "2026-04-23T17:00:00.000Z"
}

Error codes

CodeReason
401Missing or invalid CRON_SECRET
500Underlying database write failed (transient DB issue)

POST /api/cron/tick

System cron endpoint that evaluates every enabled alert rule and fires every due report schedule for every tenant in a single pass. The intended automated caller is AWS EventBridge, invoking the endpoint at whatever cadence matches your windowMinutes values (every 1–5 minutes is typical). See EventBridge Setup for the wiring path.
Pilot deployments: During pilot / initial rollout, EventBridge is typically not wired. The endpoint still exists and can be invoked on demand via curl with a valid CRON_TOKEN — useful for development, smoke testing, or one-off evaluation pushes. Without an external caller hitting it on a cadence, alerts and scheduled reports do not fire automatically; use the UI’s Run Now / Test buttons or the per-entity /run-now APIs for immediate delivery.

Authentication

Requires a CRON_TOKEN via either:
  • x-cron-token: <CRON_TOKEN> header (preferred)
  • x-cron-secret: <CRON_TOKEN> header (legacy, same value)
  • Authorization: Bearer <CRON_TOKEN> header
Unset CRON_TOKEN → the endpoint rejects all requests with 401 (fail-closed).

Example

curl -X POST https://your-deployment/api/cron/tick \
  -H "x-cron-token: $CRON_TOKEN"

Response

{
  "ok": true,
  "tenantsProcessed": 3,
  "rulesEvaluated": 12,
  "rulesFired": 2,
  "errors": [],
  "durationMs": 187,
  "timestamp": "2026-04-17T12:34:56.789Z"
}

Error Isolation

Per-tenant and per-rule errors are caught and reported in the errors array; a failing tenant does not abort the tick for other tenants:
{
  "ok": false,
  "tenantsProcessed": 2,
  "rulesEvaluated": 7,
  "rulesFired": 1,
  "errors": [
    { "tenantId": "tenant-c", "error": "evaluator threw: pg offline" }
  ],
  "durationMs": 245,
  "timestamp": "2026-04-17T12:34:56.789Z"
}
ok is true only when errors is empty.

Environment Variables

VariableRequiredDescription
CRON_SECRETRecommendedShared secret for /api/v1/cron/* maintenance endpoints
CRON_TOKENRequired only when /api/cron/tick is usedShared secret for /api/cron/tick alert + schedule evaluation. Falls back to CRON_SECRET when unset. Leave unset during pilot if you’re not wiring a scheduler.
APPROVAL_MAX_AGE_HOURSNoCutoff age (in hours) for /api/v1/cron/approvals-expire. Default 168 = 7 days.
When you wire an automated scheduler, match the cadence to the workload:
  • tick: every 1–5 minutes (matches the smallest windowMinutes across your alert rules)
  • export-interactions: Every hour or every 6 hours depending on data volume
  • cleanup: Once daily (e.g., 0 3 * * *)