Ready-to-use functions. All of them are also templates in Studio → Edge Functions → New function.
#Read data as the calling user
TypeScript
import { createClient } from 'https://stitchdb.com/sdk/stitchdb-js.mjs'
Deno.serve(async (req) => {
// Queries run as the caller: Row Level Security applies.
const db = createClient(Deno.env.get('STITCHDB_URL')!, Deno.env.get('STITCHDB_ANON_KEY')!, {
global: { headers: { Authorization: req.headers.get('Authorization') ?? '' } },
auth: { persistSession: false },
})
const { data: { user } } = await db.auth.getUser()
if (!user) return Response.json({ error: 'Sign in first' }, { status: 401 })
const { data } = await db.from('todos').select('*')
return Response.json(data)
})#Trusted work with the service role key
TypeScript
import { createClient } from 'https://stitchdb.com/sdk/stitchdb-js.mjs'
// The service role key bypasses Row Level Security: use it only for trusted work.
const admin = createClient(Deno.env.get('STITCHDB_URL')!, Deno.env.get('STITCHDB_SERVICE_ROLE_KEY')!, {
auth: { persistSession: false },
})
Deno.serve(async () => {
const { count } = await admin.from('orders').select('*', { count: 'exact', head: true })
return Response.json({ orders: count })
})#Query Postgres directly
TypeScript
import postgres from 'npm:postgres@3'
// STITCHDB_DB_URL connects through the transaction pooler as the project owner.
const sql = postgres(Deno.env.get('STITCHDB_DB_URL')!, { prepare: false, max: 1 })
Deno.serve(async () => {
const rows = await sql`select id, task from public.todos order by id desc limit 5`
return Response.json(rows)
})#Stripe webhook
Deploy with JWT verification off and add the secrets STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET; point the Stripe webhook at the function URL.
TypeScript
import Stripe from 'npm:stripe@17'
const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!)
const crypto = Stripe.createSubtleCryptoProvider()
Deno.serve(async (req) => {
const body = await req.text()
try {
const event = await stripe.webhooks.constructEventAsync(
body, req.headers.get('stripe-signature')!, Deno.env.get('STRIPE_WEBHOOK_SECRET')!, undefined, crypto)
console.log('Stripe event', event.type)
return Response.json({ received: true })
} catch (e) {
return new Response(`Bad signature: ${(e as Error).message}`, { status: 400 })
}
})#Send an email
With a Resend API key in the secret RESEND_API_KEY:
TypeScript
Deno.serve(async (req) => {
const { to, subject, html } = await req.json()
const r = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: { Authorization: `Bearer ${Deno.env.get('RESEND_API_KEY')}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ from: 'My App <[email protected]>', to, subject, html }),
})
return new Response(await r.text(), { status: r.status, headers: { 'Content-Type': 'application/json' } })
})#Keep an AI key on the server
With an Anthropic API key in the secret ANTHROPIC_API_KEY; your app calls the function instead of the AI provider:
TypeScript
import Anthropic from 'npm:@anthropic-ai/sdk'
const client = new Anthropic({ apiKey: Deno.env.get('ANTHROPIC_API_KEY') })
Deno.serve(async (req) => {
const { prompt } = await req.json()
const message = await client.messages.create({
model: 'claude-opus-5-5',
max_tokens: 16000,
messages: [{ role: 'user', content: String(prompt ?? '') }],
})
if (message.stop_reason === 'refusal') return Response.json({ error: 'Declined' }, { status: 422 })
const text = message.content.flatMap((b) => (b.type === 'text' ? [b.text] : [])).join('')
return Response.json({ text })
})