Skip to main content

HTTP Client

REST API client for character management, 3D model generation, and asset downloading.

EstuaryHttpClient

Provides access to Estuary's REST API endpoints from Lens Studio. Uses the global fetch() API available in Lens Studio 5.3+ / Spectacles OS 5.58+.

Location: src/Core/EstuaryHttpClient.ts

import { EstuaryHttpClient, EstuaryConfig } from 'estuary-lens-studio-sdk';

Constructor

const config: EstuaryConfig = {
serverUrl: 'wss://api.estuary-ai.com',
apiKey: 'your-api-key',
characterId: 'your-character-id',
playerId: 'user-id'
};

const httpClient = new EstuaryHttpClient(config);
URL Handling

The client automatically converts ws:// / wss:// URLs to http:// / https:// for REST calls.


Character Management

getCharacters

List characters with pagination.

getCharacters(limit?: number, offset?: number): Promise<CharacterListResponse>
ParameterTypeDefaultDescription
limitnumber20Number of characters per page (1-100)
offsetnumber0Offset into results
const list = await httpClient.getCharacters(20, 0);

print(`Showing ${list.characters.length} of ${list.total} characters`);
for (const character of list.characters) {
print(`${character.name}: ${character.tagline}`);
}

getCharacter

Get a single character by ID.

getCharacter(characterId: string): Promise<AgentResponse>
const character = await httpClient.getCharacter('character-uuid');
print(`Name: ${character.name}`);
print(`Model status: ${character.modelStatus}`);

Image-to-Character Generation

uploadImageToCharacter

Create an AI character from an image. The server analyzes the image to generate a persona, appearance description, and voice configuration.

uploadImageToCharacter(
imageBase64: string,
mimeType: string,
options?: ImageToCharacterOptions
): Promise<AgentResponse>
ParameterTypeDefaultDescription
imageBase64stringrequiredBase64-encoded image data
mimeTypestringrequiredImage MIME type (image/jpeg, image/png)
optionsImageToCharacterOptions-Optional generation hints

ImageToCharacterOptions

interface ImageToCharacterOptions {
appearancePrompt?: string; // Hint for appearance description
voicePrompt?: string; // Hint for voice selection
}
// Capture an image and create a character from it
const agent = await httpClient.uploadImageToCharacter(
imageBase64,
'image/jpeg',
{
appearancePrompt: 'A friendly cartoon character',
voicePrompt: 'Warm and cheerful voice'
}
);

print(`Created character: ${agent.name}`);
print(`ID: ${agent.id}`);
Spectacles Limitation

Spectacles does not support multipart/form-data, so image uploads use JSON with Base64-encoded data. Maximum ~7.5MB Base64 payload (encodes to ~10MB image).


3D Model Generation

generateModel

Trigger 3D model generation for a character. Requires the character to have an appearance description (typically set by uploadImageToCharacter).

generateModel(agentId: string): Promise<ModelStatusResponse>
const status = await httpClient.generateModel(agent.id);
print(`Model generation started: ${status.modelStatus}`);
// status.modelStatus will be "generating"

getModelStatus

Check the current status of a 3D model generation.

getModelStatus(agentId: string): Promise<ModelStatusResponse>
const status = await httpClient.getModelStatus(agent.id);
print(`Status: ${status.modelStatus}, Progress: ${status.progress}%`);

if (status.modelStatus === 'completed') {
print(`GLB URL: ${status.modelUrl}`);
}

pollModelStatus

Poll for model generation status with exponential backoff. Calls your callbacks as status changes.

pollModelStatus(
agentId: string,
onStatusChanged: (status: ModelStatusResponse) => void,
onCompleted: (status: ModelStatusResponse) => void,
onError: (error: string) => void,
initialIntervalMs?: number,
maxIntervalMs?: number,
maxDurationMs?: number
): void
ParameterTypeDefaultDescription
agentIdstringrequiredCharacter UUID
onStatusChangedfunctionrequiredCalled on each status update
onCompletedfunctionrequiredCalled when model is ready
onErrorfunctionrequiredCalled on failure
initialIntervalMsnumber2000Initial poll interval
maxIntervalMsnumber10000Maximum poll interval
maxDurationMsnumber300000Maximum total polling time (5 min)
httpClient.pollModelStatus(
agent.id,
(status) => {
print(`Progress: ${status.progress}%`);
print(`Status: ${status.modelStatus}`);
},
(status) => {
print(`Model ready! URL: ${status.modelUrl}`);
// Download and instantiate the GLB
},
(error) => {
print(`Model generation failed: ${error}`);
}
);

stopPolling

Cancel an active polling operation.

httpClient.stopPolling();

GLB Model Download

downloadAndInstantiateGlb

Download a GLB 3D model and instantiate it in the scene. Uses Lens Studio's InternetModule and RemoteMediaModule pipeline.

downloadAndInstantiateGlb(
url: string,
parent: SceneObject,
material: Material,
onProgress?: (progress: number) => void,
gltfSettings?: GltfSettings
): Promise<SceneObject>
ParameterTypeDescription
urlstringURL to the GLB file
parentSceneObjectParent object in scene hierarchy
materialMaterialMaterial to apply to the model
onProgressfunctionOptional progress callback (0-1)
gltfSettingsGltfSettingsOptional GLTF import settings
// After model generation completes
const sceneObject = await httpClient.downloadAndInstantiateGlb(
status.modelUrl,
parentObject,
myMaterial,
(progress) => {
print(`Download: ${Math.round(progress * 100)}%`);
}
);

print('3D model loaded into scene!');
Prerequisites
  • setInternetModule() must have been called before downloading
  • Requires RemoteMediaModule for GLB loading (available in Lens Studio)

Complete Example: Image to 3D Character

import { EstuaryHttpClient, EstuaryConfig } from 'estuary-lens-studio-sdk';

@component
export class CharacterGenerator extends BaseScriptComponent {
@input parentObject: SceneObject;
@input material: Material;

private httpClient: EstuaryHttpClient;

onAwake() {
const config: EstuaryConfig = {
serverUrl: 'wss://api.estuary-ai.com',
apiKey: 'your-api-key',
characterId: '',
playerId: 'user-id'
};
this.httpClient = new EstuaryHttpClient(config);
}

async createCharacterFromImage(imageBase64: string) {
// Step 1: Create character from image
const agent = await this.httpClient.uploadImageToCharacter(
imageBase64, 'image/jpeg'
);
print(`Created: ${agent.name}`);

// Step 2: Generate 3D model
await this.httpClient.generateModel(agent.id);

// Step 3: Poll until complete, then download
this.httpClient.pollModelStatus(
agent.id,
(status) => print(`${status.progress}%`),
async (status) => {
// Step 4: Download and instantiate GLB
const obj = await this.httpClient.downloadAndInstantiateGlb(
status.modelUrl,
this.parentObject,
this.material
);
print('Character loaded!');
},
(error) => print(`Failed: ${error}`)
);
}
}

See Also