ORUS
Documentation35 sectionsVersioned with the engine

How it works,
end to end.

What a strategy actually contains, how a screener page becomes a position, what closes it, and which limits bind before any capital moves. Every number here is quoted from the engine, and every field name is the strategy's own — so you can go from this page to the strategy form without a translation step. Building an integration? The partner API reference below covers authentication, query parameters and every response field.

Something unclear, or not on this page? Ask in the Discord — the team reads it.

01Start here

What the thing is, the objects you need to hold in your head, and how to get in.

What Orus is

An autonomous desk for Robinhood Chain, running in the open.

Orus discovers tokens across the chain's DEXes and launchpads, waits for one to fall far enough from its all-time high, buys the dip, and manages the position until a target, a stop or a time limit closes it. No part of that requires anyone to be at a screen.

It runs on Robinhood Chain — an Arbitrum Nitro L2, chain id 4663, gas paid in ETH. Two chain facts shape everything downstream. USDG, not WETH, is the dominant quote asset, so every price in the system is denominated in USD and a "price in native" is meaningless across venues. Blocks land in about 100 ms with first-come-first-served sequencing, so there is no priority-fee auction to win: the race is on data freshness, not on tips.

Every decision an agent makes — every candidate looked at, every rejection and the measurement behind it, every entry and exit — is written to an event log. The public desk reads that log. Refusals and losses are published on the same page as the wins.

Strategies and agents

A strategy is the rulebook. An agent is one copy of it, running on a clock.

A strategy is a row of parameters covering every step of the pipeline: what to screen for, which holder profiles to reject, how deep and how recent a dip has to be, how much to spend, and when to sell. It holds no wallet and takes no action on its own. Every one of its fields is documented in the pipeline sections below, at the step that reads it.

An agent binds one strategy to a cadence, an execution mode and, optionally, a wallet. The cron fires every minute and ticks every thirty seconds inside it; an agent only runs when its own frequency has elapsed, and each run is claimed before it starts — the last-run timestamp is bumped under an optimistic lock — so a run that overruns its interval is never started twice by two concurrent ticks.

Two agents on two strategy rows that share every entry rule and differ only in their exits attribute any difference in results to the exit policy alone. That is how the desk's strategies are compared.

Pausing an agent stops new entries. It does not stop the exits: an agent that is paused or stopped but still holds positions gets a monitor-only pass on its own cadence, so the stop loss, the hold limit and the take profit keep working on what is already held.

nameStrategy Name
What the strategy is called on your console and, for the house's, on the public desk.
descriptionDescription
One line on what the strategy is for. Shown on the strategy card.
frequency_seconds
How often the agent runs. The cron ticks every thirty seconds; the agent runs at the first tick this has elapsed for.
execution_mode
simulation, manual or automatic — see the next section.
status
running, paused or stopped. Paused and stopped agents still monitor what they hold.

Execution modes

Simulation and automatic differ in exactly one thing: whether a transaction is sent.

Simulation needs no funds. The agent runs the full pipeline, including the guard rails and the round-trip check, and books each position at the fill the real routers quote — tokens received, price implied — not at the oracle price. Nothing is broadcast. A simulated exit is quoted out through the same router and booked at the native it would return. It is how a strategy earns the right to hold money.

Automatic does the whole thing: quotes, wraps ETH, approves the router for the exact amount, swaps, and records the position from the fill it actually got. Switching an agent to automatic runs a pre-flight — a wallet, automated trading enabled on it, and enough ETH for one entry plus gas — and refuses with the numbers when one is missing.

Manual, where a signal waits for a human to execute it, is the desk operator's mode. A user's agent is either simulating or automatic.

simulation
No funds. Positions booked at the routed quote, status simulated_open.
automatic
Quotes, wraps, approves, swaps, records the real fill. Needs automated trading enabled and a funded wallet.

Wallets and keys

Your agents trade from a wallet you hold. Orus signs within a policy you can read, and revoke.

Your trading wallet is an embedded wallet on Robinhood Chain, created at your first sign-in and held for you by Privy: the key lives in Privy's enclave, never on Orus's servers and never in your browser. The wallet page shows its address and a QR code to fund it, lets you send ETH from a wallet you already own, and lets you withdraw — by signing yourself, through Privy's confirmation, to an address you choose. Sells return WETH; a withdrawal converts it on the way out.

Automated trading is a delegation: with one click you add Orus's signer to your wallet, under a policy. The policy is the whole of what Orus may sign — wrap ETH up to 0.05 ETH per transaction, approve the listed routers for an exact amount, and call those routers. It has no rule for a transfer, for another chain, or for an approval to anyone else; a request outside it is refused by Privy before it is signed. The console records the delegation only after asking Privy that the signer is really there, and you can turn it off at any time. While it is off, an automatic agent can neither open nor close positions.

Before any real entry the engine checks the wallet again: the delegation stands, the account is enabled, and the balance covers the stake plus gas for the round trip. A wrap keeps a gas reserve as ETH so the exit can always pay for itself. The house desk's own agents trade from a key the operator holds; a user's agent never touches it.

Fund it with ETH, on Robinhood Chain, and with nothing else. Your wallet holds the same address on every EVM chain, so a deposit sent on Ethereum or Base does arrive — at an address where Orus has no router to trade it and no permission to move it, because the policy is refused on every chain but this one. The wallet page reads Robinhood Chain, and also asks Privy what the address holds elsewhere, so a deposit that went to the wrong network is named rather than silently absent. Getting it back is yours to do: export your private key from the wallet page, import it into a wallet of your own, and move the funds — that chain will want its own gas first.

/app/wallet
Address, balance, QR, fund from your own wallet, withdraw, export your key, automated trading on/off.
fund with
ETH, on Robinhood Chain only. Anything else reaches the same address and is stranded there.
policy
Wrap ≤ 0.05 ETH · approve and call listed routers · nothing else. Refused before signing otherwise.
fees
3% of the net gain on each closed real trade, accrued to the token buyback.

Access

Sign in, copy a strategy, run it in simulation, then fund your wallet and go live. The desk itself needs no account.

The console at /app sits behind a login: an email one-time code, or a wallet you already own. The first sign-in creates your account and your trading wallet — an embedded wallet held for you, on Robinhood Chain only. Pressing the button on that page is where you accept the terms it states: Orus runs the strategies you define on a volatile market, nothing here guarantees a profit, and funds you send to your wallet can be lost.

Your console shows what is yours: your strategies, your agents, their radar, signals, positions, history and reports. The desk's own agents are not in it; they are on /live, and their strategies are the templates you can copy. Every account may generate 3 reports a day and send 30 messages a day to a report; how many agents it may run, how many strategies it may hold and whether it may ask its agent to write one are tiers — see $ORUS below. A user's strategy is bounded — min_liquidity_at_dip at least 1,000 $; buy_amount_native at most 0.05 ETH; slippage_pct at most 15 %; max_price_impact_pct at most 10 %; max_open_positions at most 25; website_regex is not available — by the same rules in the API and in a database check.

An agent's cadence is its account's tier, and the tier is the $ORUS in its wallet: Free runs every 60 seconds, Pro every 30 seconds on 1M $ORUS held, Premium every 10 seconds on 3M $ORUS held. Nothing is chosen and nothing is bought with a card — the balance is read from the chain every few hours, and an agent follows it both ways: buy more and it speeds up, sell and it slows down. The thresholds are token amounts rather than dollar ones so a price move cannot take an account's tier away overnight. Going live is four steps, all in the console: copy or write a strategy, deploy an agent on it, fund the wallet on the wallet page and enable automated trading there, then set the agent to automatic. Changing the stake, the caps, the stop or the slippage under a live agent moves it back to simulation — it went live on the old numbers, and the new ones need a new decision.

Nothing on the desk is a mock. What you read is the same database the engine writes to, on the same fifteen-second poll the operator sees.

/app
Your console. Sign in required.
/app/wallet
Your trading wallet: fund, withdraw, automated trading.
/leaderboard
Every wallet and every strategy on Orus, ranked, the house included. Every UTC day, the three best P&L, the house included, split half of the day's fees. No account needed.
/live
The public desk. No account needed.
/pricing
The three tiers and what each holds. No account needed.
/docs
This page.
/llms.txt
This documentation for machines — see Machine-readable docs below.

$ORUS

The token does two things: it takes a share of what a winning real trade makes, and holding it sets what your account can do.

It earns. Orus keeps 3% of the realised profit of a winning real trade — the figure net of the gas both legs paid, read from the receipt — and nothing at all on a losing one; a loss never offsets a later win. Simulated positions and the house's own agents pay nothing. Every UTC day, half of that day's fees is paid out as prizes to the three best net P&L, and the rest buys back $ORUS.

It opens. Your tier is the $ORUS in your wallet, and it is the only thing that sets how often your agents run: Free runs every 60 seconds, Pro every 30 seconds on 1M $ORUS held, Premium every 10 seconds on 3M $ORUS held. Pro and above also open the AI reports — the agent report and the token report, the two features that spend a model call rather than a database row. It also sets how many agents you may run at once (1 on Free, 3 on Pro, 20 on Premium), how many strategies you may hold (1 on Free, 10 on Pro, unlimited on Premium), and whether "Ask your agent" — the assistant that writes a strategy from a conversation — is open, which it is from Pro up, with no message count on it. Going over is never possible by surprise and never destructive — an account that drops a tier keeps every agent it built and simply cannot add another. Everything else is in every tier: every desk template to copy, simulation on live data, real trading, and your own tape.

The thresholds are token amounts, not dollar ones, and deliberately so: a dollar threshold on a young token would take your tier away overnight without you selling anything. The consequence is the honest one — if the price runs, a tier costs more in dollars than it did; if it falls, less. The amounts are a constant we can recalibrate, and changing them is announced.

Jev contextual validation is Premium only (3M $ORUS held), in simulation or live trading at the owner’s choice. Enable it per agent for entries, take-profit exits, or both, with optional written conditions. Below this tier, Jev reviews stop and delegated entries and take profits wait until access is restored or Jev is disabled; stop loss, maximum hold and manual exits remain available. Saved strategies and decision history are kept.

Your balance is read from the chain every few hours and stored; your wallet page shows the figure your tier was decided on. Nothing is ever moved: the tokens stay in the same wallet your agent trades from, and Orus only ever reads the balance. It works both ways — buy more and your agents speed up within hours, sell and they slow to the tier you still hold, with a line on each agent's own tape saying so.

Free
1 agent and 1 strategy, a run every 60 seconds.no token
Pro
3 agents and 10 strategies, a run every 30 seconds, Ask your agent, AI reports.1M $ORUS held
Premium
20 agents and unlimited strategies, a run every 10 seconds, Ask your agent, AI reports, and Jev validation in simulation or live trading.3M $ORUS held

What we measure about you

Google Analytics on the public pages, with advertising switched off, and nothing else.

The site runs Google Analytics 4. It records the pages you open, where you arrived from, and six events on the way to an account: a call to action pressed, the sign-in dialog opened, the sign-in completed, a sign-in stopped at the terms, an account created, and a returning sign-in. That is the whole list. Nothing about what your agents scan, hold or trade is sent anywhere — it lives in the database, and the parts of it that are public are on /live and /leaderboard because we chose to publish them.

Advertising is off: the tag is configured with Google's advertising signals and ad personalisation both disabled, so the data is not used to build an advertising profile and no ad network is contacted. Once you are signed in, the console attaches your account's internal identifier so a funnel can be followed end to end. Never your email, never your wallet address, never your Privy identifier.

Analytics sets cookies in your browser. To refuse them, use your browser's tracking protection, an ad blocker, or Google's own opt-out extension — none of it changes how the product works, and none of it is required to sign in, deploy an agent or trade.

Where the numbers come from

One Orus market layer for screening, token observations and execution quotes.

Orus screens the chain's token list against the strategy's thresholds, then gathers token observations: price, market cap, launch date, pool, all-time high, holder concentration, bundler and sniper shares, launchpad state and security flags. The market layer also supplies candles, earliest-trade samples and execution quotes. Chain reads and transaction broadcasting use the chain RPC.

Every provider sits behind one market module. The engine imports that module and nothing else, so replacing a provider means reimplementing one function, and every filter is re-checked locally even when the screener already applied it — a provider change can never silently weaken a rule.

Every price is in USD. Execution quotes are normalised to the same economics before the engine compares them: expected output in token units, USD in and out, and price impact.

02The pipeline

Scan, filter, launch check, radar, dip detection, signal, execution. Every stage can reject, and every rejection is logged with the test that failed and how far off it was. Each strategy field is listed at the step that reads it.

Scan

Narrow the chain to a few hundred candidates, then enrich them.

The Orus screener narrows the chain's token list under the thresholds it can enforce server-side — 24-hour volume, liquidity, market cap, trade count. That is the cheap pass, and it exists to keep the expensive one small. The native sentinel and the two quote assets, WETH and USDG, are dropped here: the screener lists them as tokens, but they are not candidates.

Each survivor gets one token-details read, which returns the observations the filter and chart analyser need in a single response. Details are shared across the agents running in one process, so nine agents screening the same chain cost one call per token, not nine.

Output: up to 200 candidates per run.

min_volumeMin Volume ($)
Minimum 24-hour volume in USD. A rolling 24 hours, not volume since launch. Passed to the screener and re-checked locally.default 100,000 $ · ≥ 0
min_market_capMin Market Cap ($)
Minimum market cap in USD. Passed to the screener and re-checked locally.default 20,000 $ · ≥ 0
min_transactions_24hMin Transactions 24h
Minimum 24-hour trade count. Passed to the screener and re-checked locally.default 200 · ≥ 0

Filters and risk

Every check, applied locally to every candidate. Where most of them die.

Three checks are fixed and cannot be loosened: a token with no pool is out, a token that cannot be sold — a honeypot — is out, and a buy or sell tax above 10% is out. There is no mint or freeze authority on an ERC-20, so the Solana-era checks do not apply; taxes and honeypots are the equivalent traps, and they are rejected rather than scored.

The venue whitelist matches the venue key, its name or the launchpad the token graduated from, so a strategy that names a launchpad admits its graduated tokens on whichever DEX they now trade. Bonding state can be required either way.

The rest is activity and holder distribution. A token whose supply sits with bundler wallets, launch snipers, insiders or the deployer is a token whose price is somebody's decision rather than a market's. Each has its own ceiling, and a wash-trading floor compares organic volume against reported volume.

Missing data fails the check it is missing from. A strategy that sets a threshold is asking a question, and "unknown" is not the answer it wants: a token with no creation date fails an age-bounded strategy, one with no sniper figure fails the sniper ceiling. These rejections carry their own codes — missing_age, missing_snipers, missing_holders — so the tape shows what was absent rather than what was exceeded. A strategy that leaves a threshold unset asks nothing and is unaffected.

A candidate that fails a numeric test still produces an event with the value and the threshold. That distance is what the near-miss board on the activity page is built from.

allowed_dexesAllowed Venues
Venue whitelist, e.g. pons, noxafun, uniswap-v3. Each entry is matched, case-insensitively and as a substring, against the venue key (uniswap-v4), the venue name (Uniswap) and the launchpad the token came from (pons-v2), so a launchpad name admits its graduated tokens on whichever DEX they now trade. Empty accepts any venue.default pons
require_bondedLaunchpad State
true admits graduated tokens only, false admits tokens still on their bonding curve only, unset admits both.default unset
max_age_hoursMax Age (hours)
Maximum token age, in hours since creation. A token with no creation date fails an age-bounded strategy.default 168 hours · ≥ 0, ≤ 8760
min_age_hoursMin Age (hours)
Minimum token age, in hours since creation. 0.083 is five minutes.default 0.083 hours · ≥ 0, ≤ 8760
min_volume_liquidity_ratioMin Volume/Liquidity Ratio
Floor on 24-hour volume divided by liquidity. High turnover on thin liquidity is a token being traded rather than parked.default unset · ≥ 0
max_volume_fees_ratioMax Volume/Fees Ratio
Ceiling on 24-hour volume divided by the fees that volume paid. On an AMM the two are proportional — fees are a fixed share of every trade — so the ratio is one over the fee rate and sits near 220 on this chain whatever the token's size — measured as the median of 1,000 signalled tokens. That is the normal value, not a target: a ceiling belongs well above it, and at 2,000 it refuses about one token in twenty where 220 would refuse half. A far higher ratio is volume that reached no pool: wash trading, or an accounting that has lost track. Both figures are the same 24-hour window; dividing by the fees a pool has earned since launch would measure its age instead. A pool under three hours old can read high because the provider's fee counter lags its volume counter, and a token with no fee figure fails this check when it is set.default 2,000 · ≥ 1
min_buysMin Buys
Minimum 24-hour buy count.default 100 · ≥ 0
min_sellsMin Sells
Minimum 24-hour sell count. A token that is only bought has nobody able to sell it.default 100 · ≥ 0
min_total_feesMin Total Fees ($)
Floor on the cumulative fees the pool has earned, in USD. A proxy for how much real trading the pool has seen.default unset · ≥ 0
max_bundled_buy_pctMax Bundled Buy (%)
Ceiling on the share of supply held by bundler wallets — buys bundled into the launch transaction.default 40 % · ≥ 0, ≤ 100
max_snipers_pctMax Snipers (%)
Ceiling on the share of supply held by wallets that sniped the launch. A token with no sniper figure fails this check when it is set.default unset · ≥ 0, ≤ 100
max_insiders_pctMax Insiders (%)
Ceiling on the share of supply held by insider wallets.default unset · ≥ 0, ≤ 100
max_dev_holdings_pctMax Dev Holdings (%)
Ceiling on the deployer's own holdings.default unset · ≥ 0, ≤ 100
max_top10_holdings_pctMax Top-10 Holdings (%)
Ceiling on the top ten holders combined.default unset · ≥ 0, ≤ 100
min_organic_volume_ratioMin Organic Volume Ratio
Floor on organic volume over reported volume, from 0 to 1 — the wash-trading floor.default unset · ≥ 0, ≤ 1
min_holdersMin Holders
Minimum holder count. A token with no holder figure fails this check when it is set.default unset · ≥ 0
website_regexWebsite Regex
A regular expression matched against the token's socials and description. Evaluated inside the cron, so it is reserved for the house: a pathological pattern would stall every agent's tick.users: not available

Launch market cap and the radar

Survivors are tracked over time rather than judged in one frame.

A token's market cap one second after its first trade says something its current cap does not: a launch at a high cap is usually sniped or bundled, and the dip pattern is unreliable on it. The clock starts at the first trade, not at contract creation — on a launchpad the two coincide, on a DEX listing made after deployment they do not. Supply is read from the token. The value is cached, so the check costs one request per token, once.

What survives lands on the radar — the watchlist — where it is tracked across runs with its last known all-time high, the instant of that high, the current dip and the liquidity behind it. Nothing is bought from the radar; it is the pool the chart analyser reads every cycle.

A token leaves the radar for one of three reasons, and each is recorded: it dropped out of the scan, its entry window expired, or its launch cap exceeded the ceiling. It comes back on its own terms. One that dropped out returns when it reappears, keeping the dip it was tracking. One whose window expired, or that has already been signalled, returns only on a new all-time high — a new high starts a new dip — and only if nothing is still open on it. A launch-cap rejection, or a token hidden by hand, is permanent.

Eviction only happens on a scan that observed the market. When the screener returns nothing — an outage, a rate limit — nothing is evicted, because a blind scan is indistinguishable from an empty market.

max_launch_mcapMax Launch Market Cap ($)
Ceiling on the market cap one second after the token's first trade. A launch at a high cap is usually sniped or bundled, and the dip pattern is unreliable on it; the exclusion is permanent. Supply is read from the token. Unset skips the check.default 50,000 $ · ≥ 0

Dip detection

The entry test, and the window it opens.

For each radar token the analyser takes the all-time high from the details it already has, pulls five-minute candles only when that high moved or no crossing is stored yet, and measures the current price against it.

Depth alone is not enough. A dip that happened in ninety seconds is a flash crash, and one that took two days is a dead token — so timing is bounded on both sides, measured from the high and, optionally, from launch. Liquidity at entry and, optionally, the market cap at the high have floors of their own. A ceiling on the dip itself separates a discount from a rug.

The first-dip rule is what makes an entry expire. The analyser walks candles forward from the high to the first close below the threshold; that instant starts the clock. With a window set, the entry is valid for that many minutes after the crossing and then written off — which is why a token can be rejected for being too late on a dip that is still deep. A crossing belongs to its high: a new high clears it.

dip_threshold_pctDip Threshold (%)
Minimum fall from the all-time high before an entry is considered. The analyser walks candles forward from the high to the first close below ATH × (1 − threshold/100); that instant is the first dip.default 75 % · ≥ 1, ≤ 99
max_dip_pctMax Dip (%)
Ceiling on the dip at entry. A token down more than this from its high is treated as dead rather than dipped. Unset means no ceiling.default unset · ≥ 1, ≤ 100
min_dip_timing_minutesMin Dip Timing Since ATH (min)
Floor on the time from the all-time high to the dip — the flash-crash guard. A dip that took ninety seconds is not a dip.default 5 min · ≥ 0
max_dip_timing_minutesMax Dip Timing Since ATH (min)
Ceiling on the time from the all-time high to the dip — the dead-token guard. 600 is ten hours.default 600 min · ≥ 0
min_dip_timing_launch_minutesMin Dip Timing Since Launch (min)
Floor on the time from launch to the dip.default unset · ≥ 0
max_dip_timing_launch_minutesMax Dip Timing Since Launch (min)
Ceiling on the time from launch to the dip.default unset · ≥ 0
max_first_dip_minutesMax Time After First Dip (min)
How long the entry stays valid after the first crossing of the threshold. The crossing opens a window; past it the entry is written off, which is why a token can be rejected for being too late on a dip that is still deep. A pending signal expires on it too. This is the only bound on the AGE of a crossing — max_dip_timing_minutes bounds the ATH-to-crossing duration, which is a different quantity. Left empty the window never closes, and one all-time high keeps producing entries as the price falls away beneath it.default 60 min · ≥ 1
min_liquidity_at_dipMin Liquidity at Dip ($)
Minimum USD liquidity in the pool at entry. Also passed to the screener as its liquidity floor. What decides whether you can get back out.default 5,000 $ · ≥ 0 · users: ≥ 1,000 $
min_ath_market_capMin ATH Market Cap ($)
Minimum market cap at the all-time high, in USD. A dip from a high that never meant anything is not a dip worth buying.default unset · ≥ 0

Signals

One entry per dip regime. A regime starts at an all-time high.

A buy signal carries the price at signal, the all-time high it was measured from, the dip depth and duration, the liquidity behind it and the venue it would trade on.

An agent's latest signal on a token — executed, expired or dismissed — blocks a new one only while it was raised at or after the high this dip is measured from. A signal older than the high belongs to a previous regime: the token has since made a new high and dipped again, and the strategy that entered the first dip has the same case for entering this one. A held position blocks regardless. The lookups are batched, two per run rather than two per candidate.

Once the signal row exists the radar entry moves to signal-generated and the desk operator is notified on Telegram. Sell signals are not produced here; they come from the position monitor when an exit condition fires.

A pending signal does not live forever. It expires on the strategy's own window measured from the crossing, and on a global ceiling of 60 minutes regardless. And it is executed only while the dip still exists: every entry in a batch is re-priced from one refresh at execution time, then once more on the price the router's own buy quote implies, and a token that has bounced back above the threshold on either expires its signal with a dip-recovered event instead of being bought.

Execution

Quote both ways, record before broadcasting, and read the fill rather than assume it.

With Jev enabled for entries, an eligible proposal also needs its contextual approval in the same cycle. Jev cannot restore a candidate rejected by the strategy. Its approval is short-lived and is checked again before execution; the price, quote, exposure and wallet checks below still apply.

Three limits are asserted first — see guard rails below. Then the token is quoted both ways: a buy of the strategy's size, and the sale of what that buy would return. No buy route, no sell route, or an immediate round trip losing more than 25% refuses the entry outright. The signal is retired, not retried, and the reason — no route, unsellable, round-trip loss — goes on the tape. This runs in every mode, so a simulation declines what a real agent would decline. The provider's honeypot and tax flags are absent on many tokens; a router quote measures the trap directly.

ETH is wrapped before a buy, because the router quotes ERC-20 legs only and rejects the native address. Selling an ERC-20 needs an approval first. The Orus execution layer compares available swap routes, signs the selected transaction and broadcasts it to the chain. The quote is taken before the wrap, so a pair with no route costs nothing.

The position row is written before the transaction is broadcast, so a confirmed swap can never end up untracked; if the swap fails, the placeholder is deleted. The amount received is read from the transaction's transfer logs, not from the quote, and the entry price is the fill price in every mode — what was spent over what was received. The oracle price the signal was raised on stays on the signal. Multipliers, the stop and the target are all measured from the fill, so a fill a few percent above the oracle is drawdown the position carries from the start.

An exit sells what the position holds, capped at the wallet balance for fee-on-transfer shortfalls — never the wallet's whole balance, which may hold the same token for another agent or for the operator. Every signed sequence on a wallet — a buy's wrap, approve and swap; a sell's approve, swap and unwrap — runs under a lease on that wallet held in the database, so two processes never sign against one nonce, and a position is re-read under the lease before it is sold.

03Running it

Exits, the limits that bind before capital moves, and how to read the desk.

Exits and position monitoring

Three conditions, checked in order, first match wins — and none of them trusts a single number.

At the end of every run, each position that still holds tokens has its price, multiplier and P&L refreshed. A quote more than 100× the entry is a bad print: that tick is skipped and recorded rather than acted on.

Stop loss first. It fires when the drawdown reaches the strategy's stop — but only once a second feed agrees. The details provider is asked once, and the sell proceeds if it shows at least 80% of the way to the stop. Feeds differ by a few percent; a bad print differs by orders of magnitude. If the second feed cannot answer, the stop proceeds: capital protection does not wait on a vendor.

Maximum hold second. This is a clock, not a price: it fires even when the feed has no quote for the token — liquidity pulled, pool abandoned — at a secondary-feed price or, failing that, the last mark, and the event says which. It is the most common exit on the desk by a wide margin.

Take profit last, and for a real position the fill is checked before the sell: the router is asked what the exit would return, and the sell proceeds only if it delivers at least half the promised gain and never less than the stake. A fill that fails the check is neither an exit nor a failure; the position stays open and the next tick asks again.

With Jev enabled for take-profit exits, that proposed exit needs its contextual approval. A deferral is reviewed again on a later cycle, even below the original target, and the real fill check still applies. Jev cannot veto a stop loss, the maximum holding deadline or an explicit manual exit.

Exits run one at a time per wallet — they share a nonce, so concurrent swaps would collide. Agents on different wallets run concurrently. A failed exit does not close the position: if the swap reverts or is never confirmed, the position is marked sell-failed with the error and an attempt counter, and retried on later runs up to 3 times. Closing it would report a realised P&L for tokens the wallet still holds.

When an exit settles, realised P&L is the native the swap returned against what was spent, less the gas both legs paid, including attempts that reverted. Not oracle prices. When a position closes on the hold limit with no usable quote at all, it closes with no P&L rather than a made-up one, and the desk skips it.

min_sell_multiplierMin Sell Multiplier (x)
Take profit at this multiple of the fill price. For a real position the router is asked what the exit would return first, and the sell proceeds only if it delivers at least half the promised gain and never less than the stake.default 2 x · ≥ 1.01, ≤ 100
stop_loss_pctStop Loss (%)
Sell when the position is down this much from the fill — once a second price feed agrees the drawdown is real. Unset disables it.default unset · ≥ 1, ≤ 99
stop_loss_max_hoursMax Hold Duration (hours)
Sell after holding this long, at whatever the market pays — quote or no quote. A clock, not a price, and the most common exit on the desk by a wide margin. Unset disables it.default unset · ≥ 0.1, ≤ 720
jev_exit_instructionsJev take-profit condition
Additional condition for Jev's Premium-only take-profit review in simulation or live trading. Jev may approve an exit or defer it for another observation; deferred exits are reviewed even below the original target. Stop loss, maximum hold and explicit manual exits remain outside Jev's veto.

Guard rails

Checked before any capital is committed, in every mode.

Three limits are asserted on every buy, before the quote and before the wrap. The buy size must be greater than zero — set it to zero and the agent produces signals and never spends. The open-position cap counts open, simulated-open and sell-failed positions together, so a stuck exit still occupies a slot rather than quietly freeing one. The daily spend cap is a rolling 24-hour window, not a calendar day.

They are strategy fields, so two agents on the same rules can carry different ceilings by running two strategy rows. Leaving one unset disables that particular limit, which is a choice worth making deliberately. A user's stake is capped at 0.05 ETH per entry by the same rule in the API and in the database.

buy_amount_nativeBuy Amount (ETH)
ETH to spend per entry. 0 means the strategy produces signals and never spends. The engine wraps it to WETH before the buy and keeps a gas reserve aside.default 0 ETH · ≥ 0 · users: ≤ 0.05 ETH
slippage_pctSlippage (%)
Slippage tolerance passed to the router, on both legs.default 5 % · ≥ 0.1, ≤ 50 · users: ≤ 15 %
max_price_impact_pctMax Price Impact (%)
Ceiling on the price impact the router estimates for the entry itself. A buy whose own size would move the pool more than this is refused and its signal retired: the round trip would start from a hole no dip pays for. Unset disables the check.default 5 % · ≥ 0.1, ≤ 50 · users: ≤ 10 %
max_open_positionsMax Open Positions
Cap on positions held at once. Open, simulated-open and sell-failed positions all count, so a stuck exit occupies a slot rather than freeing one. Unset means no cap — the wallet becomes the limit.default unset · ≥ 1 · users: ≤ 25
max_daily_spend_nativeMax Daily Spend (ETH)
Cap on ETH committed to entries per rolling 24 hours, not per calendar day. Unset means no cap.default unset · ≥ 0
jev_entry_instructionsJev entry condition
Additional condition for Jev's Premium-only contextual entry review in simulation or live trading. Jev evaluates observed transactions and participant histories after the quantitative filters; missing evidence means waiting, never automatic approval. Enable Jev on the agent.

Reading the public desk

Everything above, live, without an account — and how each number is made.

The desk publishes the book, the trades table, the strategy board with every rule each strategy runs on, the analyses, and the decision tape — one row per decision the engine made, including the rejections and the measurement behind each one. Consecutive decisions with the same reason collapse into one row that says how many it stands for. The tape polls every eight seconds; the aggregates are computed over the whole closed book and cached for forty-five seconds.

The book is an index. These trades never shared a wallet, so the line is what a single 12 ETH float would have done taking every one of them, indexed to 1,000 — 12 ETH because it is above the most the desk ever had deployed at once and above its deepest drawdown, so the floor holds and the slope is profit. Below 1,000 the desk is down.

A closed trade whose only exit price was a quote more than 100× its entry is withheld from the book and from the trades table, and the note under the ribbon says how many. A trade that closed on its hold limit with no usable quote counts as closed and carries no P&L. Headline figures come from the receipt when there is one; a simulated trade is marked at the routed quote.

Results are forward-tested, not backtested. A backtest with no stop loss and no maximum hold can only close a trade by hitting its target, so every closed trade is a winner by construction — which is why the numbers on the desk come from running it live instead.

04Your agent

Writing a strategy with your agent, what you can do by hand while an agent runs, and where a machine can read all of this.

Writing a strategy with your agent

Describe what you want; your agent drafts the rules onto the form. You read them, change what you like, and save.

On the strategies page, New strategy opens as a drawer with the form; Ask your agent unfolds a conversation beside it. You say what you are after — how much risk, how much per entry, launches or established tokens, how long you are willing to hold — and the agent answers in prose and hands back a complete strategy. It lands on the form field by field, each one marked until you edit it, and you can ask for a change as many times as you like: the next proposal replaces the last, and any earlier one can be put back with one click.

The agent is briefed on exactly what this page describes: the pipeline and what each step refuses, the limits the engine holds itself to, every field with its meaning and its bounds, and the desk's own strategies with the results they have produced — as evidence, not as instructions. It is told to explain the three to five choices that matter, to say what the strategy will and will not catch, and to refuse a wish the engine cannot grant rather than invent a field for it. It answers in the language you write in.

Nothing the agent says reaches the database on its own. What it proposes is validated field by field before it touches the form — a value the engine would refuse is dropped and named, a required field it left out is filled from the default and named, and a user's proposal is brought inside the same bounds as any other — and it is your Save, not the agent, that creates the strategy. Each message counts against the account's 30 chat messages a day.

Write it
The form on its own, every field editable, the same rules as always.
Ask your agent
Unfolds the conversation beside the form. The latest proposal is applied as it arrives.
Apply to form
On an earlier proposal's card: put that one back on the form.
set by your agent
The mark on a field the agent just filled; it clears the moment you edit the field.
to fit your limits
A value the agent proposed above a bound, and what it was brought down to.

Sell a position by hand

Every held position has a Sell button. It runs the same exit the monitor runs on a stop loss, now.

On an agent's page and on the dashboard, a position that still holds tokens — open, simulated, or waiting on a failed exit — can be sold on demand. The sale is not a shortcut around the engine: it raises the sell signal, quotes the router, sends the swap, reads what came back from the receipt and books the P&L net of gas, exactly as an automatic exit would, with the reason recorded as manual. A simulated position is quoted out through the router and closed at what it would have returned.

It is immediate — the request stays open while the swap confirms, which is seconds on a good day and a couple of minutes on a slow one — and it is safe alongside the cron because of the wallet lease: the sale takes the lease on the wallet, re-reads the position under it, and never signs against a nonce a running cycle is using nor sells tokens a cycle has just sold. A wallet that is still busy after forty-five seconds answers wallet busy, and the button offers a retry rather than a promise to sell later.

A position whose exit already failed 3 times shows Retry exit instead: asking again resets its attempt budget. A user's real position sells through the delegated wallet, so automated trading must be enabled on the wallet page; the global kill switch does not stop an exit, and neither does the account's trading switch — a way out is never switched off.

closed
Settled on-chain; what came back was read from the receipt.
pending
Broadcast; the receipt has not arrived yet. The next pass reads it and closes the position.
failed
The swap did not settle. The position is still held; the agent retries on its next pass.
wallet_busy
Another transaction was being signed from the wallet. Nothing was tried; try again in a moment.

Machine-readable docs

The same reference, written for a language model to read.

Everything on this page — the pipeline, the limits the engine holds itself to, every strategy field with its default, its unit and its bounds — is published at /llms.txt as a short index and at /llms-full.txt in full, following the llms.txt convention. Both are generated from the same table and the same constants as this page, in the same build, so they cannot say something this page does not.

They exist so that an assistant helping you write a strategy, on Orus or elsewhere, describes the system that will actually run it: which fields exist, what each one means, what a user's strategy may not do, and what the engine refuses before any capital moves.

/llms.txt
The index: what Orus is, the chain, the pipeline in eight lines, every field in one line, the account limits, the links.
/llms-full.txt
The index plus every section of this page and the full field reference with defaults, ranges and user bounds.
05Jev validation

What Jev adds to your strategy, when to use it, and how to read its decisions. Optional for Premium, in simulation or live trading at your choice.

What is Jev?

An AI model that makes a specific decision from the observations it receives.

Jev is an evaluation model from TypeSafe AI, available through Vercel AI Gateway. It interprets observations against written criteria and returns one of a defined set of answers. In Orus, that answer can approve, refuse or delay an entry, or approve or defer a take-profit exit.

Think of it as a contextual reviewer inside your agent. Your strategy first checks its numeric rules, such as dip depth, liquidity and position limits. If you enable Jev for the proposed trade, the agent waits for its decision in the same trading cycle. Only an approval can continue to execution, where price, quote and wallet checks still apply.

The strategy assistant helps you write rules before you save them. Jev instead evaluates a trading opportunity while your agent runs. It does not rewrite your strategy, choose your stake, predict a target price or receive permission to sign transactions.

When is Jev useful?

When the order and persistence of trading activity matter more than another threshold.

Two tokens can pass the same volume and dip filters while showing different activity. In one, purchases follow an initial sell-off and remain held across observations. In the other, recent buyers quickly sell back out. A volume total hides that sequence; Jev can assess it against your entry criteria.

At a take-profit trigger, you can ask whether observed purchases are still being retained while selling is absorbed. Jev may allow the exit or defer it for another review. Deferring keeps the position exposed: a later exit can be worse than taking the original profit.

Use ordinary strategy fields for exact requirements such as minimum liquidity, maximum stake or a holding deadline. Use Jev for a question about the supplied sequence of events. If that question needs facts Orus does not provide, Jev should return insufficient evidence. More reviews or fewer trades do not by themselves mean a better strategy; any improvement needs a comparison.

Enable Jev on an agent

Choose the decisions you delegate. Your execution mode remains your choice.

Jev is Premium only, unlocked by holding 3M $ORUS. In the agent form, open Jev contextual validation and choose Entries, Take-profit exits, or Entries and take-profit exits. Disabled keeps the ordinary strategy behavior. Save the form to apply your choice.

Simulation uses simulated positions. Automatic uses real trades through your configured wallet. Enabling Jev does not switch between them or start an agent. New agents initially use simulation; changing an existing agent to Automatic follows the usual wallet setup. The operator's Manual mode leaves entry execution by hand and can review proposed take-profit exits.

The switch belongs to each agent. Optional written conditions belong to its strategy, under Buy Position and Sell Criteria. Saving a condition does not activate Jev, and agents sharing that strategy read the same conditions. Leaving both conditions blank uses the standard review criteria, which you can expand in the form. Jev and Fly cannot be enabled together on the same agent.

Changing a saved condition is a strategy risk change. For a user-owned strategy, its automatic agents return to simulation when that condition changes, just as when the stake or stop changes. Review the new criteria before choosing Automatic again. Simply changing the agent's Jev scope does not change its execution mode.

You can turn Jev off to return to ordinary strategy decisions on subsequent cycles. This does not close positions or erase the journal. Pausing an agent stops new entries; held positions remain monitored. If Premium access is lost, Jev reviews stop and delegated entries and take profits wait until access returns or Jev is disabled. Stop loss, maximum holding time and manual exits remain available.

Write an entry condition

Describe the evidence you want before accepting a dip that already passed your rules.

The standard entry review looks for demand that persists after initial selling. It can refuse an opportunity when purchases are rapidly reversed or selling continues, wait when an observed transition needs another sample, or report insufficient evidence when the available history cannot distinguish those readings.

Example: “Require purchases after the initial sell-off to remain held across the available observations; rapidly reversed purchases should not count as persistent demand.” This asks about event order and changes in observed holdings, rather than repeating a volume threshold.

Write one clear, observable requirement in the Jev entry condition field, up to 500 characters. It adds to the standard criteria. Avoid requests such as “only buy tokens that will double” or “prove the wallets are independent”: future returns and unknown wallet relationships are not evidence Jev has. A condition that cannot be established may leave an entry waiting until its window expires.

Write a take-profit condition

State what would justify keeping the position after the profit target is reached.

The standard exit review validates the proposed take profit unless the observations sufficiently support continuing the position. Holding requires purchases retained over time and selling being absorbed; a higher price alone is not enough. Missing or contradictory evidence does not authorize the delegated exit.

Example: “Defer the take profit only while successive observations show retained purchases and absorption of selling; do not defer on price strength alone.” Write this in Jev take-profit condition, up to 500 characters. The condition helps qualify a deferral; the stop-loss percentage and holding deadline still belong in their normal strategy fields.

A deferred take profit is reviewed again on a later cycle, even if the price has fallen below the original target. A real sale must still pass the existing take-profit fill check. Stop loss, maximum holding time and an explicit manual exit bypass Jev's decision, while retaining their normal execution checks. Jev can delay a take profit, but it cannot veto those exits.

Read the decision journal

A model decision and a completed trade are two separate events.

Open Jev on the agent page to see the latest reviews. Decision is the model's answer or the review's status. Applied action records what the engine subsequently did. An approval can still expire or be stopped by a changed setting, a price or quote check, unavailable funds or a failed transaction. A pending action is not a settled trade; No recorded action is not proof of execution.

No reviews yet can mean there has been no eligible entry or take-profit trigger for the enabled scope. Jev does not run on every scanned token. When a review cannot run because of missing data, a timeout, unavailable service or a cycle's time budget, it never grants approval by default. Delegated entries wait within their existing window; delegated take profits remain open for a later review. Protective and manual exits remain available.

View under Evidence opens the captured observations, saved criteria and structured answer. It lets you inspect what was actually available at decision time. Any returned choice probabilities describe the model's assessment of those choices, not the chance of making a profit.

Entry approved
The proposed entry may continue through execution checks. It is not yet a confirmed purchase.
Entry refused
This opportunity is retired. It does not permanently ban all future opportunities in the token.
Waiting for another observation
An observed transition needs another sample. The signal can be reconsidered while its entry window remains valid.
Exit approved
The proposed take profit may continue through the exit checks.
Take profit deferred
Keep the position for another review. Stop loss and maximum hold still apply.
Insufficient evidence / insufficient data
No delegated trade is approved. The observations cannot support the required decision.
Unavailable / budget exhausted
The review could not complete in this cycle. This is an operational outcome, not a negative judgment on the token.

What evidence does Jev use?

Recent transactions and changes in observed holdings, with gaps kept visible.

Orus supplies a recent sequence of buys and sells with times, amounts and pseudonymous participant identifiers, a sample of participants' holdings and cumulative purchases and sales, and earlier observations when available. The proposed trade's context includes the current price, entry or dip information, and whether a take profit was already deferred.

The sample is bounded and can miss trades or holders. A single balance cannot prove that someone retained a recent purchase; that requires observations over time. Unknown wallet relationships remain unknown, and different identifiers do not prove independent traders. Missing values are kept missing rather than treated as zero or a sign of safety.

Jev only evaluates the observations supplied for that review. It does not independently browse social media, inspect private chats or see future trades. Your optional text cannot add a data source. The journal exposes coverage information so you can distinguish an uncertain market reading from incomplete input.

Compare with and without Jev

Measure whether contextual decisions help your strategy, including the opportunities they miss.

Public agent, strategy and account pages identify the current JEV scope and how many agents use it. The With JEV leaderboard filter selects current configurations; it does not turn the historical P&L into a JEV performance measurement. Public activity covers the last 24 hours and follows the selected real/simulation filter, independently of the chart period.

Public activity separates model responses, missing data before a review, and unavailable or expired reviews. Repeated reviews of one signal or held position count as one distinct opportunity. An approval is separate from a confirmed execution. Detailed examples are published only for ORUS agents; user instructions, tokens under review and individual observations remain private.

For a comparison, create two agents using the same strategy, execution mode, cadence and starting conditions. Leave Jev disabled on one and enable a chosen scope on the other. Run them over the same period without changing the parameters midway. Simulation lets you do this without risking funds; it is a testing option, not a restriction on Jev access.

Compare net realized results after trading costs, open exposure and drawdown, trade count, entries refused or missed, and exits deferred. Read the journal for unavailable or insufficient reviews and added latency. A higher average profit per completed trade can hide fewer opportunities or losses still held open. Different holdings can also make the agents encounter different later opportunities, despite identical rules.

If a frozen experiment comparison is attached to the agent, its table also shows review errors, latency and reported inference costs. Open marks are estimates, and the displayed inference cost is not the total cost of market data. Frozen comparison agents remain in simulation to keep the experiment consistent; ordinary Premium agents may use live trading.

Jev can misread context, miss an entry or postpone an exit that would have been better taken. Its availability and structured answers do not establish a performance benefit. Judge results over enough opportunities and different market conditions before attributing a difference to the model.

06Partner API

Integrate Orus token data into your product. One authenticated GET request returns market observations, risk indicators and trading-agent activity.

API v1Robinhood mainnet · 4663Bearer authenticationRead only

Quickstart & authentication

Scan one contract with a server-side request.

GET/api/v1/scanapplication/json

Base URL: https://www.orusagent.xyz. Send your partner key in the Authorization: Bearer <key> header. No request body is needed.

Whitelisted partners only

Request access from @Orus_agent on X ↗ with your product and expected traffic. Orus approves your account and issues a private key with its expiry and quotas.

Keep the key in your backend secret manager as ORUS_PARTNER_API_KEY. Console cookies do not authenticate API calls. Never put the key in client-side code, a URL, or a Telegram message.

curl --get 'https://www.orusagent.xyz/api/v1/scan' \
  --header "Authorization: Bearer $ORUS_PARTNER_API_KEY" \
  --data-urlencode 'chainId=4663' \
  --data-urlencode 'token=0x1111111111111111111111111111111111111111' \
  --data-urlencode 'include=chart,launch' \
  --data-urlencode 'dipThresholdPct=30' \
  --data-urlencode 'lookbackHours=48'

Replace the illustrative 0x111…111 contract with the token to scan. These examples request chart and launch indicators explicitly. Use include=none for a token card without those extra reads.

Query parameters

Five query parameters. Defaults and bounds are part of the contract.

Only Robinhood Chain mainnet (chainId=4663) is supported. Robinhood testnet (46630) returns 400 unsupported_chain. A bot running in testnet mode must not scan its testnet contracts as mainnet addresses. Enable live scans on mainnet cards; use the clearly labeled synthetic response examples to test the renderer offline. There is no testnet scan endpoint.

Scan query parameters
ParameterType / requiredDefaultValues & behavior
chainIdintegerRequired

Robinhood Chain mainnet (4663) only. Testnet (46630) returns 400 unsupported_chain. Never relabel a testnet contract as mainnet.

4663

tokenstringRequired

Non-zero EVM contract address. Normalized to lowercase.

0x + 40 hexadecimal characters

includestringOptionalchart

Optional chart and launch reads. Core data and agents are always included.

none · chart · launch · chart,launch · launch,chart

dipThresholdPctnumberOptional30

Percent decline from ATH that defines a dip. Used when chart is included.

1–99 inclusive

lookbackHoursnumberOptional48

Hours of five-minute candle history. Used when chart is included; does not change the fixed 24h agent window.

1–168 inclusive

Unknown parameters, repeated parameters, invalid addresses, unsupported chains and out-of-range values return 400. Decimal values are accepted for dipThresholdPct and lookbackHours; send plain numbers without units.

Choose what to include

Include options
includeDip / chartLaunchUse case
noneNoNoToken cards: core data and agents only.
chartYesNoDefault. Add dip timing and chart coverage.
launchNoYesAdd the earliest-trade launch sample.
chart,launchYesYesRequest all available indicators. launch,chart is equivalent.

Token, market, pool, security, risk, ATH/ATL, deployer, socials, agents and card data are always returned. include only controls chart and launch reads. Candles have a fixed five-minute interval; raw OHLCV arrays are not returned.

Response examples

A successful request can still contain unavailable observations.

These complete JSON responses use synthetic values to illustrate the contract. The partial example shows missing security observations and an agent-data failure while the market scan remains available. Always inspect availability, warnings and checkedAt.

{
  "apiVersion": "1.0",
  "requestId": "11111111-1111-4111-8111-111111111111",
  "chainId": 4663,
  "checkedAt": "2026-09-17T12:00:00.000Z",
  "cache": {
    "hit": false,
    "ageSeconds": 0,
    "maxAgeSeconds": 30
  },
  "token": {
    "address": "0x1111111111111111111111111111111111111111",
    "name": "Example token",
    "symbol": "EXAMPLE",
    "image": null,
    "createdAt": "2026-09-15T12:00:00.000Z",
    "decimals": 18,
    "ageSeconds": 172800,
    "totalSupply": 1000000000,
    "circulatingSupply": 1000000000
  },
  "market": {
    "priceUsd": 0.0006,
    "marketCapUsd": 600000,
    "fdvUsd": 600000,
    "liquidityUsd": 90000,
    "maxLiquidityUsd": null,
    "liquidityToMarketCapPct": 15,
    "volumeChange5mPct": null,
    "totalFeesUsd": null,
    "secondsSinceLastTrade": 5,
    "latestTradeAt": "2026-09-17T11:59:55.000Z",
    "priceUpdatedAt": null,
    "windows": {
      "1m": {
        "volumeUsd": null,
        "buyVolumeUsd": null,
        "sellVolumeUsd": null,
        "organicVolumeUsd": null,
        "organicBuyVolumeUsd": null,
        "organicSellVolumeUsd": null,
        "buys": null,
        "sells": null,
        "trades": null,
        "buyers": null,
        "sellers": null,
        "traders": null,
        "organicTrades": null,
        "organicTraders": null,
        "feesUsd": null,
        "priceChangePct": null
      },
      "5m": {
        "volumeUsd": null,
        "buyVolumeUsd": null,
        "sellVolumeUsd": null,
        "organicVolumeUsd": null,
        "organicBuyVolumeUsd": null,
        "organicSellVolumeUsd": null,
        "buys": null,
        "sells": null,
        "trades": null,
        "buyers": null,
        "sellers": null,
        "traders": null,
        "organicTrades": null,
        "organicTraders": null,
        "feesUsd": null,
        "priceChangePct": null
      },
      "15m": {
        "volumeUsd": null,
        "buyVolumeUsd": null,
        "sellVolumeUsd": null,
        "organicVolumeUsd": null,
        "organicBuyVolumeUsd": null,
        "organicSellVolumeUsd": null,
        "buys": null,
        "sells": null,
        "trades": null,
        "buyers": null,
        "sellers": null,
        "traders": null,
        "organicTrades": null,
        "organicTraders": null,
        "feesUsd": null,
        "priceChangePct": null
      },
      "1h": {
        "volumeUsd": null,
        "buyVolumeUsd": null,
        "sellVolumeUsd": null,
        "organicVolumeUsd": null,
        "organicBuyVolumeUsd": null,
        "organicSellVolumeUsd": null,
        "buys": null,
        "sells": null,
        "trades": null,
        "buyers": null,
        "sellers": null,
        "traders": null,
        "organicTrades": null,
        "organicTraders": null,
        "feesUsd": null,
        "priceChangePct": null
      },
      "4h": {
        "volumeUsd": null,
        "buyVolumeUsd": null,
        "sellVolumeUsd": null,
        "organicVolumeUsd": null,
        "organicBuyVolumeUsd": null,
        "organicSellVolumeUsd": null,
        "buys": null,
        "sells": null,
        "trades": null,
        "buyers": null,
        "sellers": null,
        "traders": null,
        "organicTrades": null,
        "organicTraders": null,
        "feesUsd": null,
        "priceChangePct": null
      },
      "6h": {
        "volumeUsd": null,
        "buyVolumeUsd": null,
        "sellVolumeUsd": null,
        "organicVolumeUsd": null,
        "organicBuyVolumeUsd": null,
        "organicSellVolumeUsd": null,
        "buys": null,
        "sells": null,
        "trades": null,
        "buyers": null,
        "sellers": null,
        "traders": null,
        "organicTrades": null,
        "organicTraders": null,
        "feesUsd": null,
        "priceChangePct": null
      },
      "12h": {
        "volumeUsd": null,
        "buyVolumeUsd": null,
        "sellVolumeUsd": null,
        "organicVolumeUsd": null,
        "organicBuyVolumeUsd": null,
        "organicSellVolumeUsd": null,
        "buys": null,
        "sells": null,
        "trades": null,
        "buyers": null,
        "sellers": null,
        "traders": null,
        "organicTrades": null,
        "organicTraders": null,
        "feesUsd": null,
        "priceChangePct": null
      },
      "24h": {
        "volumeUsd": null,
        "buyVolumeUsd": null,
        "sellVolumeUsd": null,
        "organicVolumeUsd": null,
        "organicBuyVolumeUsd": null,
        "organicSellVolumeUsd": null,
        "buys": null,
        "sells": null,
        "trades": null,
        "buyers": null,
        "sellers": null,
        "traders": null,
        "organicTrades": null,
        "organicTraders": null,
        "feesUsd": null,
        "priceChangePct": null
      }
    }
  },
  "pool": {
    "address": null,
    "dex": null,
    "dexKey": null,
    "launchpad": null,
    "factory": null,
    "bonded": null,
    "bondingPct": null,
    "bondedAt": null,
    "bondingCurveAddress": null,
    "launchpadUrl": null
  },
  "security": {
    "isHoneypot": false,
    "isProxy": false,
    "buyTaxPct": 0,
    "sellTaxPct": 0,
    "liquidityBurnPct": 99.8
  },
  "risk": {
    "bundlersPct": 4,
    "snipersPct": null,
    "insidersPct": null,
    "devHoldingsPct": null,
    "top10Pct": null,
    "top50Pct": null,
    "top100Pct": null,
    "top200Pct": null,
    "freshTradersPct": null,
    "proTradersPct": null,
    "smartTradersPct": null,
    "holdersCount": 1200,
    "bundlersCount": null,
    "snipersCount": null,
    "insidersCount": null,
    "laggedFields": [
      "bundlersPct",
      "snipersPct",
      "insidersPct"
    ]
  },
  "ath": {
    "priceUsd": 0.001,
    "at": "2026-09-17T10:00:00.000Z",
    "ageSeconds": 7200,
    "marketCapUsd": 1000000,
    "changeFromAthPct": -40,
    "drawdownPct": 40,
    "supplyBasis": "current_supply"
  },
  "atl": {
    "priceUsd": null,
    "at": null
  },
  "dip": {
    "thresholdPct": 30,
    "thresholdPriceUsd": 0.0007,
    "firstDipAgeSeconds": 3600,
    "athToFirstDipSeconds": 3600,
    "secondsSinceLastObservedDip": 3600,
    "requestedLookbackHours": 48,
    "candleCount": 24,
    "lastCandleAgeSeconds": 0,
    "windowLowUsd": 0.0005,
    "windowHighUsd": 0.001,
    "reboundFromWindowLowPct": 20,
    "isCurrentlyBelowThreshold": true,
    "firstDipAt": "2026-09-17T11:00:00.000Z",
    "lastObservedDipAt": "2026-09-17T11:00:00.000Z",
    "windowStart": "2026-09-17T10:00:00.000Z",
    "windowEnd": "2026-09-17T12:00:00.000Z",
    "historyStatus": "covers_ath",
    "hasGaps": false,
    "interval": "5m"
  },
  "launch": {
    "firstTradeAt": "2026-09-15T12:00:00.000Z",
    "sampleWindowSeconds": 1,
    "priceUsd": 0.00001,
    "marketCapUsd": 10000,
    "sampledTrades": 100,
    "supplyBasis": "current_supply",
    "mayBeTruncated": true
  },
  "deployer": {
    "status": "partial",
    "address": "0x2222222222222222222222222222222222222222",
    "launches": 3,
    "migrations": 1,
    "rugs": null,
    "reason": "Rug classification is unavailable."
  },
  "socials": {
    "website": null,
    "twitter": null,
    "telegram": null,
    "discord": null,
    "description": null
  },
  "agents": {
    "status": "available",
    "scope": "all_orus_agents",
    "coverage": "retained_history",
    "asOf": "2026-09-17T12:00:00.000Z",
    "windowHours": 24,
    "real": {
      "tradedAgents": 8,
      "holdingAgents": 3,
      "entries24h": 5,
      "exits24h": 2,
      "lastEntryAt": "2026-09-17T11:50:00.000Z",
      "lastExitAt": "2026-09-17T11:40:00.000Z"
    },
    "simulation": {
      "tradedAgents": 12,
      "holdingAgents": 4,
      "entries24h": 7,
      "exits24h": 3,
      "lastEntryAt": "2026-09-17T11:55:00.000Z",
      "lastExitAt": "2026-09-17T11:45:00.000Z"
    }
  },
  "availability": {
    "details": {
      "status": "available"
    },
    "chart": {
      "status": "available"
    },
    "launch": {
      "status": "available"
    },
    "agents": {
      "status": "available"
    },
    "security": {
      "status": "available",
      "missingFields": [],
      "conflictingFields": []
    }
  },
  "warnings": [
    "rug_classification_unavailable",
    "price_timestamp_unavailable"
  ],
  "attribution": {
    "text": "checked by orus",
    "url": "https://www.orusagent.xyz/token/4663/0x1111111111111111111111111111111111111111"
  },
  "card": {
    "text": "orus: no honeypot reported · tax 0/0 · bundled 4% · deployer 3 launches, rugs unknown · checked by orus ↗",
    "url": "https://www.orusagent.xyz/token/4663/0x1111111111111111111111111111111111111111"
  }
}

USD

Prices, liquidity and market caps

Seconds

Durations; timestamps are UTC ISO 8601

Percentage points

Tax 1 means 1%; ATH change may be negative

null means unknown or unavailable. It never means zero, false or safe. dip and launch are null when not requested; their availability is not_requested. Requested but missing indicators can contain null fields.

Security coverage, taxes & v4 pools

Security is always requested, including include=none. Orus combines token observations with a dedicated security check when available. Inspect availability.security.status: available means all five security fields are known, partial means some are known, and unavailable means none are known. None of these statuses is a safety verdict. missingFields names exactly which security values are null. security_data_incomplete means that list is nonempty, even if honeypot and taxes are known but liquidity burn is not.

Coverage varies by token; Uniswap v4 does not by itself imply missing data or a safe contract. null means no usable observation, a timeout, or conflicting observations. conflictingFields names disagreements; those fields remain null and raise security_data_conflict. A missing check does not fail the entire scan. Display the known fields and preserve unknown values; never turn null into false or 0.

buyTaxPct and sellTaxPct describe reported token taxes, not the total cost of a trade. They exclude pool fees, v4 hook fees, price impact, slippage and gas. A reported 0/0 therefore does not mean a free swap. isHoneypot=false means no honeypot was reported by the available checks, not that every wallet, route or future trade can sell. This endpoint does not simulate a specific trade, and checkedAt is collection time rather than the underlying audit time.

Response field reference

Every response field, grouped by subject, with its JSON type and meaning.

Top-level keys are present on success. Child fields apply when their parent object is available. A nullable type permits null; new fields may be added within v1. The eight market.windows keys are 1m, 5m, 15m, 1h, 4h, 6h, 12h, 24h. Each has the same fields shown as {window} below.

envelopeobjectVersion, chain, collection time and request ID.4 fields
envelope response fields
Field / typeDescription
apiVersionstringResponse contract version (1.0).
requestIdstringRequest correlation ID; include this when contacting support.
chainIdintegerRobinhood Chain mainnet: 4663. Testnet 46630 is unsupported.
checkedAtstringCollection start; not the quote timestamp.
cacheobjectCache hit and observation age.3 fields
cache response fields
Field / typeDescription
cache.hitbooleanTrue when this scan was served from the shared cache.
cache.ageSecondsintegerElapsed seconds since checkedAt.
cache.maxAgeSecondsintegerMaximum cache lifetime: 30 seconds.
tokenobjectIdentity, supply and creation time.9 fields
token response fields
Field / typeDescription
token.addressstringRequested contract, normalized to lowercase.
token.namestring | nullToken name.
token.symbolstring | nullToken ticker.
token.imagestring | nullPublic image URL, or null when the image cannot be published.
token.createdAtstring | nullReported token creation timestamp.
token.decimalsnumber | nullToken decimal precision.
token.ageSecondsnumber | nullSeconds since token creation.
token.totalSupplynumber | nullTotal supply in token units.
token.circulatingSupplynumber | nullCirculating supply in token units.
marketobjectUSD price, capitalization, liquidity and rolling activity windows.27 fields
market response fields
Field / typeDescription
market.priceUsdnumber | nullCurrent reported token price in USD.
market.marketCapUsdnumber | nullReported circulating market capitalization in USD.
market.fdvUsdnumber | nullFully diluted valuation in USD.
market.liquidityUsdnumber | nullCurrent reported liquidity in USD.
market.maxLiquidityUsdnumber | nullMaximum reported liquidity in USD.
market.liquidityToMarketCapPctnumber | nullLiquidity / market cap × 100. May exceed 100.
market.volumeChange5mPctnumber | nullCurrent 5m volume versus the average of the preceding two 5m periods, derived from 15m volume.
market.totalFeesUsdnumber | nullCumulative reported pool fees in USD.
market.secondsSinceLastTradenumber | nullSeconds since latestTradeAt.
market.latestTradeAtstring | nullTimestamp of the latest reported trade, separate from quote freshness.
market.priceUpdatedAtnullExact quote timestamp is unavailable; latestTradeAt is separate.
market.windows.{window}.volumeUsdnumber | nullTotal USD volume in this rolling window.
market.windows.{window}.buyVolumeUsdnumber | nullBuy-side USD volume.
market.windows.{window}.sellVolumeUsdnumber | nullSell-side USD volume.
market.windows.{window}.organicVolumeUsdnumber | nullUSD volume classified as organic.
market.windows.{window}.organicBuyVolumeUsdnumber | nullOrganic buy-side USD volume.
market.windows.{window}.organicSellVolumeUsdnumber | nullOrganic sell-side USD volume.
market.windows.{window}.buysnumber | nullNumber of buys.
market.windows.{window}.sellsnumber | nullNumber of sells.
market.windows.{window}.tradesnumber | nullNumber of trades.
market.windows.{window}.buyersnumber | nullDistinct buyers in the window.
market.windows.{window}.sellersnumber | nullDistinct sellers in the window.
market.windows.{window}.tradersnumber | nullDistinct traders in the window.
market.windows.{window}.organicTradesnumber | nullTrades classified as organic.
market.windows.{window}.organicTradersnumber | nullTraders classified as organic.
market.windows.{window}.feesUsdnumber | nullFees in USD for this window.
market.windows.{window}.priceChangePctnumber | nullSigned price change, in percentage points.
poolobjectVenue, launchpad and bonding state.10 fields
pool response fields
Field / typeDescription
pool.addressstring | nullDominant pool address.
pool.dexstring | nullVenue display name.
pool.dexKeystring | nullVenue identifier.
pool.launchpadstring | nullOriginating launchpad.
pool.factorystring | nullPool factory address.
pool.bondedboolean | nullWhether the token has graduated from its bonding curve.
pool.bondingPctnumber | nullBonding-curve progress in percent.
pool.bondedAtstring | nullReported graduation timestamp.
pool.bondingCurveAddressstring | nullBonding-curve contract address.
pool.launchpadUrlstring | nullLaunchpad token page URL.
securityobjectHoneypot, proxy, taxes and liquidity burn observations.5 fields
security response fields
Field / typeDescription
security.isHoneypotboolean | nullReported honeypot flag; null is unknown. false is not a safety guarantee or an execution simulation.
security.isProxyboolean | nullReported proxy-contract flag; null is unknown.
security.buyTaxPctnumber | nullReported token buy tax in percent: 1 means 1%. Excludes pool fees, hook fees, slippage and gas. null is unknown.
security.sellTaxPctnumber | nullReported token sell tax in percent: 1 means 1%. Excludes pool fees, hook fees, slippage and gas. null is unknown.
security.liquidityBurnPctnumber | nullReported liquidity burn percentage; null is unknown. Independent of honeypot and tax coverage.
riskobjectHolder concentration and wallet classifications.16 fields
risk response fields
Field / typeDescription
risk.bundlersPctnumber | nullSupply held by wallets classified as bundlers.
risk.snipersPctnumber | nullSupply held by wallets classified as launch snipers.
risk.insidersPctnumber | nullSupply held by wallets classified as insiders.
risk.devHoldingsPctnumber | nullSupply held by the developer.
risk.top10Pctnumber | nullSupply held by the top 10 holders.
risk.top50Pctnumber | nullSupply held by the top 50 holders.
risk.top100Pctnumber | nullSupply held by the top 100 holders.
risk.top200Pctnumber | nullSupply held by the top 200 holders.
risk.freshTradersPctnumber | nullSupply held by wallets classified as fresh traders.
risk.proTradersPctnumber | nullSupply held by wallets classified as pro traders.
risk.smartTradersPctnumber | nullSupply held by wallets classified as smart traders.
risk.holdersCountnumber | nullReported number of holders.
risk.bundlersCountnumber | nullReported number of bundler wallets.
risk.snipersCountnumber | nullReported number of sniper wallets.
risk.insidersCountnumber | nullReported number of insider wallets.
risk.laggedFieldsstring[]Risk field names whose classifications can change after launch.
athobjectAll-time high, drawdown and elapsed time.7 fields
ath response fields
Field / typeDescription
ath.priceUsdnumber | nullReported all-time high price in USD.
ath.ageSecondsnumber | nullSeconds elapsed since the ATH.
ath.marketCapUsdnumber | nullATH price × current circulating supply (total supply fallback). Approximation.
ath.changeFromAthPctnumber | null(current price / ATH − 1) × 100. Negative below the ATH.
ath.drawdownPctnumber | nullDecline from the ATH in percent, clamped at zero.
ath.atstring | nullTimestamp of the reported ATH.
ath.supplyBasisstringcurrent_supply: the market-cap approximation uses current supply.
atlobjectAll-time low price and date.2 fields
atl response fields
Field / typeDescription
atl.priceUsdnumber | nullReported all-time low price in USD.
atl.atstring | nullTimestamp of the reported ATL.
dipobject | nullCandle-based dip timing; null when chart was not requested.19 fields
dip response fields
Field / typeDescription
dip.thresholdPctnumber | nullRequested drawdown threshold; defaults to 30%.
dip.thresholdPriceUsdnumber | nullATH × (1 − thresholdPct / 100).
dip.firstDipAgeSecondsnumber | nullSeconds elapsed since firstDipAt.
dip.athToFirstDipSecondsnumber | nullSeconds between the ATH and firstDipAt.
dip.secondsSinceLastObservedDipnumber | nullSeconds elapsed since lastObservedDipAt.
dip.requestedLookbackHoursnumber | nullRequested candle history window in hours.
dip.candleCountnumber | nullClosed, valid five-minute candles in the window.
dip.lastCandleAgeSecondsnumber | nullSeconds since the latest closed candle ended.
dip.windowLowUsdnumber | nullLowest candle low in the returned window.
dip.windowHighUsdnumber | nullHighest candle high in the returned window.
dip.reboundFromWindowLowPctnumber | null(current price / window low − 1) × 100.
dip.isCurrentlyBelowThresholdboolean | nullWhether the current reported price is at or below the threshold.
dip.firstDipAtstring | nullFirst qualifying closed-candle crossing since the ATH; null without complete history.
dip.lastObservedDipAtstring | nullLatest observed crossing from above to below the threshold, not a local low.
dip.windowStartstring | nullFirst retained candle open timestamp.
dip.windowEndstring | nullLast retained candle close timestamp.
dip.historyStatusstringcovers_ath, partial or unavailable. Only covers_ath supports a first-dip claim.
dip.hasGapsbooleanWhether the observed post-ATH candles contain missing intervals.
dip.intervalstringFixed five-minute candles (5m).
launchobject | nullEarliest-trade sample; null when launch was not requested.7 fields
launch response fields
Field / typeDescription
launch.firstTradeAtstring | nullEarliest returned trade timestamp.
launch.sampleWindowSecondsnumber | nullLaunch sampling interval: one second from the first trade.
launch.priceUsdnumber | nullPrice of the last sampled trade within that first second.
launch.marketCapUsdnumber | nullLaunch sample price × current total supply (circulating supply fallback).
launch.sampledTradesnumber | nullNumber of earliest valid trades inspected, up to 100.
launch.supplyBasisstringcurrent_supply: historical market cap is an approximation.
launch.mayBeTruncatedbooleanTrue when the sample reaches 100 trades; other trades may be missing.
deployerobjectReported launches and migrations; rug count remains unknown.6 fields
deployer response fields
Field / typeDescription
deployer.statusstringpartial when an address is known, otherwise unavailable.
deployer.addressstring | nullReported deployer address.
deployer.launchesnumber | nullReported token launches by this deployer.
deployer.migrationsnumber | nullReported migrations by this deployer.
deployer.rugsnullAlways null: rug classification is unavailable. Never display 0 rugs.
deployer.reasonstringExplanation of deployer coverage.
socialsobjectReported metadata and external links.5 fields
socials response fields
Field / typeDescription
socials.websitestring | nullReported website URL.
socials.twitterstring | nullReported X/Twitter URL.
socials.telegramstring | nullReported Telegram URL.
socials.discordstring | nullReported Discord URL.
socials.descriptionstring | nullReported token description. Treat metadata and links as untrusted.
agentsobjectAggregate real and simulated agent activity.17 fields
agents response fields
Field / typeDescription
agents.statusstringavailable or unavailable. Unavailable means null counts, not zero.
agents.scopestringDesk and customer agents on the requested chain, regardless of current agent status or mode. Aggregates only.
agents.coveragestringCurrent retained positions, not guaranteed lifetime history. Real entries require a non-empty recorded entry_tx; entry_pending is excluded. Mode is determined by position status, not current agent settings.
agents.asOfstring | nullObservation timestamp for agent activity; null if unavailable. Cached with the scan for at most 30 seconds from checkedAt.
agents.windowHoursintegerFixed 24-hour activity window; independent of lookbackHours.
agents.real.tradedAgentsinteger | nullDistinct agents with eligible entries in retained history, including agents currently holding. Not a count of trades or independent strategies.
agents.real.holdingAgentsinteger | nullDistinct agents with open positions in the recorded book. Real includes sell_failed, including paused/stopped agents. No on-chain balance verification.
agents.real.entries24hinteger | nullEligible position entries in [asOf - 24h, asOf]. Counts positions, not distinct agents; uses recorded entry_at.
agents.real.exits24hinteger | nullPosition closures in [asOf - 24h, asOf], using exit_at and closed status. Includes simulated write-offs; not proof of a successful on-chain sale.
agents.real.lastEntryAtstring | nullLatest eligible recorded entry_at in retained history, or null if none.
agents.real.lastExitAtstring | nullLatest recorded exit_at of a closed eligible position, or null if none. Failed exits are excluded.
agents.simulation.tradedAgentsinteger | nullDistinct agents with eligible entries in retained history, including agents currently holding. Not a count of trades or independent strategies.
agents.simulation.holdingAgentsinteger | nullDistinct agents with open positions in the recorded book. Real includes sell_failed, including paused/stopped agents. No on-chain balance verification.
agents.simulation.entries24hinteger | nullEligible position entries in [asOf - 24h, asOf]. Counts positions, not distinct agents; uses recorded entry_at.
agents.simulation.exits24hinteger | nullPosition closures in [asOf - 24h, asOf], using exit_at and closed status. Includes simulated write-offs; not proof of a successful on-chain sale.
agents.simulation.lastEntryAtstring | nullLatest eligible recorded entry_at in retained history, or null if none.
agents.simulation.lastExitAtstring | nullLatest recorded exit_at of a closed eligible position, or null if none. Failed exits are excluded.
availabilityobjectAvailability of each requested data section.7 fields
availability response fields
Field / typeDescription
availability.details.statusstringCore token details availability. available on a successful scan.
availability.chart.statusstringavailable, unavailable or not_requested for the chart analysis.
availability.launch.statusstringavailable, unavailable or not_requested for the launch sample.
availability.agents.statusstringavailable or unavailable for agent activity; always requested.
availability.security.statusstringCoverage of the five security fields: available = all known, partial = some known, unavailable = none known. Not a safety verdict. Always requested, including include=none.
availability.security.missingFieldsstring[]Names of security fields that are null. security_data_incomplete is emitted when this list is nonempty.
availability.security.conflictingFieldsstring[]Fields with conflicting observations, returned as null and also listed in missingFields. Raises security_data_conflict. Empty when no conflict was observed.
warningsstring[]Coverage and freshness caveats.1 field
warnings response fields
Field / typeDescription
warningsstring[]Machine-readable caveats. May be nonempty on HTTP 200; clients should tolerate new codes.
attributionobjectOrus label and public token link.2 fields
attribution response fields
Field / typeDescription
attribution.textstringAttribution label: checked by orus.
attribution.urlstringPublic Orus token intelligence URL, without a partner key.
cardobjectTelegram-ready summary and attribution link.2 fields
card response fields
Field / typeDescription
card.textstringReady-to-display plain-text summary, preserving unknown values.
card.urlstringPublic token deep link for the card's attribution arrow.

Reading ATH, dips and launch values

A dip is a closed five-minute candle at or after the reported ATH whose close is at or below ATH × (1 − dipThresholdPct / 100). Wicks and the unfinished candle do not qualify. firstDipAt is populated only when the history covers the ATH without gaps. athToFirstDipSeconds measures the ATH-to-first-crossing duration; firstDipAgeSeconds measures time elapsed since that crossing.

lastObservedDipAt is the latest observed transition from above to below that same threshold. It is not the most recent local low. secondsSinceLastObservedDip measures its age. A later recovery does not erase the observation. A truncated window or a gap may hide other crossings: inspect historyStatus, hasGaps, windowStart, windowEnd and lastCandleAgeSeconds. Times label candle opens, with five-minute resolution. A missing crossing is null, not proof that no dip occurred.

launch samples the last trade in the first second after the earliest returned trade, using at most 100 earliest trades. mayBeTruncated identifies samples reaching the cap. Its price and implied market cap follow the strategy engine's launch metric. No individual customer positions, strategy thresholds, wallets or private reports are included.

Rug classification is unavailable: deployer.rugs is always null. Wallet classifications can change after launch; risk.laggedFields lists affected fields.

Agent activity

Measure recorded agent activity alongside the market scan.

agents.real and agents.simulation each contain the following fields. Both include house and customer agents on the requested chain, including paused or stopped agents. Mode follows the recorded position, not the agent’s current settings.

Agent activity counters
FieldMeaning
tradedAgentsDistinct agents with eligible entries in retained history, including agents currently holding. Not a count of trades or independent strategies.
holdingAgentsDistinct agents with open positions in the recorded book. Real includes sell_failed, including paused/stopped agents. No on-chain balance verification.
entries24hEligible position entries in [asOf - 24h, asOf]. Counts positions, not distinct agents; uses recorded entry_at.
exits24hPosition closures in [asOf - 24h, asOf], using exit_at and closed status. Includes simulated write-offs; not proof of a successful on-chain sale.
lastEntryAtLatest eligible recorded entry_at in retained history, or null if none.
lastExitAtLatest recorded exit_at of a closed eligible position, or null if none. Failed exits are excluded.

holdingAgents is a subset of tradedAgents; do not add them. Entries and exits count position records, not distinct agents. Real entries require a recorded entry transaction hash; pending entries are excluded. Failed sells still count as holdings.

coverage=retained_history is the history still in the position book. It is not a guaranteed lifetime history or a fresh wallet-balance check. Closed simulations may include write-offs. The 24-hour window is anchored to agents.asOf and does not change with lookbackHours.

When agents.status=available, zero means no eligible records. When unavailable, counts and dates are null. No customer identifiers, wallets, amounts or strategy settings are exposed. Refusal counts and acceptance rates are unavailable because the existing logs do not cover every evaluation.

Errors, limits & freshness

Handle status codes explicitly and preserve observation timestamps.

API error responses
HTTPError codeAction
400invalid_request / invalid_token / unsupported_chainFix the query. Unknown or repeated parameters are rejected.
401unauthorizedMissing, invalid, expired or revoked key, or inactive partner. Stop and contact Orus.
404token_not_foundToken is not indexed. This does not prove the contract is invalid.
429rate_limitedPartner quota exceeded. Wait the number of seconds in Retry-After.
503scan_unavailable / market_data_unavailable / unverified_token_dataTemporarily unavailable. Honor Retry-After; retry at most twice with jitter.
405Method not allowedUse GET. This framework response does not use the JSON error envelope.

GET errors use { error: { code, message }, requestId }. On 401, stop retrying and contact Orus. HEAD uses the same authentication and quota as GET; OPTIONS is handled automatically.

Headers & quotas

Request and response headers
HeaderWhereMeaning
AuthorizationRequestBearer <partner key>. Required; send from your backend over HTTPS.
X-Request-IdResponseCorrelation ID on every GET response.
X-RateLimit-LimitResponsePartner minute quota, after admission.
X-RateLimit-RemainingResponseRemaining admitted requests this minute.
X-RateLimit-Day-RemainingResponseRemaining admitted requests this UTC day.
Retry-After429 / 503Seconds to wait before retrying.
Cache-ControlResponseprivate, no-store. Orus maintains the shared scan cache internally.

Default allowance: 30 admitted requests per minute · 5,000 per UTC day. Limits are configured per partner and shared across keys. Cache hits, validation failures and upstream failures consume admitted requests.

A successful scan is cached for at most 30 seconds from checkedAt. agents.asOf retains its original timestamp on cache hits. market.priceUpdatedAt is null because the exact quote timestamp is unavailable; latestTradeAt is a separate trade timestamp.

Security, chart, launch or agent-data failures can return HTTP 200 with explicit coverage and warnings. Missing core details fail the scan. Public token pages refresh observations for tokens already scanned or traded by Orus, show their age, and request updates every 30 seconds while visible.

Telegram & AI integration

Use the card fields directly and keep unknown values visible.

Illustrative Telegram line

orus: no honeypot reported · tax 0/0 · bundled 4% · deployer 3 launches, rugs unknown · checked by orus ↗

Place card.text above your buy/sell controls and link “checked by orus ↗” to card.url. Send plain text or escape dynamic content for your Telegram parse mode. Preserve unknown values and the observation time.

When retained public desk reports exist, the token page lists dated snapshots with their UTC collection time. Open a report to see its saved market figures, chart and available analysis. Historical data is not refreshed when opened; private customer reports and strategy context are excluded.

You can add Agents (real): 8 traded · 3 holding · 5 entries / 24h from the corresponding agents.real fields when activity is available. Label simulation separately. If the scan fails, omit the badge or show “orus: scan unavailable”.

Need help?

This page is the reference. For everything it does not cover — why your agent refused a token, which threshold to move first, or anything that looks wrong — ask in the Discord. The team is in there, and so are the people running the same strategies.

Ask on Discord →
Watch it run.

Every decision on the desk is published, refusals included — and your own agents are a sign-in away.