AgentRaaS
If your agent already trades

A safety layer for AI agents that trade

For people who already use an AI agent for trading or stocks. AgentRaaS doesn't recommend trading, pick trades or trade for anyone; it keeps your agent in bounds. An agent whose order request times out will often send it again, and buy twice. AgentRaaS sits between your agent and your broker: each order runs once, limits and allowed symbols are checked before the broker sees the order, large orders wait for a person, and every order is in the audit trail.

Set up the guardrailsSelf-host it

What it stops

What goes wrongWhat AgentRaaS does
A retried order fills twiceThe same order runs once; a repeat gets the first answer back.
The agent sizes an order wrongAn action policy caps qty and notional, and blocks the order before it is sent.
It trades something it shouldn'tA policy lists the symbols and order types it may use.
A large order needs a second lookAbove a limit, the order waits for a person to approve it in Slack, Teams, Telegram or email (Team plan).
It loops, or trades too much in a dayA spend cap limits orders per day and the total notional per day.
It trades when the market is closedA policy's hours allow orders only during market hours, in the market's own time zone.
It closes everything at onceA policy denies positions.close_all for that agent.
You need to know what happenedEvery order, sent or refused, is in the audit trail with the reason.

Connect Alpaca

In the dashboard, Connect a service, pick Alpaca (paper trading) and paste the paper account's API key ID and secret. Your agent then sends orders to AgentRaaS instead of to Alpaca:

curl -X POST https://agentraas.io/v1/webhook/org_acme/trader \
  -H "Authorization: Bearer ar_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "service": "alpaca_paper",
    "action": "order.create",
    "payload": { "symbol": "AAPL", "qty": "1", "side": "buy", "type": "market",
                 "time_in_force": "day", "client_order_id": "run-42-buy-aapl" }
  }'
ActionAlpaca call
order.createPOST /v2/orders
order.replacePATCH /v2/orders/{order_id}
order.cancelDELETE /v2/orders/{order_id}
orders.cancel_allDELETE /v2/orders
position.closeDELETE /v2/positions/{symbol}
positions.close_allDELETE /v2/positions

Use alpaca instead of alpaca_paper for the live account. Send a client_order_id that stays the same when your agent retries: Alpaca refuses a second order with the same one, which covers a retry that reaches Alpaca some other way. Undo (dashboard, Monitor) cancels an order that has not filled yet; a filled order needs an opposite order.

Guardrails as code

Apply these with agentraas apply -f trading.yaml (see Rules as code), then change the numbers to yours:

# trading.yaml
apiVersion: agentraas.io/v1alpha1
kind: DedupRule
metadata: {name: same-order-once, org: org_acme}
spec: {service: alpaca_paper, action: order.create, fields: [symbol, side, qty, notional], ttlSeconds: 60}
---
apiVersion: agentraas.io/v1alpha1
kind: ActionPolicy
metadata: {name: hard-limits, org: org_acme}
spec: {agentId: trader, service: alpaca_paper, action: order.create, effect: require,
       fields: {symbol: {enum: [AAPL, MSFT, SPY]}, type: {enum: [market, limit]}, qty: {max: 10}, notional: {max: 5000}},
       hours: {tz: America/New_York, days: [mon, tue, wed, thu, fri], from: "09:30", to: "16:00"}}
---
apiVersion: agentraas.io/v1alpha1
kind: ActionPolicy
metadata: {name: never-liquidate-all, org: org_acme}
spec: {agentId: trader, service: alpaca_paper, action: positions.close_all, effect: deny}
---
apiVersion: agentraas.io/v1alpha1
kind: SpendCap
metadata: {name: daily-limits, org: org_acme}
spec: {agentId: trader, service: alpaca_paper, action: order.create, window: day, timezone: America/New_York,
       maxCalls: 20, amountField: notional, maxAmount: 10000, onExceed: block}

Then add the approval step (Team plan) in the dashboard under Rules → Approval rules: service alpaca_paper, action order.create, field notional greater than 1000.

Together: the same order inside a minute runs once; orders above $5,000, more than 10 shares, or off the list are blocked; orders outside 09:30 to 16:00 New York time on weekdays are blocked; orders above $1,000 that pass those wait for approval; after 20 orders or $10,000 in a New York day, the rest are blocked. Limits hold whether the agent sends "notional": 500 or "notional": "500". The daily total needs notional on every order: an order by qty alone is refused by that cap, so have your agent size orders in dollars.

India (NSE/BSE)

Two Indian brokers are built in: upstox (Upstox API, order endpoints v3) and dhan (DhanHQ API v2). Each has order.place, order.modify and order.cancel, and undo on order.place cancels the order if it has not filled yet.

ActionUpstox callDhan call
order.placePOST /v3/order/placePOST /v2/orders
order.modifyPUT /v3/order/modifyPUT /v2/orders/{order_id}
order.cancelDELETE /v3/order/cancel?order_id=...DELETE /v2/orders/{order_id}

Field names are the broker's own: Upstox takes instrument_token (for example NSE_EQ|INE002A01018), transaction_type, product (D is delivery), order_type, validity, quantity, price and a tag of up to 40 characters. Dhan takes dhanClientId, transactionType, exchangeSegment, productType (CNC is delivery), orderType, validity, securityId, quantity, price and a correlationId of up to 30 characters. Dhan's order.modify takes the order id twice: order_id for the URL and orderId for the body. Undo on an Upstox order cancels the first order id it returns, so don't use Upstox's slice with undo.

SEBI's framework for retail algo trading (in effect since April 1, 2026, per the brokers' notices) changes how an API order reaches the exchange:

So live Indian orders need self-hosted AgentRaaS on a server with a static IP, registered with your broker. AgentRaaS Cloud has no fixed outbound IP, so the broker would refuse its orders.

Save the new token every morning

Get the day's token from your broker (Dhan can issue one from your client ID, PIN and TOTP; Upstox through its login flow), then save it to AgentRaaS. Saving a credential for a service replaces the one stored before it, so a scheduled script like this before 09:15 is enough:

# AGENTRAAS_URL is your self-hosted AgentRaaS, BROKER_TOKEN the day's token
curl -s -c /tmp/ar.jar -X POST "$AGENTRAAS_URL/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d "{\"email\": \"$AGENTRAAS_EMAIL\", \"password\": \"$AGENTRAAS_PASSWORD\"}"
curl -s -b /tmp/ar.jar -X POST "$AGENTRAAS_URL/api/v1/credentials" \
  -H "Content-Type: application/json" \
  -d "{\"org_id\": \"org_acme\", \"service\": \"dhan\", \"credentials\": {\"api_key\": \"$BROKER_TOKEN\"}}"

Guardrails for NSE cash equity

# india.yaml
apiVersion: agentraas.io/v1alpha1
kind: ActionPolicy
metadata: {name: nse-delivery-only, org: org_acme}
spec: {agentId: trader, service: dhan, action: order.place, effect: require,
       fields: {exchangeSegment: {enum: [NSE_EQ]}, productType: {enum: [CNC]}, orderType: {enum: [LIMIT]},
                securityId: {enum: ["11536"]}, price: {required: true, max: 5000}},
       hours: {tz: Asia/Kolkata, days: [mon, tue, wed, thu, fri], from: "09:15", to: "15:30"}}
---
apiVersion: agentraas.io/v1alpha1
kind: SpendCap
metadata: {name: daily-size, org: org_acme}
spec: {agentId: trader, service: dhan, action: order.place, window: day, timezone: Asia/Kolkata,
       maxCalls: 20, amountField: quantity, maxAmount: 40, onExceed: block}

Together: only delivery (CNC) limit orders in NSE cash for the listed securities, so F&O segments (NSE_FNO, BSE_FNO) and intraday are blocked; only from 09:15 to 15:30 India time on weekdays (exchange holidays are not known to AgentRaaS); at most 20 orders and 40 shares a day, India time. An Indian order has no order-value field, so the daily rupee limit comes from the two: 40 shares at a price of at most ₹5,000 is at most ₹2,00,000 a day. For Upstox the same rules use instrument_token (list the NSE_EQ|... keys you allow, which also keeps out F&O), product: {enum: [D]} and order_type: {enum: [LIMIT]}.

This is not investment or legal advice. SEBI's and your broker's rules change: check the current ones before you trade live.

Before you go live

Using another broker?

Any broker with an HTTP API works today as a Custom Action, with the same dedup, policies and approvals. Tell us which one you want built in.

Ask in the communityCustom actions