Partner SDK
Webhooks, API keys, and analytics integration for HoloScript partners. Enables third-party platforms to build on top of HoloScript with authenticated API access.
Overview
Partner SDK provides webhooks for real-time events, REST API access with API keys, and analytics dashboards for monitoring usage.
Installation
bash
npm install @holoscript/partner-sdkQuick Start
Register as Partner
typescript
import { PartnerSDK } from '@holoscript/partner-sdk';
const partner = new PartnerSDK({
organizationId: 'my-org',
apiKey: process.env.HOLOSCRIPT_PARTNER_KEY,
webhookSecret: process.env.WEBHOOK_SECRET,
});
// Verify credentials
const verified = await partner.verify();
console.log(verified.organization); // 'my-org'
console.log(verified.tier); // 'professional', 'enterprise'API Key Management
Create API Key
typescript
const key = await partner.createApiKey({
name: 'Production Key',
scopes: ['read:scenes', 'write:scenes', 'export:marketplace'],
expiresIn: 31536000, // 1 year
});
console.log(key.token); // sk_live_***
console.log(key.rotationDate); // When to rotateUse API Key
typescript
import fetch from 'node-fetch';
const response = await fetch('https://api.holoscript.dev/scenes', {
headers: {
Authorization: `Bearer sk_live_***`,
'Content-Type': 'application/json',
},
});
const scenes = await response.json();Revoke API Key
typescript
await partner.revokeApiKey('key-uuid');
// All requests using this key will fail immediatelyREST API Endpoints
Scenes
typescript
// List scenes
const scenes = await partner.api.scenes.list({
limit: 50,
skip: 0,
filter: { visibility: 'public' },
});
// Get scene
const scene = await partner.api.scenes.get(sceneId);
// Create scene
const newScene = await partner.api.scenes.create({
name: 'My Scene',
description: 'A test scene',
visibility: 'private',
});
// Update scene
await partner.api.scenes.update(sceneId, {
name: 'Updated Name',
});
// Delete scene
await partner.api.scenes.delete(sceneId);
// Export scene
const exported = await partner.api.scenes.export(sceneId, {
format: 'godot', // godot, unity, unreal, webgpu
includeAssets: true,
});Objects & Templates
typescript
// List objects in scene
const objects = await partner.api.scenes.objects.list(sceneId);
// Get object
const obj = await partner.api.scenes.objects.get(sceneId, objectId);
// Update object
await partner.api.scenes.objects.update(sceneId, objectId, {
position: [0, 1, 0],
color: '#ff0000',
});Marketplace
typescript
// Get marketplace listings
const listings = await partner.api.marketplace.list({
category: 'vr-games',
sort: 'downloads',
});
// Publish scene to marketplace
const published = await partner.api.marketplace.publish(sceneId, {
category: 'vr-games',
tags: ['multiplayer', 'action'],
price: 9.99,
});
// Get sales analytics
const analytics = await partner.api.marketplace.analytics(publishedId, {
period: '30d', // '7d', '30d', '90d', 'all'
});
console.log(analytics.downloads);
console.log(analytics.revenue);Webhooks
Subscribe to Events
typescript
const webhook = await partner.createWebhook({
url: 'https://myapp.com/webhooks/holoscript',
events: ['scene.created', 'scene.updated', 'scene.published', 'marketplace.purchase'],
secret: 'webhook-secret-key',
});
console.log(webhook.id); // webhook-***
console.log(webhook.signedUrl); // With signatureHandle Webhook Events
typescript
import express from 'express';
import { PartnerSDK } from '@holoscript/partner-sdk';
const app = express();
const partner = new PartnerSDK();
app.post('/webhooks/holoscript', express.json(), async (req, res) => {
const signature = req.headers['x-holoscript-signature'];
const payload = req.body;
// Verify webhook signature
const valid = partner.verifyWebhookSignature(
JSON.stringify(payload),
signature,
process.env.WEBHOOK_SECRET
);
if (!valid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Handle event
switch (payload.event) {
case 'scene.created':
console.log('New scene:', payload.data.sceneId);
break;
case 'marketplace.purchase':
console.log('Purchase:', payload.data.orderId);
break;
}
res.json({ received: true });
});Webhook Events
| Event | Payload | Sent When |
|---|---|---|
scene.created | { sceneId, userId, timestamp } | New scene created |
scene.updated | { sceneId, changes, timestamp } | Scene modified |
scene.deleted | { sceneId, timestamp } | Scene removed |
scene.published | { sceneId, visibility, timestamp } | Made public |
scene.exported | { sceneId, format, timestamp } | Exported to target |
marketplace.listed | { sceneId, listingId, price } | Listed in marketplace |
marketplace.purchase | { listingId, orderId, buyer, amount } | Item purchased |
marketplace.refund | { orderId, reason, amount } | Refund issued |
Analytics
Get Usage Metrics
typescript
const metrics = await partner.analytics.getMetrics({
period: '30d',
metrics: ['api_calls', 'scenes_created', 'exports', 'monthly_active_users'],
});
console.log(metrics.api_calls); // 45230
console.log(metrics.scenes_created); // 128
console.log(metrics.exports); // { godot: 45, unity: 32, webgpu: 87 }Billing
typescript
// Get current plan
const plan = await partner.billing.getPlan();
console.log(plan.tier); // 'professional'
console.log(plan.apiCallQuota); // 100000/month
console.log(plan.costPerCall); // $0.0001
// Get usage
const usage = await partner.billing.getUsage();
console.log(usage.apiCallsUsed); // 45230
console.log(usage.estimatedCost); // $4.52
console.log(usage.renewsAt); // Date
// Upgrade plan
await partner.billing.upgradePlan({
newTier: 'enterprise',
});Error Handling
typescript
try {
const scene = await partner.api.scenes.get(sceneId);
} catch (error) {
if (error.code === 'SCENE_NOT_FOUND') {
console.error('Scene does not exist');
} else if (error.code === 'UNAUTHORIZED') {
console.error('API key is invalid or expired');
} else if (error.code === 'RATE_LIMITED') {
console.error('Rate limit exceeded, retry after:', error.retryAfter);
} else if (error.code === 'QUOTA_EXCEEDED') {
console.error('Monthly quota exceeded');
} else if (error.code === 'INVALID_REQUEST') {
console.error('Invalid parameters:', error.details);
}
}Rate Limiting
Standard Tier:
- 10 requests/second
- 100,000 requests/month
Professional Tier:
- 100 requests/second
- 1,000,000 requests/month
Enterprise Tier:
- Custom limits
- Dedicated supportCheck rate limit headers:
typescript
const response = await fetch('https://api.holoscript.dev/...');
console.log(response.headers.get('x-ratelimit-limit')); // 100000
console.log(response.headers.get('x-ratelimit-remaining')); // 99950
console.log(response.headers.get('x-ratelimit-reset')); // Unix timestampEnvironment Variables
bash
# Partner credentials
HOLOSCRIPT_PARTNER_ID=***
HOLOSCRIPT_PARTNER_KEY=***
HOLOSCRIPT_WEBHOOK_SECRET=***
# API configuration
HOLOSCRIPT_API_BASE_URL=https://api.holoscript.dev
HOLOSCRIPT_API_TIMEOUT=30000
# Webhook
WEBHOOK_URL=https://myapp.com/webhooks/holoscriptBest Practices
- Store API keys securely — Never commit to version control
- Rotate keys regularly — Every 90 days minimum
- Verify webhook signatures — Always validate incoming events
- Implement exponential backoff — Retry failed API calls
- Cache responses — Reduce API calls with intelligent caching
- Monitor rate limits — Stay below quota to avoid service disruption
- Use webhooks instead of polling — More efficient, real-time updates
- Document API usage — Track which endpoints you call and why
See Also
- Auth — API key authentication details
- Security Sandbox — Safely execute partner code
- MCP Server — Tool discovery for partners