API Reference
Activoice.init(config)
Initializes one embed instance inside the target container.
If the container already contains an active embed (for example after a client-side navigation), it is destroyed and replaced with a fresh instance.
window.Activoice.init(config: ActivoiceEmbedConfig): void
ActivoiceEmbedConfig
The root configuration object passed to Activoice.init().
| Property | Type | Required | Description |
|---|---|---|---|
container | string | ✓ | CSS selector of the host element (e.g. '#av-embed-container'). Must match exactly one element in the DOM at the time init() is called. |
campaignId | string | ✓* | Slug or identifier of the campaign to embed. Visible in your Activoice admin, in the campaign URL and in the campaign's Share step, Embed tab. |
petitionId | string | ✓* | Slug or identifier of the petition to embed, found in the same place for a petition. |
embedOptions | EmbedOptions | — | Optional display and behavior settings. |
campaignOverrides | CampaignOverrides | — | Optional overrides applied on top of the campaign configuration defined in your Activoice admin. |
* Exactly one of campaignId and petitionId. Both, or neither, is an error reported in the browser console, and nothing is mounted.
EmbedOptions
All fields are optional. Omitting a field uses the default value.
| Property | Type | Default | Description |
|---|---|---|---|
spinnerColor | string | '#fed13a' | CSS color of the loading spinner shown before the campaign is ready. Accepts any valid CSS color value (hex, rgb(), named colors, etc.). |
initialPage | 'steps' | 'landing' | 'form' | 'full' | 'steps' for a campaign, 'form' for a petition | Controls which page is shown first. For a campaign, 'steps' opens directly on the action flow and 'landing' shows the landing page. For a petition, 'form' shows the counter and signature form alone and 'full' the whole petition page. A value meant for the other kind is ignored with a warning and the default applies. |
displayMode | 'fixedHeight' | 'inline' | 'fixedHeight' | 'fixedHeight' uses internal scrolling and the height option. 'inline' continuously adjusts the iframe to its content and ignores height. Unknown modes, including the removed 'fullHeight', fall back to 'fixedHeight' with 'auto' height. |
height | 'auto' | '100%' | '${number}px' | 'auto' | Applies only to 'fixedHeight'. 'auto' freezes the first screen's natural height at a minimum of 600 px. '100%' fills a container with a definite height. A positive pixel value (e.g. '700px') sets an exact height without sizing the container. Explicit heights have no 600 px minimum; unsupported height values use 'auto'. |
withToolbar | boolean | false | Renders the public toolbar inside the embed where available (back button, step indicator and My information profile button). Disabled by default for a seamless embedded look. |
withBackground | boolean | false | Paints the campaign's background color, or the color_background override, on the iframe body. When disabled, the background is transparent so the host page shows through. Text and UI elements automatically switch to a light color when the background color is dark. |
withPadding | boolean | false | Adds horizontal padding to the campaign content area. |
bypassStateCheck | boolean | false | When true, a campaign or petition renders even if it is a draft, and a campaign even when ended. Intended for preview and testing purposes only — do not enable in production. |
bypassCampaignStateCheck | boolean | false | Deprecated: former name of bypassStateCheck, still accepted with the same effect. |
scrollIntoView | boolean | true | When a petition embed opens its follow-up campaign, scrolls the host page so the top of the container is visible. false disables the scroll. No effect on a campaign embed. |
CampaignOverrides
Overrides applied on top of the campaign configuration defined in your Activoice admin.
interface CampaignOverrides {
recipients?: Recipient[] // Global recipient override for all interpellations
interpellations?: Array<{
id: string // UUID of the interpellation to override
recipients?: Recipient[] // Per-interpellation override (takes priority)
}>
color_background?: string // #rrggbb, surface the embed sits on
color_main?: string // #rrggbb, brand color
color_buttons?: string // #rrggbb, call-to-action buttons
custom_css?: string // Replaces the organization's custom CSS, '' removes it
}
Every override applies to the pages shown in the frame. In a petition embed, the design fields style the petition and its follow-up campaign, and recipients and interpellations apply to the follow-up campaign once it opens.
Recipient resolution order
Recipients are resolved per interpellation with the following priority:
- Per-interpellation override —
interpellations[].recipientsif provided for that entry - Root-level override — top-level
recipientsapplied to all interpellations that don't have their own override - Admin configuration — original recipients preserved when no override applies
interpellations is provided, only the listed interpellations are shown — any interpellation whose id is not included is hidden from the embed. Omit interpellations entirely to keep all interpellations visible.recipients is a convenient shortcut when you want to set the same recipients across all interpellations without repeating them in each entry.Design fields
Each design field replaces the campaign page's value from your Activoice admin (the campaign's own design when it has one, the organization's otherwise); an omitted field keeps it.
| Field | Type | Description |
|---|---|---|
color_background | string | #rrggbb color of the surface the embed sits on. Drives the text color and derived surfaces; painted on the body only with embedOptions.withBackground. |
color_main | string | #rrggbb brand color: landing gradient, toolbar, links, focus states. |
color_buttons | string | #rrggbb color of the call-to-action buttons; the label color is picked for contrast. |
custom_css | string | Replaces the campaign page's custom CSS; '' removes it. Written from the custom CSS template, see the Integration Guide. Checked before it is applied: no external URL, Google Fonts @import only, 50 000 characters at most. |
A color that is not #rrggbb, null included, or a custom_css that is not a string is ignored with a warning in the browser console and the campaign page's value stays. A CSS that fails a check is dropped entirely, with a warning too.
Recipient
All fields are optional.
| Field | Type | Description |
|---|---|---|
first_name | string | First name of the recipient. |
last_name | string | Last name of the recipient. |
gender | 'M' | 'F' | 'O' | Gender: M (male), F (female), O (other / not specified). Used to personalize AI-generated messages. |
display_title | string | Title or role displayed to the user (e.g. 'Mayor of Lyon'). |
photo_url | string | null | Absolute URL of the recipient's photo. |
email | string | null | Email address (used for email interpellation modes). |
phone_number | string | null | Phone number (used for call interpellation modes). |
personal_link | string | null | Absolute URL to the recipient's personal or professional website. |
facebook_page | string | Absolute URL of the recipient's Facebook page. |
twitter_handle | string | Twitter/X handle, without the @ prefix. |
instagram_handle | string | Instagram handle, without the @ prefix. |
linkedin_page | string | Absolute URL of the recipient's LinkedIn profile. |
tiktok_handle | string | TikTok handle, without the @ prefix. |
geo_type | string | null | Type of geographic area (e.g. 'municipality', 'department'). Used for geospatial targeting when supporters search by location. |
geo_id | string | null | Identifier of the geographic area, matching the geo_type taxonomy. |
party_name | string | null | Full name of the political party. |
party_short_name | string | null | Abbreviated party name displayed in the UI. |
custom_fields | Record<string, string> | Arbitrary key-value pairs injected as extra variables into AI-generated message templates. |
Events
Every analytics event the campaign or petition records is also posted to the host window as an ACTIVOICE_EVENT message, through postMessage, at the moment it happens. Listen for it to follow where visitors go and where they stop.
{
"type": "ACTIVOICE_EVENT",
"payload": {
"event": "submit_questions",
"campaignId": "a4e2b000-1234-4567-89ab-0123456789ab",
"petitionId": null,
"interpellationId": "7c1f3d2a-5b6e-4f8a-9c0d-1e2f3a4b5c6d",
"sessionId": "3b9e8d7c-6f5a-4e3d-8c2b-1a0f9e8d7c6b",
"medium": "email",
"newsletterChoice": "subscribed",
"customizationSkipped": false
}
}
| Property | Type | Description |
|---|---|---|
event | string | Name of the event, see the table below. |
campaignId | string | null | UUID of the campaign the event happened on, even if you initialized the embed with a slug or a petition; null on a petition. |
petitionId | string | null | UUID of the petition the event happened on; null on a campaign. |
interpellationId | string | null | UUID of the recipient group the event concerns, null before one is selected. |
sessionId | string | Identifier of the visitor's session, the same on every event of one journey, across the petition and its follow-up campaign. It rotates after thirty minutes of inactivity, or after a day. |
medium | string | null | Channel the event concerns, once the visitor has chosen one: email, twitter, facebook, instagram, linkedin, tiktok, form, review, or call. |
Every other property of an event is listed below. The order depends on the campaign: a geolocated campaign selects the recipient before its group, a single-channel campaign selects the channel automatically. The list grows with the product: ignore the events and properties you do not know.
event | Other properties | When |
|---|---|---|
session_start | hasUserInfo, hasUserEmail, utmSource, utmMedium, utmCampaign... | The visitor's session on the campaign or petition opens, or rotates after inactivity. |
follow_referral | referrerCode | The visitor arrived through a link another visitor shared. referrerCode designates who shared it. |
select_interpellation | automatic | A recipient group is selected. |
search_address | recipientsFound (number), exactMatch (boolean) | A geolocated campaign searched the recipients of an address. |
select_recipient | automatic, recipientKind (geolocation, list or business) | A recipient, or the business to review or call, is selected. |
select_medium | automatic | A channel is selected. |
submit_questions | customizationSkipped (boolean), newsletterChoice | The questions step is left, by either of its buttons. |
generate_message | A message is generated. | |
send_message | The visitor opens the mail client, X composer, Facebook, Instagram, LinkedIn, TikTok, an external link/form, or Google Maps for a review, or reports the call done. Opening a channel does not verify that the message was sent; confirm_sent records the visitor's confirmation. | |
confirm_sent | The visitor confirms they completed the action, including a call. Sent before navigating to the success page. | |
share_campaign | shareType | The visitor shares the campaign. |
sign_petition | The visitor signs the petition. | |
share_petition | shareType, sharedPageId | The visitor shares a petition. On a campaign's success page, the event is the campaign's and sharedPageId names the petition. |
show_donation_ask | The donation ask is shown on the success page. | |
start_donation | amount (minor units), frequency (one_time or monthly) | The visitor chose an amount and opened the payment form. |
complete_donation | amount, frequency | The payment completed in the page. A payment that left the page for a bank authentication is not reported, though the donation counts. |
decline_donation | The visitor continued without donating. |
automatic is true when the campaign made the selection on the visitor's behalf: a single recipient group, a single channel, a channel preset by the page. A selection is only reported when its value changes.
submit_questions is posted by the Generate button only when the form is valid, and by Do not use customization always, since that button validates nothing. newsletterChoice is the answer to the "keep me informed" checkbox:
newsletterChoice | Meaning | As a boolean |
|---|---|---|
subscribed | The box was checked, with a first name, last name and valid email. | true |
declined | The box was pre-checked and the visitor unchecked it. | false |
not_subscribed | The box was shown unchecked and left so. | false |
already_subscribed | The box was hidden because the visitor had already consented. | null |
null | The question was not asked (no CRM on the campaign), or the box was checked without a usable identity. | null |
The value records the choice submitted in the questions step, not a confirmed subscription: it is reported whether or not the CRM synchronization succeeds. A consent remembered from a previous campaign, petition, action, accepted CRM subscriber identity, or the My information dialog hides the box and reports already_subscribed; entering a different email address shows the box again.
confirm_sent records the visitor's confirmation, not verified delivery to the recipient. Reporting an issue, or answering that the action was not completed, does not post it. Loading the success page directly does not post it either.
Check both the source iframe and its origin before using a message. Register your listener before calling Activoice.init():
window.addEventListener('message', (event) => {
const iframe = document.querySelector('#av-embed-container iframe')
if (
iframe &&
event.source === iframe.contentWindow &&
event.origin === new URL(iframe.src).origin &&
event.data?.type === 'ACTIVOICE_EVENT'
) {
const { event: name, campaignId, petitionId, sessionId, medium } =
event.data.payload
// Forward these values to your analytics integration.
console.log({ name, campaignId, petitionId, sessionId, medium })
}
})
TypeScript types
Download the type definitions file and reference it in your project for full IDE autocompletion: activoice-embed.d.ts
Then point your tsconfig.json to it:
{
"include": ["./activoice-embed.d.ts", "src/**/*"]
}