Deploy a New App (Management API)
End-to-end example: create a project, provision a database, connect them, and trigger a deploy — all via the Management API using your slx_cli_* token.
deploy.sh
#!/bin/bash
# Full deploy flow using the Sylphx Management API
BASE="https://sylphx.com/api/v1"
AUTH="Authorization: Bearer slx_cli_YOUR_TOKEN_HERE"
# ── Step 1: Create the project ────────────────────────────
PROJECT=$(curl -s -X POST \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{
"name": "My App",
"slug": "my-app",
"gitRepository": "shtse8/my-repo",
"gitBranch": "main",
"port": 3000,
"domain": "my-app.sylphx.app"
}' "$BASE/projects")
PROJECT_ID=$(echo "$PROJECT" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "✅ Project created: $PROJECT_ID"
# ── Step 2: Provision a PostgreSQL database ───────────────
DB=$(curl -s -X POST \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{"name": "My App DB", "kind": "database", "provider": "postgresql", "config": {"env": "production", "storageGb": 10}}' \
"$BASE/resources")
DB_ID=$(echo "$DB" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "⏳ Database provisioning: $DB_ID"
# ── Step 3: Wait for the database to be ready ─────────────
while true; do
STATUS=$(curl -s -H "$AUTH" "$BASE/resources/$DB_ID" | python3 -c "import sys,json; print(json.load(sys.stdin)['reconcileStatus'])")
echo " DB status: $STATUS"
[ "$STATUS" = "synced" ] && break
sleep 10
done
CONN=$(curl -s -H "$AUTH" "$BASE/resources/$DB_ID" | python3 -c "import sys,json; print(json.load(sys.stdin)['connectionString'])")
echo "✅ Database ready"
# ── Step 4: Set DATABASE_URL as an env var ────────────────
curl -s -X POST \
-H "$AUTH" -H "Content-Type: application/json" \
-d "{
\"envType\": \"production\",
\"vars\": [{ \"key\": \"DATABASE_URL\", \"value\": \"$CONN\", \"secret\": true }]
}" "$BASE/projects/$PROJECT_ID/env-vars"
echo "✅ Env var set"
# ── Step 5: Deploy ────────────────────────────────────────
DEPLOY=$(curl -s -X POST \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{"envType": "production"}' \
"$BASE/projects/$PROJECT_ID/deploy")
echo "🚀 Deploying: $(echo $DEPLOY | python3 -c "import sys,json; print(json.load(sys.stdin)['deploymentId'])")"
echo " Live at: https://my-app.sylphx.app"AI API — OpenAI-Compatible (Management API Token)
Your slx_cli_* token works directly as an OpenAI-compatible API key. Just point any OpenAI client at Sylphx:
Python
from openai import OpenAI
client = OpenAI(
base_url="https://sylphx.com/api/v1",
api_key="slx_cli_YOUR_TOKEN_HERE"
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello from Sylphx!"}]
)
print(response.choices[0].message.content)TypeScript
import OpenAI from 'openai'
const client = new OpenAI({
baseURL: 'https://sylphx.com/api/v1',
apiKey: process.env.SYLPHX_CLI_TOKEN,
})
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Hello from Sylphx!' }],
})
console.log(response.choices[0].message.content)Next.js Full-Stack App
A complete example showing authentication, protected routes, and billing integration:
app/layout.tsx
import { SylphxProvider } from '@sylphx/sdk/react'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<SylphxProvider appId={process.env.NEXT_PUBLIC_SYLPHX_APP_ID ?? ""}>
{children}
</SylphxProvider>
</body>
</html>
)
}app/dashboard/page.tsx
import { auth, currentUser } from '@sylphx/sdk/nextjs'
import { redirect } from 'next/navigation'
export default async function DashboardPage() {
const user = await currentUser()
if (!user) {
redirect('/login')
}
return (
<div>
<h1>Welcome, {user.name}!</h1>
<p>Email: {user.email}</p>
</div>
)
}components/user-menu.tsx
'use client'
import { useUser, useAuth } from '@sylphx/sdk/react'
export function UserMenu() {
const { user, isLoading } = useUser()
const { signOut } = useAuth()
if (isLoading) return <div>Loading...</div>
if (!user) return <a href="/login">Sign In</a>
return (
<div>
<span>{user.name}</span>
<button onClick={() => signOut()}>Sign Out</button>
</div>
)
}Subscription Gating
Check subscription status to gate premium features:
Server Component
import { platform } from '@/lib/platform'
import { currentUser } from '@sylphx/sdk/nextjs'
export default async function PremiumFeature() {
const user = await currentUser()
if (!user) {
return <div>Please sign in to access this feature.</div>
}
const subscription = await platform.billing.getSubscription(user.id)
if (subscription?.status !== 'active') {
return (
<div>
<p>This is a premium feature.</p>
<a href="/pricing">Upgrade to Pro</a>
</div>
)
}
return <div>Premium content here!</div>
}Client Component
'use client'
import { useUser, useBilling } from '@sylphx/sdk/react'
export function PremiumContent() {
const { user } = useUser()
const { subscription, isLoading } = useBilling()
if (isLoading) return <div>Loading...</div>
if (!subscription || subscription.status !== 'active') {
return <button onClick={() => window.location.href = '/pricing'}>
Upgrade to Pro
</button>
}
return <div>Premium content!</div>
}Event Tracking
Track user behavior and custom events:
Track button clicks
'use client'
import { useAnalytics } from '@sylphx/sdk/react'
export function CTAButton() {
const { track } = useAnalytics()
const handleClick = () => {
track('cta_clicked', {
location: 'hero',
variant: 'primary',
})
// Continue with action...
}
return <button onClick={handleClick}>Get Started</button>
}Track purchases (server)
import { platform } from '@/lib/platform'
export async function completePurchase(userId: string, orderId: string, amount: number) {
// Process order...
// Track the event
await platform.analytics.track({
userId,
event: 'purchase_completed',
properties: {
orderId,
amount,
currency: 'USD',
},
})
}AI Chat Integration
Build an AI-powered chat feature:
app/api/chat/route.ts
import { platform } from '@/lib/platform'
import { currentUser } from '@sylphx/sdk/nextjs'
import { NextRequest } from 'next/server'
export async function POST(req: NextRequest) {
const user = await currentUser()
if (!user) {
return new Response('Unauthorized', { status: 401 })
}
const { messages } = await req.json()
const response = await platform.ai.chat({
model: 'gpt-4',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
...messages,
],
})
return Response.json({ message: response.message.content })
}components/chat.tsx
'use client'
import { useState } from 'react'
export function Chat() {
const [messages, setMessages] = useState<Array<{ role: string; content: string }>>([])
const [input, setInput] = useState('')
const sendMessage = async () => {
const userMessage = { role: 'user', content: input }
setMessages(prev => [...prev, userMessage])
setInput('')
const res = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ messages: [...messages, userMessage] }),
})
const { message } = await res.json()
setMessages(prev => [...prev, { role: 'assistant', content: message }])
}
return (
<div>
<div>
{messages.map((m, i) => (
<div key={i} className={m.role === 'user' ? 'text-right' : ''}>
{m.content}
</div>
))}
</div>
<input value={input} onChange={e => setInput(e.target.value)} />
<button onClick={sendMessage}>Send</button>
</div>
)
}File Upload
Upload files with the storage API:
components/avatar-upload.tsx
'use client'
import { useStorage } from '@sylphx/sdk/react'
import { useState } from 'react'
export function AvatarUpload() {
const { upload } = useStorage()
const [uploading, setUploading] = useState(false)
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0]
if (!file) return
setUploading(true)
try {
const result = await upload(file, {
path: 'avatars',
public: true,
})
console.log('Uploaded:', result.url)
} catch (error) {
console.error('Upload failed:', error)
} finally {
setUploading(false)
}
}
return (
<div>
<input type="file" accept="image/*" onChange={handleFileChange} disabled={uploading} />
{uploading && <span>Uploading...</span>}
</div>
)
}