TypeScript SDK
Install
Section titled “Install”npm install @runplex/sylonew SyloClient(options)
Section titled “new SyloClient(options)”import { SyloClient, credential } from "@runplex/sylo";
const sylo = new SyloClient({ apiUrl: "https://sylo.runplex.dev", developerSecret: process.env.SYLO_SECRET, gatewayHost: "sylo.runplex.dev:8443", // optional, derived from apiUrl});| Option | Type | Required | Description |
|---|---|---|---|
apiUrl | string | Yes | Platform API URL |
developerSecret | string | Yes | Developer secret (sylo_sk_...) |
gatewayHost | string | No | Gateway tunnel host (default: {apiUrl hostname}:8443) |
fetch | typeof fetch | No | Custom fetch implementation |
createSandboxToken(request)
Section titled “createSandboxToken(request)”Create a session with credentials, policies, and configuration.
const session = await sylo.createSandboxToken({ tenantId: "acme", userId: "user_123", expiresIn: "10m", credentials: [ credential("openai", process.env.OPENAI_API_KEY!), credential("github", process.env.GITHUB_TOKEN!), ], // mitm is auto-inferred from credential domains passthrough: ["your-api.com"], policies: { default: "deny", // credentialed domains are implicitly allowed rateLimit: { "api.openai.com": "20/min" }, }, pii: { action: "redact", patterns: ["ssn", "credit_card"] }, limits: { maxRequests: 1000, maxDuration: "30m" },});// Returns: { token: "sylo_stk_...", expiresAt: "2026-...", credentials: [...] }credential() helper
Section titled “credential() helper”One-liner for built-in services — handles domain, header, prefix, and env var:
import { credential } from "@runplex/sylo";
credential("openai", process.env.OPENAI_API_KEY!)// → { name: "openai", domain: "api.openai.com", header: "Authorization", value: "Bearer sk-...", envVar: "OPENAI_API_KEY" }Built-in services (12): anthropic, openai, github, stripe, linear, slack, huggingface, cohere, replicate, groq, mistral, fireworks.
Override name or env var:
credential("github", token, { name: "github-read", envVar: "GITHUB_READ" })For custom APIs, use the full config:
{ name: "custom", domain: "api.example.com", header: "Authorization", value: "Bearer ..." }How credentials and policies work together
Section titled “How credentials and policies work together”- Credentials implicitly allow their domain — with
default: "deny", you don’t need explicit allow rules for credentialed domains - MITM is auto-inferred — domains from credentials and policy rules are automatically intercepted
- Policy rules restrict — limit methods, paths, or add rate limits on allowed domains
- Default policy — only applies to domains with no credential
sandboxEnv(session)
Section titled “sandboxEnv(session)”Get environment variables for tunnel mode:
const env = sylo.sandboxEnv(session);// {// SYLO_TOKEN: "sylo_stk_...",// SYLO_GATEWAY: "sylo.runplex.dev:8443",// SYLO_GATEWAY_API: "https://sylo.runplex.dev",// NODE_EXTRA_CA_CERTS: "/etc/sylo/ca.crt",// SSL_CERT_FILE: "/etc/sylo/ca.crt",// REQUESTS_CA_BUNDLE: "/etc/sylo/ca.crt",// OPENAI_API_KEY: "sylo_cred:openai", // from credentials[].envVar// }proxyEnv(session)
Section titled “proxyEnv(session)”Get environment variables for proxy mode:
const env = sylo.proxyEnv(session);// {// HTTPS_PROXY: "https://sylo_stk_...:x@sylo.runplex.dev:8443",// HTTP_PROXY: "https://sylo_stk_...:x@sylo.runplex.dev:8443",// ...same as sandboxEnv// }Security Profiles
Section titled “Security Profiles”Save credential + policy configurations and reuse across sessions.
createProfile(request)
Section titled “createProfile(request)”const profile = await sylo.createProfile({ name: "code-review-agent", profileData: { credentials: [ credential("anthropic", process.env.ANTHROPIC_API_KEY!), // saved credential credential("github", process.env.GITHUB_TOKEN!), // saved credential ], policies: { default: "deny" }, },});MITM domains are auto-inferred from credentials and policy rules.
Credentials have two modes:
- Saved (
value: "sk-...") — encrypted in the profile, reused every session - Runtime slot (
value: null) — must be filled per-session, for tenant-specific keys
// Profile with a runtime slotconst profile = await sylo.createProfile({ name: "multi-tenant", profileData: { credentials: [ credential("anthropic", process.env.ANTHROPIC_API_KEY!), // saved { name: "tenant-api", envVar: "TENANT_API_KEY", domain: "api.example.com", header: "Authorization", value: null }, // runtime ], policies: { default: "deny" }, },});
// Fill runtime slots when creating sessionsconst session = await sylo.createSandboxToken({ tenantId: "customer-123", securityProfile: "multi-tenant", credentials: [ { name: "tenant-api", domain: "api.example.com", header: "Authorization", value: `Bearer ${tenantKey}` }, ],});listProfiles()
Section titled “listProfiles()”const { profiles } = await sylo.listProfiles();getProfile(id)
Section titled “getProfile(id)”const profile = await sylo.getProfile("profile-id");updateProfile(id, request)
Section titled “updateProfile(id, request)”await sylo.updateProfile(profile.id, { name: "renamed", profileData: { ... },});deleteProfile(id)
Section titled “deleteProfile(id)”await sylo.deleteProfile(profile.id);revokeSession(token)
Section titled “revokeSession(token)”Immediately revoke a session:
await sylo.revokeSession("sylo_stk_...");listSessions(options?)
Section titled “listSessions(options?)”const { sessions, total } = await sylo.listSessions({ status: "active", limit: 50, offset: 0,});queryAudit(options?)
Section titled “queryAudit(options?)”const { events, total } = await sylo.queryAudit({ tenantId: "acme", destination: "api.openai.com", policyDecision: "allow", limit: 100, offset: 0,});Error handling
Section titled “Error handling”import { SyloError } from "@runplex/sylo";
try { await sylo.createSandboxToken({ tenantId: "acme" });} catch (err) { if (err instanceof SyloError) { console.error(err.status); // HTTP status console.error(err.code); // "unauthorized", "invalid_request", etc. console.error(err.message); }}