Trigger kinds
Button triggers
buttons trigger add <button> attaches a trigger to one button. Exactly one of --cron, --watch, or --webhook is required. These fire while buttons serve (the local REST API server) is running — its in-process engine runs the cron and file-watch triggers and mounts webhook trigger routes on the same listener. Skip the engine with buttons serve --no-triggers.
--arg KEY=VALUE (repeatable) to set the args the press receives when the trigger fires. Webhook auth at this layer is a single shared token: when --token is set, the request must carry it as the X-Buttons-Token header or a ?token= query param. The POST body is not mapped into args — v1 uses the trigger’s configured --arg values. The endpoint presses asynchronously and returns 202 Accepted.
Drawer triggers
buttons drawer <name> trigger webhook [PATH] attaches a webhook trigger to a drawer (default path /<drawer-name>). These fire under buttons webhook listen, a foreground dispatcher that — unless you pass --no-tunnel — runs behind a Cloudflare tunnel so third-party services can reach it. webhook is the only drawer trigger kind implemented today.
--auth none|basic|header|jwt (with --auth-user/--auth-pass, --auth-header-name/--auth-header-value, or --jwt-secret and friends). Secret values accept $ENV{VAR} so drawer.json stays commit-safe. Unlike button triggers, the incoming POST is materialized into the drawer as ${inputs.webhook.body} (plus headers, query, method, path, received_at).
Status
Button cron, watch, and webhook triggers are shipped and run underbuttons serve. Drawer webhook triggers are shipped and run under buttons webhook listen. Drawer cron/file/mcp trigger kinds are reserved in the schema but not yet implemented.