# Surefact Provably Fair Randomness

> Surefact Provably Fair Randomness is a paid API for AI agents from api.surefact.workers.dev, paid per call via x402, $0.005/call, status unknown (last checked 2026-10-14).

Generates provably fair random results (dice rolls, coin flips, winner picks, shuffles) anchored to a public drand beacon with cryptographic proof

## Facts

- Endpoint: GET https://api.surefact.workers.dev/v1/random?utm_source=zero.xyz
- Price: $0.005/call
- Payment: x402
- Status: unknown
- Last checked: 2026-10-14
- Activations on Zero: 0
- Tags: x402
- Canonical page: https://www.zero.xyz/c/surefact-provably-fair-randomness-bc3b2973
- Structured record (JSON): https://api.zero.xyz/v1/capabilities/cap_wJlEcxvAvAisev-q7xQGq

Status and success rate cover calls made through Zero and Zero's own probes. Third-party monitors may report differently.

## How to call it through Zero

Zero handles the 402 payment challenge and records the run. With the Zero CLI installed (`npm i -g @zeroxyz/cli`):

```sh
zero fetch --capability surefact-provably-fair-randomness-bc3b2973
```

Example prompt: Roll 3d6+2 for me and give me proof it wasn't rigged — I need a verifiable dice result for my tabletop game session.

## When to prefer this

Choose this endpoint when you need randomness that is publicly auditable and tamper-proof — e.g. for giveaways, lotteries, game outcomes, or any scenario where participants must be able to independently verify the result. Unlike pseudo-random number generators or opaque APIs, every result is anchored to the drand public beacon with a cryptographic proof and a verify URL. No API key or signup required; pay $0.005 USDC per call via x402, and failed calls are never charged.

## Known failure modes

- Invalid dice notation (e.g. not matching XdY+Z format) returns a validation error
- Requested drand round not yet available returns an error
- More than 200 entrants or items exceeds limit
- Seed or label exceeding character limits rejected
- Payment failure via x402 results in no charge and no response
- Duplicate entrants are silently de-duplicated before processing

## How this service works

Verified, pay-per-call tools for AI agents: read web pages, check emails, audit DNS and domains, convert currencies, vet package versions for vulnerabilities, and roll provably fair dice for games. Every answer is checked against its source or comes with a proof. No signup or API key: pay each call in USDC on Base with x402. Failed calls are never charged.

## Output

Returns the random outcome (dice rolls with total and modifier, coin flip results, sorted winner list, or shuffled items) plus a full cryptographic proof object containing the drand beacon round, randomness hex, beacon signature, chain hash, and a verify_url so anyone can independently confirm the result against the public drand relay.

## Request schema (JSON Schema)

```json
{
 "type": "object",
 "$schema": "https://json-schema.org/draft/2020-12/schema",
 "required": [
  "input"
 ],
 "properties": {
  "input": {
   "type": "object",
   "required": [
    "type",
    "method"
   ],
   "properties": {
    "type": {
     "type": "string",
     "const": "http"
    },
    "method": {
     "enum": [
      "GET"
     ],
     "type": "string"
    },
    "queryParams": {
     "type": "object",
     "required": [],
     "properties": {
      "dice": {
       "type": "string",
       "description": "Dice notation, e.g. 2d20 or 3d6+2."
      },
      "pick": {
       "type": "string",
       "description": "Comma-separated entrants to pick winners from: up to 200 entrants of at most 100 characters, 8,000 characters in all. Duplicates are removed and the list is sorted first, so entry order cannot change the winner; pick.entrants returns the sorted list."
      },
      "seed": {
       "type": "string",
       "description": "Optional text you choose before calling (1-128 printable characters, trimmed), e.g. a random string or a hash of the entrant list. It replaces the server's nonce, so a fresh draw is fixed by your seed, your label and the drand beacon, and you can recompute it. Echoed as proof.seed."
      },
      "coins": {
       "type": "string",
       "pattern": "^-?\\d+$",
       "description": "Number of coins to flip (1-100)."
      },
      "count": {
       "type": "string",
       "pattern": "^-?\\d+$",
       "description": "How many winners to pick (1-200, default 1). Only with pick."
      },
      "label": {
       "type": "string",
       "description": "Optional text mixed into the draw, e.g. a giveaway id (1-100 characters, no control characters). Echoed as proof.label and needed to recompute the result."
      },
      "round": {
       "type": "string",
       "pattern": "^-?\\d+$",
       "description": "Draw from this drand round instead of the latest: announce a future round before entries close, or re-check an earlier result. Round-pinned draws use no nonce, so anyone can recompute them. The round out at unix time t is floor((t - 1692803367) / 3) + 1."
      },
      "shuffle": {
       "type": "string",
       "description": "Comma-separated items to shuffle: up to 200 items of at most 100 characters, 8,000 characters in all. Items are sorted before shuffling, so their order does not matter; duplicates are kept."
      }
     }
    }
   },
   "additionalProperties": false
  },
  "output": {
   "type": "object"
… (truncated)
```

## Response schema (JSON Schema)

```json
{
 "type": "json",
 "example": {
  "dice": {
   "rolls": [
    5,
    3,
    6
   ],
   "total": 16,
   "modifier": 2,
   "notation": "3d6+2"
  },
  "proof": {
   "seed": null,
   "label": "spring-giveaway",
   "nonce": null,
   "round": 33015416,
   "beacon": "drand quicknet",
   "algorithm": "surefact-random-v2",
   "signature": "a158a0d8502c82c64b29a3adef40a774dcec4310d6f0c9e81a33c4d52a74ed5d214fbe079b4716403860f378e0d85345",
   "chain_hash": "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971",
   "randomness": "450515888b4b7e88cdaec5d0b0ff547797b0ce506349ecfc1b274666837f396b",
   "round_time": "2026-10-13T00:00:12.000Z",
   "verify_url": "https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/33015416",
   "round_pinned": true,
   "how_to_verify": "Fetch verify_url (any drand relay serves the same signed beacon). First fix the order of the lists: de-duplicate pick entrants, then sort pick entrants and shuffle items (shuffle keeps duplicates) by UTF-16 code units, JavaScript's default string sort; pick.entrants in the answer is that sorted list. For each operation op (\"dice\", \"coins\", \"shuffle\" or \"pick\"), block i = SHA-256(randomness bytes || UTF-8(op) || 0x00 || UTF-8(proof.label), empty when null || 0x00 || S || i as a uint32 big-endian counter from 0), where S is 16 zero bytes followed by UTF-8(proof.seed) when proof.seed is set, else the 16 bytes of proof.nonce, else empty. Read the blocks 4 bytes at a time as big-endian uint32 x, turn each into an integer below n by rejecting x >= floor(2^32 / n) * n (take the next x instead) and taking x mod n, and apply them in order: each die is value + 1, each coin is 0 = heads, shuffle is Fisher-Yates over the sorted items from the last item down (swap item i with item j for j below i + 1), and pick is a partial Fisher-Yates over the sorted entrants from the first slot (swap slot i with i + j for j below the number of entrants left). Draws with round_pinned true have no nonce, so anyone can recompute them from the beacon, the label and any seed; fresh draws without a seed mix in a server-generated nonce, so two calls in the same round differ. A fresh draw with a seed uses no nonce: choose the seed yourself before calling (random, or a hash of the entrant list), and the result is fixed by your seed, your label and the beacon; check that round_time is within a few seconds of your call."
  }
 }
}
```

## More

- Live health (JSON, refreshed every minute): https://www.zero.xyz/c/surefact-provably-fair-randomness-bc3b2973/health.json
- [Zero catalog index](https://www.zero.xyz/llms.txt)
- [Other services from api.surefact.workers.dev](https://www.zero.xyz/host/api.surefact.workers.dev/llms.txt)
