reference
rest api reference
The same capabilities as the MCP tools, over plain HTTPS and JSON. Agents use /v1/agent/*, admins use /api/*, on one base URL.
basics
| item | value |
|---|---|
| base URL | https://mcp.nostro.ag |
| auth | Authorization: Bearer nst_… on /v1/agent/*, Bearer nsa_… on /api/* |
| format | JSON in, JSON out. Send content-type: application/json on POST. |
| amounts | Numbers in EUR in requests; money objects {value, currency} with string values in balances. |
| CORS | Open (*). Keys are bearer secrets: call from servers, not browsers. |
| health | GET /health → {"ok":true,"bankMode":"…"} |
curl -s -X POST https://mcp.nostro.ag/v1/agent/pay \
-H "Authorization: Bearer $NOSTRO_AGENT_KEY" \
-H "content-type: application/json" \
-d '{"amount":49,"merchant":"Vercel","mcc":"5734","description":"Pro plan"}'sandbox signup
POST /api/sandbox/signup
https://mcp.nostro.ag/api/sandbox/signupPublic, no auth. Creates a sandbox workspace funded with 10 000 EUR of fake money, an admin key and a demo-agent key (per payment 500, per day 2 000, approval above 250). Keys are returned once.
| name | type | description | |
|---|---|---|---|
email | string | required | Where we can reach you about the preview. |
company | string | optional | Company name, used for the workspace. |
lang | string | optional | "en" (default) or "fr": language of the demo agent and of limit messages. |
{
"email": "you@company.com",
"company": "Acme",
"lang": "en"
}{
"workspace_id": "ws_7c1e9a42b0d3",
"admin_key": "nsa_9Hc2••••••••••••••••••••••••",
"agent": {
"id": "agt_3f2b8d10",
"name": "demo-agent",
"key": "nst_k3Jd••••••••••••••••••••••••",
"policy": {
"currency": "EUR",
"perTxMax": 500,
"dailyMax": 2000,
"monthlyMax": 5000,
"approvalAbove": 250,
"allowedMccs": [],
"blockedMerchants": [],
"transfersEnabled": false,
"transferApprovalAbove": 0
}
},
"mcp_url": "https://mcp.nostro.ag/mcp",
"balance": {
"amount": 10000,
"currency": "EUR",
"fake": true
},
"sandbox": true
}| limit | value | on breach |
|---|---|---|
| sandbox workspaces per email | 3 | 429 |
| signups per IP | 10 per hour | 429 |
| signups overall | 500 per hour | 429 |
| invalid email | 400 |
Browsers can call this endpoint only from nostro.ag and docs.nostro.ag (CORS). Server-side and terminal calls are unaffected.
GET /api/sandbox/stats
https://mcp.nostro.ag/api/sandbox/statsPublic, no auth, cached 30 s. Aggregate counters of the public sandbox (test domains excluded).
{
"workspaces": 128,
"agents": 241,
"payments": 1873,
"volume_eur": 96412.5
}agent endpoints
Key: nst_…. Every call is scoped to the agent that owns the key.
GET /v1/agent/wallet
https://mcp.nostro.ag/v1/agent/walletRemaining budget (day, month), caps, card status and the available balance of the company account. Agents are instructed to call it before any spend. Same as MCP get_wallet.
{
"agent": {
"id": "agt_3f2b8d10",
"name": "demo-agent",
"status": "active"
},
"card": {
"id": "vcard_5e1d77a0c4b2",
"maskedNumber": "4970 •••• •••• 3182",
"status": "Enabled"
},
"accountAvailable": {
"value": "10000.00",
"currency": "EUR"
},
"budget": {
"currency": "EUR",
"perTxMax": 500,
"approvalAbove": 250,
"dailyRemaining": 2000,
"monthlyRemaining": 5000
},
"transfersEnabled": false
}POST /v1/agent/pay
https://mcp.nostro.ag/v1/agent/payPays a merchant with the agent's virtual card. Evaluated against the mandate first: executed, blocked, or held for human approval. Same as MCP pay.
| name | type | description | |
|---|---|---|---|
amount | number | required | Amount in EUR, > 0. Rounded to 2 decimals, e.g. 19.99. |
merchant | string | required | Merchant name. Matched against blockedMerchants. |
mcc | string | optional | Merchant category code, exactly 4 digits, e.g. 5734. Required when the mandate has allowedMccs. |
description | string | optional | What the spend is for. Stored in the audit log. |
{
"amount": 49,
"merchant": "Vercel",
"mcc": "5734",
"description": "Pro plan, November"
}{
"status": "paid",
"transactionId": "vtx_883b5610e2a1",
"amount": 49,
"merchant": "Vercel"
}POST /v1/agent/transfer
https://mcp.nostro.ag/v1/agent/transferSends a SEPA transfer from the company account, only if the mandate enables transfers. Usually held for human approval. Same as MCP send_transfer.
| name | type | description | |
|---|---|---|---|
amount | number | required | Amount in EUR, > 0. |
iban | string | required | Beneficiary IBAN. Spaces are stripped; must match ^[A-Z]{2}\d{2}[A-Z0-9]{10,30}$. |
beneficiaryName | string | required | Beneficiary name. |
label | string | optional | Transfer label, max 140 characters. Defaults to "Nostro <agent name>". |
{
"amount": 1200,
"iban": "FR7630006000011234567890189",
"beneficiaryName": "Acme SAS",
"label": "Invoice 2026-114"
}{
"status": "pending_approval",
"requestId": "req_51c0aa9e",
"reason": "Virement soumis à approbation humaine",
"message": "Demande transmise à un humain de l'entreprise. Vérifie son statut avec get_request_status."
}GET /v1/agent/requests/:id
https://mcp.nostro.ag/v1/agent/requests/:idStatus of a spend held for human approval. Agents can only read their own requests. Same as MCP get_request_status.
{
"id": "req_ef5c846c",
"kind": "card_payment",
"amount": 320,
"status": "executed",
"reason": "Au-dessus du seuil d'approbation (250 €)",
"result": {
"amount": 320,
"status": "paid",
"merchant": "AWS",
"transactionId": "vtx_acf5376d09be"
},
"createdAt": "2026-11-05T09:19:33.478Z",
"decidedAt": "2026-11-05T09:20:41.561Z"
}GET /v1/agent/activity
https://mcp.nostro.ag/v1/agent/activityThe agent's last 50 events, newest first. Same as MCP list_my_activity.
[
{
"id": 7,
"workspace_id": "ws_7c1e9a42b0d3",
"agent_id": "agt_3f2b8d10",
"type": "card_payment",
"amount": 320,
"counterparty": "AWS",
"decision": "executed",
"reason": null,
"bank_ref": "vtx_acf5376d09be",
"created_at": "2026-11-05T09:20:41.560Z",
"agent_name": "demo-agent"
},
{
"id": 5,
"workspace_id": "ws_7c1e9a42b0d3",
"agent_id": "agt_3f2b8d10",
"type": "card_payment",
"amount": 900,
"counterparty": "Apple",
"decision": "denied",
"reason": "Dépasse le plafond par transaction (500 €)",
"bank_ref": null,
"created_at": "2026-11-05T09:18:02.491Z",
"agent_name": "demo-agent"
}
]admin endpoints
Key: nsa_…. Scoped to the admin key's workspace.
| method | path | description | MCP |
|---|---|---|---|
| GET | /api/overview | Account, balance, number of active agents, pending approvals and spend this month. | overview |
| GET | /api/agents | Every non-revoked agent with its card, mandate and current spend. | list_agents |
| POST | /api/agents | Creates an agent with its own virtual card in the company's name, its mandate and its API key. The key is returned once and never again. | create_agent |
| GET | /api/agents/:id | One agent (card, mandate, spend). | · |
| POST | /api/agents/:id/refresh | Re-reads the card status from the issuer. | · |
| POST | /api/swan/bootstrap | Operator only (owner workspace). Returns 403 with a sandbox key. | · |
| POST | /api/agents/:id/policy | Patches an agent's mandate. Only the fields you send change; the rest is kept. Changing monthlyMax also updates the card limit. | update_agent_policy |
| POST | /api/agents/:id/freeze | Kill switch: blocks every spend of the agent immediately. Reversible. | freeze_agent |
| POST | /api/agents/:id/unfreeze | Re-activates a frozen agent. | unfreeze_agent |
| POST | /api/agents/:id/revoke | Revokes the agent's key and cancels its card. Irreversible. | revoke_agent |
| GET | /api/requests?status= | Requests by status: pending (default), executed, failed, rejected or all. Max 100. | list_pending_approvals |
| POST | /api/requests/:id/approve | Approves a pending request and executes it right away. One decision per request, even with concurrent clicks. | approve_request |
| POST | /api/requests/:id/reject | Rejects a pending request. Nothing is charged. | reject_request |
| POST | /api/fund | Sandbox only: credits the workspace's virtual ledger (simulated incoming SEPA transfer, fake euros). {"amount":5000} | fund_account |
| GET | /api/events?agentId=&limit= | Every decision and operation in the workspace, newest first, optionally for one agent. Default limit 100, max 500. | audit_log |
Bodies and responses are the same as the MCP tools, with one difference: POST /api/agents nests the mandate under policy, where the MCP tool takes the fields flat.
{
"name": "procurement-bot",
"purpose": "Buys SaaS seats",
"policy": {
"perTxMax": 200,
"dailyMax": 600,
"monthlyMax": 3000,
"approvalAbove": 100,
"allowedMccs": [
"5734",
"7372"
]
}
}{
"agent": {
"id": "agt_91ad04c2",
"name": "procurement-bot",
"purpose": "Buys SaaS seats",
"status": "active",
"keyPrefix": "nst_Qm7v",
"card": {
"id": "vcard_0c44e1b9a7d0",
"status": "Enabled",
"maskedNumber": "4970 •••• •••• 7745",
"consentUrl": null
},
"policy": {
"currency": "EUR",
"perTxMax": 200,
"dailyMax": 600,
"monthlyMax": 3000,
"approvalAbove": 100,
"allowedMccs": [
"5734",
"7372"
],
"blockedMerchants": [],
"transfersEnabled": false,
"transferApprovalAbove": 0
},
"spend": {
"today": 0,
"month": 0
},
"createdAt": "2026-11-05T09:12:04.118Z"
},
"apiKey": "nst_Qm7v••••••••••••••••••••••••"
}{
"approvalAbove": 100,
"blockedMerchants": [
"casino"
]
}