Documentation Index Fetch the complete documentation index at: https://docs.getspine.ai/llms.txt
Use this file to discover all available pages before exploring further.
Bolt.new, Replit Agent, and Lovable all run in the browser. Since the Spine API authenticates via an X-API-KEY header, you need a thin server-side proxy to keep the key off the client. The calling pattern is the same across all three.
Download reference proxy spine-proxy.ts — a minimal Next.js / Edge-compatible proxy
Architecture
Browser (Bolt / Replit / Lovable)
│ POST /api/spine/run { prompt, template }
▼
Your proxy (serverless / edge function)
│ POST https://api.getspine.ai/v1/run
│ X-API-KEY: sk_spine_...
▼
Spine API
Set your API key
Add SPINE_API_KEY to your project’s environment / secrets:
Tool Where Bolt.new Project settings → Environment variables Replit Secrets tab (lock icon in sidebar) Lovable Project settings → Secrets
Create a key at platform.getspine.ai/keys .
Proxy setup
Bolt.new / Next.js
Create app/api/spine/run/route.ts:
const SPINE_API_KEY = process . env . SPINE_API_KEY ! ;
export async function POST ( req : Request ) {
const { prompt , template } = await req . json () ;
const form = new FormData () ;
form . set ( " prompt " , prompt ) ;
if ( template ) form . set ( " template " , template ) ;
const res = await fetch ( " https://api.getspine.ai/v1/run " , {
method : " POST " ,
headers : { " X-API-KEY " : SPINE_API_KEY } ,
body : form ,
}) ;
return new Response ( await res . text () , {
status : res . status ,
headers : { " Content-Type " : " application/json " } ,
}) ;
}
Replit
Create a simple Express endpoint or use Replit’s built-in HTTP handler:
app . post ( " /api/spine/run " , async ( req , res ) => {
const form = new FormData () ;
form . set ( " prompt " , req . body . prompt ) ;
if ( req . body . template ) form . set ( " template " , req . body . template ) ;
const r = await fetch ( " https://api.getspine.ai/v1/run " , {
method : " POST " ,
headers : { " X-API-KEY " : process . env . SPINE_API_KEY } ,
body : form ,
}) ;
res . status ( r . status ) . json ( await r . json ()) ;
}) ;
Lovable
Lovable uses Supabase Edge Functions. Create supabase/functions/spine-run/index.ts:
Deno . serve ( async ( req ) => {
const { prompt , template } = await req . json () ;
const form = new FormData () ;
form . set ( " prompt " , prompt ) ;
if ( template ) form . set ( " template " , template ) ;
const res = await fetch ( " https://api.getspine.ai/v1/run " , {
method : " POST " ,
headers : { " X-API-KEY " : Deno . env . get ( " SPINE_API_KEY " ) ! } ,
body : form ,
}) ;
return new Response ( await res . text () , {
status : res . status ,
headers : { " Content-Type " : " application/json " } ,
}) ;
}) ;
Browser-side calling pattern
Once your proxy is deployed, the browser code is the same regardless of tool:
// Create a run
const { data } = await fetch ( " /api/spine/run " , {
method : " POST " ,
headers : { " Content-Type " : " application/json " } ,
body : JSON . stringify ({
prompt : " Create a competitive analysis of AI search APIs " ,
template : " deep_research " ,
}) ,
}) . then (( r ) => r . json ()) ;
// Poll until complete
let run ;
do {
await new Promise (( r ) => setTimeout ( r , 30000 )) ;
run = await fetch ( ` /api/spine/run/ ${ data . run_id } ` ) . then (( r ) => r . json ()) ;
} while ( run . data . status === " running " ) ;
// Use the results
console . log ( run . data . result . final_output ) ;
run . data . result . artifacts . forEach (( a ) => {
console . log ( ` ${ a . name } : ${ a . download_url } ` ) ;
}) ;