Where miners on subnet 103 send recipes. Your recipe stays private until the run that pays it opens, so nobody can copy it while it is being measured.
Submitting here is the whole process. There is no on-chain step — no commitment, no transaction, no fee. You need a registered hotkey and a signature, nothing more.
Your recipe is held privately and published 2 runs later, once copying it can no longer help anyone: submitted in run N, measured in N+1, paid in N+2.
| route | |
|---|---|
| POST /submit | Send a recipe. Up to 3 per run. |
| GET /status/{hotkey} | How many attempts you have left this run. |
| GET /run/{id} | A run's submissions. Bodies appear 2 runs on. |
| GET /contract | The same rules, machine-readable. |
| GET /docs | Full API reference. |
Submissions are not written to a public ledger, so this service is the record. Everything needed to check a run is served here, and all of it opens at the same moment — the run that pays it, 2 runs after the one submitted in.
| GET /run/{id} | What was submitted, and by whom. |
| GET /run/{id}/results | Every score, gate verdict and rank. |
| GET /run/{id}/weights | What the run pays, and whether it sums to one. |
| GET /run/{id}/instances/{hotkey} | The per-instance record: what each package was asked, what it answered, what counted. |
A run asked for before it opens answers with released: false and
the run it opens in, rather than an error.
3 submissions per hotkey per run. Only your last one is measured, and only it is stored. Re-sending an identical recipe does not cost an attempt, so retrying a request that timed out is safe.
Sign this exact string with your hotkey, where the digest is
sha256 over the precise bytes you send as recipe:
capcomp-submit:v1:<run_id>:sha256:<hex>
The run is taken from the chain by this service, so read it from
/status/<your hotkey> first. Recipes are capped at
262,144 bytes.
import hashlib, json, requests
from bittensor_wallet import Wallet
API = "https://api.capcomp.ai"
wallet = Wallet(name="miner", hotkey="default")
body = json.dumps(my_recipe) # exactly these bytes are hashed
sha = "sha256:" + hashlib.sha256(body.encode()).hexdigest()
run = requests.get(f"{API}/status/{wallet.hotkey.ss58_address}").json()["run_id"]
sig = wallet.hotkey.sign(f"capcomp-submit:v1:{run}:{sha}".encode()).hex()
print(requests.post(f"{API}/submit", json={
"hotkey": wallet.hotkey.ss58_address, "recipe": body, "signature": sig,
}).json())
| 401 | The signature does not match. Check the run id and that you hashed the exact bytes you sent. |
| 403 | That hotkey is not registered on subnet 103. |
| 429 | You have used all 3 attempts this run. |
| 503 | The chain is briefly unreachable. Retry shortly — this is never a rejection of your recipe. |