JavaScript SDK
Official JavaScript/TypeScript client for GlyphNet.
Installation
npm install @glyphnet/sdk
# or
yarn add @glyphnet/sdk
# or
pnpm add @glyphnet/sdkRequirements: Node.js 16+
Quick Start
import { GlyphNet } from '@glyphnet/sdk';
// Initialize client
const client = new GlyphNet({ apiKey: 'gn_live_...' });
// Verify text
const result = await client.verify('The Earth orbits the Sun');
console.log(`Verified: ${result.verified}`);
console.log(`Confidence: ${result.confidence}`);TypeScript Support
Full TypeScript support with complete type definitions:
import { GlyphNet, VerificationResult, Claim } from '@glyphnet/sdk';
const client = new GlyphNet({ apiKey: 'gn_live_...' });
const result: VerificationResult = await client.verify(text);
result.claims.forEach((claim: Claim) => {
console.log(`${claim.text}: ${claim.confidence}`);
});Configuration
Using Environment Variables
export GLYPHNET_API_KEY="gn_live_..."import { GlyphNet } from '@glyphnet/sdk';
// Automatically uses GLYPHNET_API_KEY
const client = new GlyphNet();Client Options
import { GlyphNet } from '@glyphnet/sdk';
const client = new GlyphNet({
apiKey: 'gn_live_...', // Required (or use env var)
baseUrl: 'https://api.glyphnet.io', // Optional
timeout: 30000, // Timeout in milliseconds
maxRetries: 3, // Retry failed requests
retryDelay: 1000, // Initial retry delay (ms)
});Verification Methods
Basic Verification
const result = await client.verify('Paris is the capital of France');
console.log(result.verified); // true
console.log(result.confidence); // 0.98
console.log(result.claims); // Array of claim objectsWith Options
// Flagging mode (default)
const result = await client.verify(text, { mode: 'flagging' });
// Blocking mode - throws if unverified
const result = await client.verify(text, { mode: 'blocking' });
// Logging mode - always succeeds
const result = await client.verify(text, { mode: 'logging' });
// Custom threshold
const result = await client.verify(text, { threshold: 0.8 });
// Combined options
const result = await client.verify(text, {
mode: 'flagging',
threshold: 0.75,
});Response Types
VerificationResult
interface VerificationResult {
requestId: string;
text: string;
flagged: boolean;
claims: Claim[];
summary: {
totalClaims: number;
verified: number;
unverified: number;
avgConfidence: number;
};
processingTimeMs: number;
}
// Convenience getters
result.verified; // !result.flagged
result.confidence; // result.summary.avgConfidenceClaim
interface Claim {
text: string;
verified: boolean;
confidence: number;
sources?: string[];
}Error Handling
import { GlyphNet } from '@glyphnet/sdk';
import {
GlyphNetError,
AuthenticationError,
RateLimitError,
QuotaExceededError,
ValidationError,
APIError,
NetworkError,
} from '@glyphnet/sdk/errors';
const client = new GlyphNet();
try {
const result = await client.verify(text);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid or missing API key');
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter}s`);
await sleep(error.retryAfter * 1000);
// Retry...
} else if (error instanceof QuotaExceededError) {
console.error(`Quota exceeded. Resets at ${error.resetsAt}`);
} else if (error instanceof ValidationError) {
console.error(`Invalid request: ${error.message}`);
console.error(`Field: ${error.field}`);
} else if (error instanceof NetworkError) {
console.error(`Network error: ${error.message}`);
} else if (error instanceof APIError) {
console.error(`API error ${error.statusCode}: ${error.message}`);
} else if (error instanceof GlyphNetError) {
console.error(`GlyphNet error: ${error.message}`);
} else {
throw error;
}
}Harm Detection
const result = await client.harmDetect(text);
console.log(result.harmful); // true if harmful detected
console.log(result.categories); // Array of detected categories
console.log(result.severity); // "low" | "medium" | "high"
// Iterate categories
for (const category of result.categories) {
console.log(`${category.name}: ${category.confidence}`);
}API Key Management
// List all keys
const keys = await client.keys.list();
keys.forEach(key => {
console.log(`${key.name}: ${key.prefix}...`);
});
// Create a new key
const newKey = await client.keys.create({ name: 'Production Key' });
console.log(`New key: ${newKey.apiKey}`); // Only shown once!
// Revoke a key
await client.keys.revoke('key_abc123');Usage Statistics
const usage = await client.usage.get();
console.log(`Used: ${usage.currentUsage}`);
console.log(`Limit: ${usage.monthlyLimit}`);
console.log(`Remaining: ${usage.remaining}`);
console.log(`Percentage: ${usage.percentageUsed}%`);
console.log(`Resets: ${usage.resetsAt}`);
// Rate limit info
console.log(`This minute: ${usage.rateLimit.currentMinuteUsage}`);
console.log(`Per-minute limit: ${usage.rateLimit.requestsPerMinute}`);Batch Processing
// Process multiple texts concurrently
const texts = [
'The Earth is round.',
'Water boils at 100°C.',
'The speed of light is constant.',
];
// Concurrent verification
const results = await Promise.all(
texts.map(text => client.verify(text))
);
// With concurrency limit
async function batchVerify(
texts: string[],
maxConcurrent: number = 10
): Promise<VerificationResult[]> {
const results: VerificationResult[] = [];
for (let i = 0; i < texts.length; i += maxConcurrent) {
const batch = texts.slice(i, i + maxConcurrent);
const batchResults = await Promise.all(
batch.map(text => client.verify(text))
);
results.push(...batchResults);
}
return results;
}Streaming Support
// For long content, stream claim-by-claim
const stream = await client.verifyStream(longText);
for await (const claim of stream) {
console.log(`Claim: ${claim.text}`);
console.log(`Verified: ${claim.verified}`);
console.log(`Confidence: ${claim.confidence}`);
}Retry Configuration
import { GlyphNet, RetryConfig } from '@glyphnet/sdk';
const client = new GlyphNet({
apiKey: 'gn_live_...',
retry: {
maxRetries: 3,
initialDelay: 1000,
maxDelay: 60000,
exponentialBase: 2,
retryOn: [429, 500, 502, 503, 504],
} as RetryConfig,
});Framework Examples
Next.js API Route
// app/api/verify/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { GlyphNet } from '@glyphnet/sdk';
const client = new GlyphNet();
export async function POST(request: NextRequest) {
try {
const { text } = await request.json();
const result = await client.verify(text);
return NextResponse.json(result);
} catch (error) {
return NextResponse.json(
{ error: 'Verification failed' },
{ status: 500 }
);
}
}Express.js Middleware
import express from 'express';
import { GlyphNet } from '@glyphnet/sdk';
const app = express();
const client = new GlyphNet();
// Verification middleware
const verifyAIContent = async (
req: express.Request,
res: express.Response,
next: express.NextFunction
) => {
if (req.body.aiGenerated) {
try {
const result = await client.verify(req.body.content);
req.verification = result;
if (result.flagged) {
res.setHeader('X-Verification-Warning', 'true');
}
} catch (error) {
console.error('Verification failed:', error);
}
}
next();
};
app.use(express.json());
app.use(verifyAIContent);Vercel Serverless
// api/verify.ts
import type { VercelRequest, VercelResponse } from '@vercel/node';
import { GlyphNet } from '@glyphnet/sdk';
const client = new GlyphNet();
export default async function handler(
req: VercelRequest,
res: VercelResponse
) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const result = await client.verify(req.body.text);
return res.status(200).json(result);
} catch (error) {
return res.status(500).json({ error: 'Verification failed' });
}
}React Hook
// hooks/useVerification.ts
import { useState, useCallback } from 'react';
interface UseVerificationResult {
verify: (text: string) => Promise<void>;
result: VerificationResult | null;
loading: boolean;
error: Error | null;
}
export function useVerification(): UseVerificationResult {
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const verify = useCallback(async (text: string) => {
setLoading(true);
setError(null);
try {
const response = await fetch('/api/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text }),
});
if (!response.ok) throw new Error('Verification failed');
const data = await response.json();
setResult(data);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}, []);
return { verify, result, loading, error };
}Browser Usage
Important: Never expose your API key in browser code. Always use a backend proxy.
// Frontend - calls your backend
async function verifyText(text: string) {
const response = await fetch('/api/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text }),
});
return response.json();
}
// Backend - uses SDK with API key
import { GlyphNet } from '@glyphnet/sdk';
const client = new GlyphNet({
apiKey: process.env.GLYPHNET_API_KEY,
});
export async function POST(req) {
const { text } = await req.json();
const result = await client.verify(text);
return Response.json(result);
}