Build
TypeScript SDK
Using the Arke TypeScript SDK for type-safe API interaction.
Installation
npm install @arke-institute/sdkConfiguration
The SDK is auto-generated from the OpenAPI specification using openapi-typescript and openapi-fetch, so types stay in sync with the API.
import { ArkeClient } from '@arke-institute/sdk';
// With JWT token (from Supabase auth)
const arke = new ArkeClient({
authToken: 'your-jwt-token',
});
// With agent API key
const arke = new ArkeClient({
authToken: 'ak_your-agent-api-key',
});
// With user API key
const arke = new ArkeClient({
authToken: 'uk_your-user-api-key',
});Configuration Options
interface ArkeClientConfig {
// Base URL for the Arke API (default: 'https://api.arke.institute')
baseUrl?: string;
// Authentication token - JWT, agent key (ak_), or user key (uk_)
// Authorization header format is auto-detected from token prefix
authToken?: string;
// Network to use: 'main' or 'test' (default: 'main')
// Test network uses 'II' prefixed IDs and isolated data
network?: 'main' | 'test';
// Custom headers to include in all requests
headers?: Record<string, string>;
// Retry configuration (or false to disable)
retry?: RetryConfig | false;
}
interface RetryConfig {
maxRetries?: number; // Default: 3
initialDelay?: number; // Default: 100ms
maxDelay?: number; // Default: 5000ms
retryOn5xx?: boolean; // Default: true
retryOnNetworkError?: boolean; // Default: true
onRetry?: (attempt: number, error: Error, delayMs: number) => void;
}Making API Calls
The SDK exposes the raw openapi-fetch client via arke.api, which provides type-safe GET, POST, PUT, and DELETE methods.
// Create an entity
const { data, error } = await arke.api.POST('/entities', {
body: {
collection_id: '01ABC...',
type: 'file',
properties: { label: 'My File' }
}
});
if (error) {
console.error('Failed to create entity:', error);
} else {
console.log('Created entity:', data.id);
}
// Get an entity
const { data } = await arke.api.GET('/entities/{id}', {
params: { path: { id: '01XYZ...' } }
});
// Update an entity (with CAS tip for optimistic locking)
const { data } = await arke.api.PUT('/entities/{id}', {
params: { path: { id: '01XYZ...' } },
body: {
tip: 'bafyrei...', // Current CID for compare-and-swap
properties: { title: 'Updated Title' }
}
});
// Delete an entity
const { data } = await arke.api.DELETE('/entities/{id}', {
params: { path: { id: '01XYZ...' } }
});File Content Methods
The SDK provides convenience methods for handling binary file content, since openapi-fetch doesn't automatically handle non-JSON responses.
// Get file content as Blob
const { data, error } = await arke.getFileContent('01ABC...');
if (data) {
const text = await data.text();
}
// Get file content as ArrayBuffer
const { data, error } = await arke.getFileContentAsArrayBuffer('01ABC...');
if (data) {
const bytes = new Uint8Array(data);
}
// Get file content as ReadableStream (for large files)
const { data, error } = await arke.getFileContentAsStream('01ABC...');
if (data) {
const reader = data.getReader();
// Process chunks...
}
// Upload file content
const blob = new Blob(['Hello, world!'], { type: 'text/plain' });
const { data, error } = await arke.uploadFileContent('01ABC...', blob, 'text/plain');
// Upload from ArrayBuffer or Uint8Array
const buffer = new TextEncoder().encode('Hello, world!').buffer;
const { data, error } = await arke.uploadFileContent('01ABC...', buffer, 'text/plain');Client Utility Methods
// Update auth token (recreates underlying client)
arke.setAuthToken('new-token');
// Clear auth token
arke.clearAuthToken();
// Check authentication status
if (arke.isAuthenticated) {
// Token is set
}
// Get base URL
console.log(arke.baseUrl);
// Get current config
const config = arke.getConfig();Type Exports
The SDK exports the generated OpenAPI types for use in your application:
import type { paths, components, operations } from '@arke-institute/sdk';
// Use component schemas
type Entity = components['schemas']['Entity'];
type Collection = components['schemas']['Collection'];
type File = components['schemas']['File'];
// Use operation types for request/response
type CreateEntityBody = operations['createEntity']['requestBody']['content']['application/json'];Error Classes
The SDK provides typed error classes for common API errors:
import {
ArkeError,
CASConflictError,
NotFoundError,
ValidationError,
AuthenticationError,
ForbiddenError,
parseApiError,
} from '@arke-institute/sdk';
const { data, error } = await arke.api.PUT('/entities/{id}', {
params: { path: { id: entityId } },
body: { tip: oldTip, properties: { title: 'New Title' } }
});
if (error) {
const apiError = parseApiError(error.status, error);
if (apiError instanceof CASConflictError) {
// Entity was modified - refresh and retry
console.log('Expected tip:', apiError.expectedTip);
console.log('Actual tip:', apiError.actualTip);
} else if (apiError instanceof NotFoundError) {
// Entity doesn't exist
} else if (apiError instanceof ValidationError) {
// Invalid request data
} else if (apiError instanceof AuthenticationError) {
// Token expired or invalid
} else if (apiError instanceof ForbiddenError) {
// Permission denied
}
}Upload Module
The SDK includes a high-level upload module for uploading folder trees:
import { ArkeClient } from '@arke-institute/sdk';
import { uploadTree, buildUploadTree } from '@arke-institute/sdk/operations';
const client = new ArkeClient({ authToken: 'your-token' });
// Build upload tree from file data (works in browser and Node.js)
const tree = buildUploadTree([
{ path: 'docs/readme.md', data: readmeBuffer },
{ path: 'images/logo.png', data: logoBlob },
]);
// Upload to a new collection
const result = await uploadTree(client, tree, {
target: {
createCollection: {
label: 'My Upload',
description: 'Uploaded folder contents',
},
},
onProgress: (p) => console.log(`${p.phase}: ${p.phasePercent}%`),
});
console.log('Created collection:', result.collection.id);
console.log('Uploaded files:', result.files.length);Upload Options
interface UploadOptions {
target: {
// Use existing collection
collectionId?: string;
// Parent folder/collection ID
parentId?: string;
// Or create a new collection
createCollection?: {
label: string;
description?: string;
roles?: Record<string, string[]>;
};
};
// Progress callback
onProgress?: (progress: UploadProgress) => void;
// Max concurrent operations (default: 5)
concurrency?: number;
// Continue uploading even if some files fail (default: false)
continueOnError?: boolean;
// Max bytes in flight during upload (default: 200 MB)
maxBytesInFlight?: number;
// Custom note for created entities
note?: string;
}Browser File Scanning
import { scanFileSystemEntries, scanFileList } from '@arke-institute/sdk/operations';
// From drag-and-drop DataTransferItemList
const tree = await scanFileSystemEntries(dataTransfer.items);
// From file input FileList
const tree = await scanFileList(fileInput.files);CID Utilities
import { computeCid, verifyCid } from '@arke-institute/sdk/operations';
// Compute CID for content (CIDv1, raw codec, SHA-256)
const cid = await computeCid(fileBuffer);
// Verify content matches expected CID
const isValid = await verifyCid(fileBuffer, expectedCid);Factory Function
For functional style, use createArkeClient:
import { createArkeClient } from '@arke-institute/sdk';
const arke = createArkeClient({ authToken: 'your-token' });See Also
- API Reference for the full list of available endpoints
- Authentication for token management
- Entities for working with entities