It starts as a script on your laptop
Python, shell or Node, as it is. One command publishes the folder, and the parts in braces become inputs. Files the script writes come back as downloads.
Scripts for your team, your software and your agents
Publish a script once. Your team gets a form, your software an API, your agents a tool, and you decide which runs wait for approval.
Publish a script once. Your team, your software and your agents can all run it.
Start free Read the quickstart
npm install -g @reminix/cli
Refund a customer v2
Run
Order A-10423
Amount (USD) (optional) 40
Reason (optional) Charged twice for the same order
Recent runs
| 9:44 AM | App | |
| 9:41 AM | Awaiting approval | Agent · token Claude |
| 9:38 AM | Running | API · key billing |
| 9:12 AM | Succeeded | App |
Python, shell or Node, as it is. One command publishes the folder, and the parts in braces become inputs. Files the script writes come back as downloads.
import argparse, json, sys, requests
STRIPE = "https://api.stripe.com/v1"
CAP = 500_00 # cents; larger refunds need a manager
parser = argparse.ArgumentParser()
parser.add_argument("order_id")
parser.add_argument("--amount", type=float) # USD; all if left out
parser.add_argument("--reason", default="")
args = parser.parse_args()
# No key here: Reminix adds it to requests to api.stripe.com.
query = f"metadata['order_id']:'{args.order_id}'"
found = requests.get(f"{STRIPE}/payment_intents/search",
params={"query": query}).json()
payment = found["data"][0]
cents = payment["amount_received"]
if args.amount:
cents = round(args.amount * 100)
if cents > CAP:
sys.exit("Refunds over $500 need a manager.")
refund = requests.post(f"{STRIPE}/refunds", data={
"payment_intent": payment["id"],
"amount": cents,
"metadata[order_id]": args.order_id,
"metadata[reason]": args.reason,
}).json()
print(json.dumps({"order": args.order_id, "refund": refund["id"],
"amount": f"${cents / 100:.2f}"})) $ ls refund.py requirements.txt $ python refund.py A-10423 # works, but only here, and only for you $ reminix login $ reminix publish \ --command "python refund.py {orderId} [--amount {amount}] [--reason {reason}]"
Paste this prompt into Claude Code or Codex. It reads Reminix's agent skill and lists your scripts. Pick one, and it prepares it, tests a draft, and publishes only when you say so.
Read https://reminix.com/docs/skill/SKILL.md and follow it. List the scripts in this project that people run by hand, one line each, and wait for me to pick one to publish to Reminix.
Each way checks the same inputs and shows up in the same list of runs. Share a script with your whole workspace or only with certain teams. Other members don't see it at all, not even through the API.
Run
Order A-10423
await reminix.run("refund-customer", { orderId: order.number, amount: 40, reason: "Charged twice for the same order", });
Reminix
refund_customer
Refund a customer
Refunds an order through Stripe, up to $500. Larger refunds need a manager. Returns its output. Runs version 2, and Reminix records every run.
orderId amount reason $ reminix run refund-customer --log \ --input \ '{"orderId":"A-10423","amount":40}' → GET api.stripe.com/v1/payment_intents/search 200 (231 ms) → POST api.stripe.com/v1/refunds 200 (412 ms) { "order": "A-10423", "refund": "re_3Q8xM02eZvKY", "amount": "$40.00" }
Every night
Every day at 2:00 (Europe/London) · next run tomorrow at 2:00 AM
Enabled
Nightly sync failed
On run.failed script.slug = nightly-sync
Enabled
Support gets a form. Your billing app calls the API. Claude or ChatGPT sees it as a tool. Other scripts run on a timetable, or when something happens. Each one checks the same inputs and shows up in the same list of runs.
Share a script with your whole workspace or only with certain teams. Other members don't see it at all, not even through the API.
Run
Order A-10423
await reminix.run("refund-customer", { orderId: order.number, amount: 40, reason: "Charged twice for the same order", });
Reminix
refund_customer
Refund a customer
Refunds an order through Stripe, up to $500. Larger refunds need a manager. Returns its output. Runs version 2, and Reminix records every run.
orderId amount reason $ reminix run refund-customer --log \ --input \ '{"orderId":"A-10423","amount":40}' → GET api.stripe.com/v1/payment_intents/search 200 (231 ms) → POST api.stripe.com/v1/refunds 200 (412 ms) { "order": "A-10423", "refund": "re_3Q8xM02eZvKY", "amount": "$40.00" }
Schedules
A schedule runs this script at set times, with the inputs you choose.
Every night
Every day at 2:00 (Europe/London) · next run tomorrow at 2:00 AM
Enabled
Triggers
A trigger runs this script when something happens in the workspace, such as another script's run failing.
Nightly sync failed
On run.failed script.slug = nightly-sync
Enabled
Support, operations and finance ask Claude, ChatGPT or the agent they already use. Every script you publish is a tool their agent can call by name. Anything that changes data waits for a person to approve it.
Refund $40 on order A-10423. The customer paid twice.
Used Reminix
refund_customer
The $40.00 refund for A-10423 is waiting for approval. It goes out as soon as someone approves it.
Waiting for approval: refund-customer, order A-10423, $40.00
You save the Stripe key in Reminix once. When the script calls api.stripe.com, Reminix adds the key to that request on the way out. It blocks any host the script didn't list, and every request lands in the run's log. The script can read a key only if you turn that on for it.
{
"command": "python refund.py {orderId} [--amount {amount}] [--reason {reason}]",
"inputSchema": {
"type": "object",
"required": ["orderId"],
"properties": {
"orderId": { "type": "string", "title": "Order" },
"amount": { "type": "number", "title": "Amount (USD)" },
"reason": { "type": "string", "title": "Reason" }
}
},
"hosts": ["api.stripe.com"],
"secrets": {
"STRIPE_KEY": {
"host": "api.stripe.com",
"header": "Authorization",
"format": "Bearer {secret}"
}
}
} → GET api.stripe.com/v1/payment_intents/search 200 (231 ms) → POST api.stripe.com/v1/refunds 200 (412 ms) → GET api.example.net/collect — blocked: Host not allowed: api.example.net — declare it in reminix.json "hosts"
Set a script so runs started by an AI agent wait for an owner or admin. The person sees exactly what the agent asked for, then approves or denies it. On Business, every run can wait for approval.
Approval request
Run a script Waiting for a decision
Requested by Claude on behalf of Jordan Lee in Acme Ops.
What will happen
Run refund-customer (version 2)
Inputs
{
"amount": 40,
"reason": "Charged twice for the same order",
"orderId": "A-10423"
}
Reminix records who ran it, from where, with which inputs, what it printed and any files it wrote. If a run prints a key it had access to, the log shows [secret] instead. The record stays. Logs and files last 7 days on Free, 30 on Pro and 90 on Business.
Every change is a new version, and runs keep using the published one until someone publishes another. Rolling back is publishing the one before.
Refund a customer v2 Succeeded
Output
{
"order": "A-10423",
"refund": "re_3Q8xM02eZvKY",
"amount": "$40.00"
} Log
→ GET api.stripe.com/v1/payment_intents/search 200 (231 ms) → POST api.stripe.com/v1/refunds 200 (412 ms)
Each of these has a guide in the docs. Using something else today? See how Reminix compares.
refund-customer An agent asks to refund an order, a person approves it, and the run is on record. Guide unlock-account Support unlocks a customer's account from a form. Guide monthly-report Finance gets last month's revenue as a CSV file on the 1st. Guide nightly-sync A script copies the day's orders from the shop to the warehouse every night. Guide alert-on-failure When nightly-sync fails, Slack gets the error. Guide Free has room for 1 publisher and 5 people who only run scripts. You get 500 runs a month, and you don't need a card. Pro is $29 a month for the whole workspace.