# rdrand.com: full documentation > Free hardware random number API. No sign-up, no API key. Values come from the RDRAND instruction of the servers' Intel and AMD CPUs. Client libraries for Node.js, Kotlin/Java, Rust and .NET generate on the caller's own CPU (RDRAND or ARM RNDR) and fall back to the API. ## API overview - Base URL: `https://rdrand.com/API/` (`https://www.rdrand.com/API/` also works; plain HTTP redirects to HTTPS) - Method: `POST` only. Any other method returns 404. - Authentication: none. An `apiKey` parameter from older examples is accepted and ignored. - CORS: every response, errors included, carries `Access-Control-Allow-Origin: *`, and `OPTIONS` preflight requests are answered, so browsers can send form data or JSON. - OpenAPI 3.1 description: https://rdrand.com/openapi.json | Endpoint | Parameter | Response body | |---|---|---| | `POST /API/GenerateKey` | `length`: 0 to 16777216 | `length` characters, each uniform over the 63 symbols `0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz` | | `POST /API/GenerateBytes` | `length`: 0 to 16777216 | `length` random bytes, encoded as standard base64 (RFC 4648 alphabet `A-Z a-z 0-9 + /`, with `=` padding) | | `POST /API/GenerateUInt` | none | a decimal integer from 0 to 2147483647 (2^31 - 1), so it fits signed and unsigned 32-bit types | | `POST /API/FlipCoin` | none | `Heads` or `Tails`, each with probability 1/2 (just for fun) | | `POST /API/Magic8Ball` | `question`: optional, ignored | one of the 20 classic Magic 8 Ball answers, chosen uniformly (just for fun; see below) | Magic 8 Ball answers, with no trailing punctuation: `It is certain`, `It is decidedly so`, `Without a doubt`, `Yes, definitely`, `You may rely on it`, `As I see it, yes`, `Most likely`, `Outlook good`, `Yes`, `Signs point to yes` (yes); `Reply hazy, try again`, `Ask again later`, `Better not tell you now`, `Cannot predict now`, `Concentrate and ask again` (non-committal); `Don't count on it`, `My reply is no`, `My sources say no`, `Outlook not so good`, `Very doubtful` (no). ## Requests Send `length` in any one of these ways: - Form body: `Content-Type: application/x-www-form-urlencoded`, body `length=32` (recommended; what `curl -d`, HTML forms, jQuery `$.post` and `URLSearchParams` send) - JSON body: `Content-Type: application/json`, body `{"length": 32}` - Query string: `POST https://rdrand.com/API/GenerateKey?length=32` with an empty body - Multipart form data with a `length` text field `GenerateUInt`, `FlipCoin` and `Magic8Ball` take no parameters. Send a POST with an empty body (`curl -d ""`), ideally with `Content-Length: 0`. Anything sent, such as a Magic 8 Ball `question`, is ignored. Details, for completeness: - Endpoint paths are case-insensitive (`/api/generatekey` works). A trailing slash is fine. - The parameter name is case-insensitive (`Length=32` works). If both the body and the query string have `length`, the body wins. If a form repeats `length`, the first value wins. - `length` is a 32-bit integer. Surrounding whitespace and a leading `+` are allowed. `0x10` and `#10` are read as hexadecimal. In JSON, a number with a fraction is rounded to the nearest integer (halves to even), `true` is 1 and `false` is 0, and numeric strings such as `"32"` work. - Bodies with other content types (for example `text/plain`) are not read for parameters. ## Responses Success: HTTP 200. The body is the value itself with no quotes, JSON or trailing newline. Headers: - `Content-Type: text/html; charset=utf-8`. The body is plain text despite the label. Read it as text. - `Cache-Control: private` - `Access-Control-Allow-Origin: *` `length=0` returns HTTP 200 with an empty body and no `Content-Type`. Errors: HTTP 500 with an HTML error page (about 3 KB). Causes: - `length` missing, empty, non-numeric, a decimal string such as `1.5`, or outside the 32-bit range - `length` negative, or larger than 16777216 - a malformed JSON body (also for the endpoints that take no parameters) Treat any non-200 status as a failure and do not parse the body. GET and PUT requests to the endpoints return HTTP 404; OPTIONS returns a CORS preflight response (204). Large requests: `GenerateBytes` with the maximum length returns about 22.4 MB of base64. Prefer several smaller requests, or a client library, which generates locally. ## Browsers Any origin may call the API. Form data (`URLSearchParams`, `FormData`, jQuery `$.post`, an HTML form) is a "simple" request and needs no preflight. JSON bodies and custom headers trigger a preflight, which the API answers (`Access-Control-Allow-Methods: POST, OPTIONS`, `Access-Control-Max-Age: 86400`). Error responses carry the CORS header too, so browser code sees the HTTP 500 status rather than a network error. ## Examples ### curl ```sh curl -d length=32 https://rdrand.com/API/GenerateKey curl -d length=16 https://rdrand.com/API/GenerateBytes | base64 --decode > random.bin curl -d "" https://rdrand.com/API/GenerateUInt curl -H "Content-Type: application/json" -d '{"length":32}' https://rdrand.com/API/GenerateKey curl -d "" https://rdrand.com/API/FlipCoin curl -d question="Will it ship on Friday?" https://rdrand.com/API/Magic8Ball ``` ### JavaScript (browser, Deno, Node.js 18+, Bun) ```js async function rdrand(endpoint, length) { const res = await fetch(`https://rdrand.com/API/${endpoint}`, { method: "POST", body: new URLSearchParams(length === undefined ? {} : { length: String(length) }), }); if (!res.ok) throw new Error(`rdrand.com: HTTP ${res.status}`); return res.text(); } const key = await rdrand("GenerateKey", 32); // "kq9ZLx0t..." const bytes = Uint8Array.from(atob(await rdrand("GenerateBytes", 16)), (c) => c.charCodeAt(0)); const n = Number(await rdrand("GenerateUInt")); // 0 to 2147483647 ``` ### Python ```python import base64 import requests API = "https://rdrand.com/API/" def rdrand(endpoint: str, length: int | None = None) -> str: data = {} if length is None else {"length": length} r = requests.post(API + endpoint, data=data, timeout=30) r.raise_for_status() return r.text key = rdrand("GenerateKey", 32) raw = base64.b64decode(rdrand("GenerateBytes", 16)) n = int(rdrand("GenerateUInt")) ``` Standard library only: ```python import urllib.parse, urllib.request body = urllib.parse.urlencode({"length": 32}).encode() key = urllib.request.urlopen("https://rdrand.com/API/GenerateKey", data=body).read().decode() ``` ### Go ```go resp, err := http.PostForm("https://rdrand.com/API/GenerateKey", url.Values{"length": {"32"}}) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return fmt.Errorf("rdrand.com: %s", resp.Status) } key, err := io.ReadAll(resp.Body) // GenerateUInt: empty body resp, err = http.Post("https://rdrand.com/API/GenerateUInt", "application/x-www-form-urlencoded", nil) ``` ### C# (.NET HttpClient) ```csharp using var http = new HttpClient(); var res = await http.PostAsync("https://rdrand.com/API/GenerateKey", new FormUrlEncodedContent(new Dictionary { ["length"] = "32" })); res.EnsureSuccessStatusCode(); string key = await res.Content.ReadAsStringAsync(); res = await http.PostAsync("https://rdrand.com/API/GenerateUInt", new ByteArrayContent(Array.Empty())); uint n = uint.Parse(await res.Content.ReadAsStringAsync()); ``` ### Java (java.net.http, Java 11+) ```java HttpClient http = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder(URI.create("https://rdrand.com/API/GenerateKey")) .header("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString("length=32")) .build(); String key = http.send(req, HttpResponse.BodyHandlers.ofString()).body(); ``` ### Rust (ureq 3) ```rust let key = ureq::post("https://rdrand.com/API/GenerateKey") .send_form([("length", "32")])? .body_mut() .read_to_string()?; ``` ## Client libraries Four free MIT-licensed libraries, version 2.0.0, with the same API shape. Each uses the local CPU's hardware random number generator when it has one, and calls the rdrand.com API otherwise (or if the hardware fails mid-call). Outputs have the API's formats whichever source produced them: keys are uniform over the same 63 symbols, and integers are from 0 to 2^31 - 1. - Hardware sources: `RDRAND` on x86_64 (Intel and AMD; Linux, Windows, macOS) and `RNDR` on ARMv8.5+ with the RNG extension (Linux arm64, such as AWS Graviton3 and Graviton4). Graviton2, Raspberry Pi and Apple silicon have no RNDR, so the libraries use the API there. - Safety: every hardware draw's success flag is checked and retried up to 10 times, the generator must pass a self-test (64 distinct values) before use, and repeated (stuck) values are rejected. - Modes: `auto` (default; hardware, else API), `hardware` (error if there is no hardware generator), `service` (API only). - Each client reports its source: `rdrand`, `rndr` or `service`. ### Node.js (18+, no dependencies) ```sh npm install https://rdrand.com/Downloads/jebtek-rdrand-2.0.0.tgz ``` ```js const { RdRand, RdRandError } = require("@jebtek/rdrand"); // or: import { RdRand } from "@jebtek/rdrand" const rng = new RdRand(); // { mode: "auto" | "hardware" | "service", baseUrl, timeoutMs } const key = await rng.generateKey(32); // string const bytes = await rng.generateBytes(16); // Buffer const n = await rng.generateUInt(); // number, 0 to 2147483647 rng.source; // "rdrand" | "rndr" | "service" RdRand.hardwareSource(); // "rdrand" | "rndr" | null ``` Prebuilt hardware support: linux-x64, linux-arm64, win32-x64, darwin-x64, darwin-arm64. TypeScript types included. ### Kotlin / Java (JVM 11+) Download https://rdrand.com/Downloads/rdrand-kotlin-2.0.0.jar into `libs/`; its only dependency is the Kotlin standard library. ```kotlin // build.gradle.kts: implementation(files("libs/rdrand-kotlin-2.0.0.jar")) import com.jebtek.rdrand.Mode import com.jebtek.rdrand.RdRand val rng = RdRand() // RdRand(mode = Mode.AUTO, baseUrl = ..., timeout = ...) val key: String = rng.generateKey(32) val bytes: ByteArray = rng.generateBytes(16) val n: Int = rng.generateUInt() // 0 to Int.MAX_VALUE rng.source // Source.RDRAND | RNDR | SERVICE RdRand.hardwareSource() // Source? (null without hardware) ``` From Java: `new RdRand().generateKey(32)`. Calls block; hardware calls take microseconds. Errors throw `RdRandException`. ### Rust Download https://rdrand.com/Downloads/rdrand-rust-2.0.0.zip and unzip it (crate `rdrand-client`, MSRV 1.80). ```toml [dependencies] rdrand-client = { path = "rdrand-client-2.0.0" } # hardware only, no dependencies: # rdrand-client = { path = "rdrand-client-2.0.0", default-features = false } ``` ```rust use rdrand_client::{Client, Mode}; let rng = Client::new(); // Client::with_mode(Mode::Hardware), .base_url(..) let key: String = rng.generate_key(32)?; let bytes: Vec = rng.generate_bytes(16)?; let n: u32 = rng.generate_uint()?; // 0 ..= 2^31 - 1 rng.source(); // Source::Rdrand | Rndr | Service Client::hardware_source(); // Option ``` The client is blocking; from async code use `spawn_blocking`, or call a `Mode::Hardware` client directly. ### .NET (.NET Standard 2.0: .NET 6+, .NET Framework 4.6.1+) Download https://rdrand.com/Downloads/JebteK.RdRand.2.0.0.nupkg into a folder, then: ```sh dotnet add package JebteK.RdRand --version 2.0.0 --source /path/to/folder ``` ```csharp using JebteK.RdRand; using var rng = new RdRandClient(); // (RdRandMode.Auto, baseUrl, httpClient) string key = await rng.GenerateKeyAsync(32); byte[] bytes = await rng.GenerateBytesAsync(16); uint n = await rng.GenerateUIntAsync(); // 0 to 2147483647 rng.Source; // RdRandSource.Rdrand | Rndr | Service RdRandClient.HardwareSource; // RdRandSource? (null without hardware) ``` Blocking versions: `GenerateKey`, `GenerateBytes`, `GenerateUInt`. Errors throw `RdRandException`. Hardware support: linux-x64, linux-arm64, win-x64, osx-x64, osx-arm64. ### Legacy .NET wrapper v1.1 https://rdrand.com/Downloads/RdRandom-v1_1.zip: .NET Framework, requires RestSharp, calls the API only. Static methods: `RdRandom.Randomizer.GenerateKey(int length)`, `RdRandom.Randomizer.GenerateBytes(int length)`, `RdRandom.Randomizer.GenerateUInt()`. The base URL can be changed with the `URL` app setting (default `https://rdrand.com/API/`). ## About rdrand.com is run by JebteK, LLC. Support: support@jebtek.freshdesk.com. Website: https://rdrand.com/