Integration guides

Cloudflare Workers

Moderate content from a Worker, with the key as a Worker secret.

A Worker runs on the server side of your application, so it can hold the key. Call it from your front end, and let it call openshield.

Set the key as a secret

npx wrangler secret put OPENMOD_API_KEY

For local development, put it in a .dev.vars file that is not committed:

OPENMOD_API_KEY=om_live_...

The Worker

src/index.ts
export interface Env {
  OPENMOD_API_KEY: string
}

const base = "https://api.openshield.dev"

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method !== "POST") return new Response("Method not allowed", { status: 405 })
    const { text, ref } = (await request.json()) as { text: string; ref?: string }

    let answer: Response
    try {
      answer = await fetch(`${base}/v1/text`, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${env.OPENMOD_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ text, ref }),
        signal: AbortSignal.timeout(10_000),
      })
    } catch {
      // The check could not be made: fail closed, keep the content hidden.
      return Response.json({ decision: "hold" })
    }

    const body = (await answer.json()) as {
      summary?: { action: string; reject_reason: Array<{ id: string }> }
      error?: { type: string }
      request_id?: string
    }
    if (!answer.ok || body.summary === undefined) {
      const refused = [400, 413, 415].includes(answer.status)
      return Response.json({ decision: refused ? "refuse" : "hold", error: body.error?.type ?? "unknown" })
    }

    const { action, reject_reason } = body.summary
    return Response.json({
      decision: action === "accept" ? "publish" : action === "review" ? "hold" : "refuse",
      reason: reject_reason[0]?.id ?? null,
      requestId: body.request_id,
    })
  },
}
Your Worker is the one that calls openshield, from Cloudflare's servers. A browser must call your Worker, never openshield: a request to our API with an Origin header is refused.