1. Refresh local signal data

pnpm run scrape:open
pnpm run analyze
scrape:open updates public/data/open-channel-messages.json. The v1 API parses that file at request time so parser-rule exports are picked up without a rebuild.

2. Start the API

Prefer a stable local route:
pm2 start "portless charan-signal-api pnpm dev" --name "charan-signal-api-dev"
The primary local server URL is https://charan-signal-api.localhost. The raw Vite port remains an implementation detail.

3. Read latest signal events

const response = await fetch(
  "https://charan-signal-api.localhost/api/v1/signal-events?ticker=AMD&limit=10",
);
const payload = await response.json();
const events = payload.data;

4. Hand trade intents to the router

const response = await fetch(
  "https://charan-signal-api.localhost/api/v1/trade-intents?source=CHARAN&limit=25",
);
const { data: intents } = await response.json();

for (const intent of intents) {
  if (intent.readiness !== "ready_for_sizing") continue;
  await submitToYourPaperRouter(intent);
}
Every intent ships with safeguards.submit: false. Treat the payload as an input to the QuantVPS/Nautilus risk layer, not as authorization to trade.