buildx-sdk
v1.7.9
Published
Official JavaScript/TypeScript SDK for Buildx low-code platform
Downloads
475
Maintainers
Readme
Buildx SDK
Official JavaScript/TypeScript SDK for Buildx APIs.
buildx-sdk gives you typed services for auth, collections, storage, flows, templates, functions, and Buildx system objects.
Contents
- Install
- Quick Start
- SDK Boundary
- How Scoping Works
- Configuration
- Error Handling
- Authentication
- Collections
- Storage
- Projects
- Flows
- Templates
- Functions
- Buildx Objects
- API Keys
- Production Notes
- Generate Docs
Install
yarn add buildx-sdk
# or
npm install buildx-sdkQuick Start
import { Buildx } from "buildx-sdk";
const buildx = new Buildx({
apiEndpoint: "https://api.buildx.app",
apiKey: process.env.BUILDX_API_KEY!,
projectId: process.env.BUILDX_PROJECT_ID!, // required for most project data operations
});
const auth = buildx.auth();
const collections = buildx.collections();
// 1) login
const user = await auth.login({
username: "[email protected]",
password: "secret",
});
// 2) query collection data
const orders = await collections.query("orders", {
filter: { status: "paid" },
limit: 20,
sort: { createdAt: -1 },
});SDK Boundary
buildx-sdk is the public/client SDK for Buildx APIs.
Use this SDK when:
- building frontend or backend application logic against Buildx APIs
- you need typed access to auth, collections, storage, flows, templates, functions
Do not treat this package as an admin-only runtime layer.
Admin/machine concerns are handled by buildx-admin-sdk together with private datastore routes used by buildx-edge-function.
How Scoping Works
Buildx API has three practical scopes:
project-scoped: routes like/project/:project_id/...organization-scoped: routes like/:organization_id/...for org resourcesroot: routes like/auth/...and/projects
This SDK maps scope automatically from your config and selected method:
- services like
collections,storage,flows,templates,functions,buildxObjectsare project-scoped apiKeys.list/get/getSecretcan be root or organization-scopedauth.requestPasswordResetandauth.resetPasswordsupport:- project scope when
projectIdis configured - root scope when
projectIdis omitted or"default"
- project scope when
- OTP login is project-scoped only in this SDK/API
Configuration
const buildx = new Buildx({
apiEndpoint: "https://api.buildx.app",
apiKey: "YOUR_API_KEY",
projectId: "YOUR_PROJECT_ID", // optional at init, but required for project-scoped services
organizationId: "YOUR_ORG_ID", // optional; used by org helpers (for example api keys/users)
});Update runtime config:
buildx.updateConfig({
apiKey: "NEW_API_KEY",
projectId: "ANOTHER_PROJECT_ID",
});Error Handling
All methods return either success data or:
type ErrorResponse = {
error: string;
message: string;
statusCode: number;
success: false;
};Recommended type guard:
import type { ErrorResponse } from "buildx-sdk";
function isError<T>(value: T | ErrorResponse): value is ErrorResponse {
return !!value && typeof value === "object" && "success" in value && value.success === false;
}Authentication
Login / Signup / Current User
const auth = buildx.auth();
await auth.login({ username: "user", password: "pass" });
await auth.loginWithGoogle({ credential: "google-id-token" });
await auth.signup({ username: "new-user", password: "pass" });
const me = await auth.getCurrentUser();Token Management
login, signup, and OTP verify auto-store tokens if response contains them.
auth.setAccessToken("token");
auth.setRefreshToken("refresh");
auth.getAccessToken();
auth.getRefreshToken();
auth.isAuthenticated();
auth.clearTokens();
await auth.refreshToken();OTP Login (Project-Scoped Only)
// request OTP
await auth.requestEotp({ email: "[email protected]" });
// alias: requestEotpAuth / requestOtpLogin
// verify OTP and receive auth tokens
await auth.verifyEotp({ email: "[email protected]", otp: "123456" });
// alias: verifyEotpAuth / verifyOtpLoginNotes:
- requires valid
projectId - root OTP login is intentionally not supported
Auth Flows
EOTP Login Flow
sequenceDiagram
participant C as Client App
participant B as buildx-sdk
participant A as Buildx API
C->>B: auth.requestEotp({ email })
B->>A: POST /project/:projectId/auth/eotp/auth/request
A-->>C: OTP sent (email)
C->>B: auth.verifyEotp({ email, otp })
B->>A: POST /project/:projectId/auth/eotp/auth/verify
A-->>B: user + access_token (+ refresh_token)
B-->>C: stores tokens in Auth serviceFailure points to handle:
- invalid/expired OTP
- suspended/deleted user
- missing
projectId(OTP route is not available at root scope)
Change Password (Authenticated User)
// simple
await auth.updatePassword("new-password");
// richer payload
await auth.changePassword({
currentPassword: "old-password",
newPassword: "new-password",
});Admin Password Update
await auth.adminUpdatePassword("USER_ID", "new-password");Password Reset (Token-Based)
// request reset link
await auth.requestPasswordReset({
email: "[email protected]",
reset_url: "https://your-app.com/reset-password",
});
// reset with token
await auth.resetPassword({
token: "reset-token-from-email",
new_password: "new-secret",
email: "[email protected]", // optional; token-only also supported
});Scope behavior:
- with
projectId:POST /project/:id/auth/password/reset/... - without
projectIdor with"default":POST /auth/password/reset/...
Password Reset Flow
sequenceDiagram
participant C as Client App
participant B as buildx-sdk
participant A as Buildx API
participant M as User Mailbox
C->>B: auth.requestPasswordReset({ email, reset_url? })
B->>A: POST /project/:projectId/auth/password/reset/request OR /auth/password/reset/request
A-->>M: reset link with token
C->>B: auth.resetPassword({ token, new_password, email? })
B->>A: POST /project/:projectId/auth/password/reset OR /auth/password/reset
A-->>C: reset successUser Management
await auth.listUsers(); // root
await auth.listUsers("org-id"); // organization scope
await auth.lookupUsers();
await auth.getUser("user-id");
await auth.deleteUser("user-id");
await auth.updatePushToken("expo-or-fcm-token");Collections
List / Schema / Upsert / Delete Collection
const collections = buildx.collections();
await collections.list(); // filters out buildx_* by default
await collections.list(true, true); // withStats + include buildx_*
await collections.getSchema("orders", 1); // depth default 1
await collections.set({ collection_id: "orders", name: "Orders" });
await collections.deleteCollection("orders");Query Data
await collections.query("orders", {
filter: { status: "paid" },
select: ["_id", "customer", "total", "createdAt"],
sort: { createdAt: -1 },
limit: 50,
skip: 0,
});Query options:
qorsearchQueryfilter,jsonFilterselect,projectionoptions,sortlimit,skipquick_filter_fields
Raw Query (No Populate)
await collections.queryRaw("orders", {
filter: { status: "paid" },
select: ["_id", "customer", "total"],
});Pagination Metadata
const page = await collections.queryWithPagination("orders", {
limit: 100,
skip: 0,
sort: { _id: -1 },
});
// page = { data: [...], meta: { count, limit, skip, transport, ... } }Pagination Transport (HTTP / WS / Auto)
await collections.queryWithPagination("orders", {
limit: 100,
paginationTransport: "auto", // "auto" | "http" | "ws"
});auto tries WebSocket first then falls back to HTTP.
Relation Hydration
await collections.query("orders", {
select: ["_id", "customer", "items"],
relations: [
{ field: "customer", collectionId: "customers" },
{ field: "items", collectionId: "products", many: true },
],
relationSelect: "_id,_display,name,price",
});Realtime (SSE)
const sub = collections.subscribeRealtime("orders", {
onConnected: () => console.log("connected"),
onEvent: (event) => console.log(event),
onError: (error) => console.error(error),
}, {
// Optional (default: true): ignore heartbeat/non-JSON messages from SSE stream.
ignoreNonJsonMessages: true,
});
// later
sub.close();Document CRUD
await collections.getDocument("orders", "doc-id");
await collections.getDocument("orders", "doc-id", ["customer"]);
await collections.createDocument("orders", { status: "new" });
await collections.updateDocument("orders", "doc-id", { status: "paid" });
// update with query mode=updateOnly
await collections.updateDocumentWithOptions(
"orders",
"doc-id",
{ total: 1200 },
{ updateOnly: true }
);
await collections.getDocumentRevisions("orders", "doc-id");
await collections.deleteDocument("orders", "doc-id");
await collections.deleteByFilter("orders", { status: "archived" });Utility Methods
await collections.lookup("users", { limit: 20 });
await collections.getDataTypes();
await collections.validate("orders");
await collections.migrate("orders");
await collections.import("orders", file, {
ext_ref: "external_ref",
amount: "total",
});Storage
const storage = buildx.storage();
await storage.upload(file, "invoices/2026");
await storage.uploadToCollection(file, "orders", "attachments");
await storage.list("invoices/");
await storage.getSize("invoices/");
await storage.delete("invoices/2026/a.pdf");Projects
const projects = buildx.projects();
await projects.list();
await projects.get("project-id");
await projects.create({ name: "My Project" });
await projects.update("project-id", { description: "Updated" });
await projects.deleteById("project-id");
await projects.backup("project-id");
await projects.restore("project-id", backupFile);Flows
const flows = buildx.flows();
await flows.getTypes();
await flows.run("flow-id", null, "root", { orderId: "123" });
await flows.getGptFlowSuggestions("Create approval flow");
await flows.getGptCollectionSuggestions("Design invoice schema");
await flows.getGptLifecycleSuggestions("Draft to approved states");Templates
const templates = buildx.templates();
await templates.preview(templateJson, { customerName: "Alice" });
await templates.render("template-id", { customerName: "Alice" });
await templates.renderPDF("template-id", { customerName: "Alice" });Functions
const functions = buildx.functions();
await functions.list();
await functions.getByName("sendInvoice");
await functions.update("sendInvoice", { code: "exports.handler = async () => {};" });
await functions.getLogs("sendInvoice");Buildx Objects
const bo = buildx.buildxObjects();
await bo.getCollection("roles");
await bo.getDocument("roles", "role-id");
await bo.query("roles", { limit: 50, sort: { createdAt: -1 } });
await bo.create("roles", { role_id: "auditor", name: "Auditor" });
await bo.update("roles", "role-id", { name: "Senior Auditor" });
await bo.deleteObject("roles", "role-id");API Keys
const keys = buildx.apiKeys();
await keys.list(); // root scope
await keys.list("org-id"); // org scope
await keys.get("api-key-id");
await keys.getSecret("api-key-id");Production Notes
- Keep
apiKeyserver-side when possible. - If using browser apps, treat API keys as public identifiers and rely on JWT + backend authorization rules.
- Rotate API keys and refresh tokens on schedule.
- For uploads in Node.js, ensure
File/FormDatacompatibility (Node 18+ or polyfills). - Handle
ErrorResponsecentrally and mapstatusCodeto UX states. - Prefer
queryWithPaginationfor large datasets. - Use
paginationTransport: "auto"for large list views when WS is available.
Generate Docs
This package uses TypeDoc and includes README.md in generated docs.
yarn docsOutput locations:
docs/api/htmldocs/api/html/docs.jsondocs/api/markdown
For generated API reference, see:
docs/api/markdowndocs/api/html
