Send a report every month
Say someone exports last month’s revenue from Stripe on the 1st of every month, tidies it into a spreadsheet and sends it to Finance. Here’s how to make that a script that runs on a schedule and leaves a CSV file Finance can download.
1. Save the Stripe key
Section titled “1. Save the Stripe key”A workspace owner or admin saves a Stripe restricted key with read-only
access, sendable only to api.stripe.com:
printf %s "$STRIPE_READ_KEY" | reminix secrets set STRIPE_KEY --hosts api.stripe.com2. Write the script
Section titled “2. Write the script”{ "slug": "monthly-report", "name": "Monthly report", "description": "Last month's revenue as a CSV file.", "command": "python report.py [--month {month}]", "hosts": ["api.stripe.com"], "secrets": { "STRIPE_KEY": { "host": "api.stripe.com", "header": "Authorization", "value": "Bearer {secret}" } }, "inputSchema": { "type": "object", "properties": { "month": { "type": "string", "title": "Month", "description": "Like 2026-09. Leave it empty for last month.", "examples": ["2026-09"] } } }}Reminix leaves [--month {month}] out of the command when the month is
empty, so the script reports on last month:
import argparse, csv, datetime, json, os, sys
last_month = (datetime.date.today().replace(day=1) - datetime.timedelta(days=1)).strftime("%Y-%m")parser = argparse.ArgumentParser()parser.add_argument("--month", default=last_month)month = parser.parse_args().month
rows = revenue_by_day(month) # your query, reading api.stripe.comprint(f"{len(rows)} days in {month}", file=sys.stderr)
path = os.path.join(os.environ["REMINIX_OUTPUTS"], f"revenue-{month}.csv")with open(path, "w", newline="") as f: writer = csv.writer(f) writer.writerow(["day", "charges", "refunds", "net"]) writer.writerows(rows)print(json.dumps({"month": month, "net": sum(row[3] for row in rows)}))The code holds no key: Reminix adds it to each request to
api.stripe.com. Reminix keeps anything the script writes to
/outputs (the folder in $REMINIX_OUTPUTS) with the run, so the CSV
file is there to download when the run ends.
Publish it, and run it once by hand for a month you know:
reminix publish ./monthly-reportreminix run monthly-report --input '{"month":"2026-09"}' --out ./reports--out saves the files the run wrote, here reports/revenue-2026-09.csv.
3. Add the schedule
Section titled “3. Add the schedule”On the script’s page, choose Schedules → Add schedule, then
Custom (cron), and enter 0 8 1 * *: 8:00 on the 1st of every
month. Choose your timezone and leave the month empty. Or through the
API:
curl -X POST https://api.reminix.com/v1/scripts/monthly-report/schedules \ -H "Authorization: Bearer $REMINIX_TOKEN" -H "X-Workspace: acme" \ -H "Content-Type: application/json" \ -d '{ "name": "First of the month", "cron": "0 8 1 * *", "timezone": "Europe/London" }'The schedule runs as you, with your access, and needs no inputs. Each run is on the script’s page, marked Schedule. If Reminix skips a time, for example because the plan has no runs left this month, the schedule’s card says why.
4. Where Finance finds the file
Section titled “4. Where Finance finds the file”Share the script with Finance (Settings → Who can use it). They find each month’s CSV file under Files in the app, or on the script’s page under its latest files, and download it from there. Each file links to the run that wrote it. Reminix keeps a run’s files for your plan’s number of days (see Plan allowances).
5. Hear about it when it fails
Section titled “5. Hear about it when it fails”Add a trigger on this script’s run.failed. See
Alert when a run fails.
Related: Schedules and triggers, Files, Secrets.