Overview
HoodPortal is a REST layer over Robinhood Chain. It manages wallets, executes trades, and launches tokens on Pons — so you can automate all three from a backend instead of a browser wallet.
There are no API keys. Every write request is signed by the wallet performing the action, and HoodPortal checks that wallet's live $PORTAL balance before it executes anything — hold at least 1,000 $PORTAL, or the request is rejected. See Access for the exact mechanics.
https://api.hoodportal.xyz/v1.Access
No API keys. Access is tied to the wallet signing each request, not to an account or a plan.
Every write request (POST) must be signed by the wallet performing the action. HoodPortal recovers the signer from that signature, confirms it matches the wallet you're claiming to act as, and reads that wallet's live $PORTAL balance on-chain before doing anything else.
| Requirement | Detail |
|---|---|
| Minimum balance | 1,000 $PORTAL, held by the signing wallet at the moment the request is processed. |
| Applies to | All POST endpoints — wallets, trades, launches, webhooks. |
| Does not apply to | GET endpoints. Price, quote, and token lookups are open with no balance or signature required. |
| Signature freshness | The signed timestamp must be within 60 seconds of the request. Older signatures are rejected. |
Signing a request
Sign the message hoodportal:{timestamp}:{sha256(body)} with the wallet's private key, then attach the result as headers:
X-Wallet-Address: 0x4dd2...9a71 X-Wallet-Signature: 0x9c1f...02ad X-Timestamp: 1725556800
insufficient_portal_balance until it's topped back up.Wallets
Create sub-wallets under one account and issue scoped session keys for each.
POST/wallets
Creates a new wallet. Funds must be deposited to its address before it can trade, and it needs at least 1,000 $PORTAL before it can sign any further request.
| Field | Type | Required | Description |
|---|---|---|---|
| label | string | required | A name for your own reference. Not shown on-chain. |
{ "label": "sniper-03" }
// 200 OK
{
"wallet_id": "wl_8f2ac1",
"address": "0x4dd2...9a71",
"status": "ready"
}
POST/wallets/:id/session-keys
Issues a scoped session key for a wallet. HoodPortal uses this key to execute trades and launches on the wallet's behalf — it can never exceed the scope you set here, and it stops working the moment the wallet's $PORTAL balance drops below 1,000, regardless of expiry.
| Field | Type | Required | Description |
|---|---|---|---|
| spend_cap_eth | number | required | Maximum ETH the key can move, in total, over its lifetime. |
| daily_cap_eth | number | optional | Resets every 24h. Omit for no daily limit below the spend cap. |
| expires_in | string | required | Duration string, e.g. "30d". Max 90d per key. |
| allowed_contracts | string[] | optional | Restrict to specific contracts. Omit to allow any Pons curve or Uniswap v4 pool. |
{
"spend_cap_eth": 2.0,
"daily_cap_eth": 0.5,
"expires_in": "30d"
}
// 200 OK
{ "session_key_id": "sk_9d41", "expires_at": "2026-10-05T00:00:00Z" }
GET/wallets/:id
Returns balances across every token the wallet holds, plus its active session keys. No signature or $PORTAL balance required to read.
Trading
Buy or sell any Robinhood Chain token. HoodPortal reads the token's phase and routes the order to its Pons curve or its Uniswap v4 pool automatically.
POST/trades/buy
| Field | Type | Required | Description |
|---|---|---|---|
| wallet_id | string | required | The wallet executing the trade. Must hold at least 1,000 $PORTAL. |
| token | address | required | Token contract address. |
| amount_eth | number | required | Amount to spend, in the token's quote asset. |
| slippage_bps | integer | optional | Max acceptable slippage, in basis points. Defaults to 200 (2%). |
{
"wallet_id": "wl_8f2ac1",
"token": "0x39dBED3a2bd333467115dE45665cC57F813C4571",
"amount_eth": 0.05,
"slippage_bps": 200
}
// 200 OK
{
"status": "confirmed",
"venue": "curve",
"tx_hash": "0x7ad3f1...e02c",
"tokens_out": "142893.221",
"price_usd": 0.000041
}
POST/trades/sell
Same shape, in reverse — pass a token amount instead of an ETH amount.
{
"wallet_id": "wl_8f2ac1",
"token": "0x39dBED3a2bd333467115dE45665cC57F813C4571",
"amount_tokens": "50000",
"slippage_bps": 200
}
GET/tokens/:address
Live price, market cap, phase (curve or graduated pool), and graduation progress for any token on the chain. No signature or balance required.
{
"phase": "curve",
"price_usd": 0.000041,
"market_cap_usd": 41000,
"graduation_progress": 0.71
}
Launching on Pons
Deploy a new token and, optionally, buy your own opening allocation — atomically, so nothing can trade in between.
POST/launches
| Field | Type | Required | Description |
|---|---|---|---|
| wallet_id | string | required | Wallet that deploys the launch and receives creator fees. Must hold at least 1,000 $PORTAL. |
| name / symbol | string | required | Token name and ticker. |
| quote_asset | string | optional | "ETH" by default. See Pons docs for approved alternatives. |
| creator_tax_bps | integer | optional | Your own tax on top of the standard fee. Capped by the protocol. |
| initial_buy_eth | number | optional | If set, buys your opening allocation in the same transaction as the launch. |
{
"wallet_id": "wl_8f2ac1",
"name": "Sherwood",
"symbol": "SHRWD",
"quote_asset": "ETH",
"creator_tax_bps": 100,
"initial_buy_eth": 0.05
}
// 200 OK
{
"status": "launched",
"token": "0x2fe1...a04b",
"curve": "0x88ab...11de",
"tx_hash": "0x51ac...90fd"
}
Webhooks
Subscribe to an event instead of polling for it.
| Event | Fires when |
|---|---|
| trade.confirmed | A buy or sell you submitted lands on-chain. |
| launch.graduated | A token you launched sells out its curve and moves to its Uniswap v4 pool. |
| rewards.claimable | A weekly $PORTAL creator-rewards payout becomes available to claim. |
{
"url": "https://yourapp.com/hooks/hoodportal",
"events": ["trade.confirmed", "launch.graduated"]
}
Errors
Errors return a 4xx or 5xx status with a machine-readable code.
| Code | Status | Meaning |
|---|---|---|
| insufficient_portal_balance | 403 | The signing wallet holds less than 1,000 $PORTAL. Top up and retry. |
| invalid_signature | 401 | The signature doesn't recover to the claimed wallet address, or the timestamp is stale. |
| slippage_exceeded | 422 | Price moved past your slippage_bps before the trade settled. |
| session_key_expired | 401 | The wallet's session key has expired or was revoked. Issue a new one. |
| spend_cap_exceeded | 403 | The request would exceed the session key's remaining spend cap. |
| curve_graduated | 409 | The token finished its curve between your quote and your trade. Retry — HoodPortal will route to the pool. |
| insufficient_balance | 402 | The wallet doesn't hold enough of the quote asset. |
$PORTAL & rewards
$PORTAL gates access and funds creator rewards. There is no fee tier, no subscription, and no metering.
The access requirement
| Requirement | Detail |
|---|---|
| Minimum balance | 1,000 $PORTAL in the signing wallet, checked live on every write request. |
| Cost | None. It's a balance check, not a fee — the tokens aren't spent or transferred to use the API. |
| Reads | GET endpoints are open to everyone, no balance required. |
Creator rewards
Launching through POST /v1/launches instead of directly through Pons adds a second, ongoing reward stream on top of your normal Pons creator fees:
- Your token trades — on the curve, then in its graduated pool.
- Pons pays your standard creator share directly, in the launch's quote asset, exactly as it would without HoodPortal involved.
- Every HoodPortal launch also carries a small built-in 0.5% protocol fee, separate from Pons' own, pooled weekly.
- Half of that pool is paid out weekly, in $PORTAL, to the wallet that launched the token — for as long as it keeps trading.
{
"token": "0x2fe1...a04b",
"week_ending": "2026-09-06",
"volume_usd": 184200,
"portal_reward": "412.6 PORTAL",
"claimable": true
}