A JavaScript SDK for integrating A.D.A.M. 3D avatars into your web applications.
npm install adam-sdk
import { AvatarSDK } from 'adam-sdk';
// Get the iframe element from your page
const avatarIframe = document.getElementById('avatar-iframe');
// Instantiate the SDK
const sdk = new AvatarSDK(avatarIframe);
// Listen for the 'ready' event, which fires after a successful and secure connection
sdk.on('ready', () => {
console.log('SDK is ready! The avatar can now receive commands.');
sdk.speak('Hello from the packaged SDK!');
});
// Always handle potential connection errors
sdk.connect().catch(error => {
console.error("Failed to connect to avatar:", error);
});
All SDK commands wait for handshake completion before sending messages to the avatar iframe. This ensures consistent behavior and reliable communication between the parent application and the avatar.
All commands, including speak, playAnimation, and setExpression, follow the same pattern of verifying the connection before sending messages.
Protecting user data and sensitive API keys is the most critical aspect of the A.D.A.M. platform. Our security model is designed to be robust and transparent, ensuring that your keys are never exposed to the client-side.
The responsibility for security is intentionally separated between this SDK and the A.D.A.M. iframe application.
adam-sdk): Acts as a well-behaved messenger. Its only job is to send commands and listen for events. It has no access to your configuration or API keys.adam-speaks.com): Acts as the security gatekeeper. It is solely responsible for verifying the identity of the website it is embedded on before loading any sensitive data.When you call sdk.connect(), the following secure handshake takes place:
CHECK_READY_STATUS message to the iframe.event.origin property, which is a browser-verified value indicating the domain of your website.IframeSecurityService sends the origin to a secure backend Cloud Function. This function retrieves the Trusted Origins list associated with your avatar's configuration from Firestore.origin against your list of trusted domains.
IframeSecurityService call a second, separate Cloud Function to fetch the sensitive configuration, including your API keys.AVATAR_READY message back to the SDK. The ready event is fired, and your application can begin sending commands.To complete this security model, our Firestore database is locked down with the following rule, making it impossible for any client-side code to read or write to the avatar configuration collection. All data access is brokered through secure, server-side Cloud Functions.
// firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Disallow ALL client-side reads/writes to the avatars collection.
match /avatars/{avatarId} {
allow read, write: if false;
}
}
}
If the sdk.connect() promise rejects with a timeout error, it is a direct result of the security model working as intended.
This error means that the domain of the website where you are running the SDK has not been added to the "Trusted Origins" list in your A.D.A.M. admin console. To fix this, simply add the required domain (e.g., https://www.your-production-site.com or http://localhost:3000 for development) to the list.
The SDK and example templates communicate with the avatar iframe using window.postMessage. Messages are simple JSON objects with a type and an optional payload.
Security note: Always set the targetOrigin to your trusted iframe origin (e.g., https://your-avatar-host.example) instead of * in production.
speak{
"type": "speak",
"requestId": "optional-uuid",
"payload": {
"text": "Hello world",
"animation": { "name": "wave" },
"expression": { "name": "smile", "intensity": 0.8 },
"voice": { "id": "en-US-JennyNeural" },
"backgroundUrl": "https://cdn.example.com/scenes/lobby.jpg",
"scene": "lobby",
"customFlag": true
}
}
animation{ "type": "animation", "payload": { "name": "wave" }, "requestId": "optional-uuid" }
expression{ "type": "expression", "payload": { "name": "smile", "intensity": 0.8 }, "requestId": "optional-uuid" }
Fields:
type: Command name.payload: Command parameters (text is required; animation, expression, and voice are optional).
You may include any additional custom key/value pairs. They will be forwarded to the iframe payload as-is.requestId (optional): Provide to correlate command responses.{ "type": "ready" }
{ "type": "speech:start", "payload": { "utteranceId": "u1" } }
{ "type": "speech:end", "payload": { "utteranceId": "u1" } }
{ "type": "command:success", "payload": { "requestId": "optional-uuid", "result": { } } }
{ "type": "command:error", "payload": { "requestId": "optional-uuid", "message": "details" } }
Event notes:
event.origin against your trusted domain list before acting on events.requestId on commands, include it in success/error payloads for correlation.We include minimal, no-bloat starter templates under adam-sdk/examples/ that are ready to embed the avatar via an iframe and communicate using window.postMessage. Each template exposes simple placeholder methods and event handling:
speak(text)animation(name)expression(name, intensity)onEvent(handler) for iframe-emitted events like ready, speech:start, speech:end, etc.Important: In the example bridges, the postMessage origin is * for convenience. For production, replace * with your real iframe origin (e.g., https://your-avatar-host.example).
Directory: adam-sdk/examples/react/
cd adam-sdk/examples/react
npm install
npm run dev
src/avatarBridge.js to lock the origin and update the <iframe src> in src/App.jsx to your hosted avatar URL.Directory: adam-sdk/examples/angular/
cd adam-sdk/examples/angular
npm install
npm run start
src/app/avatar-bridge.ts to lock the origin and update the <iframe> src in src/app/app.component.html.Directory: adam-sdk/examples/vue/
cd adam-sdk/examples/vue
npm install
npm run dev
src/avatarBridge.js to lock the origin and update the <iframe src> in src/App.vue.All templates are intentionally small, with just enough structure to demonstrate:
docs/message-contract.htmldocs/examples-starters.htmlTo view the full, detailed API documentation:
npm run docs
npm run docs:serve
This will start a local web server and provide a URL to view the documentation in your browser.
Listen for events using the sdk.on() method:
ready: Fired when the SDK has successfully and securely connected to the avatar iframe.speech:start: Fired when the avatar starts speaking.speech:end: Fired when the avatar finishes speaking.command:success: Fired when a command is successfully executed.command:error: Fired when a command fails.We include the built API docs (docs/) in the npm package alongside the compiled library (dist/). The publish flow automatically builds both via prepublishOnly.
package.json (current: 1.0.3). For future releases: npm version patch|minor|major -m "chore(release): %s".npm run build (Vite)npm run docs (TypeDoc → docs/)prepublishOnly runs build and docs automatically.Run from adam-sdk/adam-sdk/:
# 1) Verify npm login and access
npm whoami
# 2) Install clean deps
npm ci
# 3) (Optional) Test/build/docs locally
npm test || true
npm run build
npm run docs
# 4) Publish (triggers prepublishOnly: build + docs)
npm publish --access public
Notes:
dist/ and docs/ (see the files field).