Skip to content

DEVELOPER API

Integration and contribution guide

Only endpoints that exist are documented here. Every response is JSON; data is wrapped in data, lists carry meta.nextCursor, and errors use a stable error.code.

version v1base path /api/v1records may be reset before launch

Endpoints

methodpathpurpose
GET/api/v1/healthservice and database health
GET/api/v1/network/statusdeployment, indexer and research-activity status
GET/api/v1/contractsnetwork configuration, deployment manifest and registry ABI
GET/api/v1/capabilitiescapability domains
GET/api/v1/capabilities/{slug}one capability with its suites and baselines
GET/api/v1/baselines?capability=baselines (summary)
GET/api/v1/baselines/{id}one baseline including its source
GET/api/v1/suites/{id}a test suite record (public dev seed, held-out commitment, limits)
GET/api/v1/proposals?status=&capability=&contributor=&from=&to=&repro=&cursor=&limit=proposals, newest first (from/to are YYYY-MM-DD on submission time; repro is REPRODUCED, PENDING, DIVERGED or NONE for the latest evaluation)
POST/api/v1/proposalssubmit a proposal (session required)
GET/api/v1/proposals/{id}one proposal with experiments, evaluations, lineage and contributions
POST/api/v1/proposals/{id}/withdrawwithdraw your proposal (session required)
POST/api/v1/proposals/{id}/replicationsrequest another replication run (session required)
POST/api/v1/proposals/{id}/anchorreport the on-chain anchor transaction (session required)
GET/api/v1/experiments?proposal=&status=experiments
GET/api/v1/experiments/{id}one experiment including its full harness result
GET/api/v1/evaluations?proposal=&status=evaluation records
GET/api/v1/evaluations/{id}one evaluation record with its challenges
GET/api/v1/lineage?capability=the lineage graph: nodes and edges
GET/api/v1/lineage/{id}a lineage record by id or child id
GET/api/v1/challenges?evaluation=challenges
POST/api/v1/challengesopen a challenge (session required)
GET/api/v1/challenges/{id}one challenge
POST/api/v1/challenges/{id}/anchorreport the challenger's on-chain openChallenge transaction (challenger session)
POST/api/v1/challenges/{id}/resolveresolve a challenge: uphold or dismiss (registry owner session; on-chain challenges need the resolve transaction hash)
POST/api/v1/auth/nonceissue a SIWE nonce
POST/api/v1/auth/verifyverify a SIWE message and set the session cookie
GET/api/v1/auth/sessioncurrent session
POST/api/v1/auth/logoutclear the session

The machine-readable index is at /api/v1.

Authentication (Sign-In with Ethereum)

Reads are public. Writes require a session established by signing a SIWE message. The message must use this site's domain, chain id 4663, a nonce issued by POST /api/v1/auth/nonce and an expiration within one hour. Signatures are verified server-side (EIP-1271 contract wallets included) and each nonce is single-use. The session is an HttpOnly cookie valid for seven days. Signing a message sends no transaction and moves no funds.

flow
POST /api/v1/auth/nonce            → { nonce, domain, chainId, expiresAt }
sign SIWE message (viem createSiweMessage) with your wallet
POST /api/v1/auth/verify { message, signature } → sets kuxer_session cookie
POST /api/v1/proposals  (cookie)      → 201 { proposal, experiment, created, queue }

Submitting a proposal

POST /api/v1/proposals accepts the fields below. parents lists validated proposal ids to inherit from; the baseline is always added as the first parent. The source must be a JavaScript ES module exporting solve(instance, ctx) (see the candidate contract). Send an Idempotency-Key header to make retries safe; an identical resubmission returns the existing proposal with created: false.

request body
{
  "capabilityId": "cap_euclidean-tsp-v1",
  "baselineId": "bl_nearest-neighbor-v1",
  "parents": [],
  "title": "Nearest neighbor with 2-opt refinement",
  "summary": "Applies a deterministic 2-opt local search after nearest-neighbor construction.",
  "method": "Standard 2-opt with first-improvement moves until no improving swap exists or 80% of the deadline is used.",
  "source": "export function solve(instance, ctx) { /* ... */ }"
}

The response includes the queued INITIAL experiment. Poll GET /api/v1/proposals/{id} to follow status changes; the experiment's full harness result is available at GET /api/v1/experiments/{id} once it completes.

Anchoring on-chain

When the registry is deployed, a contributor can commit their proposal from their own wallet by calling commitProposal(id, contentHash, parents) on the registry, where id and each parent are keccak256(utf8(recordId)) (returned as chainKey) and contentHash is the proposal's contentHash. All parents must already be committed. Then report the transaction with POST /api/v1/proposals/{id}/anchor; the server verifies the receipt and event before recording it. Evaluations of anchored proposals are committed by the operator's evaluator signer and confirmed by the indexer.

Pagination, caching and versioning

  • List endpoints use keyset pagination: pass limit (1–100, default 25) and the meta.nextCursor value as cursor. Cursors are opaque.
  • Public GET responses carry Cache-Control with short s-maxage values; mutable records are not cached.
  • The API is versioned by path. Breaking changes ship as /api/v2; schema changes are reflected in schemaVersion on each record. Every response includes an x-api-version header.

Rate limits

scopelimit
read240 requests per 60 s
auth:nonce30 requests per 60 s
auth:verify20 requests per 60 s
proposals:create10 requests per 3600 s
replication:request10 requests per 3600 s
challenges:create5 requests per 3600 s
challenges:anchor30 requests per 3600 s
challenges:resolve60 requests per 3600 s
proposals:anchor30 requests per 3600 s

Exceeding a limit returns 429 rate_limited with details.retryAfterSeconds. Limits apply per wallet for writes and per IP for anonymous requests.

Errors and retries

error shape
{
  "error": {
    "code": "validation_error",
    "message": "request failed validation",
    "details": [
      {
        "path": "summary",
        "message": "Too small: expected string to have >=10 characters"
      }
    ]
  }
}
statuscodemeaning
400bad_request · validation_errormalformed body, query or cursor; details lists field issues
401unauthorizedno or invalid session; SIWE verification failed
403forbiddenacting on another contributor's proposal; challenging your own record; resolving a challenge without the registry owner session
404not_foundunknown record
409conflictidempotency key reused with a different body; open challenge exists
422unprocessablevalid shape, invalid state (unknown baseline, unvalidated parent, wrong status)
429rate_limitedretry after details.retryAfterSeconds
503service_unavailabledatabase or registry not configured; safe to retry later

Retry 429 and 503 with backoff and the same Idempotency-Key. Never retry 4xx validation failures without changing the request.