7.9k★revolut – OpenClaw Skill
revolut is an OpenClaw Skills integration for security workflows. Revolut Business API CLI — accounts, balances, transactions, counterparties, payments, FX exchange, CSV export. Auto-refreshes OAuth tokens. Business accounts only (not personal).
Skill Snapshot
| name | revolut |
| description | Revolut Business API CLI — accounts, balances, transactions, counterparties, payments, FX exchange, CSV export. Auto-refreshes OAuth tokens. Business accounts only (not personal). OpenClaw Skills integration. |
| owner | christianhaberl |
| repository | christianhaberl/revolut-business |
| language | Markdown |
| license | MIT |
| topics | |
| security | L1 |
| install | openclaw add @christianhaberl/revolut-business |
| last updated | Feb 7, 2026 |
Maintainer

name: revolut description: "Revolut Business API CLI — accounts, balances, transactions, counterparties, payments, FX exchange, CSV export. Auto-refreshes OAuth tokens. Business accounts only (not personal)." version: 1.0.0 metadata: {"clawdbot":{"emoji":"💶","requires":{"bins":["python3"]}}}
Revolut Business API
Full CLI for Revolut Business — accounts, transactions, payments, FX, exports.
Entry point: python3 {baseDir}/scripts/revolut.py
Setup
Interactive Setup Wizard (recommended)
python3 {baseDir}/scripts/setup.py
Walks you through everything: key generation, Revolut certificate upload, OAuth callback, authorization.
Manual Setup
- Python 3.10+,
pip install PyJWT cryptography - Revolut Business account with API certificate
- See README for detailed step-by-step guide
Credentials
Stored in ~/.clawdbot/revolut/:
private.pem— RSA private key (for JWT signing)certificate.pem— X509 cert (uploaded to Revolut)tokens.json— OAuth tokens (auto-managed)config.json— client ID, domain, redirect URI
Environment variables (in .env):
REVOLUT_CLIENT_ID— from Revolut API settingsREVOLUT_ISS_DOMAIN— your redirect URI domain (without https://)
Commands
Accounts & Balances
python3 {baseDir}/scripts/revolut.py accounts # List all accounts with balances
python3 {baseDir}/scripts/revolut.py balance # Total EUR balance
python3 {baseDir}/scripts/revolut.py accounts --json # JSON output
Transactions
python3 {baseDir}/scripts/revolut.py transactions # Last 20
python3 {baseDir}/scripts/revolut.py tx -n 50 # Last 50
python3 {baseDir}/scripts/revolut.py tx --since 2026-01-01 # Since date
python3 {baseDir}/scripts/revolut.py tx --since 2026-01-01 --to 2026-01-31
python3 {baseDir}/scripts/revolut.py tx -a Main # Filter by account
python3 {baseDir}/scripts/revolut.py tx --type card_payment # Filter by type
python3 {baseDir}/scripts/revolut.py tx --json # JSON output
Transaction types: card_payment, transfer, exchange, topup, atm, fee, refund
Counterparties
python3 {baseDir}/scripts/revolut.py counterparties # List all
python3 {baseDir}/scripts/revolut.py cp --name "Lisa" # Search by name
python3 {baseDir}/scripts/revolut.py cp --json
Payments
# Send payment (with confirmation prompt)
python3 {baseDir}/scripts/revolut.py pay -c "Lisa Dreischer" --amount 50.00 --currency EUR -r "Lunch"
# Create draft (no immediate send)
python3 {baseDir}/scripts/revolut.py pay -c "Lisa Dreischer" --amount 50.00 --draft -r "Lunch"
# Skip confirmation
python3 {baseDir}/scripts/revolut.py pay -c "Lisa Dreischer" --amount 50.00 -y
Currency Exchange
python3 {baseDir}/scripts/revolut.py exchange --amount 100 --sell EUR --buy USD
python3 {baseDir}/scripts/revolut.py fx --amount 500 --sell EUR --buy GBP
Internal Transfers
python3 {baseDir}/scripts/revolut.py transfer --from-account <ID> --to-account <ID> --amount 100
Export (CSV)
python3 {baseDir}/scripts/revolut.py export # Print CSV to stdout
python3 {baseDir}/scripts/revolut.py export -n 200 -o transactions.csv # Save to file
python3 {baseDir}/scripts/revolut.py export --since 2026-01-01 -o jan.csv
Token Status
python3 {baseDir}/scripts/revolut.py token-info
Token Auto-Refresh
- Access tokens expire after ~40 minutes
- Automatically refreshed using the refresh token before API calls
- No manual intervention needed after initial auth
Security Notes
- Private key and tokens are stored in
~/.clawdbot/revolut/— treat as sensitive - Payments require explicit confirmation (use
--yesto skip) --draftcreates payment drafts that need approval in Revolut app- Never share your private key, tokens, or client assertion JWT
Revolut Business API — OpenClaw Skill
Full CLI for Revolut Business — accounts, balances, transactions, counterparties, payments, FX exchange, CSV export.
⚠️ Business only — Revolut Personal API requires PSD2 Open Banking (AISP) registration and is not supported.
Features
- 💰 Accounts & Balances — list all accounts, total EUR balance
- 📋 Transactions — filter by date, type, account; JSON output
- 👥 Counterparties — list, search by name
- 💸 Payments — send payments (with confirmation) or create drafts
- 💱 FX Exchange — exchange currencies between accounts
- 🔄 Internal Transfers — move funds between own accounts
- 📊 CSV Export — export transactions for bookkeeping
- 🔑 Auto Token Refresh — OAuth tokens refresh automatically via JWT
Setup (Step by Step)
Prerequisites
- Python 3.10+
pip install PyJWT cryptography- A Revolut Business account (not personal!)
- A domain you control (for OAuth redirect URI)
Step 1: Generate RSA Key Pair & X509 Certificate
mkdir -p ~/.clawdbot/revolut
cd ~/.clawdbot/revolut
# Generate private key
openssl genrsa -out private.pem 2048
# Generate X509 certificate (Revolut requires this format, NOT just a public key!)
openssl req -new -x509 -key private.pem -out certificate.pem -days 730 -subj "/CN=openclaw/O=YourCompany/C=AT"
⚠️ Revolut rejects a plain public key — you must upload an X509 certificate.
Step 2: Set Up OAuth Callback URL
Revolut needs a real HTTPS URL to redirect to after authorization. You have two options:
Option A: Cloudflare Worker (recommended, free)
If you have a domain on Cloudflare, create a simple worker that displays the auth code:
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const url = new URL(request.url)
const code = url.searchParams.get("code")
if (code) {
return new Response(`<html><body style="font-family:sans-serif;padding:40px">
<h1>✅ Revolut Authorization Code</h1>
<pre style="background:#f0f0f0;padding:20px;font-size:18px">${code}</pre>
<p>Copy this code and paste it into the CLI.</p>
</body></html>`, { headers: { "content-type": "text/html" } })
}
return new Response("Waiting for redirect...", { headers: { "content-type": "text/html" } })
}
Deploy it to e.g. https://revolut.yourdomain.com/callback
You'll also need a DNS record pointing to the worker:
- Type:
AAAA, Name:revolut, Content:100::, Proxy: ON (orange cloud)
Option B: n8n Webhook
If you run n8n, create a webhook workflow that returns the code query parameter.
Option C: Any HTTPS endpoint
Any URL that captures the ?code= parameter and shows it to you works.
❌
localhostwill not work as a redirect URI. ❌revolut.comwill not work (Revolut blocks their own domain).
Step 3: Register API Certificate in Revolut
- Go to business.revolut.com → Settings → API
- Click Add Certificate
- Fill in:
- Certificate title:
openclaw(or any name) - OAuth redirect URI: Your callback URL from Step 2 (e.g.
https://revolut.yourdomain.com/callback) - X509 public key: Paste the entire content of
certificate.pem(including-----BEGIN CERTIFICATE-----and-----END CERTIFICATE-----)
- Certificate title:
- Production IP whitelist: Add your server's public IP (
curl ifconfig.me) - Click Add → Copy the Client ID that Revolut shows you
Step 4: Configure Environment Variables
Add to your .env:
REVOLUT_CLIENT_ID=your_client_id_here
REVOLUT_ISS_DOMAIN=revolut.yourdomain.com # your redirect URI domain WITHOUT https://
⚠️ Important:
REVOLUT_ISS_DOMAINmust be the domain part of your redirect URI (withouthttps://). This is used as theiss(issuer) claim in the JWT. Revolut will reject any other value with: "The 'iss' (issuer) claim must be your domain"
Step 5: Authorize (OAuth Flow)
# Shows the consent URL
python3 scripts/revolut.py auth
This prints a URL like:
https://business.revolut.com/app-confirm?client_id=YOUR_ID&redirect_uri=https://revolut.yourdomain.com/callback&response_type=code
- Open this URL in your browser
- Log in to Revolut Business and approve the access
- You'll be redirected to your callback URL with a
?code=parameter - Copy the code and exchange it immediately (codes expire in minutes!):
python3 scripts/revolut.py auth --code oa_prod_xxxxx
If successful, you'll see: ✅ Authenticated successfully!
Tokens are saved to ~/.clawdbot/revolut/tokens.json and auto-refresh from now on.
Step 6: Verify It Works
python3 scripts/revolut.py accounts # Should show your accounts + balances
python3 scripts/revolut.py tx -n 5 # Last 5 transactions
python3 scripts/revolut.py token-info # Token status
Usage
# Accounts & Balances
revolut accounts # All accounts with balances
revolut balance # Total EUR balance
# Transactions
revolut tx # Last 20 transactions
revolut tx -n 50 # Last 50
revolut tx --since 2026-01-01 # Since date
revolut tx --since 2026-01-01 --to 2026-01-31
revolut tx -a Main # Filter by account name
revolut tx --type card_payment # Filter by type
revolut tx --json # JSON output
# Counterparties
revolut cp # List all
revolut cp --name "Lisa" # Search
# Payments
revolut pay -c "Lisa Dreischer" --amount 50.00 -r "Lunch"
revolut pay -c "Lisa Dreischer" --amount 50.00 --draft # Draft (approve in app)
revolut pay -c "Lisa Dreischer" --amount 50.00 --yes # Skip confirmation
# Currency Exchange
revolut fx --amount 100 --sell EUR --buy USD
# Internal Transfers
revolut transfer --from-account <ID> --to-account <ID> --amount 100
# Export
revolut export -o transactions.csv
revolut export --since 2026-01-01 -n 200 -o jan.csv
# Token Status
revolut token-info
Transaction types: card_payment, transfer, exchange, topup, atm, fee, refund
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
Invalid public key | Uploaded plain RSA public key | Use X509 certificate (openssl req -new -x509 ...) |
Bad Request: redirect URL | Redirect URI mismatch | Must match exactly what's in Revolut API settings |
unauthorized_client: Failed to authorise client | Wrong Client ID or expired auth code | Check Client ID in Revolut settings; get a fresh code |
The 'iss' claim must be your domain | JWT issuer doesn't match | Set REVOLUT_ISS_DOMAIN to your redirect URI domain (without https://) |
| Auth code doesn't work | Codes expire in minutes | Get a new code and exchange immediately |
Security
- Private key and tokens stored in
~/.clawdbot/revolut/— treat as sensitive - Payments require explicit confirmation (use
--yesto skip,--draftfor approval in app) - Never share your private key, tokens, or client assertion JWT
- Access tokens expire after ~40 minutes and auto-refresh
License
MIT
Permissions & Security
Security level L1: Low-risk skills with minimal permissions. Review inputs and outputs before running in production.
- Private key and tokens are stored in `~/.clawdbot/revolut/` — treat as sensitive - Payments require explicit confirmation (use `--yes` to skip) - `--draft` creates payment drafts that need approval in Revolut app - Never share your private key, tokens, or client assertion JWT
Requirements
- OpenClaw CLI installed and configured.
- Language: Markdown
- License: MIT
- Topics:
FAQ
How do I install revolut?
Run openclaw add @christianhaberl/revolut-business in your terminal. This installs revolut into your OpenClaw Skills catalog.
Does this skill run locally or in the cloud?
OpenClaw Skills execute locally by default. Review the SKILL.md and permissions before running any skill.
Where can I verify the source code?
The source repository is available at https://github.com/openclaw/skills/tree/main/skills/christianhaberl/revolut-business. Review commits and README documentation before installing.
