5-minute walkthrough

Quickstart

Five minutes: grab an API key, install the SDK, ship your first routed call, then open the trace to see the routing decision. Every snippet below is production-shaped — copy it as-is.

Prerequisites

  • Node.js 18+, Python 3.9+, or any runtime that can do HTTPS
  • A SkyAIApp account (private-beta invite-only — see note below)
  • Five minutes and a cup of coffee
Private beta: self-serve signup isn't open yet. Request an invite via the design-partner page (1-business-day response from the founding team).
1

Get an API key

Sign into the SkyAIApp Console → Settings → API Keys → New key. Keys look like this:

# Live key — used by your production app
sk_live_01JEXAMPLE4F5G6H7J8K9LMNPQRSTUVWXYZabcdefghi

# Test key — sandbox-mode, never bills, returns canned model output
sk_test_01JEXAMPLE4F5G6H7J8K9LMNPQRSTUVWXYZabcdefghi

Do this

  • Store in env vars or a secret manager
  • Create one key per environment (dev / staging / prod)
  • Label each key in the console — easier audits
  • Front-end calls go through your own backend proxy — never ship the key to a browser

Don't do this

  • Commit keys to git (even private repos)
  • Hard-code into client bundles or mobile apps
  • DM keys via Slack / WeChat
  • Reuse the same key across test and prod
# Linux / macOS — add to ~/.zshrc or use direnv
export SKYAIAPP_API_KEY="sk_live_01JEXAMPLE..."

# Windows PowerShell — for the current session
$env:SKYAIAPP_API_KEY = "sk_live_01JEXAMPLE..."

# .env.local for Next.js / Node — never commit this file
SKYAIAPP_API_KEY=sk_live_01JEXAMPLE...
2

Install the SDK

TypeScript and Python SDKs are GA; Go is in beta; REST works for everything else.

GA

TypeScript / JavaScript

npm install @skyaiapp/sdk
# or
pnpm add @skyaiapp/sdk
# or
yarn add @skyaiapp/sdk

Works on Node ≥ 18, Bun ≥ 1.1, Deno ≥ 1.40. Vercel + Cloudflare Workers edge runtime supported out of the box.

GA

Python

pip install skyaiapp
# or
poetry add skyaiapp
# or
uv add skyaiapp

Python ≥ 3.9. Native async (built on httpx) plus a sync wrapper.

Beta

Go

go get github.com/skyaiapp/skyaiapp-go@latest

Go ≥ 1.21. The interface may shift slightly before GA.

ANY

REST / cURL

# Nothing to install — just call the API directly.
# Base URL: https://api.skyaiapp.com
# Auth: Authorization: Bearer $SKYAIAPP_API_KEY

Ruby / PHP / .NET / Rust users go straight to REST — see the SDKs section.

3

Make your first call

The three snippets below are equivalent — pick whichever language fits. Each one ships with proper error handling, timeouts, and trace inspection.

TypeScript
import { SkyAI, isRouterError, RouterTimeoutError } from "@skyaiapp/sdk";

// One client, reused across requests. The SDK handles connection pooling,
// retry budgets, and trace propagation under the hood.
const sky = new SkyAI({
  apiKey: process.env.SKYAIAPP_API_KEY!,
  // Optional: pin a routing policy version (created in console).
  // policyId: "policy_prod_v3",
  // Optional: override the base URL for self-hosted / staging.
  // baseURL: "https://api-staging.skyaiapp.com",
});

async function summarize(text: string) {
  try {
    const res = await sky.route({
      goal: "cost",                    // "cost" | "quality" | "stability"
      strategy: "balanced",            // "balanced" | "cost-optimized" | "quality-first"
      messages: [
        { role: "system", content: "You are a precise summarizer. Output 2 sentences." },
        { role: "user",   content: text },
      ],
      // Hard upper bound on per-request spend; router refuses pricier models.
      budget: { maxCostUsd: 0.01 },
      // Wall-clock timeout — surfaces as RouterTimeoutError.
      timeoutMs: 15_000,
      // Tag for analytics + per-tenant budgets in the console.
      metadata: { tenant: "acme-corp", workflow: "summary" },
    });

    return {
      summary:  res.output,
      model:    res.routing.selectedModel,    // e.g. "claude-haiku-4.5"
      cost:     res.routing.costUsd,          // e.g. 0.00021
      latency:  res.routing.latencyMs,        // e.g. 410
      cached:   res.routing.cacheHit,         // boolean
      traceId:  res.traceId,                  // open in console
    };
  } catch (err) {
    if (err instanceof RouterTimeoutError) {
      // Timeouts are recoverable — retry with a faster model or longer budget.
      return null;
    }
    if (isRouterError(err)) {
      // Structured router error — { code, message, retryAfterMs?, upstreamProvider? }
      console.error("Router error:", err.code, err.message);
    }
    throw err;
  }
}

const out = await summarize("…paste a 2-page doc here…");
console.log(out);
Python
import os
from skyaiapp import SkyAI, RouterError, RouterTimeoutError

sky = SkyAI(api_key=os.environ["SKYAIAPP_API_KEY"])

async def summarize(text: str) -> dict | None:
    try:
        res = await sky.route(
            goal="cost",                       # "cost" | "quality" | "stability"
            strategy="balanced",
            messages=[
                {"role": "system", "content": "You are a precise summarizer. Output 2 sentences."},
                {"role": "user",   "content": text},
            ],
            budget={"max_cost_usd": 0.01},
            timeout_ms=15_000,
            metadata={"tenant": "acme-corp", "workflow": "summary"},
        )
    except RouterTimeoutError:
        return None  # recoverable — retry with cheaper model or longer budget
    except RouterError as e:
        # Structured: e.code, e.message, e.retry_after_ms, e.upstream_provider
        print(f"Router error: {e.code} {e.message}")
        raise

    return {
        "summary":  res.output,
        "model":    res.routing.selected_model,
        "cost":     res.routing.cost_usd,
        "latency":  res.routing.latency_ms,
        "cached":   res.routing.cache_hit,
        "trace_id": res.trace_id,
    }
cURL
curl https://api.skyaiapp.com/v1/route \
  --max-time 15 \
  -H "Authorization: Bearer $SKYAIAPP_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-SkyAI-Metadata: tenant=acme-corp;workflow=summary" \
  -d '{
    "goal": "cost",
    "strategy": "balanced",
    "messages": [
      { "role": "system", "content": "You are a precise summarizer. Output 2 sentences." },
      { "role": "user",   "content": "…paste a 2-page doc here…" }
    ],
    "budget":  { "max_cost_usd": 0.01 },
    "timeout_ms": 15000
  }'
4

Inspect the response and trace

Every response includes a trace_id. Search it in the console to see the full decision tree — candidates considered, policy hits, cache lookups, fallbacks.

{
  "output": "The document argues that ... [2 sentences].",
  "trace_id": "tr_01JFGYZ7K8M2N3P4Q5R6S7T8U9",
  "routing": {
    "selected_model":  "claude-haiku-4.5",
    "fallback_chain":  ["gpt-5.5-mini", "deepseek-v4-pro"],
    "cost_usd":        0.00021,
    "latency_ms":      410,
    "cache_hit":       false,
    "policy_version":  "policy_prod_v3@2026-05-12",
    "tokens": {
      "input":  1842,
      "output": 64,
      "cached": 0
    },
    "decision_reason": "balanced + cost goal: claude-haiku-4.5 wins on $/quality vs alternatives in this price band."
  },
  "usage": { "rate_limit_remaining": 4998 }
}

🎮 Try it in the browser

Adjust goal and strategy and watch the routing decision update. Output is a simulated decision flow during private beta — real production traces ship at public beta.

Interactive API playground

Click to see routing in action

Response

Click 'Run' to see the result
Equivalent Code
import { SkyAI } from "@skyaiapp/sdk";

const sky = new SkyAI({
  apiKey: process.env.SKYAIAPP_API_KEY
});

const response = await sky.route({
  goal: "cost",
  strategy: "balanced",
  messages: [
    { role: "user", content: "Explain quantum computing in simple terms" }
  ]
});

Before you ship to production

Move keys into a secret manager

Vault / AWS SSM / 1Password CLI / Doppler all work. Never hard-code or commit.

Security guide
Separate keys and policies per environment

One key per environment, bound to different policy versions in the console.

Team management
Tag every request with metadata

At minimum: tenant and workflow. Lets you slice traces and billing in the console.

Observability
Configure fallbacks on critical paths

User-facing paths need ≥ 2 fallback tiers; batch jobs can be more aggressive on cost.

Routing strategies
Mock the SDK in CI — don't hit the real API

Use sk_test_ keys to hit the sandbox, or wire up the SDK's mock client for unit tests.

Testing & mocking
Subscribe to Webhook events for incidents

Pipe router.fallback_triggered, router.budget_exceeded, etc. into Slack / PagerDuty.

Webhooks

Stuck?

Send us the trace_id — the founding team replies within one business day and digs to root cause.

Was this page helpful?

Let us know how we can improve

Quickstart | SkyAIApp Docs — SkyAIApp