SegOps AIDocs

Admin SDK (`@segops/admin`)

A **server-side** SDK for driving SegOps programmatically — the same operations the dashboard performs: create segments, import products, run recomputes, manage schemas/activations/queries, and export pages.

This is not the ingestion SDK (@segops/sdk). The Admin SDK uses secret keys only (sk_…) and can mutate/delete resources. Never ship it to a browser or embed a secret key client-side.

Install#

bash
npm install @segops/admin

Requires Node 18+ (uses the global fetch). Pass a fetch implementation for older runtimes.

Quick start#

ts
import { SegOpsAdmin } from '@segops/admin';

const segops = new SegOpsAdmin({
  apiKey: process.env.SEGOPS_API_KEY!, // sk_…
  // baseUrl defaults to https://api.segops.ai/api
});

// Create + compute a segment
const segment = await segops.segments.create({
  name: 'High-value buyers',
  definition: { logic: 'AND', conditions: [{ type: 'monetary', operator: 'gte', value: 200 }] },
});
await segops.segments.recompute(segment.id);

// Iterate every segment across pages
for await (const s of segops.segments.iterate()) {
  console.log(s.id, s.name, s.member_count);
}

new SegOpsAdmin() throws SegOpsConfigError if the key isn't an sk_ key (public pk_ and MCP mk_ keys are rejected).

Resources#

Every resource shares the CRUD surface (list, iterate, get, create, update, delete) plus resource-specific actions.

NamespaceHighlights
segmentsrecompute(id), members(id), membership(userId), export(id, { format }), preview(definition)
productSegmentsCRUD + recompute(id)
productsbulkUpsert(rows), importCsv(blob), score(id), scoreAll(), facets(), schema()
schemasinfer(events), validate(eventType, payload)
activationssync(id)
userssearch(), get(id), events(id), segments(id), explain(id, segmentId)
queriesrun(id), results(id), simulate(body), dashboard(), winRate()
pagesbulkGenerate(), regenerate(id), build(id, body), publish(id), export(id, { format }), query(q)
analyticsoverview(), usage(), segments(), overlap(), activations()

Examples#

ts
// Products — bulk upsert by SKU, then score the catalog
await segops.products.bulkUpsert([
  { sku: 'TR-01', name: 'Trail Runner', data: { price: 120, category: 'shoes' } },
]);
await segops.products.scoreAll();

// Activations — sync a segment to a connector
await segops.activations.sync(activationId);

// AI visibility — register, run, read results
const q = await segops.queries.create({ query_text: 'best trail running shoes' });
await segops.queries.run(q.id);
const results = await segops.queries.results(q.id);

// Pages — export to HTML
const job = await segops.pages.export(pageId, { format: 'html' });

Pagination#

List endpoints are page-number paginated. list() returns the { count, next, previous, results } envelope; iterate() walks every page:

ts
const firstPage = await segops.segments.list({ page: 1, page_size: 100 });
for await (const item of segops.products.iterate({ page_size: 200 })) {
  // …every product
}

Errors, retries, idempotency#

  • Non-2xx responses throw SegOpsApiError with .status and .body.
  • 429 and 5xx are retried (honoring Retry-After, exponential backoff; configurable via maxRetries).
  • Mutations send an Idempotency-Key header automatically (forward-compatible with server-side idempotency).
ts
import { SegOpsApiError } from '@segops/admin';
try {
  await segops.segments.get(999999);
} catch (err) {
  if (err instanceof SegOpsApiError && err.status === 404) { /* … */ }
}

Webhook verification#

Verify SegOps outbound webhooks (X-SegOps-Signature: sha256=…):

ts
import { verifyWebhook } from '@segops/admin/webhook';

if (!verifyWebhook(rawBody, req.headers['x-segops-signature'], webhookSecret)) {
  return res.status(401).end();
}

CLI#

The package ships a CLI for quick ops and scripting:

bash
export SEGOPS_API_KEY=sk_…
export SEGOPS_API_URL=https://api.segops.ai/api   # optional

npx @segops/admin segments list
npx @segops/admin segments recompute 12
npx @segops/admin products import users.csv
npx @segops/admin pages export 8 --format=html

Run npx @segops/admin help for the full command list.

Escape hatch#

For endpoints not yet wrapped, use the low-level client:

ts
await segops.http.request('POST', '/some/endpoint/', { body: { … } });