Simula delivers contextually relevant in chat ads tailored for AI games and companions. It's lightweight, easy to integrate, and MRC-compliant out of the box.

Integrate in two steps:
SimulaProvider<InChatAdSlot /> where you want adsfunction App() {
return (
<SimulaProvider apiKey="SIMULA_xxx">
<YourChatApp />
</SimulaProvider>
);
}
function ChatMessage() {
return (
<div>
{/* Chat UI */}
<InChatAdSlot
character_desc="A stick of butter who can talk..."
format="all"
theme={{ theme: "light", accent: "blue" }}
/>
</div>
);
}
SimulaProviderInitializes the SDK and manages session state.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey |
string |
✅ | — | Your Simula API key from the dashboard |
children |
ReactNode |
✅ | — | Your app components |
devMode |
boolean |
❌ | false |
Enables development mode |
primaryUserID |
string |
❌ | — | Publisher-provided user identifier. Recommended for consistent tracking across devices and sessions. |
// Wrap your entire app
<SimulaProvider apiKey="SIMULA_xxx">
<App />
</SimulaProvider>
// Or wrap logged-in content (recommended for authenticated apps)
function App() {
const { user } = useAuth();
if (!user) return <LoginPage />;
return (
<SimulaProvider apiKey="SIMULA_xxx" primaryUserID={user.id}>
<AuthenticatedApp />
</SimulaProvider>
);
}
💡 Provider Best Practices
SimulaProviderdoesn't need to wrap your entire app. But for best results:
- Wrap logged-in content – Place it around authenticated sections where we can track a user across a single session
- Provide
primaryUserID– Use your user's ID to enable cross-device tracking and cookie-independent identification. This approach delivers:
- Higher CPMs – Better user attribution leads to more valuable ad placements
- Frequency capping – Prevents oversending ads to the same user
- Better ad experience – Optimized targeting based on consistent user history
- Accurate analytics – Reliable performance metrics across devices and sessions
For anonymous users, you can still use
SimulaProviderwithoutprimaryUserID, but tracking will rely on cookies.
InChatAdSlotDisplays an ad based on conversation context. Ad slots can either render as a below-chat component or be mounted into an existing dropdown node, depending on the host component hierarchy.
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
character_desc |
string |
✅ | — | Description of the AI character or assistant personality for contextual ad matching. |
messages |
Message[] |
❌ | — | Array of { role, content }; pass recent conversation (e.g. last 6 turns) for additional context. |
trigger |
Promise<any> |
❌ | Fires immediately on viewability | Promise to await before fetching the ad (e.g. LLM call). |
formats |
`string | string[]` | ❌ | ['all'] |
| A/B Testing: Pass an array to automatically A/B test different formats and let Simula pick the best over time. | ||||
theme |
SimulaTheme |
❌ | { theme: 'auto', width: 'auto', accent: ['neutral','image'], font: 'sans-serif', cornerRadius: 8 } |
Customize ad appearance (see Theme Options). Arrays trigger A/B testing. |
debounceMs |
number |
❌ | 0 |
Delay in milliseconds before fetching. |
onImpression |
(ad: AdData) => void |
❌ | undefined |
Callback when ad is viewable (50% visible for ≥1s). |
onClick |
(ad: AdData) => void |
❌ | undefined |
Callback when ad is clicked. |
onError |
(err: Error) => void |
❌ | undefined |
Callback when ad fails or no-fill occurs. |
Behavior: