@loxtep/sdk
v0.5.0
Published
Loxtep SDK for Node.js — the Enterprise Context Layer: data products, workflows, projects, queues, and machine-usable context for AI
Readme
Loxtep Node.js SDK
Client for the Loxtep API, organized around one journey: ingest → define → deliver. Install the SDK and get to your first event in five steps (below), then reach for the namespace that matches the stage you're in:
- Ingest —
triggers,connectors,workflows,data_products.get_writer - Define —
data_products,schemas,quality,catalog,discovery,domains,standards,data_contracts,thesaurus,procedures - Deliver —
data_products(reader/stream/replay/query),targets - Advanced / platform —
projects,templates,instances,observe,queues,metrics
Node.js 22+ is the supported runtime (engines in package.json). Live
queue/flow writes use the Loxtep stream data plane; configure stream bus
resources (streams on LoxtepClient and instance env from your stack) and AWS
credentials for SigV4 on both REST and the bus.
Ways to get started
This SDK supports two developer workflows:
| Path | Use case | Entry point |
|------|----------|-------------|
| Programmatic | Write/read events from application code (microservices, lambdas, scripts) | LoxtepClient → data_products.get_writer / get_reader |
| Code-first CLI | Author workflows as TypeScript, test locally, deploy via CI | loxtep init → attach → generate → test → deploy |
There are also two additional paths that don't require this SDK:
- Agent-first (MCP) — drive Loxtep conversationally from Cursor, Kiro, Claude, etc. See loxtep-plugins-skills.
- Web UI — visual project setup and management at app.loxtep.io.
All paths are documented in the Loxtep Quickstart.
Quick start — Programmatic (< 5 min to first stream)
Install
npm install @loxtep/sdkLog in
npx loxtep loginA browser window opens — sign in to Loxtep and you're authenticated. Tokens are saved to
~/.loxtep/credentials.jsonand refresh automatically.CI/headless: Use
npx loxtep login --email [email protected] --password ...or setLOXTEP_AUTH_TOKENin your environment.Create a client, write and read events
import { LoxtepClient } from '@loxtep/sdk'; const client = new LoxtepClient({ api_url: 'https://api.loxtep.com', auth: { type: 'jwt', token: process.env.LOXTEP_AUTH_TOKEN! }, }); // Write events to a data product const writer = await client.data_products.get_writer('shopify_gql_customer'); writer.write({ customer_id: '123', name: 'Alice', email: '[email protected]', }); await writer.close(); // Read events from a data product const reader = await client.data_products.get_reader('shopify_gql_customer'); for await (const event of reader) { console.log(event); }That's it. The SDK resolves the data product's queue, bot identity, and stream bus configuration automatically from the deployment metadata. No manual queue names, no stream config, no bot IDs.
Stream config from the platform (optional) — after login,
await client.observe.stream_config()returns stream resource names needed for the data plane. Merge intonew LoxtepClient({ ...opts, streams: { ...partial } })with your JWT-backed client. Note:data_products.get_writerandget_readerresolve stream config automatically — this is only needed for manual bus access.
Quick start — Code-first CLI (init → deploy)
For developers who author workflows as TypeScript and want the full local-dev-to-production lifecycle:
# 1. Install
npm install @loxtep/sdk
# 2. Authenticate
npx loxtep login
# 3. Scaffold a project from a template
npx loxtep init --template shopify-orders
# 4. Bind to a runtime instance
npx loxtep attach --instance prod
# 5. Generate typed workspace constants
npx loxtep generate
# 6. Author a workflow (see authoring module docs below)
# 7. Test locally with a sample event
npx loxtep test orders-enricher --event ./events/order-created.json
# 8. Deploy to the workflow engine
npx loxtep deployThe generate step produces .loxtep/generated/index.ts with typed constants for every data product, connector, domain, and queue in your workspace. Import them in your workflow modules for compile-time safety:
import { defineDataWorkflow, on } from '@loxtep/sdk/authoring'
import { workspace } from './.loxtep/generated'
export default defineDataWorkflow({
name: 'orders-enricher',
triggers: [on.queueEvent(workspace.queues.orders_raw)],
async handler(ctx, event) {
await ctx.toolbox.dataProducts.upsert({
dataProduct: workspace.dataProducts.orders_enriched,
domain: workspace.domains.commerce,
record: event,
})
},
})See loxtep init --help, loxtep attach --help, etc. for all flags. The full CLI reference is in the CLI reference section below.
API surface
Every method is snake_case. Namespaces are grouped by the stage of the journey
they serve, and labelled by kind: Resource (full CRUD), Reference
(read-only), Runtime (live stream I/O).
Ingest — connect sources, write events
- triggers (Resource) –
get,list,create,update,delete,test— ingest source bindings (external systems that feed a workflow) - connectors (Resource) –
list,get,create,update,delete,test,get_oauth_url— org-level catalog of connectable system types - workflows (Resource) –
list,get,create,get_graph,deploy— the ingestion → transformation → export DAG - data_products.get_writer(name) (Runtime) – the write path for events
Define — semantics, schema, quality, governance
- data_products (Resource + Runtime) –
get,get_lexicon,list,search,query,list_tables,get_queue_info,get_reader_checkpoint,create,readiness,promote,get_usage_map,invalidate_cache - schemas (Reference) –
get,list,tag_pii_fields - quality (Resource) –
list,get,create - catalog (Reference) –
search - discovery (Reference) –
search,get_evidence,get_lineage_impact,get_governance_flags,run - domains (Reference) –
list,get - standards (Reference) –
list,get - data_contracts (Resource) –
list,get,create,update,delete - thesaurus (Reference) –
list_terms,resolve_canonical_key,append_synonym - procedures (Reference) –
list
Deliver — consume and route data
- data_products (Runtime) –
get_reader,stream,replay - targets (Resource) –
list,get,create,update,delete— delivery sink bindings (webhook, API, export, DB sync, BI, event stream)
Advanced / platform
- projects (Resource) –
list,get,create,update,delete,apply_template,repository - templates (Reference) –
list,get - instances (Reference) –
list,get,get_stream_config - observe –
status,stream_config - queues –
get_queue_metadata,get_reader_checkpoint,open_reader,open_writer - metrics –
log,get_reporter
Data product writer and reader
await client.data_products.get_writer('name') resolves the data product's
queue, bot identity, and stream bus config automatically, then returns a
FlowWriter:
const writer = await client.data_products.get_writer('shopify_gql_customer');
writer.write({ customer_id: '123', name: 'Alice', email: '[email protected]' });
await writer.close();await client.data_products.get_reader('name') returns an async iterable over
the data product's queue:
const reader = await client.data_products.get_reader('shopify_gql_customer');
for await (const event of reader) {
console.log(event);
}Options:
- Writer:
{ bot_id?, batch_size?, max_retries? } - Reader:
{ bot_id?, from?, batch_size? }
Cache: call client.data_products.invalidate_cache('name') to force
re-resolution on the next call.
Stream helpers
Use mapStream and filterStream with data_products.stream(),
data_products.replay(), or queues.open_reader().read():
import { mapStream, filterStream } from '@loxtep/sdk';
for await (const event of mapStream(reader.read(), e => e.payload)) {
console.log(event);
}
for await (const event of filterStream(
reader.read(),
e => e.event_id !== 'skip'
)) {
console.log(event);
}Targets (delivery)
Configure how a data product delivers data to external systems.
import { LoxtepClient } from '@loxtep/sdk';
import type { Target, TargetCreateInput } from '@loxtep/sdk';
const client = new LoxtepClient({
api_url: 'https://api.loxtep.com',
auth: { type: 'jwt', token: process.env.LOXTEP_AUTH_TOKEN! },
});
// List targets for a data product
const { items, pagination } = await client.targets.list('dp_abc123');
// Create a webhook target
const webhook = await client.targets.create('dp_abc123', {
targetType: 'webhook',
name: 'Order notifications',
endpoint_url: 'https://example.com/webhooks/orders',
method: 'POST',
});
// Update a target
await client.targets.update('dp_abc123', webhook.consumption_id, {
is_active: false,
});
// Delete a target
await client.targets.delete('dp_abc123', webhook.consumption_id);Documentation
- Getting started – Zero to first event in under 5 minutes.
- Quick reference – Single-page cheat sheet.
- Event replay cookbook – Replay events from a data product or queue.
- MCP + SDK pairing – One auth story, when MCP vs SDK.
- MCP → SDK mapping – Agent-oriented table.
- Typed errors –
import { … } from '@loxtep/sdk/errors'. - API reference –
npm run docs(Typedoc).
CLI reference
| Command | Description |
| ---------------------------------------------------- | ------------------------------------------------------------------ |
| login | Log in via browser OAuth (default) or email/password |
| login --browser | Explicitly use browser OAuth flow |
| login --email <e> --password <p> | Headless login for CI (optional --mfa-code) |
| logout | Remove stored credentials |
| whoami | Print current user and organization |
| init [--template <slug>] | Scaffold project structure, AGENTS.md, and default skill |
| init --create-repo [name] | Scaffold + create a new GitHub repo (private default) |
| init --from-repo <url> | Scaffold + import from an existing repo |
| attach --instance <name-or-id> | Bind project to a runtime instance |
| generate | Codegen typed workspace constants to .loxtep/generated/index.ts |
| test <module> --event <file> | Run a workflow module locally with sample event(s) |
| deploy | Compile modules, validate resources, deploy to workflow engine |
| config list | Show api_url, organization_id, project_id, instance_id |
| config paths | Show resolved URLs for auth and SDK path matrix |
| config set <key> <value> | Set api_url | organization_id | project_id | instance_id |
| config export --from-data-product <id> | Print shell exports / JSON for SDK bootstrap |
| config export --from-connector <id> | Print env exports from SDK connector |
| bus login | Explain bus vs JWT (placeholder for future session API) |
| data-products list | List data products |
| data-products get <id> | Get data product by id |
| data-products create --name … --domain-id … | Create data product |
| data-products query <id> <SQL> | Run SQL in data product context (or --file query.sql) |
| data-products tables <id> | List tables for data product |
| workflows list [--project-id <id>] | List workflows (project_id required or from config) |
| workflows get <id> | Get workflow by id (with nodes) |
| workflows create --name <n> --project-id <id> | Create workflow (optional: --template-id, --description) |
| workflows deploy --project-id <id> | Deploy workflow (optional: --instance-id, --version-id) |
| triggers list | List triggers (ingest source bindings) |
| triggers get <id> | Get trigger by id |
| triggers create --name <n> --type <t> --key <k> | Create trigger |
| triggers test <id> | Test trigger |
| observe status | Show observability status (bots) |
| queue info <data-product-id> | Queue info by data product id |
| queue info --queue <name> | Queue info by queue name |
| queue checkpoint <id> --bot <bot-id> | Reader checkpoint for data product and bot |
| domains list | domains get <id> | List or get domain |
| standards list | standards get <id> | List or get standard (policy) |
| data-contracts list | data-contracts get <id> | List or get data contract |
| metrics rate-limits | Show rate limit info |
| metrics log --id <id> --value <n> | Log metric (optional --tags k=v,...) |
Examples:
loxtep login
loxtep whoami
loxtep data-products list
loxtep workflows list --project-id <project-id>
loxtep workflows get <workflow-id>
loxtep workflows deploy --project-id <id> --instance-id <id>
loxtep config export --from-connector <connector-id> --format json
loxtep queue info <data-product-id>
loxtep data-products query <data-product-id> "SELECT * FROM t LIMIT 10"
loxtep metrics rate-limitsModule exports
The SDK also ships standalone modules for configuration, authentication, code generation, skill scoping, and workflow authoring. Import them directly from the relevant subpath.
config module
import { loadConfig, loadConfigSync, saveConfig } from '@loxtep/sdk/config';| Export | Type | Description |
| --- | --- | --- |
| loadConfig | function | Load config from env vars and optional file (async). Precedence: env > file > defaults |
| loadConfigSync | function | Synchronous variant of loadConfig using readFileSync |
| saveConfig | function | Persist config (api_url, org/project/instance IDs) to file. No secrets written to disk |
| parseStreamsPartial | function | Extract a partial bus config from unknown JSON, keeping only valid stream resource keys |
| getConfigDir | function | Return the default config directory path (~/.loxtep) |
| getDefaultConfigPath | function | Return the default config file path (~/.loxtep/config.json) |
| buildAuthServiceUrl | function | Build the full URL for auth endpoints (/auth/login, /auth/refresh) with path prefix |
| extendClientBaseUrl | function | Extend api_url with a microservice path segment, avoiding duplication |
| buildPlatformRequestUrl | function | Build a full request URL for the shared control-plane host, handling microservice routing |
| resolveAutoConfig | function | Resolve configuration with full precedence: env > explicit > workspace files |
auth module
import { login, refresh, browserLogin, TokenManager } from '@loxtep/sdk/auth';| Export | Type | Description |
| --- | --- | --- |
| decodeJwtPayload | function | Decode JWT payload to read exp (expiry) without verification. Client-side only |
| login | function | Authenticate with email/password via POST /auth/login. Returns access + refresh tokens |
| refresh | function | Refresh an access token via POST /auth/refresh |
| browserLogin | function | Run OAuth 2.1 browser-based login flow with a localhost callback server |
| TokenManager | class | In-memory token manager with auto-refresh support. No tokens persisted to disk |
| LoginMfaRequiredError | class | Error thrown when login returns 403 and the user must supply a TOTP code |
codegen module
import { loadWorkspaceContext, deriveKey, normalizeContext, emitArtifact, writeArtifact, computeCounts } from '@loxtep/sdk/codegen';| Export | Type | Description |
| --- | --- | --- |
| loadWorkspaceContext | function | Fetch all workspace resources from the control plane and assemble a WorkspaceContext |
| deriveKey | function | Derive a deterministic, valid TypeScript identifier key from a resource name |
| normalizeContext | function | Transform raw WorkspaceContext into canonical NormalizedContext with stable keys and id-sorted ordering |
| emitArtifact | function | Render a NormalizedContext into a complete TypeScript source string with as const exports |
| writeArtifact | function | Atomic file write of the generated artifact; returns per-resource-type counts |
| computeCounts | function | Compute per-resource-type counts from a NormalizedContext |
skills module
import { checkScope, parseSkillYaml, loadSkillsFromDirectory } from '@loxtep/sdk/skills';| Export | Type | Description |
| --- | --- | --- |
| checkScope | function | Fail-closed scope decision: check whether an operation on a resource is permitted by a skill |
| checkScopeByName | function | Resolve a skill by name from a map and check scope in one step |
| parseSkillYaml | function | Parse a YAML string into a validated SkillDefinition |
| loadSkillFromFile | function | Load a single skill definition from a .yaml file path |
| loadSkillsFromDirectory | function | Load all skill definitions from a .loxtep/skills/ directory |
| validateSkillReferences | function | Validate all skill resource references against the loaded WorkspaceContext |
| formatSkillValidationErrors | function | Format skill validation errors into human-readable messages |
| SkillDefinitionSchema | object | Zod schema for validating skill definition YAML structure |
authoring module
import { defineDataWorkflow, on, createToolbox, agent } from '@loxtep/sdk/authoring';| Export | Type | Description |
| --- | --- | --- |
| defineDataWorkflow | function | Validate and return a DataWorkflowModule spec. Throws ValidationError on invalid input |
| on | object | Trigger builders: queueEvent, connectorEvent, schedule, webhook |
| createToolbox | function | Create a deterministic typed platform-call toolbox (no model in the loop) |
| agent | function | Agentic operation entry point with scope enforcement and action trace |
| validateAgentOptions | function | Validate agent options (prompt length, skills references) against available skills |
| computeReachableScope | function | Compute the union of all resource scopes from supplied skill definitions |
| enforceAgentScope | function | Check whether a resource access is within the merged scope of the agent's skills |
| createScopeGuardedToolbox | function | Create a scope-guarded proxy that enforces scope and records traces before every call |
| compileModule | function | Pure compiler: lower a DataWorkflowModule into GraphPatchOp[] for deployment |
| computeRemovalSet | function | Compute workflows present on instance but absent from project modules (for cleanup) |
| ActionTrace | class | Mutable action trace recorder with monotonically increasing sequence numbers |
| AgentScopeError | class | Error thrown when an agentic operation is blocked due to a scope violation |
| ToolboxOperationError | class | Error thrown when a toolbox operation fails (network, validation, or platform error) |
http module
import { signRequest, LoxtepHttpClient } from '@loxtep/sdk/http';| Export | Type | Description |
| --- | --- | --- |
| signRequest | function | Sign an HTTP request with AWS SigV4 for API Gateway (execute-api). Returns headers including Authorization and x-amz-* |
| LoxtepHttpClient | class | HTTP client that signs requests with AWS SigV4 and attaches JWT. Provides get, post, put, delete helpers with retry on 5xx/network errors and typed Loxtep errors on 4xx |
checkpoint module
import { createMemoryCheckpointStore } from '@loxtep/sdk/checkpoint';| Export | Type | Description |
| --- | --- | --- |
| createMemoryCheckpointStore | function | Create an in-memory checkpoint store for stream/replay resume. Suitable for tests or single-process use |
Error classes
import { AuthorizationError, ConflictError, ValidationError, DefinitionValidationError, SchemaValidationError, CheckpointError, parseHttpError } from '@loxtep/sdk/errors';| Export | Type | Description |
| --- | --- | --- |
| AuthorizationError | class | 403 — Insufficient permissions |
| ConflictError | class | 409 — Resource already exists or version conflict |
| ValidationError | class | 400 — Invalid input with optional field_errors array |
| DefinitionValidationError | class | 400 — Payload doesn't match data product definition (schema validation failures) |
| SchemaValidationError | class | Alias for DefinitionValidationError (backend terminology) |
| CheckpointError | class | 500 — Failed to save or load a stream checkpoint |
| parseHttpError | function | Map an HTTP status code and response body to the appropriate typed Loxtep error class |
DataProductResolver class
import { DataProductResolver } from '@loxtep/sdk/client';| Export | Type | Description |
| --- | --- | --- |
| DataProductResolver | class | Resolves a data product name or UUID into full runtime configuration (queue name, bot_id, stream bus resources). Caches results in memory. Used internally by client.data_products.get_writer/get_reader |
