Documentation
Everything you need to integrate MachineWallet into your application or AI agent.
Base URL
https://api.machinewallet.ai
All requests require HTTPS. HTTP requests receive a 301 redirect.
MachineWallet gives you programmable wallets on Philippine Instapay rails. Send money to any bank or e-wallet, collect payments via QR, and let AI agents operate within guardrails you define.
Apply for access. Once approved, create an OAuth2 client in Dashboard → OAuth2 Clients. You'll get a client_id and client_secret.
pip install machinewallet
from machinewallet import MachineWallet
mw = MachineWallet(client_id="mwc_...", client_secret="mws_...")
mw.send(
account_no="09171234567",
account_name="Juan Dela Cruz",
bank_name="G-Xchange / GCash",
amount_php=100.00
)
That's it. Auth is automatic. Money arrives in seconds via Instapay.
All API requests are authenticated with OAuth2 bearer tokens. Create a client, exchange credentials for a token, and pass it in the Authorization header.
Authorization: Bearer mw_your_token_here
Tokens expire after 1 hour. When you get a 401, request a new one. See OAuth2 details below.
All requests must use HTTPS. HTTP requests are rejected.
Go to Dashboard → OAuth2 Clients and create a client. You'll get a client_id (prefix mwc_) and client_secret (prefix mws_). Save the secret — it's only shown once.
2. Exchange credentials for a bearer token:
curl -X POST https://api.machinewallet.ai/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "mwc_your_client_id",
"client_secret": "mws_your_client_secret"
}'
Response
{
"access_token": "mw_dGhpcyBpcyBub3QgYSByZWFs...",
"token_type": "bearer",
"expires_in": 3600,
"scope": "wallets transactions payments"
}
curl https://api.machinewallet.ai/wallets \
-H "Authorization: Bearer mw_dGhpcyBpcyBub3QgYSByZWFs..."
Cache the token. When you get a 401, request a new one.
🔄 Secret rotation
Rotate your client secret from the dashboard at any time. All active tokens are immediately revoked.
💡 Token caching
Tokens last 1 hour. Don't request a new one per API call — cache and refresh on 401.
Every merchant gets a default wallet on signup. Create additional wallets for different purposes — payroll, supplier payments, one per AI agent.
List all wallets in your merchant account.
[
{
"id": "a1b2c3d4e5f6",
"name": "Operations Wallet",
"balance": 500000,
"balance_php": 5000.00,
"status": "active",
"daily_limit": 5000000,
"single_limit": 500000
}
]
💰 All monetary amounts are in centavos unless the field ends in _php. ₱1.00 = 100 centavos.
Get wallet details including balance, limits, daily spend, and transaction count.
List transactions for a wallet.
Query params: limit (max 500), offset, type (fund|disburse|transfer), status (pending|completed|failed)
Freeze a wallet. All sends blocked until unfrozen. Admin only.
Unfreeze a wallet. Admin only.
Load funds into your wallet by scanning a QR code with any Philippine banking app that supports QR Ph.
Generate a QR code
From the dashboard or via API:
curl -X POST https://api.machinewallet.ai/api/v1/payments/qr/dynamic \
-H "Authorization: Bearer mw_..." \
-H "Content-Type: application/json" \
-d '{"wallet_id":"your_wallet_id","amount_php":5000,"description":"Top-up"}'
Scan with your banking app
Funds arrive instantly
Balance updates in real-time via Instapay. Your agent can start spending immediately.
Generate a permanent QR code — print it, stick it on your desk. Scan whenever you need to add funds. Amount is entered in your banking app each time.
curl -X POST https://api.machinewallet.ai/api/v1/payments/qr/static \
-H "Authorization: Bearer mw_..." \
-H "Content-Type: application/json" \
-d '{"wallet_id":"your_wallet_id","device_info":"TOPUP001","label":"Office QR"}'
Send money to any Philippine bank account or e-wallet via Instapay. Funds arrive in seconds.
{
"account_no": "09171234567",
"account_name": "Juan Dela Cruz",
"bank_name": "G-Xchange / GCash",
"amount_php": 500.00,
"reference": "Payroll Week 9"
}
| Field | Type | Description |
|---|---|---|
| account_no | string | Account or mobile number |
| account_name | string | Recipient's full name |
| bank_name | string | Full bank name (see examples below) |
| amount_php | number | Amount in PHP. Min ₱1, max ₱50,000 |
| reference | string? | Your reference (optional) |
bank_name must be the exact name from our bank list:
Response
{
"success": true,
"transaction_id": "tx_8f3a9b2c...",
"amount_php": 500.00,
"status": "processing",
"reference": "202603011045..."
}
Status moves from processing → completed (or failed). Listen on webhooks for real-time updates.
Lower-level send — lets you specify a wallet, use saved contacts, and set approval thresholds. Amounts in centavos.
// Send to a saved contact
{"contact": "Rose Sumang", "amount": 50000}
// Send with full details + approval threshold
{"bank": "G-Xchange / GCash", "account_no": "09171234567",
"account_name": "Juan", "account_last": "Cruz",
"amount": 50000, "approval_threshold": 100000}
If amount exceeds approval_threshold, returns 202 Accepted with an approval ID. See Approvals.
Accept payments via QR Ph-compliant QR codes.
Print once, accept payments forever. Customer enters the amount.
One-time QR with a fixed amount. Customer just scans and pays.
{
"wallet_id": "a1b2c3d4e5f6",
"amount_php": 299.00,
"description": "Order #5678"
}
Response
{
"success": true,
"qr_string": "00020101021226...",
"order_no": "20260301...",
"amount_php": 299.00,
"expires_at": "2026-03-01T11:00:00"
}
Retrieve QR details and a base64-encoded PNG image. Use qr_image_base64 to render the QR in your app.
Check settlement account balances (disbursement pool and repayment pool). Also returns the full list of supported banks.
Save recipient bank details as contacts for faster, less error-prone payments. Each wallet has its own contact book.
List all contacts for a wallet.
{
"name": "Rose Sumang",
"bank": "G-Xchange / GCash",
"account_no": "09171234567",
"account_name": "Rose",
"account_last": "Sumang",
"nickname": "rose"
}
Once saved, send money by name: {"contact": "Rose Sumang", "amount": 50000}
Move funds between wallets within your merchant account. Instant, no fees.
{
"to_wallet_id": "b2c3d4e5f6a7",
"amount": 100000,
"description": "Move funds to agent wallet"
}
Amount in centavos. Creates a debit on the source wallet and a credit on the destination.
Payments above a configurable threshold require human approval before execution. This is how you let AI agents operate autonomously while keeping a human in the loop for large transactions.
1. Agent sends a payment with approval_threshold: 100000 (₱1,000)
2. If amount ≤ threshold → auto-executes immediately
3. If amount > threshold → returns 202 Accepted with an approval_id
4. Human approves or denies via dashboard or API
5. On approval → payment executes. On deny → funds return to wallet.
Approve and execute a pending transaction. Admin only.
Deny a pending transaction. Funds return to wallet. Admin only.
Get notified in real-time when payments arrive or disbursements complete. Configure your webhook URL in Dashboard → Settings.
We POST a signed JSON body to your URL:
{
"event": "payment.received",
"transaction_id": "tx_8f3a...",
"wallet_id": "a1b2c3d4e5f6",
"amount_centavos": 29900,
"amount_php": 299.00,
"status": "completed",
"timestamp": "2026-03-01T10:30:00Z"
}
| Event | When |
|---|---|
| payment.received | QR payment received and credited to wallet |
| disbursement.completed | Send money reached the recipient |
| disbursement.failed | Send money failed (wrong account, bank error) |
| disbursement.reversed | Previously completed send was reversed |
🔒 Webhook security
All webhooks are signed with RSA. Verify the signature before processing. Unsigned or invalid-signature webhooks are rejected in production.
MachineWallet is built for autonomous systems. Give your AI agent a wallet with spending controls and a human-in-the-loop for large amounts.
Create a wallet for your agent
Set daily and per-transaction limits. ₱5,000/day, ₱1,000/send — you decide the guardrails.
Create OAuth2 credentials
Give your agent a client_id + client_secret. It'll exchange them for short-lived tokens automatically.
Set approval thresholds
Payments under threshold → auto-execute. Over threshold → human approval via dashboard or Telegram.
Monitor everything
Full audit trail. Every transaction logged with actor, timestamp, and approval chain.
If you're using OpenClaw, install the MachineWallet skill:
openclaw skill install machinewallet
Your agent can then send payments, check balances, and generate QR codes through natural language.
Install:
pip install machinewallet
Use:
from machinewallet import MachineWallet
mw = MachineWallet(client_id="mwc_...", client_secret="mws_...")
# Token refresh is automatic. Just make calls.
wallets = mw.wallets()
print(f"Balance: ₱{wallets[0]['balance_php']:,.2f}")
# Send money
result = mw.send(
account_no="09171234567",
account_name="Juan Dela Cruz",
bank_name="G-Xchange / GCash",
amount_php=100.00,
reference="Agent payment #1"
)
# Generate a QR to receive payment
qr = mw.create_qr(wallet_id=wallets[0]["id"], amount_php=500.00)
# Send to a saved contact
mw.send_to_contact(wallet_id=wallets[0]["id"], contact_name="Rose", amount_centavos=50000)
The SDK handles token refresh automatically. Tokens are cached and only refreshed when they expire — your code never thinks about auth.
If you're not using the SDK, get a token first and pass it as a Bearer header:
# 1. Get a token (cache this — lasts 1 hour)
TOKEN=$(curl -s -X POST https://api.machinewallet.ai/oauth/token \
-H "Content-Type: application/json" \
-d '{"grant_type":"client_credentials",
"client_id":"mwc_...","client_secret":"mws_..."}' | jq -r .access_token)
# 2. Use it
curl https://api.machinewallet.ai/wallets -H "Authorization: Bearer $TOKEN"
All endpoints require authentication. Admin-only endpoints are marked.
| Method | Endpoint | Description |
|---|---|---|
| GET | /health | Health check (no auth needed) |
| POST | /oauth/token | Exchange client credentials for bearer token |
| Wallets | ||
| GET | /wallets | List wallets |
| POST | /wallets | Create wallet admin |
| GET | /wallets/{id} | Get wallet details |
| POST | /wallets/{id}/fund | Fund wallet (manual) admin |
| POST | /wallets/{id}/send | Send money from wallet |
| POST | /wallets/{id}/transfer | Transfer between wallets |
| GET | /wallets/{id}/transactions | List wallet transactions |
| POST | /wallets/{id}/freeze | Freeze wallet admin |
| POST | /wallets/{id}/unfreeze | Unfreeze wallet admin |
| Contacts | ||
| GET | /wallets/{id}/contacts | List contacts |
| POST | /wallets/{id}/contacts | Add contact |
| Payments | ||
| POST | /api/v1/payments/send | Disburse to bank/e-wallet |
| GET | /api/v1/payments/balance | Settlement balances + bank list |
| POST | /api/v1/payments/qr/static | Generate static QR |
| POST | /api/v1/payments/qr/dynamic | Generate dynamic QR |
| GET | /api/v1/payments/qr/{id} | Get QR details + image |
| GET | /api/v1/transactions | List all merchant transactions |
| Approvals | ||
| POST | /approvals/{tx_id}/approve | Approve pending transaction admin |
| POST | /approvals/{tx_id}/deny | Deny pending transaction admin |
| Limit | Default | Configurable |
|---|---|---|
| Per transaction | ₱5,000 | Yes |
| Daily per wallet | ₱50,000 | Yes |
| Monthly per wallet | ₱500,000 | Yes |
| API rate limit | 100 req/min | Growth+ |
| OAuth2 token TTL | 1 hour | No |
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created (new wallet, contact, etc.) |
| 202 | Accepted — pending human approval |
| 400 | Bad request (invalid params or grant_type) |
| 401 | Invalid/missing/expired credentials |
| 403 | Access denied (wrong merchant or role) |
| 404 | Wallet, contact, or resource not found |
| 422 | Insufficient funds or limit exceeded |
| 423 | Wallet is frozen |
| 429 | Rate limit exceeded |
Error responses always include a detail field:
{"detail": "Insufficient funds. Balance: 5000, Requested: 10000"}
100+ Philippine banks and e-wallets via Instapay:
Full list via GET /api/v1/payments/balance
Our team responds within a few hours during Philippine business hours (GMT+8).
Contact Support