Why use the SDK instead of raw HTTP
Everything the SDK does is achievable with plain HTTP calls against the REST API — the SDK exists to remove the boilerplate: header management, pagination cursors, and typed responses instead of raw JSON, so integration code stays short and readable.
Installation
npm install @seobox/sdk
Requires Node.js 18 or later.
Initializing the client
import Seobox from '@seobox/sdk';
const client = new Seobox({
apiKey: process.env.SEOBOX_API_KEY,
workspaceId: process.env.SEOBOX_WORKSPACE_ID, // required for workspace-scoped calls
});
Never hardcode apiKey in source — load it from an environment variable or secrets manager, the same way you would any other credential.
Listing sites
const sites = await client.sites.list();
// [{ uid: 'site_9f2a...', domain: 'example.com', status: 'active', ... }]
Listing and fetching articles
// First page
const { data, nextCursor } = await client.blogs.list({ limit: 20 });
// Next page
const page2 = await client.blogs.list({ limit: 20, cursor: nextCursor });
// Single article
const blog = await client.blogs.get('blog_7c1e...');
Triggering generation
const result = await client.pipeline.generate({
siteUid: 'site_9f2a...',
keyword: 'b2b saas seo',
secondaryKeywords: ['saas content marketing'],
tone: 'expert, direct',
});
console.log(result.runId, result.blogUid);
Generation is asynchronous — this resolves as soon as the run is queued, not when the article is finished. Poll client.blogs.get(result.blogUid) or handle the generation.completed event via your registered webhook to know when it's ready.
Handling errors
The SDK throws a typed SeoboxApiError for any non-2xx response, carrying the HTTP status and the API's error message:
import { SeoboxApiError } from '@seobox/sdk';
try {
await client.pipeline.generate({ siteUid: 'site_9f2a...', keyword: 'b2b saas seo' });
} catch (err) {
if (err instanceof SeoboxApiError) {
console.error(err.status, err.message);
if (err.status === 429) {
// back off and retry
}
} else {
throw err;
}
}
Full example: generate and wait for completion
import Seobox from '@seobox/sdk';
const client = new Seobox({
apiKey: process.env.SEOBOX_API_KEY,
workspaceId: process.env.SEOBOX_WORKSPACE_ID,
});
async function generateAndWait(siteUid, keyword) {
const { blogUid } = await client.pipeline.generate({ siteUid, keyword });
while (true) {
const blog = await client.blogs.get(blogUid);
if (blog.status === 'published' || blog.status === 'ready_for_review') return blog;
if (blog.status === 'failed') throw new Error(`Generation failed for ${blogUid}`);
await new Promise((r) => setTimeout(r, 5000));
}
}
In production, prefer the webhook-driven approach over polling — it's cheaper and faster to react to.
FAQ
Is there an SDK for languages other than Node.js? Node.js is the officially maintained SDK today. Every endpoint it wraps is a plain REST call, so any language can integrate directly against the REST API in the meantime.
Does the SDK support browser environments? No — it's built for server-side use only, since it requires your API key, which must never be exposed to a browser client.
How do I upgrade to a new SDK version safely? Check the changelog before upgrading a major version; minor and patch releases are backward compatible within the same major version.
