โ† Dashboard

API Reference

REST API for AI agents to create, update, and query tasks. All endpoints return JSON.

Authentication

Every request (except GET /health, /, and /docs) must include the API key as a header.

x-api-key: YOUR_API_KEY

Missing or incorrect key returns 401 {"error": "Invalid or missing x-api-key"}.

Task Fields

FieldTypeDescription
idstring (UUID)Auto-generated. Read-only.
titlestringrequired Short description of the task.
statusenum pending in_progress done blocked Default: pending
priorityenum low medium high urgent Default: medium
notesstring | nullFree-text context, progress updates, or error details.
action_neededstring | nullSet this when a human must intervene. Surfaces at the top of every email report and the dashboard.
agent_namestring | nullIdentifier for the agent that owns this task (e.g. engagement-scanner).
created_atISO 8601Auto-set on create. Read-only.
updated_atISO 8601Auto-updated on every PATCH. Read-only.
completed_atISO 8601 | nullAuto-set when status becomes done. Cleared if status changes away from done.
Tasks with status: "done" are automatically deleted 24 hours after completed_at.

Endpoints

GET/health
Server health check. No auth required.
{ "ok": true, "ts": "2026-04-30T12:00:00.000Z" }
GET/tasks
List all tasks, ordered by priority then created date. Filter by status with ?status=pending|in_progress|done|blocked.
curl https://tryrelayapp.com/tasks \
  -H "x-api-key: YOUR_KEY"
GET/tasks/summary
Lightweight snapshot โ€” counts by status plus all tasks needing human action. Ideal for an agent's startup health check.
{
  "total": 5,
  "by_status": { "pending": 2, "in_progress": 1, "done": 1, "blocked": 1 },
  "action_needed": [
    { "id": "uuid", "title": "Fix auth", "action_needed": "Rotate the key", "priority": "high" }
  ]
}
GET/tasks/:id
Fetch a single task by ID. Returns 404 if not found.
curl https://tryrelayapp.com/tasks/TASK_ID \
  -H "x-api-key: YOUR_KEY"
POST/tasks
Create a task. Returns 201 with the created task. Only title is required.
curl -X POST https://tryrelayapp.com/tasks \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Generate weekly digest",
    "status": "in_progress",
    "priority": "medium",
    "notes": "Processing 47 posts from this week",
    "agent_name": "weekly-digest-agent"
  }'
PATCH/tasks/:id
Update any fields on a task. Send only the fields you want to change. Setting status: "done" auto-sets completed_at.
# Mark done
curl -X PATCH https://tryrelayapp.com/tasks/TASK_ID \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "done"}'

# Flag for human action
curl -X PATCH https://tryrelayapp.com/tasks/TASK_ID \
  -H "x-api-key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "blocked", "action_needed": "OAuth token expired โ€” needs manual re-auth"}'
DELETE/tasks/:id
Delete a task immediately. Returns 204 No Content.
curl -X DELETE https://tryrelayapp.com/tasks/TASK_ID \
  -H "x-api-key: YOUR_KEY"
POST/tasks/cleanup
Manually delete all done tasks older than 24h. Also runs automatically at midnight ET.
{ "removed": 3 }
POST/tasks/report
Trigger an email report immediately. Use ?period=evening for the evening template (default: morning).
curl -X POST "https://tryrelayapp.com/tasks/report?period=morning" \
  -H "x-api-key: YOUR_KEY"

Agent Integration

Drop this helper into any TypeScript/JavaScript agent:

const BASE = "https://tryrelayapp.com";
const KEY  = process.env.TASK_TRACKER_API_KEY;
const h    = { "x-api-key": KEY!, "Content-Type": "application/json" };

const tracker = {
  async create(task: { title: string; priority?: string; status?: string; notes?: string; action_needed?: string; agent_name?: string }) {
    const res = await fetch(`${BASE}/tasks`, { method: "POST", headers: h, body: JSON.stringify(task) });
    const { task: t } = await res.json();
    return t.id as string;
  },
  async update(id: string, patch: Record<string, string>) {
    await fetch(`${BASE}/tasks/${id}`, { method: "PATCH", headers: h, body: JSON.stringify(patch) });
  },
  async done(id: string, notes?: string) {
    await this.update(id, { status: "done", ...(notes ? { notes } : {}) });
  },
  async block(id: string, action_needed: string) {
    await this.update(id, { status: "blocked", action_needed });
  },
  async summary() {
    const res = await fetch(`${BASE}/tasks/summary`, { headers: h });
    return res.json();
  },
};

Python

import requests, os

BASE = "https://tryrelayapp.com"
HEADERS = {"x-api-key": os.environ["TASK_TRACKER_API_KEY"], "Content-Type": "application/json"}

def create_task(title, status="pending", priority="medium", notes=None, action_needed=None, agent_name=None):
    r = requests.post(f"{BASE}/tasks", headers=HEADERS, json={
        "title": title, "status": status, "priority": priority,
        "notes": notes, "action_needed": action_needed, "agent_name": agent_name
    })
    return r.json()["task"]["id"]

def update_task(task_id, **kwargs):
    requests.patch(f"{BASE}/tasks/{task_id}", headers=HEADERS, json=kwargs)

def mark_done(task_id):
    update_task(task_id, status="done")

def block_task(task_id, action_needed):
    update_task(task_id, status="blocked", action_needed=action_needed)

Agent Quickstart Pattern

Standard lifecycle for a long-running agent job:

Agent Task Tracker  ยท  Dashboard  ยท  Reports sent 8AM & 6PM Eastern  ยท  Done tasks auto-deleted after 24h