---
title: "Supabase Edge Functions"
description: "Moderate content from a Supabase Edge Function, with the key as a project secret."
canonical_url: "https://www.openshield.dev/docs/integration-guides/supabase-edge-functions"
---
# Supabase Edge Functions

> Moderate content from a Supabase Edge Function, with the key as a project secret.

An Edge Function runs on the server, so it is the right place for the key. Call it from your app, and let it call openshield.

## Set the key as a secret

```bash
supabase secrets set OPENSHIELD_API_KEY=om_live_...
```

Read it in the function with `Deno.env.get("OPENSHIELD_API_KEY")`. Never put it in the code of your front end.

## The function

```ts [supabase/functions/moderate-text/index.ts]
const base = "https://api.openshield.dev"

Deno.serve(async (request) => {
  const { text, ref } = await request.json()

  let answer: Response
  try {
    answer = await fetch(`${base}/v1/text`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${Deno.env.get("OPENSHIELD_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()
  if (!answer.ok) {
    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",
    // Choose your user's message from this id, in your own words.
    reason: reject_reason[0]?.id ?? null,
    requestId: body.request_id,
  })
})
```

Deploy it with `supabase functions deploy moderate-text`. Your app calls it with the Supabase client:

```ts
const { data } = await supabase.functions.invoke("moderate-text", { body: { text, ref: commentId } })
```

<note>

Your function is the one that calls openshield, from the Supabase servers. The browser calls your function, never openshield: a request to our API with an `Origin` header is refused.

</note>


## Sitemap

See the full [sitemap](https://www.openshield.dev/sitemap.md) for all pages.
