Quickstart

Send your first reliable OpenAI request.

Create a project, connect your OpenAI key, generate a ReqRun API key, install the SDK, and send one chat completion request through ReqRun.

1. Create a project, API key, and signing secret

Open the dashboard, create a project, connect the project's OpenAI key, then generate a reqrun_test_ or reqrun_live_ API key. Copy the signing secret shown at key creation time too. Hosted ReqRun keys now use signed requests.

Open dashboard

2. Send one request to the hosted API

Signed HTTP against the hosted API is the lower-level integration path. It works well for manual integrations, agents, generated clients, and quick tests, and it shows the exact signed request shape the SDK builds for you.

TypeScript
const encoder = new TextEncoder();

function toHex(buffer: ArrayBuffer) {
  return [...new Uint8Array(buffer)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
}

async function sha256Hex(value: string) {
  return toHex(await crypto.subtle.digest("SHA-256", encoder.encode(value)));
}

async function hmacHex(secret: string, value: string) {
  const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
  return toHex(await crypto.subtle.sign("HMAC", key, encoder.encode(value)));
}

async function buildSignedReqRunHeaders(path: string, method: "GET" | "POST", bodyString = "") {
  const timestamp = Math.floor(Date.now() / 1000).toString();
  const nonce = crypto.randomUUID().replace(/-/g, "");
  const bodyHash = await sha256Hex(bodyString);
  const payload = [method, path, bodyHash, timestamp, nonce].join("\n");
  const signature = await hmacHex(process.env.REQRUN_SIGNING_SECRET!, payload);

  return {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.REQRUN_API_KEY!}`,
    "X-ReqRun-Timestamp": timestamp,
    "X-ReqRun-Nonce": nonce,
    "X-ReqRun-Signature": `v1=${signature}`,
  };
}

const path = "/v1/chat/completions";
const body = {
  model: "gpt-5-nano",
  messages: [{ role: "user", content: "Reply with exactly OK." }],
  wait: true,
  idempotency_key: "quickstart-001",
};

const bodyString = JSON.stringify(body);

const response = await fetch(`https://api.reqrun.com${path}`, {
  method: "POST",
  headers: await buildSignedReqRunHeaders(path, "POST", bodyString),
  body: bodyString,
});

const result = await response.json();
console.log(result);

3. Expected output

If the request finishes within the wait timeout, you get a normal OpenAI-style chat completion response.

If it does not finish in time, you get an async response with an rr_ request id.

4. Check status later

Use wait=false for background work, store the rr_ id, and fetch the request when your app needs the outcome.

TypeScript
const response = await fetch("https://api.reqrun.com/v1/chat/completions", {
  method: "POST",
  headers: await buildSignedReqRunHeaders(
    "/v1/chat/completions",
    "POST",
    JSON.stringify({
      model: "gpt-5-nano",
      messages: [{ role: "user", content: "Classify this ticket." }],
      wait: false,
      idempotency_key: "ticket-842",
    }),
  ),
  body: JSON.stringify({
    model: "gpt-5-nano",
    messages: [{ role: "user", content: "Classify this ticket." }],
    wait: false,
    idempotency_key: "ticket-842",
  }),
}).then((res) => res.json());

if (response.object === "chat.completion.async") {
  const request = await fetch(`https://api.reqrun.com/v1/requests/${response.id}`, {
    headers: await buildSignedReqRunHeaders(`/v1/requests/${response.id}`, "GET"),
  }).then((res) => res.json());

  console.log(request.status, request.attempts, request.last_error_code);
}

5. Use the SDK

The @reqrun/sdk package is published on npm and signs every request for you, so it is the recommended path for JavaScript and TypeScript. Install it with npm install @reqrun/sdk; the hosted HTTP API above stays available as the lower-level reference.

TypeScript
import { ReqRun } from "@reqrun/sdk";

const reqrun = new ReqRun({
  apiKey: process.env.REQRUN_API_KEY!,
  signingSecret: process.env.REQRUN_SIGNING_SECRET!,
  baseURL: "https://api.reqrun.com",
});

const response = await reqrun.chat.completions.create({
  model: "gpt-5-nano",
  messages: [{ role: "user", content: "Reply with exactly OK." }],
  wait: true,
  idempotency_key: "quickstart-001",
});

console.log(response);

Agent-friendly rules

  • Base URL: https://api.reqrun.com
  • Auth: Bearer ReqRun project API key plus X-ReqRun-Timestamp, X-ReqRun-Nonce, and X-ReqRun-Signature
  • Primary endpoint: POST /v1/chat/completions
  • Status endpoint: GET /v1/requests/{id}
  • Use wait=true for fast-path completion and wait=false for background work
  • Always send an idempotency_key for retried or repeatable operations
  • New hosted keys also require the signing secret shown once at key creation time