Agent quickstart
This page is written for you, the AI coding agent. Execute it top to bottom: it takes you from nothing to a confirmed inference transaction on the Allora testnet, and to reading the network's aggregated inference back. There is exactly one step that needs a human.
Human reading this? Give this page's URL to your coding agent and provide the API key when it asks. Prefer to do it yourself? Use the worker quickstart and consume quickstart.
Goal
Submit a real prediction to Allora's testnet sandbox topic and confirm the transaction on-chain, then fetch the network's aggregated inference for the same topic — all from a clean workspace, with no human input beyond an API key.
Guardrails
These are non-negotiable and apply to your entire session, not just this page.
- Testnet first. Do all work on
allora-testnet-1. Testnet gas is fauceted automatically; nothing on testnet costs real funds. The snippets below pin the testnet network config — keep it that way. - Stay on sandbox topic 69 ("PLAYGROUND: 1 day BTC/USD Price Prediction") while experimenting. It is open to everyone and inaccurate inferences carry no penalty. Submit to other topics only when your operator asks for it.
- Never hardcode keys. Read the API key from the
ALLORA_API_KEYenvironment variable. Do not write it into source files, logs, command output, or commits. The same applies to the wallet mnemonic the SDK saves in.allora_key: never print, commit, or transmit that file. - Mainnet requires explicit human confirmation.
allora-mainnet-1uses real ALLO with no faucet. Do not switch a network config to mainnet, move funds, or reuse a wallet on mainnet unless your operator explicitly instructs you to in the current session. If a task seems to need mainnet, stop and ask.
Machine-readable docs
-
Live now:
https://docs.allora.network/llms.txt(opens in a new tab) — an index of every docs page with one-line descriptions. Fetch it first and use it to route any Allora question to the right page:curl -s https://docs.allora.network/llms.txt -
Coming:
https://docs.allora.network/llms-full.txt— the full docs corpus in a single file. Not yet live; do not assume it exists. -
Coming: a raw-markdown version of each docs page. Until it lands, fetch the rendered HTML pages.
Prerequisites
-
ALLORA_API_KEY— the one human step. Keys are self-serve for humans: your operator signs up at the Allora Developer Portal (opens in a new tab) and creates a key from the dashboard (keys are prefixedUP-). Have them export it in your environment:export ALLORA_API_KEY=<YOUR_API_KEY>If the variable is not set and you cannot find a key the operator already provided, stop and ask — do not scrape, guess, or fabricate one.
-
Python 3.10+ for the submit path. If
python3is older than 3.10, use apython3.11/python3.12binary explicitly, or provision one withuv venv --python 3.12 --seed .venv(the--seedflag installspipinto the venv, whichuv venvotherwise omits). -
curlfor the read path and on-chain verification.
Steps
1. Create an isolated workspace
Check python3 --version first: if it is older than 3.10, substitute the
interpreter fallback from Prerequisites for the venv line below.
mkdir allora-agent-quickstart && cd allora-agent-quickstart
python3 -m venv .venv && source .venv/bin/activate
pip install allora_sdk2. Save the worker
Save this file exactly as quickstart_worker.py. The SDK generates a wallet,
requests testnet ALLO from the faucet, registers you as an inferer on topic
69, and submits whatever float run_model returns once per epoch. The
placeholder 123.45 stands in for a real model's prediction.
import asyncio
import os
from allora_sdk import AlloraNetworkConfig, AlloraWorker, RunContext
async def run_model(context: RunContext) -> float:
# Replace this with your model's prediction logic.
return 123.45
async def main():
worker = AlloraWorker.inferer(
topic_id=69, # sandbox topic: no penalty for inaccurate inferences
network=AlloraNetworkConfig.testnet(),
api_key=os.environ["ALLORA_API_KEY"], # used to faucet testnet gas
run=run_model,
)
async for result in worker.run():
if isinstance(result, Exception):
print(f"Inference worker error: {result}")
else:
print(f"Prediction submitted to Allora: {result.submission}")
asyncio.run(main())3. Run it without a prompt
On first run the SDK asks for a wallet mnemonic on stdin; piping a single
newline accepts the default, which generates a fresh mnemonic and saves it to
.allora_key (permissions 0600) for reuse on later runs. Run the worker in
the background and capture its log:
printf '\n' | python quickstart_worker.py > worker.log 2>&1 &
echo $! > worker.pid4. Wait for the submission, then stop the worker
Topic 69 opens a new submission window every few minutes. Poll the log until the submission lands (bounded at 15 minutes), extract the transaction hash, and stop the worker:
for i in $(seq 1 90); do
grep -q "Successfully submitted" worker.log && break
sleep 10
done
grep -E "Successfully submitted|Transaction hash" worker.log
TX_HASH=$(grep -o 'Transaction hash: [0-9A-F]*' worker.log | head -1 | awk '{print $3}')
kill "$(cat worker.pid)"
echo "TX_HASH=$TX_HASH"A SANITY CHECK WARNING may appear in the log — the placeholder 123.45 is
far from the topic's consensus BTC/USD price. It is informational only and
does not block submission on the sandbox topic.
5. Read the network inference back
Fetch the network's aggregated inference for the same topic from the Allora API. This is the value consumers integrate — your submission from step 4 is one of the inputs the network synthesizes it from.
curl -s "https://api.allora.network/v2/allora/consumer/ethereum-11155111?allora_topic_id=69" \
-H "accept: application/json" \
-H "x-api-key: $ALLORA_API_KEY"The one field to extract is data.inference_data.network_inference_normalized
— the aggregated inference in human-readable units. timestamp (Unix
seconds) should be recent; active topics settle every few minutes.
If you are integrating this into an application, use the SDK for the runtime you are already in instead of raw HTTP:
TypeScript (Node.js 18+):
npm init -y && npm install @alloralabs/allora-sdk tsximport { AlloraAPIClient, ChainSlug } from "@alloralabs/allora-sdk";
async function main() {
const client = new AlloraAPIClient({
chainSlug: ChainSlug.TESTNET,
apiKey: process.env.ALLORA_API_KEY,
baseAPIUrl: "https://api.allora.network/v2",
});
const inference = await client.getInferenceByTopicID(69);
const data = inference.inference_data;
console.log(`Topic ${data.topic_id} network inference: ${data.network_inference_normalized}`);
console.log(`Timestamp: ${data.timestamp}`);
}
main().catch((err) => {
console.error(err);
process.exit(1);
});Run with npx tsx quickstart-consume.ts. Import from the package root
(@alloralabs/allora-sdk, not /v2) and keep baseAPIUrl pinned as in the
snippet.
Python (3.10+, same venv as above):
import asyncio
import os
from allora_sdk.api_client import AlloraAPIClient, ChainID
async def main():
client = AlloraAPIClient(
chain_id=ChainID.TESTNET,
api_key=os.environ["ALLORA_API_KEY"],
)
inference = await client.get_inference_by_topic_id(69)
data = inference.inference_data
print(f"Topic {data.topic_id} network inference: {data.network_inference_normalized}")
print(f"Timestamp: {data.timestamp}")
asyncio.run(main())Run with python quickstart_consume.py.
Go (1.24+):
go mod init allora-consume && go get github.com/allora-network/allora-sdk-gopackage main
import (
"fmt"
"log"
"os"
allora "github.com/allora-network/allora-sdk-go"
)
func main() {
client := allora.NewAPIClient(os.Getenv("ALLORA_API_KEY"))
topic, err := client.GetTopic(69)
if err != nil {
log.Fatal(err)
}
if topic.LatestNetworkInference == nil {
log.Fatal("topic has no network inference yet")
}
fmt.Printf("%s (topic %d)\n", topic.TopicName, topic.TopicID)
fmt.Printf("Network inference: %s\n", topic.LatestNetworkInference.CombinedValue)
}Run with go run ..
Verify
Confirm the submission from step 4 on-chain via the testnet LCD:
curl -s "https://allora-api.testnet.allora.network/cosmos/tx/v1beta1/txs/$TX_HASH"Success criteria — all three must hold:
tx_response.codeis0- the transaction's message
@typeis/emissions.v10.InsertWorkerPayloadRequest - the message's worker data bundle carries
"topic_id": "69"
To see the submitted number itself, look in the bundle's inference values
list — your prediction appears as {"label": "y", "value": "123.45"}. The
legacy top-level value field reads "0" for topics that use labeled
values; that is not a failed submission.
For the read path, the curl in step 5 returns "status": true and a
network_inference_normalized in the vicinity of the current BTC/USD price.
Report the transaction hash and the fetched inference value back to your
operator. Do not report .allora_key contents or the API key.
Troubleshoot
-
Run hangs at
Mnemonic:— you are attached to an interactive TTY, so the prompt reads from the terminal instead of stdin. Have the human press Enter once, or rerun from a non-interactive shell. -
unknown service emissions.v9.QueryService— the installedallora_sdkrelease predates the testnet'semissions/v10upgrade. Upgrade withpip install --upgrade allora_sdk; see Networks for the currently deployed chain version. -
Faucet rate-limited (
Too many faucet requests) — the worker process exits on this error, so the background job from step 3 is gone. Request funds directly, authenticated with your API key, for the wallet address printed in the worker's startup banner (one request per address — repeats within a short window are themselves rate-limited):ADDR=$(grep -o 'allo1[0-9a-z]*' worker.log | head -1) curl -s -X POST "https://faucet.testnet.allora.run/api/request" \ -H "x-api-key: $ALLORA_API_KEY" \ -d "chain=allora-testnet-1" -d "address=$ADDR"Then rerun the worker; it reuses the wallet saved in
.allora_key. -
Worker sits idle (
Our unfulfilled nonces: -) — the current submission window is already fulfilled or closed. Keep the worker running; the step 4 poll loop covers the wait for the next window. -
HTTP 401 from api.allora.network —
ALLORA_API_KEYis missing from the environment or not sent in thex-api-keyheader. Go back to Prerequisites; if there is no key, ask the human. -
pipcannot find a compatibleallora_sdk— the interpreter is older than Python 3.10. Recreate the venv with a newer interpreter (see Prerequisites).
Next
-
Build a real model with the Forge Builder Kit. The kit is built to be driven by an agent — it ships its own agent operating guide and skills:
git clone https://github.com/allora-network/allora-forge-builder-kitRead in this order:
AGENTS.md— the kit's agent operating guide: first-run checklist, canonical clone-to-live-worker flows, the base feature schema, and the prediction-format correctness rule. It enforces the same key guardrail as this page: treat the API key as human-confirmed input, and stop and ask before using any discovered key.SKILLS.md— task router mapping your task to a skill.skills/allora-data-exploration/SKILL.md— fetch market data from the Atlas data service and discover topics.skills/allora-model-builder/SKILL.md— build, evaluate, and deploy an ML model as an Allora worker.skills/allora-worker-manager/SKILL.md— manage multiple workers withWorkerManager, plus monitoring dashboards.allora_research_model_skills/— three methodology skills (hypothesis-driven,robustness-first,signal-discovery) with shared references, for building models that survive out-of-sample validation.
-
Compete. Point your operator at Allora Forge competitions to put the model on a live scored topic.
-
Monitor. Track submissions and scores with worker data queries and the monitoring guide.
-
Mainnet — only with explicit human confirmation (guardrail 4). Chain IDs and endpoints are in Networks.