@xano/run-sdk
v1.0.0
Published
JavaScript/TypeScript SDK for Xano Run API
Readme
Xano Run SDK
A modern TypeScript/JavaScript SDK for the Xano Run API
Table of Contents
- Installation
- Platform Support
- Quick Start
- API Modules
- Configuration
- API Reference
- Error Handling
- TypeScript Support
- Project Structure
- Development
- Testing
Installation
npm install @xano/run-sdkyarn add @xano/run-sdkpnpm add @xano/run-sdkPlatform Support
This SDK is designed to work across all modern JavaScript/TypeScript environments.
Node.js
Requires Node.js 18.0.0 or higher (for native fetch support).
// ESM
import { XanoRun } from '@xano/run-sdk';
// CommonJS
const { XanoRun } = require('@xano/run-sdk');Deno
The SDK works with Deno v1.30+ using npm specifiers:
import { XanoRun } from 'npm:@xano/run-sdk';
const client = new XanoRun({ authToken: 'token', projectId: 'id' });
const result = await client.runs.execute('run.job "test" { main = {} }');Or via ESM CDN:
import { XanoRun } from 'https://esm.sh/@xano/run-sdk';Browser & Edge Runtimes
The SDK uses only Web APIs (fetch, URL, Headers) and works in:
- Modern browsers (Chrome, Firefox, Safari, Edge)
- Cloudflare Workers
- Vercel Edge Functions
- Deno Deploy
- Any environment with Web API support
<script type="module">
import { XanoRun } from 'https://esm.sh/@xano/run-sdk';
const client = new XanoRun({ authToken: 'token', projectId: 'id' });
</script>TypeScript
Full TypeScript support with strict types and declaration files included. Works with TypeScript 4.7+ (for ES module resolution).
Quick Start
import { XanoRun } from '@xano/run-sdk';
// Initialize the client
const client = new XanoRun({
authToken: 'your-auth-token',
projectId: 'your-project-uuid',
});
// Execute XanoScript code (body determines job vs service)
const code = `
run.job "Hello World" {
main = { name: "hello" }
}
---
function "hello" {
response = "Hello, World!"
}
`;
const result = await client.runs.execute(code);
console.log(result.run?.session?.response); // "Hello, World!"
// Access other APIs through domain-specific modules
const projects = await client.projects.list();
const sessions = await client.sessions.list();
const me = await client.auth.getMe();API Modules
Access all functionality through domain-specific modules:
const client = new XanoRun({ authToken, projectId });
// Projects
const projects = await client.projects.list();
const project = await client.projects.create({ name: 'My Project' });
// Run code (body determines job vs service)
const result = await client.runs.execute('run.job "test" { main = {} }');
// Sessions
const sessions = await client.sessions.list();
await client.sessions.start('session-id');
// Environment & Secrets
const envKeys = await client.env.getKeys();
const secretKeys = await client.secrets.getKeys();
// History & Logs
const requests = await client.history.searchRequests(sessionId, { page: 1 });
const logs = await client.logs.getRunLogs(sessionId, { page: 1 });Available Modules
| Module | Description |
|--------|-------------|
| client.auth | User authentication |
| client.projects | Project CRUD operations |
| client.env | Environment variables |
| client.secrets | Secret management |
| client.runs | Code execution |
| client.sessions | Session management |
| client.history | Request & function history |
| client.logs | Run logs & debug logs |
| client.tables | Database tables |
| client.sink | Sink data retrieval |
Configuration
Constructor Options
const client = new XanoRun({
authToken: 'your-auth-token', // Bearer token for authentication
projectId: 'your-project-uuid', // Default project for operations
baseUrl: 'https://app.xano.com/', // API base URL (optional)
});| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| authToken | string | No | - | Bearer token for API authentication |
| projectId | string | No | - | Default project UUID for project-scoped operations |
| baseUrl | string | No | https://app.xano.com/ | Base URL for the API |
Dynamic Configuration
Update configuration at runtime:
const client = new XanoRun();
// Set auth token later (e.g., after login)
client.setAuthToken('new-token');
// Switch between projects
client.setProjectId('project-a');
await client.sessions.list(); // Lists sessions for project-a
client.setProjectId('project-b');
await client.sessions.list(); // Lists sessions for project-bAPI Reference
Auth
Get information about the authenticated user.
const user = await client.auth.getMe();
console.log(user);
// {
// id: 123,
// name: 'John Doe',
// email: '[email protected]'
// }Projects
Manage your Xano Run projects.
List Projects
const projects = await client.projects.list();
// [
// { id: 'uuid-1', name: 'My API', description: '...' },
// { id: 'uuid-2', name: 'My Backend', description: '...' },
// ]Create Project
const project = await client.projects.create({
name: 'My New Project',
description: 'A backend for my awesome app',
});Update Project
const updated = await client.projects.update('project-uuid', {
name: 'Renamed Project',
description: 'Updated description',
});Delete Project
await client.projects.delete('project-uuid');Environment Variables
Manage environment variables for your project. Requires projectId to be set.
List All Keys
const { env } = await client.env.getKeys();
console.log(env); // ['API_KEY', 'DATABASE_URL', 'SECRET_KEY']Get a Value
const { name, value } = await client.env.getValue('API_KEY');
console.log(value); // 'sk-1234567890'Set (Create or Update)
await client.env.set({
name: 'API_KEY', // Key to update (or create)
env: {
name: 'API_KEY',
value: 'new-secret-value',
},
});Delete
await client.env.delete('API_KEY');Secrets
Manage secrets for your project. Requires projectId to be set.
List All Secret Keys
const { secrets } = await client.secrets.getKeys();
// [
// { name: 'docker-creds', type: 'kubernetes.io/dockerconfigjson' },
// { name: 'tls-cert', type: 'kubernetes.io/tls' },
// ]Get a Secret Value
const secret = await client.secrets.getValue('docker-creds');Set (Create or Update)
await client.secrets.set({
name: 'docker-creds',
secret: {
name: 'docker-creds',
type: 'kubernetes.io/dockerconfigjson',
value: JSON.stringify({ auths: { 'registry.example.com': { ... } } }),
},
});Delete
await client.secrets.delete('docker-creds');Run Execution
Execute XanoScript code. Requires projectId to be set.
The XanoScript code body determines whether it runs as a job or service based on the run.job or run.service declaration.
Execute Code
const code = `
run.job "Hello" {
main = { name: "hello" }
}
---
function "hello" {
response = "Hello!"
}
`;
const result = await client.runs.execute(code);
console.log(result.run?.session?.response); // "Hello!"With Input Arguments
const code = `
run.job "Greeting" {
main = {
name: "greet"
input: { name: "World" }
}
}
---
function "greet" {
input {
text name
}
stack {
var $greeting {
value = "Hello, " ~ $input.name ~ "!"
}
}
response = $greeting
}
`;
const result = await client.runs.execute(code, {
args: { name: 'World' },
});
console.log(result.run?.session?.response); // "Hello, World!"With Environment Overrides
const result = await client.runs.execute(code, {
args: { userId: 123 },
env: {
API_KEY: 'override-for-this-run',
DEBUG: 'true',
},
});Job vs Service
The run type is determined by the XanoScript code:
| Declaration | Description |
|-------------|-------------|
| run.job "name" { ... } | One-time execution that completes and returns a result |
| run.service "name" { ... } | Long-running service that stays active |
Get Document Info
Analyze a XanoScript document before running it:
const info = await client.runs.getDocInfo(code);
// {
// type: 'job',
// input: {
// name: { type: 'string', required: true },
// count: { type: 'number', required: false },
// },
// env: ['API_KEY', 'DATABASE_URL'],
// }Sessions
Manage and observe sessions. Project-scoped methods require projectId to be set.
List Sessions (Project-scoped)
const { items, cursorId, hasMore } = await client.sessions.list();
// items: [
// { id: 'session-1', name: 'My Job', status: 'running', ... },
// { id: 'session-2', name: 'API Service', status: 'stopped', ... },
// ]Start / Stop / Delete Session
// Start a stopped session
await client.sessions.start('session-id');
// Stop a running session
await client.sessions.stop('session-id');
// Delete a session
await client.sessions.delete('session-id');Get Session Details
const session = await client.sessions.get('session-id');
// {
// id: 'session-id',
// name: 'My Session',
// status: 'running',
// created_at: '2024-01-01T00:00:00Z',
// total_time: 123.45,
// ...
// }Update Session
// Change access level
await client.sessions.updateAccess('session-id', 'public');
// Rename session
await client.sessions.updateName('session-id', 'Production API');Request History
Search and inspect HTTP requests made by your sessions.
Search Requests
const history = await client.history.searchRequests('session-id', {
page: 1,
per_page: 25,
search: {
verb: 'GET',
uri: '/api/users',
'status|in': [200, 201],
},
});
// {
// items: [
// { id: 1, verb: 'GET', uri: '/api/users', status: 200, ... },
// { id: 2, verb: 'GET', uri: '/api/users/123', status: 200, ... },
// ],
// cursorId: '...',
// hasMore: true,
// }Get Request Details
const detail = await client.history.getRequestDetail('session-id', 123);
// {
// id: 123,
// verb: 'POST',
// uri: '/api/users',
// status: 201,
// request_headers: { ... },
// request_body: { ... },
// response_headers: { ... },
// response_body: { ... },
// duration: 0.045,
// }Function History
Search and inspect function executions.
Search Functions
const history = await client.history.searchFunctions('session-id', {
page: 1,
per_page: 25,
search: {
function_name: 'processOrder',
},
});Get Function Details
const detail = await client.history.getFunctionDetail('session-id', 456);Logs
Access run logs and debug logs for your sessions.
Get Run Logs
const logs = await client.logs.getRunLogs('session-id', {
page: 1,
per_page: 50,
type: 'error,warning', // Filter by log type (comma-separated)
q: 'connection failed', // Search query
});
// {
// items: [
// { id: 1, type: 'error', message: 'Connection failed', timestamp: '...' },
// { id: 2, type: 'warning', message: 'Retry attempt 1', timestamp: '...' },
// ],
// page: 1,
// per_page: 50,
// total: 127,
// }Search Debug Logs
const logs = await client.logs.searchDebugLogs('session-id', {
page: 1,
search: {
'level|in': ['error', 'warning'],
source: 'database',
message: 'timeout',
},
});Database Tables
Inspect tables and data in your session.
List Tables
const tables = await client.tables.list('session-id', {
include_xanoscript: false, // Include XanoScript definition
page: 1,
per_page: 100,
sort: 'name',
order: 'asc',
});
// [
// { id: 1, name: 'users', columns: [...], row_count: 1000 },
// { id: 2, name: 'orders', columns: [...], row_count: 5432 },
// ]Get Table Content
const content = await client.tables.getContent('session-id', 1, 1, 25);
// {
// columns: ['id', 'name', 'email', 'created_at'],
// rows: [
// { id: 1, name: 'Alice', email: '[email protected]', ... },
// { id: 2, name: 'Bob', email: '[email protected]', ... },
// ],
// page: 1,
// per_page: 25,
// total: 1000,
// }Sink Data
Retrieve backup/sink data for completed sessions.
const sink = await client.sink.getData('session-id');
// {
// tables: [
// { name: 'users', data: [...] },
// { name: 'orders', data: [...] },
// ],
// logs: [...],
// }Error Handling
The SDK throws errors with additional context:
import type { XanoRunError } from '@xano/run-sdk';
try {
await client.runs.execute(code, 'job');
} catch (error) {
const xanoError = error as XanoRunError;
console.error('Status:', xanoError.status); // HTTP status code
console.error('Message:', xanoError.message); // Error message
console.error('Response:', xanoError.response); // API response body
}Common Error Codes
| Status | Meaning |
|--------|---------|
| 401 | Invalid or expired auth token |
| 403 | Insufficient permissions |
| 404 | Resource not found |
| 422 | Validation error |
| 429 | Rate limit exceeded |
| 500 | Server error |
TypeScript Support
The SDK is written in TypeScript and exports all types:
import {
XanoRun,
// Config
type XanoRunConfig,
type XanoRunError,
// Auth
type AuthUser,
// Projects
type Project,
type CreateProjectInput,
type UpdateProjectInput,
// Environment
type EnvKeysResponse,
type EnvValueResponse,
type UpdateEnvInput,
// Secrets
type SecretKeysResponse,
type SecretValueResponse,
type UpdateSecretInput,
// Run
type RunType,
type RunOptions,
type RunResult,
type DocInfoResult,
// Sessions
type Session,
type SessionDetail,
type PaginatedResponse,
// History
type RequestHistorySearchInput,
type RequestHistoryResponse,
type RequestHistoryDetail,
type FunctionHistorySearchInput,
type FunctionHistoryResponse,
type FunctionHistoryDetail,
// Logs
type RunLogsInput,
type RunLogsResponse,
type DebugLogSearchInput,
type DebugLogResponse,
// Tables
type TableInfo,
type TableListInput,
type TableContentResponse,
// Sink
type SinkData,
} from '@xano/run-sdk';Project Structure
src/
├── index.ts # Main entry point - exports everything
├── client.ts # XanoRun class - orchestrates modules
├── http.ts # HttpClient - shared HTTP utilities
│
├── api/ # Domain-specific API modules
│ ├── index.ts # Barrel export
│ ├── auth.ts # AuthApi
│ ├── projects.ts # ProjectsApi
│ ├── env.ts # EnvApi
│ ├── secrets.ts # SecretsApi
│ ├── run.ts # RunApi
│ ├── sessions.ts # SessionsApi
│ ├── history.ts # HistoryApi
│ ├── logs.ts # LogsApi
│ ├── tables.ts # TablesApi
│ └── sink.ts # SinkApi
│
└── types/ # Type definitions
├── index.ts # Barrel export
├── common.ts # Shared types
├── auth.ts
├── project.ts
├── env.ts
├── secret.ts
├── run.ts
├── session.ts
├── history.ts
├── logs.ts
├── table.ts
└── sink.tsDevelopment
# Install dependencies
npm install
# Build the SDK
npm run build
# Watch mode for development
npm run dev
# Lint
npm run lint
# Run tests
npm testTesting
The SDK includes comprehensive tests with 100% code coverage using Vitest.
Running Tests
# Run tests in watch mode
npm test
# Run tests once
npm test -- --run
# Run tests with coverage report
npm run test:coverageTest Structure
src/
├── http.test.ts # HttpClient tests (URL building, headers, requests)
├── client.test.ts # XanoRun client tests (config, modules, auth)
└── api/
└── api.test.ts # All API module testsCoverage
The test suite covers:
- HttpClient: URL construction, header generation, request handling, error responses
- XanoRun Client: Configuration, sub-module initialization, dynamic auth/project updates
- API Modules: All 10 API modules with their methods (auth, projects, env, secrets, runs, sessions, history, logs, tables, sink)
--------------|---------|----------|---------|---------|
File | % Stmts | % Branch | % Funcs | % Lines |
--------------|---------|----------|---------|---------|
All files | 100 | 100 | 100 | 100 |
--------------|---------|----------|---------|---------|License
MIT
