Endpoint reference
Single-proposal and batch endpoints available through the Risk Labs gateway.
All paths below are relative to https://api.risklabs.co. Send JSON with Content-Type: application/json. Use canonical lowercase addresses, signatures, and bytes32 question IDs; slugs may use lowercase letters, digits, and hyphens. Use the exact paths without trailing slashes or percent-encoded aliases.
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/proposals/eligibility/{address} | Check allowlist eligibility |
| POST | /v1/proposals/{identifier}/signing-data | Optional: prepare the complete witness |
| POST | /v1/proposals/{identifier} | Submit a signed candidate |
| GET | /v1/proposals/{identifier}/status/{candidate_id} | Follow validation and execution |
| POST | /propose/batch/signing-data | Optional: prepare signing context for 1–100 questions |
| POST | /propose/batch | Submit 1–100 independently signed candidates |
| POST | /propose/batch/status | Read status for 1–100 candidate IDs |
identifier is your question ID or market slug; prefer the canonical question ID, derived locally or returned by preparation. candidate_id is a hyphenated UUID. See Find the question ID to derive the question ID from indexed request ancillary data.
For batch request bodies, per-item results, and polling, see Batch proposing. Batch routes use their existing /propose/batch* schema; the single-proposal v1 payloads below cannot be sent to them unchanged.
Check eligibility
GET /v1/proposals/eligibility/{address}
Returns 200 with version, canonical address, and eligible. Unknown or disabled wallets return eligible: false; admission being disabled also returns false. This does not reserve a slot or guarantee acceptance.
Prepare signing data
POST /v1/proposals/{identifier}/signing-data
This endpoint is optional. It constructs the complete typed data for convenience. If you build the Permit2 witness yourself from current request data and trusted configuration, sign locally and submit directly. Submission requires no preparation token or prior signing-data call.
| Body field | Required value |
|---|---|
version | { "api": "v1", "schema": "signed-proposal-v1", "witness": "permit2-signed-proposer-v1" } |
proposer | Nonzero, lowercase wallet address |
outcome | p1, p2, or p3; must be allowed for this request |
max_payment | "0" |
permit.amount | Decimal string in raw token units, at least the current total bond |
permit.nonce | Unused uint256 Permit2 nonce as a decimal string |
permit.deadline | Unix seconds as a decimal string; at least five minutes beyond admission |
Returns 200 with:
| Field | What to do with it |
|---|---|
version, question_id | Verify contract version and question identity |
request | Verify oracle, requester, identifier, timestamp, and ancillary data |
proposal, outcomes | Confirm outcome key, label, and exact numerical price |
permit | Confirm your authorization terms were preserved |
token | Verify address; use symbol and decimals for display |
economics | Review current total bond and maximum authorization |
contracts | Verify Permit2 and SignedProposer addresses |
typed_data | Sign the complete EIP-712 payload after validation |
Preparation is stateless: it neither admits a candidate nor reserves a nonce or bond. All Solidity integers are decimal strings, including typed_data.domain.chainId. Token decimals and event indexes remain JSON numbers.
The current API supports the following binary outcome mapping. Market rules schema explains Type 1, Type 2, and clarification updates; Type 2 winner-index submissions are not supported by this API.
| Outcome key | Conventional label | Numerical price |
|---|---|---|
p1 | No | "0" |
p2 | Yes | "1000000000000000000" |
p3 | Unknown / 50-50 | "500000000000000000" |
Use the returned outcomes for request-specific labels and availability, and verify them against the rules and authorized clarifications. A p3 / 0.5 settlement requires permission in the rules and support from the settlement contract; uncertainty alone is not sufficient. Prices are oracle fixed-point values, not token amounts.
Submit a candidate
POST /v1/proposals/{identifier}
Send version, proposer, outcome, max_payment, and permit using the field requirements above, plus signature (lowercase, even-length hex, up to 8,192 bytes). You can construct this body yourself without calling preparation. If you used the helper, send its request body, unchanged, plus the signature. The API independently reconstructs the witness and validates the signature against the current request. Extra fields are rejected.
202: new candidate durably accepted for asynchronous validation.200: exact payload replay in the current request round; existing candidate returned.409: a conflicting active payload or request state prevents admission.
Both successful responses contain version, candidate_id, status, received_at, and a relative status_url. Save the exact payload and acknowledgement. There is no separate idempotency-key header.
Read status
GET /v1/proposals/{identifier}/status/{candidate_id}
Returns 200 with identity, outcome, price, receipt/validation/selection timestamps, candidate status, nullable submission, and nullable failure. The identifier scopes the lookup to the request; a mismatched or unknown candidate returns 404.
submission contains its own status, transaction_hash, submission/confirmation/indexing timestamps, and proposal_event_index. failure contains stage, code, detail, retryable, can_resubmit, and next_action. Signatures and executable transaction data are never returned. See status and retries.
Errors
Application errors use this shape; schema failures can also include a sanitized errors array:
{
"error": {
"code": "permit_amount_below_required_bond",
"detail": "Permit amount is below the current total bond"
}
}| HTTP status | Action |
|---|---|
400, 422 | Correct the identifier, schema, outcome, amount, or deadline |
403 | Check proposer eligibility and signature authorization |
404 | Verify the question/candidate identity and public route |
405 | Use the documented HTTP method |
409 | Reconcile the existing candidate or current request state |
413 | Reduce the payload; do not send ancillary data in admission |
429 | Honor Retry-After when supplied; back off with jitter |
503 | Service or authoritative state unavailable; back off |
502, 504 | Gateway failure; admission may already have committed |
Treat transport failures and gateway bodies separately from application JSON errors. On uncertain submission outcomes, replay the exact saved payload; do not immediately generate another nonce. Server-side clients are the simplest integration. Browser origins require explicit CORS configuration; this API does not use browser cookies.