Elgon DOCS ← Back to site
Elgon Documentation

The data layer for Robinhood

Elgon is a market-data API covering stocks, ETFs, options, crypto and prediction markets through one endpoint. Every response ships with a signed, timestamped, tamper-evident receipt — a SHA-256 commitment you can recompute yourself to confirm the payload wasn't altered in transit.

⚡ One API, many markets

Quotes, options chains, prediction contracts and instrument search — stocks, ETFs, options, and BTC/ETH crypto — over clean JSON.

🔏 Tamper-evident

Each response carries a receipt: sha256(data + ts). Recompute it locally or call the verify endpoint. No trust required.

🧪 Public demo key

Try every endpoint right now with the shared key elgon_sandbox_pub — no signup. Quotes & instruments return real (delayed) data; options & predictions are simulated and labeled as such.

🧪
What's real and what's simulated. Quotes and instruments return real market data — delayed, not real-time — tagged "source":"live", even on the public demo key. Options and predictions are currently simulated sample data, always tagged "source":"sandbox" with an explanatory note — don't trade or report on them. See Sandbox vs live.

Quickstart

Send your first request in under a minute using the public sandbox key elgon_sandbox_pub. No account needed.

cURL
curl "https://elgonrpc.xyz/api/v1/quotes?symbol=AAPL&key=elgon_sandbox_pub"

# or with a bearer token
curl "https://elgonrpc.xyz/api/v1/quotes?symbol=AAPL" \
  -H "Authorization: Bearer elgon_sandbox_pub"
JavaScript (fetch)
const res = await fetch(
  "https://elgonrpc.xyz/api/v1/quotes?symbols=AAPL,TSLA",
  { headers: { Authorization: "Bearer elgon_sandbox_pub" } }
);
const { data, source, plan, receipt } = await res.json();

console.log(source);          // "live" — real quotes (delayed, not real-time)
console.log(data[0].price);   // e.g. 333.74
console.log(receipt.hash);    // sha256 integrity commitment

From this site you can also call the API same-origin as /api/v1/quotes?... — the hostname resolves to the same functions.

Get an API key

Mint a free key with one request — no account, no card. The key is returned once; store it immediately.

cURL
curl -X POST "https://elgonrpc.xyz/api/keys"
Response
{
  "key": "elgon_live_9f2c8a1e4d7b0c6a5e31b8d204f6a7c1",
  "plan": "free",
  "limit": "60 requests/min",
  "note": "Store this key now — it is shown only once. Use it as Authorization: Bearer <key> or ?key=<key>."
}

You can also mint and manage keys from the dashboard, or just prototype with the shared public key elgon_sandbox_pub — no signup at all.

Base URL

All endpoints live under a single versioned base URL. Regional routing is handled for you; you always call the same host.

PurposeURL
REST API basehttps://elgonrpc.xyz/api/v1
Receipt verifierhttps://elgonrpc.xyz/api/v1/verify
Health checkhttps://elgonrpc.xyz/api/v1/ping

All endpoints are GET, respond with JSON, send CORS access-control-allow-origin: *, and answer OPTIONS preflight — so they're callable directly from the browser.

Authentication

Every request is authenticated with an API key. Pass it any of three ways — pick whichever suits your client:

Bearer header (preferred)
Authorization: Bearer $ELGON_API_KEY
x-api-key header
x-api-key: $ELGON_API_KEY
Query parameter
?key=$ELGON_API_KEY

Key types

KeyWhat it is
elgon_sandbox_pubPublic demo key. Always valid, free-tier limits. Safe to embed in client-side demos; used by the homepage "try it" widget. Data behavior is the same as any key: quotes/instruments real (delayed, "source":"live"), options/predictions simulated ("source":"sandbox").
elgon_live_<32 hex>Live keys — the literal prefix elgon_live_ followed by 32 hex characters. Minted via POST /api/keys or from your dashboard, scoped to a plan, validated server-side. Keep these secret and server-side.
⚠️
Keep live keys server-side. The elgon_sandbox_pub key is designed to be public; live keys are not. If the key backend is unreachable, live keys fail closed with 503 backend_unavailable — the sandbox key keeps working since it needs no database. A missing or invalid key returns 401 unauthorized.

Sandbox vs live

The seam between real and simulated data runs per endpoint, not per key — the same behavior applies whether you use elgon_sandbox_pub or a live key:

EndpointDatasource tag
Quotes, InstrumentsReal market data. Delayed, not real-time — don't use it as a live trading feed."live"
Options, PredictionsSimulated sample data — deterministic values seeded from the symbol, stable and plausible across calls, but not real market prices."sandbox"

Every simulated payload also carries an explicit note field: "Sandbox data — deterministic sample values seeded from the symbol, not real-time market prices. Do not trade on these."

🧪
Always read the source field before you use a number. When it says "sandbox", the data is illustrative sample data — not a market quote. When it says "live", the data is real but delayed. Elgon never presents simulated numbers as real prices, and never presents delayed quotes as real-time.

Quotes

Quotes for one or more symbols across stocks, ETFs and crypto. This is real market data, but delayed — not real-time. Responses are tagged "source":"live" even on the public demo key.

ParamTypeDescription
symbolstringA single symbol, e.g. AAPL.
symbolsstringComma-separated list, e.g. AAPL,TSLA,SPY. Use instead of symbol for batches. Crypto uses the -USD suffix, e.g. BTC-USD.
Request
GET /api/v1/quotes?symbols=AAPL,BTC-USD&key=elgon_sandbox_pub
Response — live (delayed)
{
  "data": [
    {
      "symbol": "AAPL",
      "name": "Apple Inc.",
      "price": 333.74,
      "change": 0.48,
      "changePct": 0.14,
      "bid": 333.71,
      "ask": 333.77,
      "volume": 63407059,
      "currency": "USD",
      "assetClass": "stock",
      "asOf": "2026-07-19T21:25:16.131Z"
    },
    {
      "symbol": "BTC-USD",
      "name": "Bitcoin USD",
      "price": 64422.08,
      "change": -372.17,
      "changePct": -0.57,
      "bid": 64415.64,
      "ask": 64428.52,
      "volume": 14257716224,
      "currency": "USD",
      "assetClass": "stock",
      "asOf": "2026-07-19T21:25:16.081Z"
    }
  ],
  "source": "live",
  "plan": "free",
  "receipt": {
    "alg": "sha256",
    "hash": "6effc13adb9bba63…6371bc",
    "ts": "2026-07-19T21:25:16.131Z",
    "endpoint": "/api/v1/quotes",
    "verifyUrl": "https://elgonrpc.xyz/api/v1/verify"
  }
}

changePct is rounded to 2 decimals. asOf is when Elgon served the quote — it is not proof of real-time freshness: the underlying price is delayed relative to the exchange feed.

Options

An options chain and available expirations for an underlying symbol. Always simulated: values are deterministic samples seeded from the symbol, tagged "source":"sandbox" with a do-not-trade note. Expirations are the next four monthly cycles.

ParamTypeDescription
symbolstringUnderlying symbol, e.g. AAPL. Required.
Request
GET /api/v1/options?symbol=AAPL&key=elgon_sandbox_pub
Response — always sandbox (simulated)
{
  "symbol": "AAPL",
  "underlying": 227.5,
  "expirations": ["2026-08-21", "2026-09-18", "2026-10-16", "2026-11-20"],
  "chain": [
    { "strike": 220, "type": "call", "bid": 15.67, "ask": 16.63, "iv": 0.67, "oi":  8236, "expiry": "2026-08-21" },
    { "strike": 220, "type": "put",  "bid":  3.38, "ask":  3.58, "iv": 0.49, "oi": 15217, "expiry": "2026-08-21" },
    { "strike": 225, "type": "call", "bid":  7.26, "ask":  7.70, "iv": 0.57, "oi": 19169, "expiry": "2026-08-21" }
  ],
  "source": "sandbox",
  "plan": "free",
  "receipt": {
    "alg": "sha256",
    "hash": "bc07344362ba13aa…acd180b",
    "ts": "2026-07-19T21:25:21.412Z",
    "endpoint": "/api/v1/options",
    "verifyUrl": "https://elgonrpc.xyz/api/v1/verify"
  },
  "note": "Sandbox data — deterministic sample values seeded from the symbol, not real-time market prices. Do not trade on these."
}

Note the simulated underlying price will not match the real delayed price from /quotes — the two endpoints draw from different sources by design.

Predictions

Event contracts with yes/no pricing. Always simulated: a small fixed set of sample contracts, tagged "source":"sandbox" with a do-not-trade note — not a feed from any real prediction market.

ParamTypeDescription
qstringOptional. Filter contracts by keyword, e.g. fed. Omit to list active contracts.
Request
GET /api/v1/predictions?q=fed&key=elgon_sandbox_pub
Response — always sandbox (simulated)
{
  "data": [
    {
      "id": "fed-cut-sep",
      "question": "Fed cuts rates in September?",
      "category": "macro",
      "yesPrice": 0.62,
      "noPrice": 0.38,
      "volume": 1305720,
      "closesAt": "2026-09-17T18:00:00Z"
    }
  ],
  "source": "sandbox",
  "plan": "free",
  "receipt": {
    "alg": "sha256",
    "hash": "6fb36571488bbd33…7bd6e6",
    "ts": "2026-07-19T21:25:22.397Z",
    "endpoint": "/api/v1/predictions",
    "verifyUrl": "https://elgonrpc.xyz/api/v1/verify"
  },
  "note": "Sandbox data — deterministic sample values seeded from the symbol, not real-time market prices. Do not trade on these."
}

Instruments

Search the instrument catalog — resolve a name or partial ticker to real listed symbols across exchanges. This is real reference data, tagged "source":"live".

ParamTypeDescription
qstringSearch query, e.g. apple. Required.
Request
GET /api/v1/instruments?q=apple&key=elgon_sandbox_pub
Response — live
{
  "data": [
    { "symbol": "AAPL",   "name": "Apple Inc.",                     "type": "equity", "exchange": "NASDAQ", "assetClass": "stock" },
    { "symbol": "AAPL.SW","name": "APPLE INC",                      "type": "equity", "exchange": "Swiss",  "assetClass": "stock" },
    { "symbol": "APLE",   "name": "Apple Hospitality REIT, Inc.",   "type": "equity", "exchange": "NYSE",   "assetClass": "stock" }
  ],
  "source": "live",
  "plan": "free",
  "receipt": {
    "alg": "sha256",
    "hash": "560c86c51a9105d1…4df7b",
    "ts": "2026-07-19T21:25:17.092Z",
    "endpoint": "/api/v1/instruments",
    "verifyUrl": "https://elgonrpc.xyz/api/v1/verify"
  }
}

Verify

Recompute a receipt server-side. Pass the receipt's hash and ts plus the canonical JSON of the response data you received; the endpoint recomputes the hash and tells you whether it matches.

ParamTypeDescription
hashstringThe receipt.hash value to check.
tsstringThe receipt.ts value (ISO 8601).
payloadstringURL-encoded canonical JSON of the data field you received.
Request
GET /api/v1/verify?hash=9f2c8a1e…e07b&ts=2026-07-15T15:32:04.112Z&payload=%5B%7B...%7D%5D
Response
{ "valid": true }

This is the same computation described in Verifying a receipt — use it when you'd rather not implement canonicalization yourself.

Ping

A dependency-free health check. Returns 200 with a small JSON body — handy for uptime probes.

Request
GET /api/v1/ping
Response
{ "ok": true, "service": "elgon-api", "runtime": "node", "version": "v24.18.0" }

No API key is required for ping.

Signed receipts

Every data response carries a receipt object. It is a tamper-evident integrity commitment, not a marketing badge: a SHA-256 hash over the exact payload you received plus the timestamp it was served at.

Receipt shape
"receipt": {
  "alg":       "sha256",
  "hash":      "<hex>",                 // sha256( canonicalJSON(data) + "|" + ts )
  "ts":        "2026-07-15T15:32:04.112Z", // when it was served (ISO 8601)
  "endpoint":  "/api/v1/quotes",
  "verifyUrl": "https://elgonrpc.xyz/api/v1/verify"
}

Because the hash binds the data and the time together, anyone can confirm — without contacting Elgon again — that the payload they hold is byte-for-byte what was served at ts. If a proxy, cache or man-in-the-middle alters a single digit, the recomputed hash won't match.

This is an honest integrity check over the served bytes. It proves the payload is intact and consistent with its timestamp; it is not a claim about market accuracy — for that, read the source field.

Verifying a receipt

Two ways to verify — pick one.

1. Call the verify endpoint

Send the hash, ts and the canonical data back to /api/v1/verify and read { "valid": true }.

2. Recompute it locally

Canonicalize the data field (recursively key-sorted JSON), join it to the timestamp with a |, and SHA-256 the result. Compare against receipt.hash.

Node.js
import { createHash } from "node:crypto";

// stable, recursively key-sorted JSON
function canonical(v){
  if (Array.isArray(v)) return "[" + v.map(canonical).join(",") + "]";
  if (v && typeof v === "object")
    return "{" + Object.keys(v).sort()
      .map(k => JSON.stringify(k) + ":" + canonical(v[k])).join(",") + "}";
  return JSON.stringify(v);
}

function verifyReceipt(data, receipt){
  const h = createHash("sha256")
    .update(canonical(data) + "|" + receipt.ts)
    .digest("hex");
  return h === receipt.hash;
}

// usage
const { data, receipt } = await res.json();
console.log(verifyReceipt(data, receipt)); // true → payload intact

If your client can't reproduce the exact canonical form, use the verify endpoint instead — it runs the same computation server-side.

Rate limits & plans

Limits are per-minute. On every successful response Elgon returns x-ratelimit-limit and x-ratelimit-remaining headers. Exceeding the limit returns 429 with { "error": { "code": "rate_limited" } }.

Plan / keyRequests / minNotes
elgon_sandbox_pub60 (soft)Best-effort. The public demo degrades rather than hard-failing.
Free60Default for issued live keys.
Growth600Higher throughput for production apps.
EnterpriseCustomNegotiated limits & priority.

The active plan is echoed back in the plan field on data responses.

Errors

Errors use a consistent shape: { "error": { "code": "...", "message": "..." } } with a matching HTTP status.

StatusCodeMeaning
401unauthorizedMissing or invalid API key.
429rate_limitedPer-minute limit exceeded. Check x-ratelimit-* headers.
503backend_unavailableKey-validation backend unreachable (live keys fail closed). The sandbox key still works.

FAQ

Can I use Elgon from the browser?

Yes. Endpoints send permissive CORS headers and handle preflight, and elgon_sandbox_pub is safe to expose client-side. Keep live keys on your server.

Which data is real and which is simulated?

Quotes and instruments are real — actual market data, tagged "source":"live", but delayed, not real-time. Options and predictions are simulated — deterministic sample data, tagged "source":"sandbox" with an explanatory do-not-trade note. This split applies on every key, including elgon_sandbox_pub.

Are quotes real-time?

No. Quotes are real market data but delayed. Don't build anything that assumes real-time freshness — for execution-grade data you need a real-time feed from a licensed vendor.

What does the receipt actually prove?

That the payload you hold is byte-for-byte what Elgon served at the receipt's timestamp. It's a SHA-256 integrity commitment you can recompute — it detects tampering in transit. It is not a statement about market accuracy; for that, read the source field.

How do I get a live key?

POST https://elgonrpc.xyz/api/keys mints a free key instantly (see Get an API key), or issue one from the dashboard. Live keys look like elgon_live_<32 hex>, carry a plan, and are validated server-side.

Get an API key →