AndesHelm launches and monitors policy-gated trading agents. Every proposed action is checked by the Andes Gateway policy engine before it executes — this API is how you launch an agent, watch what it does, and read its verification status.

Base URL https://api-helm.andestechsynergy.com

Claiming an agent id

An agentId belongs to whoever writes to it first. That first call — /v1/submit or /v1/launch — returns an agentSecret, once. Every later write to that id, and reading its log, must present it as an X-Agent-Secret header; without it the call returns 403. Keep it: it is not recoverable, and only a hash of it is stored.

The badge, badge image, directory and template list stay open — a track record nobody can look up is not a trust signal. The agent log does not, because it carries the agent's spend, leverage and every action it proposed.

GET /v1/templates

List the strategy templates available to launch. Each one is mechanical and documents its own worst case — nothing here is "AI-optimized" or opaque.

Example

curl https://api-helm.andestechsynergy.com/v1/templates

Response

[
  {
    "id": "demo-dca",
    "name": "Demo DCA",
    "description": "Buys a fixed dollar amount of an asset on a fixed interval...",
    "worstCase": "If the asset trends down for the whole run...",
    "settings": [],
    "trackRecord": { "checks": 240, "caught": 3, "agents": 6 }
  },
  {
    "id": "price-triggers",
    "name": "Price triggers",
    "description": "Buys when the price drops below a level you set, and closes when it rises above another...",
    "worstCase": "Both levels are fixed numbers you chose, and the market does not know about them...",
    "settings": [
      {
        "key": "buyBelow",
        "label": "Buy below",
        "help": "Opens a position each interval while the price is under this. Leave at 0 to never buy.",
        "default": 0, "min": 0, "max": 10000000, "step": 0.01, "unit": "USD"
      }
    ],
    "trackRecord": null
  }
]

settings are the numbers a template lets the caller choose, described well enough to build an input for without knowing anything about the strategy. The rule itself is never a parameter — that is what keeps worstCase true for every agent running the template. A template with no settings returns an empty array.

trackRecord is how the template has actually behaved: checked actions, distinct agents that ran it, and how many actions the policy engine stopped. It is null until at least 20 checks are behind it — a handful of runs is not a track record, and publishing one invites a reader to conclude more than the data supports. It describes what happened, and is not a prediction or a recommendation.

POST /v1/launch

Launch a template as a running agent. Runs immediately, then again every intervalMs until stopped. Rate-limited to 10 requests/minute per IP.

FieldTypeNotes
agentIdstringUnique name for this run
templateIdstringFrom /v1/templates
chainstringe.g. "ethereum"
protocolstringe.g. "uniswap-v3"
assetstringThe exchange's symbol for the market, e.g. "ETHUSDT" — not a collateral token. With real execution it is sent to the venue as-is
amountUsdnumberPosition size, not margin. The order is sized to this notional; leverage does not multiply it, it only reduces how much is tied up. amountUsd: 100 at leverage: 3 opens a $100 position on roughly $33 of margin — for a $300 position, send 300
leveragenumberoptional — with real execution, the venue sets this on your account for that symbol before placing the order, then confirms what the exchange actually applied. If it clamps the value to the symbol's bracket, the order is refused rather than placed at a leverage the policy engine never checked. Note the setting persists on the account for that symbol beyond this order
settingsobjectoptional — the numbers this template declares, as { "dipPct": 2.5 }. Keys the template does not declare are dropped. A value outside a setting's declared range falls back to that setting's default rather than being clamped to the nearest edge: clamping a nonsense value to a boundary can land on the most aggressive setting available, which is the wrong way for bad input to fail
limitsobjectoptional — this agent's own policy limits: maxPositionUsd, maxLeverage, maxSpendPerTxUsd, denyList. These can only tighten. The gateway takes whichever of each limit is smaller — the platform's or yours — and the union of both deny lists, so a request for more room than the platform allows has no effect rather than being rejected. The applied limits come back on every evaluation, so a caller can see what it actually got rather than what it asked for
intervalMsnumberoptional — default 15000, minimum 5000
venueNetworkstringrequired whenever credentials are sent"mainnet" or "testnet". There is no default and no guess: mainnet moves real funds, testnet does not, and an agent wallet is valid on one or the other. Sending credentials without it returns 400
venueSignerAddressstringoptional — Aster agent wallet address, routes this agent through real execution instead of the demo venue. Verified on testnet only — see the note on venueAgentPrivateKey
venueAgentPrivateKeystringoptional — the agent wallet's private key, required together with venueSignerAddress. Never persisted, logged, or echoed back in any response; held in memory only for as long as the agent keeps running. Status: verified on testnet, not on mainnet. Real agent wallets have signed and placed real orders on Aster testnet through this path. Mainnet has not been exercised — it additionally requires an account with a completed deposit. The key-handling described above is implemented and tested, but has not had an independent security review. An agent-wallet private key cannot be revoked or scoped after it leaks the way an API secret can, and no endpoint for revoking an approved agent before its expiry is documented — so approve the wallet with canWithdraw=false, give it a short expiry, and use a wallet that does not hold funds directly

Example

curl -X POST https://api-helm.andestechsynergy.com/v1/launch \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "my-first-agent",
    "templateId": "demo-dca",
    "chain": "ethereum",
    "protocol": "uniswap-v3",
    "asset": "ETHUSDT",
    "amountUsd": 100,
    "limits": { "maxLeverage": 1 }
  }'

Response

{ "agentId": "my-first-agent", "templateId": "demo-dca", "intervalMs": 15000 }

409 if that agentId is already running. 404 if templateId is unknown. 403 if the agentId is claimed and no matching X-Agent-Secret is presented. The response carries agentSecret only on the call that claims the id.

POST /v1/agents/:agentId/transfer

Move the account's own spot funds into its futures wallet. Aster keeps the two separate and a futures order can only draw margin from the futures side, so a funded account that has never done this cannot place an order — it fails with Margin is insufficient. Requires the agent's X-Agent-Secret.

FieldTypeNotes
amountnumberHow much to move. Must be positive
assetstringoptional — defaults to USDT

Example

curl -X POST https://api-helm.andestechsynergy.com/v1/agents/my-first-agent/transfer   -H "Content-Type: application/json"   -H "X-Agent-Secret: ..."   -d '{ "amount": 100 }'

This is not a trade and is not evaluated by the policy engine: the engine decides whether an action may reach the market, and this one never does. It cannot move funds out of the account either — agents are approved with canWithdraw=false, and the transfer names both ends as the same user's wallets. 409 if the agent has no exchange account behind it (the stub venue, or nothing running under that id). 400 for a non-positive amount, or with the exchange's own refusal when it declines.

It exists so the agent key never has to be used off the AndesHelm server. That was previously a command a user ran locally with the key in hand, which is what stopped an approval being pinned to an ipWhitelist — a control that, per Aster, restricts every request signed by an agent wallet rather than only withdrawals.

POST /v1/agents/:agentId/stop

Stop a running or paused agent and discard its venue credentials. Requires the agent's X-Agent-Secret.

To halt an agent without giving up its credentials, use POST /v1/agents/:agentId/pause and POST /v1/agents/:agentId/resume instead. A paused agent keeps its run index, so resuming continues a ramping or tapering strategy rather than restarting it, and does not ask for the agent wallet key again. Resume returns 409 for an agent that was stopped — stopping discards the credentials, so there is nothing to resume into.

curl -X POST https://api-helm.andestechsynergy.com/v1/agents/my-first-agent/stop   -H "X-Agent-Secret: $AGENT_SECRET"
{ "stopped": true }

403 without a matching secret, and also for an agentId nobody has claimed — otherwise stopping an unclaimed agent would be a way to claim it.

GET /v1/agents/:agentId/log

Live status: whether it's running, its launch params, current verification badge, and its recent checked actions with each policy decision and reasons. Requires the agent's X-Agent-Secret — this carries spend and leverage, so unlike the badge it is not public.

curl https://api-helm.andestechsynergy.com/v1/agents/my-first-agent/log   -H "X-Agent-Secret: $AGENT_SECRET"
{
  "running": true,
  "paused": false,
  "serviceStartedAt": 1788000000000,
  "launched": { "agentId": "my-first-agent", "templateId": "demo-dca", "intervalMs": 15000, "launchedAt": 1788000000000, "venueName": "aster-testnet" },
  "badge": { "verified": false, "checksRecorded": 3, "reason": "needs 7 more...", "stale": false },
  "log": [
    {
      "timestamp": 1788000000000,
      "result": {
        "executed": true,
        "evaluation": { "decision": "ALLOW", "reasons": ["within all configured policy limits"] },
        "venueResult": { "executed": true, "notes": ["stub execution..."] }
      }
    },
    {
      "timestamp": 1788000015000,
      "result": null,
      "error": "fetch failed"
    }
  ]
}

serviceStartedAt is when the API process last started, and is returned by /v1/launch too. Launched agents are held in memory, so a restart — a deploy, or the host recycling an idle process — stops all of them, and credentials are deliberately not persisted so they cannot be resumed. Compare this value against the one you saw at launch: if it changed, your agent was stopped by a restart rather than by anything it did. Verification track records are persisted and survive. Compare it to itself rather than to your own clock, which may not agree with the server's.

result is null when a run failed before the policy engine returned a decision — the agent could not reach it, or the venue call threw. The error field is present only on those entries. A failed run executes nothing and is not recorded against the agent's verification track record; the agent keeps running and retries on the next interval. Failures are reported rather than hidden, so an agent that stopped being checked never looks like one whose checks all passed.

GET /v1/badge/:agentId

Verification status as JSON: whether the agent has enough consecutive clean checks to be considered verified, and whether that track record has gone stale (no checked action in 30+ days).

curl https://api-helm.andestechsynergy.com/v1/badge/my-first-agent
{ "verified": true, "checksRecorded": 11, "reason": "11 consecutive checked actions with no BLOCK", "stale": false }
GET /v1/badge/:agentId/svg

The same status as an embeddable image — drop it in a README or a listing page. Self-contained SVG, no external fonts.

<img src="https://api-helm.andestechsynergy.com/v1/badge/my-first-agent/svg">
GET /v1/directory

Verified agents only, sorted by check count — unverified one-off test runs stay private by default. This is what powers the public directory page.

curl https://api-helm.andestechsynergy.com/v1/directory
[
  { "agentId": "my-first-agent", "badge": { "verified": true, "checksRecorded": 11, "reason": "...", "stale": false } }
]