SDK
Access Fireberry context and data from your embedded applications
Fireberry SDK
The Fireberry SDK (@fireberry/sdk) enables your app to communicate with the Fireberry platform. Use it to access information about the current user and record, and to perform data operations.
Resources:
Installation
npm install @fireberry/sdkQuick Start
import FireberryClientSDK from "@fireberry/sdk/client";
// 1. Create the client
const client = new FireberryClientSDK();
// 2. Initialize (required before using context or API)
await client.initializeContext();
// 3. Use context and API
const { user, record } = client.context;
const { fullName } = user;
console.log(`Hello, ${fullName}!`);
const results = await client.api.query(1, {
fields: "accountid,accountname",
query: 'status = "active"',
});How It Works
Your app runs in an iframe inside Fireberry. The SDK handles all communication with the parent window:
sequenceDiagram
participant App as Your App (iframe)
participant SDK as Fireberry SDK
participant FB as Fireberry Platform
App->>SDK: initializeContext()
SDK->>FB: Request context
FB-->>SDK: User + Record info
SDK-->>App: Context ready
App->>SDK: api.query(...)
SDK->>FB: Query API request
FB-->>SDK: Data response
SDK-->>App: Results
Context
Context provides information about who's using your app and what they're looking at.
Accessing Context
await client.initializeContext();
const { user, record } = client.context;
// User info (always available)
console.log(user.id); // User's unique ID
console.log(user.fullName); // User's display name
console.log(user.organizationId); // User's organization ID
// Record info (only in Record components)
console.log(record.id); // Current record ID
console.log(record.type); // Object type numberContext by Component Type
| Context | Record Component | Side Menu | Global Menu |
|---|---|---|---|
user.id | ✓ | ✓ | ✓ |
user.fullName | ✓ | ✓ | ✓ |
user.organizationId | ✓ | ✓ | ✓ |
record.id | ✓ | — | — |
record.type | ✓ | — | — |
NoteRecord context is only available in Record components. For Side Menu and Global Menu components,
recordwill be empty.
API Methods
The SDK provides four methods for working with Fireberry data:
| Method | Description |
|---|---|
api.query() | Retrieve records |
api.create() | Create a new record |
api.update() | Update an existing record |
api.delete() | Delete a record |
query
Retrieve records based on criteria.
const results = await client.api.query(objectType, {
fields: "accountid,accountname,status,createdon",
query: 'status = "active"',
page_size: 20, // optional
page_number: 1, // optional
});Parameters:
| Parameter | Type | Description |
|---|---|---|
objectType | string | number | The object type to query |
fields | string | Comma-separated list of fields to return |
query | string | Filter expression |
page_size | number | Records per page (optional) |
page_number | number | Page number, 1-indexed (optional) |
Query syntax:
| Operator | Example |
|---|---|
= | status = "active" |
!= | status != "closed" |
AND | status = "active" AND priority = "high" |
OR | status = "open" OR status = "pending" |
create
Create a new record.
const result = await client.api.create(objectType, {
name: "New Project",
status: "active",
priority: "high",
});
if (result.success) {
console.log("Created:", result.data.id);
}update
Update an existing record.
const result = await client.api.update(objectType, recordId, {
status: "completed",
});
if (result.success) {
console.log("Updated successfully");
}delete
Delete a record.
const result = await client.api.delete(objectType, recordId);
if (result.success) {
console.log("Deleted");
}Response Format
All API methods return the same structure:
interface ResponseData {
success: boolean;
data: any;
error?: {
status: number;
statusText: string;
data: { Message?: string };
};
requestId: string;
}Handling responses:
const result = await client.api.query(1, {
fields: "accountid,accountname",
query: 'status = "active"',
});
if (result.success) {
console.log("Data:", result.data);
} else {
console.error("Error:", result.error?.data.Message);
}Settings API
The Settings API provides persistent storage scoped to your app. Use it to save configuration, user preferences, or any state that should survive page reloads. Because all components within the same app share a single settings store, it also serves as the primary mechanism for cross-component communication.
| Method | Description |
|---|---|
app.settings.get() | Read the current settings value |
app.settings.set() | Write a new settings value |
app.settings.get
Read the stored settings for your app.
const settings = await client.app.settings.get();app.settings.set
Replace the stored settings with a new value. Returns the stored value after writing.
await client.app.settings.set({ theme: "dark", language: "en" });
Important: Full replace, not merge
app.settings.set()replaces the entire stored value — it does not merge or patch. If you only want to update one key, read the current settings first and spread them:// ❌ WRONG — overwrites everything; "language" is lost await client.app.settings.set({ theme: "light" }); // ✅ CORRECT — merge with existing settings, then write const current = await client.app.settings.get(); await client.app.settings.set({ ...current, theme: "light" });
How Settings Scoping Works
Settings are per-app, per-organization:
- All components in the same app read and write the same settings store.
- Different apps cannot access each other's settings.
- Settings are scoped to the organization, not to individual users — every user in the org sees the same data.
- Settings persist across page reloads and browser sessions.
flowchart TB
subgraph App["Your App"]
S[(Settings Store)]
end
R[Record Component] -->|read / write| S
G[Global Menu Component] -->|read / write| S
SM[Side Menu Component] -->|read / write| S
When your app has multiple components, coordinate which keys each component owns. For example, a Record component might own focusedAccount, while a Side Menu component owns taskSummary. Each component reads keys written by others, but only writes to its own.
NoteComponents do not receive real-time updates when another component changes settings. To see changes made by a sibling component, call
app.settings.get()again — for example, in response to a user action or a manual "Refresh" button.
System Methods
In addition to data operations, the SDK provides methods to control UI elements in the Fireberry platform.
| Method | Description |
|---|---|
system.badge.show() | Display a badge notification |
system.badge.hide() | Hide the badge notification |
system.callbar.show() | Display a callbar with call info |
system.callbar.hide() | Hide the callbar |
Badge
Display notification badges to alert users about important information or status updates.
Show Badge
Display a badge with a number and type indicator.
await client.system.badge.show({
number: 5,
badgeType: "info",
});Parameters:
| Parameter | Type | Description |
|---|---|---|
number | number | The number to display on the badge |
badgeType | 'success' | 'warning' | 'error' | 'info' | Visual style of the badge |
Badge Types:
success— Green badge for positive notificationswarning— Yellow badge for warningserror— Red badge for errors or critical alertsinfo— Blue badge for informational messages
Example:
// Show unread messages count
await client.system.badge.show({
number: 12,
badgeType: "info",
});
// Show error count
await client.system.badge.show({
number: 3,
badgeType: "error",
});Hide Badge
Remove the badge notification.
await client.system.badge.hide();Callbar
Display a callbar interface with call information and related records.
Show Callbar
Display a callbar with call status and associated record information.
await client.system.callbar.show({
callInfo: {
number: 1234567890,
status: "Talking",
},
objectConfig: [
{
objectType: "1",
order: 1,
fields: [
{ name: "accountname" },
{ name: "email" },
],
},
],
placemment: "bottom-end",
});Parameters:
| Parameter | Type | Description |
|---|---|---|
callInfo | CallInfo | Information about the current call |
objectConfig | ObjectConfig[] | Configuration for displaying records |
placemment | 'bottom-start' | 'bottom-end' | Position of the callbar |
CallInfo:
| Field | Type | Description |
|---|---|---|
number | number | Phone number of the call |
status | 'Talking' | 'Ringing' | 'Missed' | 'Dialing' | Current status of the call |
ObjectConfig:
| Field | Type | Description |
|---|---|---|
objectType | string | The object type to display records from |
fields | Field[] | Array of fields to show |
order | number | Display order (optional) |
Field:
| Field | Type | Description |
|---|---|---|
name | string | Field name |
Example:
// Display callbar for incoming call
await client.system.callbar.show({
callInfo: {
number: 5551234567,
status: "Ringing",
},
objectConfig: [
{
objectType: "1",
fields: [
{ name: "accountname", },
{ name: "phone"},
{ name: "email" },
],
},
],
placemment: "bottom-end",
});Hide Callbar
Remove the callbar from display.
await client.system.callbar.hide();TypeScript Support
The SDK includes full TypeScript definitions. You can provide two generic type parameters for stronger typing:
import FireberryClientSDK from "@fireberry/sdk/client";
const client = new FireberryClientSDK<ResponseDataType, SettingsType>();
// ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^
// 1st: API data 2nd: Settings shape| Generic | Purpose | Default |
|---|---|---|
ResponseDataType | Shape of data returned by api.query(), api.create(), etc. | any |
SettingsType | Shape of the value stored by app.settings.get() / app.settings.set() | JsonValue |
Example
import FireberryClientSDK from "@fireberry/sdk/client";
// Define the shape of records your API calls return
interface Account {
accountid: string;
accountname: string;
status: string;
telephone1?: string;
}
// Define the shape of your app's settings
interface MySettings {
theme?: string;
pinnedItems?: { id: string; name: string }[];
}
// Create a fully-typed client
const client = new FireberryClientSDK<Account, MySettings>();
await client.initializeContext();
// API responses are typed
const results = await client.api.query(1, {
fields: "accountid,accountname,status",
query: 'status = "active"',
});
// results.data is typed as Account
// Settings are typed
const settings = await client.app.settings.get();
// settings is typed as MySettings
NoteIf you only need to type API responses and don't use the Settings API, you can pass a single generic as before:
new FireberryClientSDK<Account>().
Complete Example
A React component that displays and updates data:
import { useEffect, useState } from "react";
import FireberryClientSDK from "@fireberry/sdk/client";
function TaskList() {
const [client] = useState(() => new FireberryClientSDK());
const [tasks, setTasks] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function init() {
await client.initializeContext();
const result = await client.api.query(1, {
fields: "accountid,accountname,status",
query: 'status != "completed"',
});
if (result.success) {
setTasks(Array.isArray(result.data) ? result.data : [result.data]);
}
setLoading(false);
}
init();
}, [client]);
const completeTask = async (taskId) => {
const result = await client.api.update(1, taskId, { status: "completed" });
if (result.success) {
setTasks(tasks.filter((t) => t.accountid !== taskId));
}
};
if (loading) return <div>Loading...</div>;
return (
<ul>
{tasks.map((task) => (
<li key={task.accountid}>
{task.accountname}
<button onClick={() => completeTask(task.id)}>Complete</button>
</li>
))}
</ul>
);
}Cleanup
When your component unmounts, clean up the SDK:
// Clean up event listeners and pending requests
client.destroy();In React:
useEffect(() => {
const client = new FireberryClientSDK();
// ... setup
return () => client.destroy();
}, []);Timeouts
API requests timeout after 60 seconds by default. If a request takes longer, the promise rejects with a timeout error.
Next Steps
- Design System — Build UIs with Fireberry components
- Component Types — Understand context availability by component type
- CLI — Deploy and manage your apps
Updated 6 days ago
