@novence/sdk
v0.2.6
Published
Official TypeScript SDK for Novence — static site hosting for AI agents. Create projects, upload files, run quality checks, deploy to the edge.
Maintainers
Readme
@novence/sdk
Official TypeScript SDK for Novence — static site hosting built for AI agents and the developers who wire them up.
Prefer the CLI for a first publish — no email until you claim:
npx novence deploy ./dist
novence claim --email [email protected]This SDK is for app and script code after you have an nv_ key. Create a
project, upload HTML/CSS/JS, run quality checks, and publish to the edge at
https://{suffix}.novence.ai/.
npm install @novence/sdkRequires Node 18+ (uses the global fetch). Ships both ESM and CommonJS, so
import and require both work with no configuration.
import { Novence } from "@novence/sdk"; // ESM
const { Novence } = require("@novence/sdk"); // CommonJSQuick start
import { Novence } from "@novence/sdk";
const client = new Novence({ apiKey: process.env.NOVENCE_API_KEY! });
const { project, url } = await client.projects.create({ name: "launch" });
await client.files.uploadDir(project.id, "./site");
await client.deployments.create(project.id);
console.log(url); // https://{suffix}.novence.aiOne HTML document (report, dashboard, artifact): client.publishHtml({ html, title }) then poll deployments.latest. CLI: npx novence deploy report.html.
Bootstrap + verify (email path)
When you need a key from email OTP instead of the CLI:
import { Novence, bootstrapAccount, verifyEmail } from "@novence/sdk";
// 1. Get an API key (emails a 6-digit OTP)
const { apiKey } = await bootstrapAccount("[email protected]");
// 2. Verify to unlock full Free quotas
await verifyEmail("[email protected]", process.env.VERIFY_CODE!);
// 3. Ship a site
const client = new Novence({ apiKey });
const { project, url } = await client.projects.create({ name: "launch" });
await client.files.uploadDir(project.id, "./site");
await client.deployments.create(project.id);
console.log(url); // https://{suffix}.novence.aiOr deploy anonymously from the SDK, then claim:
createDemoAccount() → ship → claimAccount(apiKey, "[email protected]").
Deploys are asynchronous. Poll deployments.latest until it settles:
const { deployment } = await client.deployments.latest(project.id);
if (deployment.status === "live") {
console.log(deployment.liveUrl);
} else if (deployment.status === "failed") {
console.error(deployment.errorMessage);
}deployment.status is a union — pending | queued | checking | promoting | live | failed
— so the compiler catches typos in status comparisons.
Checks
deployment.checksResults carries the quality gate. When skipped is true
(unverified accounts) passed is null — do not treat that as a pass:
const checks = deployment.checksResults;
if (checks?.skipped) {
console.log("checks did not run:", checks.reason);
} else if (checks?.passed === false) {
console.error("quality gate failed");
}Every method returns a typed response. Project, Deployment, ChecksResults,
Form, Quotas, Analytics, StagingFile and the rest are exported for your own
signatures:
import type { Project, Deployment, ChecksResults } from "@novence/sdk";Configuration
const client = new Novence({
apiKey: process.env.NOVENCE_API_KEY!,
baseUrl: "https://api.novence.ai", // optional
});baseUrl defaults to https://api.novence.ai. Set NOVENCE_BASE_URL to point every
call at a different control plane — useful when running the API locally.
API
| Namespace | Methods |
| --- | --- |
| client.projects | create · list · get · update · usage · analytics · brief · putBrief · events |
| client.files | uploadDir · uploadBuffer · getUploadUrl · getUploadUrlsBatch · confirm · confirmBatch |
| client.deployments | create · latest |
| client.domains | configure · status |
| client.forms | create · list · get · update · delete · listSubmissions · deleteSubmission |
| client.billing | quotas · checkout · portal · mppUpgrade |
| client.account | get · consoleKit · createSession · revokeSession |
| client.apiKeys | revoke |
Standalone helpers for the pre-auth flow: createDemoAccount, claimAccount,
bootstrapAccount, verifyEmail, resendVerification, reissueApiKey.
Identity checks
Prefer isNovenceClient() over instanceof Novence:
import { isNovenceClient } from "@novence/sdk";
if (isNovenceClient(value)) {
// value is a Novence client
}Because this package ships dual ESM/CommonJS builds, a process that loads both
copies gets two distinct Novence classes and instanceof fails across that
boundary — the "dual package hazard". isNovenceClient tests a Symbol.for
brand, which is shared by every copy, so it works regardless of how the client
was constructed.
For the same reason the base URL is resolved on each call rather than snapshotted at import, so two copies can never disagree about which control plane to hit.
Security
nv_ keys are server-side credentials. Never ship one in browser HTML, a URL, or a git commit. Read it from the environment.
Docs
- Documentation · FAQ · Pricing
- OpenAPI spec
- MCP server — drive the same API from Claude, Cursor, or any MCP client
License
MIT
