SDK reference
SDK reference
Last updated 5/24/2026
DataZoom SDK Reference
Version: 1.0.0-beta
Base URL: https://your-instance.datazoom.com
Framework: Next.js 15 App Router
Auth Provider: Clerk (multi-tenant, organization-scoped)
Table of Contents
- Installation
- Authentication Setup
- Client Initialization
- TypeScript Type Definitions
- Method Reference
- Pagination Patterns
- Rate Limiting
- Error Handling
Installation
DataZoom does not yet publish a standalone SDK package. Integrate directly against the API using the typed client below. Copy datazoom-client.ts into your project.
# Required peer dependencies
npm install @clerk/nextjs @supabase/supabase-js
# Optional: Zod for runtime validation of API responses
npm install zod
For server-side usage in Node.js or non-Next.js environments:
npm install @clerk/backend node-fetch
Authentication Setup
DataZoom uses Clerk for multi-tenant authentication. Every API request must carry a valid Clerk session token scoped to an organization. Unauthenticated requests return 401. Requests from users without an active organization context return 403.
Client-Side (Browser / React)
import { useAuth } from "@clerk/nextjs";
function useDataZoomToken(): () => Promise<string | null> {
const { getToken } = useAuth();
return () => getToken(); // returns a short-lived JWT
}
Server-Side (Next.js Route Handler / Server Action)
import { auth } from "@clerk/nextjs/server";
export async function GET(request: Request) {
const { userId, orgId } = await auth();
if (!userId || !orgId) {
return new Response("Unauthorized", { status: 401 });
}
// proceed with orgId-scoped database queries
}
Clerk Proxy
All Clerk telemetry and token refresh traffic is routed through the internal proxy at /api/clerk/proxy (product/app/api/clerk/proxy/route.ts) to avoid CORS issues and keep Clerk domain configuration minimal. Do not call Clerk's CDN endpoints directly from your embedded integration.
Client Initialization
// datazoom-client.ts
export interface DataZoomConfig {
/** Base URL of your DataZoom deployment, no trailing slash */
baseUrl: string;
/** Async function that returns a valid Clerk JWT */
getToken: () => Promise<string | null>;
/** Default organization ID; overridable per-request */
organizationId?: string;
/** Fetch timeout in milliseconds (default: 30000) */
timeoutMs?: number;
}
export class DataZoomClient {
private config: Required<DataZoomConfig>;
constructor(config: DataZoomConfig) {
this.config = {
organizationId: "",
timeoutMs: 30_000,
...config,
};
}
async request<T>(
path: string,
options: RequestInit & { params?: Record<string, string> } = {}
): Promise<T> {
const token = await this.config.getToken();
if (!token) throw new DataZoomAuthError("No Clerk session token available");
const url = new URL(`${this.config.baseUrl}${path}`);
if (options.params) {
Object.entries(options.params).forEach(([k, v]) =>
url.searchParams.set(k, v)
);
}
const controller = new AbortController();
const timer = setTimeout(
() => controller.abort(),
this.config.timeoutMs
);
let response: Response;
try {
response = await fetch(url.toString(), {
...options,
signal: controller.signal,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
...(this.config.organizationId && {
"X-Organization-Id": this.config.organizationId,
}),
...options.headers,
},
});
} finally {
clearTimeout(timer);
}
if (!response.ok) {
await DataZoomClient.throwApiError(response);
}
return response.json() as Promise<T>;
}
private static async throwApiError(response: Response): Promise<never> {
let body: unknown;
try {
body = await response.json();
} catch {
body = await response.text();
}
switch (response.status) {
case 401:
throw new DataZoomAuthError("Authentication failed", body);
case 403:
throw new DataZoomForbiddenError("Insufficient permissions", body);
case 404:
throw new DataZoomNotFoundError("Resource not found", body);
case 429:
throw new DataZoomRateLimitError("Rate limit exceeded", body);
default:
throw new DataZoomApiError(
`API error ${response.status}`,
response.status,
body
);
}
}
}
Initialization Example
import { DataZoomClient } from "./datazoom-client";
import { useAuth } from "@clerk/nextjs";
// React hook usage
function useDataZoom() {
const { getToken, orgId } = useAuth();
return new DataZoomClient({
baseUrl: process.env.NEXT_PUBLIC_APP_URL ?? "http://localhost:3000",
getToken,
organizationId: orgId ?? undefined,
});
}
// Server-side / Node.js usage
import { createClerkClient } from "@clerk/backend";
const clerk = createClerkClient({
secretKey: process.env.CLERK_SECRET_KEY,
});
const client = new DataZoomClient({
baseUrl: "https://your-instance.datazoom.com",
getToken: async () => {
const token = await clerk.sessions.getToken(
process.env.SESSION_ID!,
"datazoom"
);
return token.jwt;
},
organizationId: "org_yourOrgId",
});
TypeScript Type Definitions
// ─── Shared Primitives ───────────────────────────────────────────────────────
export type UUID = string;
export type ISODateString = string; // "2024-01-15"
export type ISOTimestamp = string; // "2024-01-15T10:30:00.000Z"
export type ImpactLevel = "critical" | "high" | "medium" | "low";
export type DocumentType =
| "equity"
| "ip_assignment"
| "financial"
| "healthcare"
| "agreement";
export type EventType =
| "equity_change"
| "agreement_signed"
| "ip_assignment"
| string;
// ─── Error Classes ────────────────────────────────────────────────────────────
export class DataZoomApiError extends Error {
constructor(
message: string,
public statusCode: number,
public body?: unknown
) {
super(message);
this.name = "DataZoomApiError";
}
}
export class DataZoomAuthError extends DataZoomApiError {
constructor(message: string, body?: unknown) {
super(message, 401, body);
this.name = "DataZoomAuthError";
}
}
export class DataZoomForbiddenError extends DataZoomApiError {
constructor(message: string, body?: unknown) {
super(message, 403, body);
this.name = "DataZoomForbiddenError";
}
}
export class DataZoomNotFoundError extends DataZoomApiError {
constructor(message: string, body?: unknown) {
super(message, 404, body);
this.name = "DataZoomNotFoundError";
}
}
export class DataZoomRateLimitError extends DataZoomApiError {
constructor(message: string, body?: unknown) {
super(message, 429, body);
this.name = "DataZoomRateLimitError";
}
}
// ─── Pagination ───────────────────────────────────────────────────────────────
export interface PaginatedResponse<T> {
data: T[];
total: number;
page: number;
pageSize: number;
hasNextPage: boolean;
}
export interface PaginationParams {
page?: number;
pageSize?: number;
}
// ─── Activity ─────────────────────────────────────────────────────────────────
export type ActivityEventType =
| "document_upload"
| "document_delete"
| "document_process"
| "risk_analysis"
| "strategic_analysis"
| "query"
| string;
export interface ActivityEvent {
id: UUID;
orgId: string;
userId: string;
eventType: ActivityEventType;
resourceType: string;
resourceId: UUID;
resourceName: string;
metadata: Record<string, unknown>;
createdAt: ISOTimestamp;
}
export interface ActivityMetrics {
totalEvents: number;
documentUploads: number;
documentsDeleted: number;
queriesRun: number;
analysesRun: number;
activeUsers: number;
periodStart: ISOTimestamp;
periodEnd: ISOTimestamp;
}
export interface UnifiedCalendarDay {
date: ISODateString;
events: ActivityEvent[];
count: number;
}
export interface UnifiedCalendarResponse {
month: number;
year: number;
days: UnifiedCalendarDay[];
}
export interface UnifiedFeedResponse extends PaginatedResponse<ActivityEvent> {}
export interface ExportActivityParams {
startDate?: ISODateString;
endDate?: ISODateString;
eventTypes?: ActivityEventType[];
format?: "json" | "csv";
}
// ─── Admin Pipeline ───────────────────────────────────────────────────────────
export type PipelineStatus =
| "idle"
| "queued"
| "processing"
| "completed"
| "failed";
export interface PipelineJob {
id: UUID;
documentId: UUID;
documentName: string;
status: PipelineStatus;
stage: string;
attempt: number;
error?: string;
createdAt: ISOTimestamp;
updatedAt: ISOTimestamp;
}
export interface PipelineHealthResponse {
status: "healthy" | "degraded" | "down";
queueDepth: number;
activeWorkers: number;
failedLast24h: number;
avgProcessingMs: number;
cloudStatus: "provisioning" | "warming" | "ready" | "unavailable";
}
export interface PipelineRoutingStats {
localJobs: number;
cloudJobs: number;
failoverCount: number;
avgCloudLatencyMs: number;
}
export interface RetryPipelineRequest {
jobIds: UUID[];
}
export interface RetryPipelineResponse {
queued: UUID[];
failed: UUID[];
}
// ─── Advisor ─────────────────────────────────────────────────────────────────
export interface AdvisorQuery {
question: string;
documentIds?: UUID[];
threadId?: UUID;
}
export interface AdvisorResponse {
answer: string;
citations: Citation[];
threadId: UUID;
messageId: UUID;
tokensUsed: number;
modelUsed: string;
}
export interface Citation {
documentId: UUID;
documentName: string;
chunkIndex: number;
excerpt: string;
relevanceScore: number;
}
export interface RiskMemoRequest {
documentIds: UUID[];
focus?: string;
}
export interface RiskMemoResponse {
memo: string;
riskItems: RiskItem[];
generatedAt: ISOTimestamp;
}
export interface RiskItem {
category: string;
severity: ImpactLevel;
description: string;
documentRef?: UUID;
}
export interface StrategicOptionsRequest {
context: string;
documentIds?: UUID[];
constraints?: string[];
}
export interface StrategicOptionsResponse {
options: StrategicOption[];
summary: string;
generatedAt: ISOTimestamp;
}
export interface StrategicOption {
title: string;
description: string;
pros: string[];
cons: string[];
feasibility: "high" | "medium" | "low";
}
export interface BatchAdvisorRequest {
queries: AdvisorQuery[];
}
export interface BatchAdvisorResponse {
results: Array<{ query: AdvisorQuery; response: AdvisorResponse }>;
}
// ─── Analysis ─────────────────────────────────────────────────────────────────
export interface PartyAnalysisRequest {
partyName: string;
documentIds?: UUID[];
}
export interface PartyAnalysisResponse {
party: string;
appearances: PartyAppearance[];
summary: string;
relatedParties: string[];
}
export interface PartyAppearance {
documentId: UUID;
documentName: string;
role: string;
sections: string[];
}
export interface RegenerateAnalysisRequest {
documentId: UUID;
analysisType: "summary" | "timeline" | "risk" | "parties";
}
export interface RegenerateAnalysisResponse {
documentId: UUID;
analysisType: string;
result: Record<string, unknown>;
regeneratedAt: ISOTimestamp;
}
// ─── Business Types ───────────────────────────────────────────────────────────
export interface BusinessType {
key: string;
label: string;
description: string;
documentCategories: string[];
}
export interface BusinessTypeProfile {
profileKey: string;
businessTypeKey: string;
name: string;
description: string;
checklistTemplate: ChecklistTemplate;
riskWeights: Record<string, number>;
}
export interface ChecklistTemplate {
id: UUID;
name: string;
items: ChecklistItem[];
}
export interface ChecklistItem {
id: UUID;
category: string;
requirement: string;
priority: ImpactLevel;
documentTypes: DocumentType[];
completed: boolean;
notes?: string;
}
// ─── Cap Table ────────────────────────────────────────────────────────────────
export interface CapTableSnapshot {
asOf: ISOTimestamp;
totalShares: number;
holders: ShareHolder[];
shareClasses: ShareClass[];
fullyDilutedShares: number;
}
export interface ShareHolder {
id: UUID;
name: string;
type: "individual" | "entity";
shares: number;
shareClass: string;
percentage: number;
options: number;
warrants: number;
}
export interface ShareClass {
name: string;
authorized: number;
issued: number;
liquidationPreference?: number;
isPreferred: boolean;
}
export interface CapTableTransaction {
id: UUID;
type:
| "issuance"
| "transfer"
| "cancellation"
| "exercise"
| "conversion"
| "repurchase";
date: ISODateString;
shares: number;
pricePerShare?: number;
fromHolder?: string;
toHolder: string;
shareClass: string;
documentId?: UUID;
status: "pending" | "approved" | "rejected" | "void";
notes?: string;
}
export interface CreateTransactionRequest {
type: CapTableTransaction["type"];
date: ISODateString;
shares: number;
pricePerShare?: number;
fromHolder?: string;
toHolder: string;
shareClass: string;
documentId?: UUID;
notes?: string;
}
export interface CapTableReviewItem {
id: UUID;
transaction: CapTableTransaction;
extractedFrom: UUID;
confidence: number;
flags: string[];
reviewedBy?: string;
reviewedAt?: ISOTimestamp;
}
export interface ExtractCapTableRequest {
documentId: UUID;
}
export interface ExtractCapTableResponse {
jobId: UUID;
status: "queued" | "processing";
estimatedMs: number;
}
export interface CapTableHealthResponse {
status: "healthy" | "degraded";
totalHolders: number;
totalTransactions: number;
pendingReview: number;
lastRecalculatedAt: ISOTimestamp;
}
// ─── Clauses ─────────────────────────────────────────────────────────────────
export interface ClauseCompareRequest {
clauseText: string;
documentIds?: UUID[];
clauseType?: string;
}
export interface ClauseCompareResponse {
matches: ClauseMatch[];
summary: string;
}
export interface ClauseMatch {
documentId: UUID;
documentName: string;
matchedClause: string;
similarityScore: number;
differences: string[];
}
// ─── Collaboration ────────────────────────────────────────────────────────────
export interface CollaborationTokenRequest {
documentId: UUID;
permissions?: ("read" | "comment" | "edit")[];
}
export interface CollaborationTokenResponse {
token: string;
wsUrl: string;
expiresAt: ISOTimestamp;
}
// ─── Company Settings ─────────────────────────────────────────────────────────
export interface CompanySettings {
orgId: string;
companyName: string;
businessType?: string;
incorporationState?: string;
foundedDate?: ISODateString;
employeeCount?: number;
linkedDocumentIds: UUID[];
updatedAt: ISOTimestamp;
}
export interface UpdateCompanySettingsRequest {
companyName?: string;
businessType?: string;
incorporationState?: string;
foundedDate?: ISODateString;
employeeCount?: number;
}
export interface LinkageMismatch {
field: string;
settingsValue: string;
documentValue: string;
documentId: UUID;
documentName: string;
severity: ImpactLevel;
}
export interface LinkageMismatchesResponse {
mismatches: LinkageMismatch[];
totalChecked: number;
lastCheckedAt: ISOTimestamp;
}
// ─── AI Tracking ─────────────────────────────────────────────────────────────
export interface TrackAIInteractionRequest {
interactionType: string;
modelUsed: string;
promptTokens: number;
completionTokens: number;
latencyMs: number;
success: boolean;
documentIds?: UUID[];
metadata?: Record<string, unknown>;
}
export interface TrackAIInteractionResponse {
tracked: boolean;
interactionId: UUID;
}
Method Reference
All methods are presented as static typed functions that call DataZoomClient.request. Import and bind them to your initialized client.
Activity API
Routes implemented in product/app/api/activity/.
getActivityFeed
Retrieves a paginated stream of activity events for the authenticated organization.
Signature
async function getActivityFeed(
client: DataZoomClient,
params?: PaginationParams & {
eventTypes?: ActivityEventType[];
userId?: string;
startDate?: ISODateString;
endDate?: ISODateString;
}
): Promise<UnifiedFeedResponse>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number, 1-indexed. Default: 1 |
pageSize | number | No | Records per page, max 100. Default: 25 |
eventTypes | ActivityEventType[] | No | Filter to specific event types |
userId | string | No | Filter to a specific Clerk user ID |
startDate | ISODateString | No | ISO date lower bound (inclusive) |
endDate | ISODateString | No | ISO date upper bound (inclusive) |
Returns: Promise<UnifiedFeedResponse>
Example
const feed = await getActivityFeed(client, {
page: 1,
pageSize: 50,
eventTypes: ["document_upload", "risk_analysis"],
startDate: "2024-01-01",
});
console.log(`${feed.total} total events`);
feed.data.forEach((event) => {
console.log(`[${event.eventType}] ${event.resourceName} at ${event.createdAt}`);
});
Error handling
try {
const feed = await getActivityFeed(client);
} catch (err) {
if (err instanceof DataZoomAuthError) {
// Redirect to sign-in
}
if (err instanceof DataZoomApiError) {
console.error(`API error ${err.statusCode}:`, err.body);
}
}
getActivityMetrics
Returns aggregate metrics for the organization over a time window.
Signature
async function getActivityMetrics(
client: DataZoomClient,
params?: {
startDate?: ISODateString;
endDate?: ISODateString;
}
): Promise<ActivityMetrics>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate | ISODateString | No | Metrics window start (inclusive) |
endDate | ISODateString | No | Metrics window end (inclusive) |
Returns: Promise<ActivityMetrics>
Example
const metrics = await getActivityMetrics(client, {
startDate: "2024-01-01",
endDate: "2024-01-31",
});
console.log(`${metrics.documentUploads} uploads, ${metrics.queriesRun} queries`);
exportActivity
Exports activity data as JSON or CSV. Returns raw text for CSV or a JSON array for JSON.
Signature
async function exportActivity(
client: DataZoomClient,
params?: ExportActivityParams
): Promise<ActivityEvent[] | string>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
startDate | ISODateString | No | Export window start |
endDate | ISODateString | No | Export window end |
eventTypes | ActivityEventType[] | No | Filter to specific event types |
format | "json" | "csv" | No | Output format. Default: "json" |
Returns: Promise<ActivityEvent[] | string>
Example
// Export last 30 days as CSV
const csv = await exportActivity(client, {
startDate: "2024-01-01",
endDate: "2024-01-31",
format: "csv",
});
const blob = new Blob([csv as string], { type: "text/csv" });
const url = URL.createObjectURL(blob);
getUnifiedCalendar
Returns a month-view calendar with activity events grouped by day.
Signature
async function getUnifiedCalendar(
client: DataZoomClient,
params: { year: number; month: number }
): Promise<UnifiedCalendarResponse>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
year | number | Yes | Four-digit year, e.g. 2024 |
month | number | Yes | Month number, 1–12 |
Returns: Promise<UnifiedCalendarResponse>
Example
const calendar = await getUnifiedCalendar(client, { year: 2024, month: 1 });
calendar.days.forEach((day) => {
if (day.count > 0) {
console.log(`${day.date}: ${day.count} events`);
}
});
getUnifiedDayActivity
Returns all activity events for a specific calendar day.
Signature
async function getUnifiedDayActivity(
client: DataZoomClient,
params: { year: number; month: number; day: number }
): Promise<ActivityEvent[]>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
year | number | Yes | Four-digit year |
month | number | Yes | Month 1–12 |
day | number | Yes | Day 1–31 |
Returns: Promise<ActivityEvent[]>
Example
const events = await getUnifiedDayActivity(client, {
year: 2024,
month: 1,
day: 15,
});
refreshUnifiedActivity
Triggers a background refresh of the unified activity materialized views.
Signature
async function refreshUnifiedActivity(
client: DataZoomClient
): Promise<{ refreshed: boolean; triggeredAt: ISOTimestamp }>
Returns: Promise<{ refreshed: boolean; triggeredAt: ISOTimestamp }>
Example
const result = await refreshUnifiedActivity(client);
console.log(`Refresh triggered at ${result.triggeredAt}`);
Admin Pipeline API
Routes implemented in product/app/api/admin/pipeline/. These endpoints require admin-level organization permissions.
getPipelineJobs
Lists document processing pipeline jobs with optional status filtering.
Signature
async function getPipelineJobs(
client: DataZoomClient,
params?: PaginationParams & { status?: PipelineStatus }
): Promise<PaginatedResponse<PipelineJob>>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number. Default: 1 |
pageSize | number | No | Records per page. Default: 25 |
status | PipelineStatus | No | Filter by job status |
Returns: Promise<PaginatedResponse<PipelineJob>>
Example
const failedJobs = await getPipelineJobs(client, {
status: "failed",
pageSize: 50,
});
console.log(`${failedJobs.total} failed jobs`);
getPipelineHealth
Returns the current health status of the document processing pipeline, including cloud worker pod state.
Signature
async function getPipelineHealth(
client: DataZoomClient
): Promise<PipelineHealthResponse>
Returns: Promise<PipelineHealthResponse>
Example
const health = await getPipelineHealth(client);
if (health.status !== "healthy") {
console.warn(`Pipeline degraded. Cloud status: ${health.cloudStatus}`);
console.warn(`Queue depth: ${health.queueDepth}`);
}
retryPipelineJobs
Re-queues one or more failed pipeline jobs.
Signature
async function retryPipelineJobs(
client: DataZoomClient,
body: RetryPipelineRequest
): Promise<RetryPipelineResponse>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
jobIds | UUID[] | Yes | Array of pipeline job IDs to retry |
Returns: Promise<RetryPipelineResponse>
Example
const result = await retryPipelineJobs(client, {
jobIds: ["job-uuid-1", "job-uuid-2"],
});
console.log(`Queued: ${result.queued.length}, could not retry: ${result.failed.length}`);
getCloudPipelineStatus
Returns the current RunPod cloud worker fleet status as tracked by the orchestrator.
Signature
async function getCloudPipelineStatus(
client: DataZoomClient
): Promise<{ cloudStatus: string; pods: unknown[]; lastUpdatedAt: ISOTimestamp }>
Returns: Promise<{ cloudStatus: string; pods: unknown[]; lastUpdatedAt: ISOTimestamp }>
Example
const cloud = await getCloudPipelineStatus(client);
console.log(`Cloud fleet: ${cloud.cloudStatus}`);
getRoutingStats
Returns statistics on local vs. cloud job routing decisions made by the model router.
Signature
async function getRoutingStats(
client: DataZoomClient
): Promise<PipelineRoutingStats>
Returns: Promise<PipelineRoutingStats>
Example
const stats = await getRoutingStats(client);
console.log(
`Local: ${stats.localJobs}, Cloud: ${stats.cloudJobs}, Failovers: ${stats.failoverCount}`
);
Advisor API
Routes implemented in product/app/api/advisor/. The advisor uses RAG over your organization's documents to answer questions and generate strategic analysis.
queryAdvisor
Sends a natural language question to the AI advisor. Uses RAG over embedded document chunks with pgvector similarity search.
Signature
async function queryAdvisor(
client: DataZoomClient,
body: AdvisorQuery
): Promise<AdvisorResponse>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
question | string | Yes | Natural language question |
documentIds | UUID[] | No | Scope retrieval to specific documents |
threadId | UUID | No | Continue an existing conversation thread |
Returns: Promise<AdvisorResponse>
Example
const response = await queryAdvisor(client, {
question: "What are the vesting cliff dates across all equity agreements?",
documentIds: ["doc-uuid-1", "doc-uuid-2"],
});
console.log(response.answer);
response.citations.forEach((c) => {
console.log(`Source: ${c.documentName} (score: ${c.relevanceScore.toFixed(2)})`