Supabase Edge Function
An AstroWay key cannot go into a frontend: anything in the bundle is visible to every visitor. An Edge Function solves it in one file: the browser calls the function, the function calls the API with the key from the project’s secrets and returns only what is needed. The same file works in Lovable and Bolt, because both put their backend on Supabase.
1. The function
Section titled “1. The function”supabase functions new big-threeReplace supabase/functions/big-three/index.ts with:
const SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', 'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces'];
const cors = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',};
const signOf = (longitude: number) => SIGNS[Math.floor(longitude / 30)];
Deno.serve(async (req) => { if (req.method === 'OPTIONS') return new Response('ok', { headers: cors });
const { date, time, timezone, latitude, longitude } = await req.json(); const res = await fetch('https://api.astroway.info/v1/chart', { method: 'POST', headers: { 'X-Api-Key': Deno.env.get('ASTROWAY_API_KEY') ?? '', 'Content-Type': 'application/json', }, body: JSON.stringify({ date, time, timezone, latitude, longitude }), }); const json = await res.json(); if (!json.ok) return Response.json({ error: json.error }, { status: res.status, headers: cors });
const planet = (name: string) => json.data.planets.find((p: { name: string }) => p.name === name); return Response.json({ sun: signOf(planet('Sun').longitude), moon: signOf(planet('Moon').longitude), rising: signOf(json.data.houses.ascendant), offset_used: json.data.input.timezoneOffset, }, { headers: cors });});2. The key in secrets
Section titled “2. The key in secrets”Create a Server only key scoped to chart with a budget, as described in A key for an automation, and put it in the project’s secrets, not in the frontend .env:
supabase secrets set ASTROWAY_API_KEY=aw_live_...supabase functions deploy big-threeThe function reads the secret as Deno.env.get('ASTROWAY_API_KEY'), and it reaches neither the code nor the browser. You can set the same secret in the Supabase dashboard under Edge Functions → Secrets.
3. Calling it from the page
Section titled “3. Calling it from the page”const { data, error } = await supabase.functions.invoke('big-three', { body: { date: '1990-05-15', time: '14:30:00', timezone: 'Europe/Kyiv', latitude: 50.45, longitude: 30.52 },});// data: { sun: 'Taurus', moon: 'Capricorn', rising: 'Virgo', offset_used: 4 }supabase-js adds the project’s anon key itself, so a function with the default JWT check accepts the call with no extra setup. The function passes an API error on with the same status and error body, so error.message can be shown to the user as it is.
Worth knowing
Section titled “Worth knowing”timezoneas a zone name.Europe/Kyiv, not an offset: the server knows Kyiv was on UTC+4 on 1990-05-15. An empty string is refused with400 INVALID_FIELD, and a missing field means UTC. Details in No-code integrations.- Cost.
POST /v1/chartcosts 20 credits. The same body within five minutes comes from cache at no charge. - The key’s budget. Anyone who opens your site can call the function. A budget on the key stops a looping or hostile client at the number you set, with
429 KEY_BUDGET_EXHAUSTED.