โšก Quick Start

Alpaca Cloud is an open-source backend platform โ€” your own Supabase, on your own infrastructure. Get a full Postgres database, REST API, auth, storage, edge functions, and realtime in seconds.

1. Create an account

Sign up at app.alpaca-cloud.com.

2. Choose your project type

  • Backend โ€” Postgres database with Auth, Storage, Edge Functions, Realtime. Choose Shared (instant) or Dedicated VM.
  • Frontend โ€” Static site / SPA hosting. Connect GitHub, deploy on every push.
  • Apps โ€” Persistent Docker containers. Any language, any framework.

3. Get your credentials (Backend projects)

Open your project โ†’ Easy Connect:

  • Project URL โ€” e.g. https://my-project.alpaca-cloud.com
  • Anon key โ€” safe for frontend code
  • Service role key โ€” admin access, server-side only

4. Query your database

npm install @alpacacloud/js

import { createClient } from '@alpacacloud/js'

const alp = createClient(
  'https://my-project.alpaca-cloud.com',
  'your-anon-key'
)

const { data, error } = await alp
  .from('posts')
  .select('id, title, author')
  .eq('published', true)
  .order('created_at', { ascending: false })
  .limit(10)

๐Ÿ—‚๏ธ Project Types

Alpaca Cloud has three distinct project types, each for a different workload:

๐Ÿ—„๏ธ Backend โ€” Shared Cluster

Instant provisioning. Your Postgres database runs on a shared, managed cluster. Best for development, small apps, and getting started quickly.

  • Ready in seconds โ€” no VM to spin up
  • Full Postgres 16, PostgREST REST API, Auth, Storage, Edge Functions, Realtime
  • Subdomain: yourproject.alpaca-cloud.com
  • Starts free; upgrade for more storage and connections
// Create via API
POST /projects
{ "name": "my-app", "backend_type": "shared" }

๐Ÿ–ฅ๏ธ Backend โ€” Dedicated VM

Your own Hetzner cloud server. Complete isolation โ€” no shared resources, no noisy neighbours. Best for production workloads requiring guaranteed performance or data residency.

  • Takes 3โ€“8 minutes to provision (spins up a real VM)
  • Full Postgres on your own server with root-level access available
  • Same services: Auth, Storage, Edge Functions, Realtime
  • Choose your server size (cpx11 โ†’ cpx41)
  • Higher cost โ€” you pay for the VM
POST /projects
{ "name": "prod-db", "backend_type": "dedicated", "plan": "pro" }

๐ŸŒ Frontend Hosting

Static site and SPA hosting with GitHub auto-deploy. Like Vercel or Netlify, on Alpaca Cloud infrastructure.

  • Connect a GitHub repo โ†’ deploys automatically on every push
  • Works with React, Vue, Next.js (static export), Svelte, Astro, plain HTML
  • Subdomain: yoursite.alpaca-cloud.com
  • Auto-SSL, instant global delivery
POST /projects
{ "name": "my-site", "backend_type": "frontend" }

๐Ÿš€ App Hosting (Docker containers)

Persistent Docker containers for any language or framework. Like Fly.io, on Alpaca Cloud infrastructure.

  • Add a Dockerfile to your project โ€” any language works
  • Your app must read process.env.PORT โ€” Alpaca assigns the port
  • Subdomain: yourapp.alpaca-cloud.com
  • Auto-SSL, live logs, env vars, health checks
  • Shared compute tier: 0.5 vCPU, 512MB RAM
POST /projects
{ "name": "my-api", "backend_type": "app" }

๐Ÿ”‘ Authentication

All Management API requests require a Bearer token. Project API keys (anon/service_role) are separate โ€” used to access the PostgREST database REST API directly.

User JWT (session token)

POST https://app.alpaca-cloud.com/auth/login
Content-Type: application/json

{ "email": "you@example.com", "password": "yourpassword" }

โ†’ { "token": "eyJ...", "user": { ... } }
Authorization: Bearer eyJ...

Personal Access Token (PAT)

Go to Dashboard โ†’ Settings โ†’ API Tokens โ†’ create a token. PATs don't expire โ€” good for CI/CD and scripts.

Authorization: Bearer pat_...

Project API Keys (anon / service_role)

Each backend project has two keys for accessing its PostgREST API:

  • anon key โ€” respects Row Level Security. Safe for frontend.
  • service_role key โ€” bypasses RLS. Server-side only โ€” never expose to clients.

๐Ÿ“ฆ JavaScript SDK

npm install @alpacacloud/js

Initialize

import { createClient } from '@alpacacloud/js'
const alp = createClient('https://your-project.alpaca-cloud.com', 'your-anon-key')

Database

const { data } = await alp.from('users').select('*').eq('active', true)
await alp.from('posts').insert({ title: 'Hello', body: '...' })
await alp.from('posts').update({ published: true }).eq('id', 42)
await alp.from('posts').delete().eq('id', 42)
// Filters: eq, neq, gt, gte, lt, lte, like, ilike, in, is, not

Auth

const { user } = await alp.auth.signUp({ email, password })
const { user, token } = await alp.auth.signIn({ email, password })
await alp.auth.signOut()
const user = alp.auth.user()

Storage

await alp.storage.from('avatars').upload('user.png', file, { contentType: 'image/png' })
const url = alp.storage.from('avatars').getPublicUrl('user.png')
const { data } = await alp.storage.from('avatars').download('user.png')

Realtime

const channel = alp.realtime.channel('room:chat')
  .on('broadcast', { event: 'message' }, ({ payload }) => console.log(payload))
  .subscribe()
channel.send({ type: 'broadcast', event: 'message', payload: { text: 'hello' } })

Edge Functions

const { data } = await alp.functions.invoke('my-function', { body: { name: 'world' } })

Python SDK

pip install alpaca-cloud
from alpaca_cloud import create_client
alp = create_client("https://your-project.alpaca-cloud.com", "your-anon-key")
response = alp.table('posts').select('id, title').eq('published', True).execute()

Flutter SDK

flutter pub add alpaca_cloud_flutter
import 'package:alpaca_cloud_flutter/alpaca_cloud.dart';
AlpacaCloud.initialize(url: 'https://your-project.alpaca-cloud.com', anonKey: 'your-anon-key');
final data = await AlpacaCloud.instance.client.from('posts').select('id, title').eq('published', true);

๐ŸŒ Frontend Hosting

Deploy static sites and single-page apps (SPAs) with GitHub auto-deploy. Every push to your main branch goes live automatically.

Supported Frameworks

  • React โ€” build command: npm run build, output: dist/
  • Vue โ€” build command: npm run build, output: dist/
  • Next.js โ€” static export only (next export), output: out/
  • Svelte / SvelteKit โ€” adapter-static, output: build/
  • Astro โ€” output: dist/
  • Plain HTML / Vanilla JS โ€” no build step needed

Setup

  1. Create a Frontend project in the dashboard (Frontend tab โ†’ New Project)
  2. Connect your GitHub repo via the Integrations tab
  3. Set your build command (e.g. npm run build) and output directory (e.g. dist)
  4. Every push to your production branch triggers an automatic build and deploy

Build Flow

git push origin main
  โ†’ Alpaca clones your repo
  โ†’ runs install_command (e.g. npm install)
  โ†’ runs build_command (e.g. npm run build)
  โ†’ deploys output_dir (e.g. dist/) to static hosting
  โ†’ live at yoursite.alpaca-cloud.com

Manual Deploy (via API)

POST /projects/:id/frontend/deploy
Content-Type: application/json
{ "branch": "main" }

Custom Domains

Your site is always available at yoursite.alpaca-cloud.com. Custom domain support is on the roadmap.

๐Ÿš€ App Hosting (Docker containers)

Run any Dockerized application as a persistent container with a public HTTPS URL. Node.js, Python, Go, Ruby, anything โ€” if it has a Dockerfile, it deploys.

Requirements

  • A Dockerfile in your project root
  • Your app must listen on the port from process.env.PORT (Alpaca assigns this โ€” do not hardcode a port)

Quick Start

  1. Create an App project in the dashboard (Apps tab โ†’ New App)
  2. Open the project โ†’ click Deploy
  3. Your app is live at yourapp.alpaca-cloud.com

Dockerfile Example

FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 8080
CMD ["node", "server.js"]
// Your server must read PORT from the environment:
const port = process.env.PORT || 8080;
app.listen(port);

Environment Variables

Set env vars in the project dashboard โ†’ Settings tab. They're injected at container start.

Resource Limits (Shared Tier)

  • CPU: 0.5 vCPU
  • Memory: 512 MB RAM
  • Public URL: yourapp.alpaca-cloud.com
  • Auto-SSL, live logs, health checks included

๐Ÿ”„ GitHub Auto-Deploy

Both Frontend and App Hosting projects support GitHub auto-deploy โ€” connect your repo once and every push triggers a deploy.

Setup

  1. Connect your GitHub account: Dashboard โ†’ Integrations tab โ†’ GitHub
  2. Open your project โ†’ Overview โ†’ GitHub tab
  3. Enter your repository URL and production branch
  4. Click Connect & enable auto-deploy

App Hosting Webhook URL (manual)

https://api.alpaca-cloud.com/projects/YOUR_PROJECT_ID/compute/github-webhook
Events: push, ping | Content-Type: application/json

Deploy Flow (App Hosting)

git push origin main
  โ†’ GitHub webhook fires
  โ†’ Alpaca pulls latest code on compute VM
  โ†’ docker build (fresh image)
  โ†’ docker run --restart unless-stopped
  โ†’ nginx updated โ†’ app is live

๐Ÿ“ก Realtime

Subscribe to live database changes and broadcast messages to connected clients via WebSocket. Powered by Postgres logical replication โ€” no polling required.

Use cases

  • Live dashboards and analytics
  • Collaborative editing (multiple users, one document)
  • Chat and messaging
  • Presence (who is online right now)
  • Real-time notifications

JavaScript SDK

import { createClient } from '@alpacacloud/js'
const alp = createClient(url, anonKey)

// Subscribe to broadcast messages
const channel = alp.realtime.channel('room:chat')
  .on('broadcast', { event: 'message' }, ({ payload }) => {
    console.log('New message:', payload)
  })
  .subscribe()

// Send a message
channel.send({ type: 'broadcast', event: 'message', payload: { text: 'hello' } })

// Presence โ€” see who is online
channel.on('presence', { event: 'join' }, ({ newPresences }) => {
  console.log('joined:', newPresences)
})

WebSocket endpoint

wss://your-project.alpaca-cloud.com/realtime/v1/websocket?apikey=YOUR_ANON_KEY

โšก Edge Functions

Serverless functions that run alongside your database on your project. Write server-side logic, webhooks, scheduled tasks, and APIs โ€” deployed in seconds from the dashboard or CLI.

Runtime

  • Deno runtime โ€” TypeScript and JavaScript natively
  • NPM-compatible (npm: specifiers)
  • Secrets injected via environment variables (set in dashboard โ†’ Vault)

Write a function

// functions/hello/index.ts
Deno.serve(async (req) => {
  const { name } = await req.json()
  return Response.json({ hello: name })
})

Deploy from dashboard

Dashboard โ†’ your project โ†’ Edge Functions tab โ†’ paste code โ†’ Deploy.

Invoke via SDK

const { data, error } = await alp.functions.invoke('hello', {
  body: { name: 'world' }
})
// โ†’ { hello: 'world' }

Invoke via HTTP

POST https://your-project.alpaca-cloud.com/functions/v1/hello
Authorization: Bearer <anon-key>
Content-Type: application/json

{ "name": "world" }

Secrets / Environment Variables

Add secrets in Dashboard โ†’ Vault tab. Access them in functions with Deno.env.get('KEY').

๐Ÿ”Œ Plugin Marketplace

One-click integrations with popular services. Install a plugin on a project and it injects the API keys / config as environment variables โ€” available in your edge functions and server-side code.

Available Plugins

  • Resend โ€” transactional email API
  • Stripe โ€” payments and subscriptions
  • OpenAI โ€” GPT, embeddings, and vision APIs
  • Upstash Redis โ€” serverless Redis (rate limiting, caching, queues)
  • Cloudflare Turnstile โ€” bot detection and CAPTCHA
  • Loops โ€” marketing email automation
  • Sentry โ€” error monitoring and alerting
  • Trigger.dev โ€” background jobs and workflows

Installing a plugin

  1. Open your project โ†’ Plugins tab
  2. Browse the marketplace and click Install
  3. Enter your API key for the service
  4. The key is stored in your project Vault and injected into edge functions automatically

Developer OAuth โ€” build your own plugin

Third-party developers can build Alpaca Cloud plugins using OAuth:

  1. Register your app at Dashboard โ†’ Developers tab
  2. Get a client_id and client_secret
  3. Users authorize your app via a consent screen at /plugins/authorize
  4. Exchange the code for a token and use the Plugin API to manage env vars and keys

๐Ÿค– MCP / AI Connect

Every Alpaca Cloud backend project includes a built-in MCP (Model Context Protocol) server โ€” letting AI assistants like Claude, Cursor, or any MCP-compatible tool interact with your database directly.

What the MCP server can do

  • Run SQL queries against your database
  • List tables and get schema information
  • List, create, and delete auth users
  • Get project info (URL, keys, status)

Claude Desktop config

// Get the config from your project โ†’ Easy Connect โ†’ MCP tab
// It will look like:
{
  "mcpServers": {
    "my-project": {
      "command": "npx",
      "args": ["-y", "@alpacacloud/mcp"],
      "env": {
        "ALPACA_PROJECT_URL": "https://my-project.alpaca-cloud.com",
        "ALPACA_SERVICE_KEY": "your-service-role-key"
      }
    }
  }
}

Easy Connect (any AI assistant)

Dashboard โ†’ your project โ†’ Easy Connect tab. Copy the prompt โ€” it includes your project URL, keys, and a description of your schema. Paste it into any AI assistant's system prompt and it can query, insert, and manage your database immediately.

MCP endpoint

GET  /projects/:id/mcp   โ†’ returns endpoint info and Claude config
POST /projects/:id/mcp   โ†’ JSON-RPC 2.0 endpoint
     Tools: run_sql, list_tables, get_table_schema,
            list_auth_users, create_auth_user, delete_auth_user,
            get_project_info

API Reference

Manage AlpacaBase projects, databases, auth, storage, and edge functions. Authenticate with: Authorization: Bearer <token> Get a token: POST /auth/login โ†’ use the token โ†’ or POST /tokens to create a PAT. Quick start: 1. POST /auth/login to get a token 2. POST /projects to create a project (backend_type: shared = instant) 3. Poll GET /projects/:id/status until status is healthy 4. Use postgrest_url from the project for your database REST API

Base URL: https://app.alpaca-cloud.com  ยท  Version: 1.4.0

Download OpenAPI JSON โ†—

System

GET/healthHealth check
Responses
StatusDescription
200{ok:true}
GET/openapi.jsonThis OpenAPI spec
Responses
StatusDescription
200OpenAPI 3.0 JSON

Auth

POST/auth/registerCreate account
Request Body application/json
FieldTypeRequiredDescription
emailstringโœ“
passwordstringโœ“
full_namestring
Responses
StatusDescription
201User created + JWT token
POST/auth/loginLogin and get JWT
Request Body application/json
FieldTypeRequiredDescription
emailstringโœ“
passwordstringโœ“
Responses
StatusDescription
200{token:...,user:{...}}
GET/auth/meGet current user
Responses
StatusDescription
200User profile
GET/tokensList personal access tokens
Responses
StatusDescription
200Token list
POST/tokensCreate a PAT
Request Body application/json
FieldTypeRequiredDescription
namestring
scopesarray
Responses
StatusDescription
201New PAT (shown once)

Projects

GET/projectsList your projects
Responses
StatusDescription
200Array of project objects
POST/projectsCreate a project

Creates a new AlpacaBase project.

  • backend_type=shared: provisioned in ~2 seconds on shared cluster
  • backend_type=dedicated: private Hetzner VM, takes 3-6 minutes. Poll /projects/:id/status.
  • backend_type=frontend: static site hosting, no database
  • Valid regions: eu-central, eu-west, eu-north, us-east, us-west, ap-south

    Valid plans: free, starter, pro, team, enterprise

    Request Body application/json
    FieldTypeRequiredDescription
    namestringโœ“3-30 chars, lowercase letters, numbers, hyphens only
    regionstring (eu-central, eu-west, eu-north, us-east, us-west, ap-south) default: eu-central
    planstring (free, starter, pro, team, enterprise) default: free
    backend_typestring (shared, dedicated, frontend)shared=instant; dedicated=private VM 3-6 min; frontend=static site default: shared
    Responses
    StatusDescription
    201Project object. If dedicated, poll /projects/:id/status until status=healthy
    GET/projects/{id}Get project details
    Responses
    StatusDescription
    200Full project object with db_url, api keys, etc.
    PATCH/projects/{id}Update project settings

    Update: repo_url, build_command, output_dir, install_command, production_branch, env_vars, email_notifications, slack_webhook, forms_enabled, webhook_secret

    Request Body application/json
    FieldTypeRequiredDescription
    repo_urlstring
    build_commandstring default: npm run build
    output_dirstring default: dist
    install_commandstring default: npm install
    production_branchstring default: main
    env_varsEnvironment variables as {KEY: value} object (preferred) or [{key, value}] array. Both are accepted.
    email_notificationsboolean
    slack_webhookstring
    forms_enabledboolean
    github_tokenstringGitHub Personal Access Token (PAT) with `repo` scope. Required to deploy private repositories. Stored encrypted. Set to null to remove. Never returned in API responses โ€” only `has_github_token: true/false` is exposed.
    Responses
    StatusDescription
    200Updated fields
    400No updatable fields or invalid request
    DELETE/projects/{id}Delete project and all resources
    Responses
    StatusDescription
    200{ok:true}
    GET/projects/{id}/statusPoll provisioning status + service health

    Returns status (provisioning|healthy|error) and per-service health.

    For dedicated projects, probes each service and returns:

  • services.database (PostgREST)
  • services.auth (alpacabase-auth)
  • services.storage (alpacabase-storage)
  • services.realtime
  • For shared projects, returns availability flags (storage: not available on shared).

    For frontend, returns hosting status only.

    Responses
    StatusDescription
    200{ status, services: { auth: { up, status, endpoint }, ... } }
    POST/projects/{id}/reprovisionRetry provisioning (dedicated, errored only)

    Re-creates the VM for a dedicated project that failed provisioning. Only works if no VM exists yet. For live projects, use /services/:service/restart instead.

    Responses
    StatusDescription
    200{ ok: true, server_type, location }
    400Already has a running server, or not a dedicated project

    Database

    POST/projects/{id}/queryExecute raw SQL
    Request Body application/json
    FieldTypeRequiredDescription
    sqlstringโœ“
    Responses
    StatusDescription
    200Query results

    MCP

    GET/projects/{id}/mcpMCP server info

    Get Model Context Protocol endpoint info and Claude Desktop config for this project.

    Parameters
    NameInTypeRequiredDescription
    idpathintegerโœ“Project ID
    Responses
    StatusDescription
    200MCP endpoint details and Claude config
    POST/projects/{id}/mcpMCP JSON-RPC endpoint

    Model Context Protocol endpoint. Send JSON-RPC 2.0 messages. Auth: apikey header (service_role key). Tools: run_sql, list_tables, get_table_schema, list_auth_users, create_auth_user, delete_auth_user, get_project_info.

    Parameters
    NameInTypeRequiredDescription
    idpathintegerโœ“
    Request Body application/json
    FieldTypeRequiredDescription
    jsonrpcstringโœ“
    idinteger
    methodstring (initialize, tools/list, tools/call, ping)โœ“
    paramsobject
    Responses
    StatusDescription
    200JSON-RPC response

    Frontend Hosting

    POST/projects/{id}/deployTrigger a frontend build/deploy

    Triggers a build and deploy for a frontend project.

    Repository access:

  • Public repos: work out of the box โ€” just set repo_url via PATCH /projects/:id
  • Private repos: require a github_token (GitHub PAT with repo scope) set via PATCH /projects/:id. Without it, the clone step will fail with a 128 exit code (auth error). Set it once and it persists across deploys.
  • Two ways to call:

    1. Authenticated: Authorization: Bearer <token> header

    2. GitHub webhook: POST /projects/:id/deploy?token=<webhook_secret> โ€” configure this URL in your GitHub repo Settings โ†’ Webhooks โ†’ Payload URL

    Get your webhook_secret and webhook_url from GET /projects/:id.

    Build flow: clone โ†’ install (install_command) โ†’ build (build_command) โ†’ deploy output_dir to static hosting.

    Track progress: Poll GET /projects/:id/status โ€” provision_message shows current step (Cloning, Installing, Building, Deployed).

    Parameters
    NameInTypeRequiredDescription
    tokenquerystringWebhook secret for unauthenticated GitHub webhook calls
    Responses
    StatusDescription
    200{ ok: true, message: "Build triggered" }
    400Not a frontend project or no repo_url set
    401Unauthorized
    GET/projects/{id}/build-logsGet full build log for a frontend project

    Returns the full stderr/stdout from the last failed build. The provision_message field on the project is limited to 500 chars; this endpoint returns the complete output.

    For successful builds, has_logs will be false (logs are cleared on success).

    Poll this endpoint after triggering a deploy to see live build progress.

    Responses
    StatusDescription
    200{ has_logs: bool, raw: string, sections: [{section, content}] }
    404Project not found
    POST/projects/{id}/deploy-keyGenerate an SSH deploy key for private repos (alternative to github_token)

    Generates an SSH key pair for this project. Returns the public key to add to your GitHub repo under Settings โ†’ Deploy Keys. The private key is stored server-side and used automatically during clones.

    Use this as an alternative to github_token when you prefer not to store a PAT. Only one deploy key is active per project at a time.

    Responses
    StatusDescription
    200{ public_key: "ssh-ed25519 AAAA...", fingerprint: "SHA256:...", note: "Add this public key to your repo deploy keys" }
    400Not a frontend project

    Discovery

    GET/regionsList valid region IDs

    Valid values: eu-central, eu-west, eu-north, us-east, us-west, ap-south

    Responses
    StatusDescription
    200Region list with names and datacenter locations
    GET/plansList plans with pricing and server specs
    Responses
    StatusDescription
    200Plan list
    GET/backend-typesList backend types with provisioning times

    shared=instant, dedicated=3-6min VM, frontend=static hosting

    Responses
    StatusDescription
    200Backend type descriptions

    Functions

    GET/projects/{id}/functionsList edge functions
    POST/projects/{id}/functionsCreate edge function
    Request Body application/json
    FieldTypeRequiredDescription
    namestringโœ“
    codestringโœ“JavaScript/TypeScript function code
    POST/projects/{id}/functions/{funcId}/deployDeploy an edge function
    Responses
    StatusDescription
    200Deployment status

    Services

    GET/projects/{id}/servicesList service statuses (dedicated only)

    Returns systemd status for all services on a dedicated project VM: auth, postgrest, storage, realtime, nginx, postgres, pgbouncer.

    Responses
    StatusDescription
    200{ services: { auth: { status, unit }, ... } }
    POST/projects/{id}/services/{service}/restartRestart a service on the VM (dedicated only)

    Restarts a named systemd service on the project VM via SSH.

    Use this when a service returns 502 (e.g. auth, storage). Valid services: auth, postgrest, storage, realtime, nginx.

    Dedicated projects only.

    Responses
    StatusDescription
    200{ ok: true, service, systemd_unit, status }
    400Invalid service name or not a dedicated project
    500SSH failed or restart failed