API Reference
Welcome to the StealthSeminar API! You can use our API to access specific StealthSeminar API endpoints to get information about upcoming times for a webinar and register leads for webinars. Our API supports our dynamic scheduling, which means you can utilize scheduling features like Just In Time with our API.
We have language bindings in JavaScript and PHP! You can view code examples in the dark area to the right, and you can switch the programming language examples with the tabs in the top right.
Webinar Registration
Get Registration Information
const request = new XMLHttpRequest();
const url = 'https://api.joinnow.live/webinars/:shortId/registration-information';
request.open('GET', url);
request.send();
request.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
console.log(JSON.parse(request.responseText));
}
};
const https = require('https');
https.get('https://api.joinnow.live/webinars/:shortId/registration-information', res => {
let data = '';
// A chunk of data has been received.
res.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
res.on('end', () => {
console.log(JSON.parse(data));
});
}).on('error', (e) => {
console.error(e);
});
<?php
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, 'https://api.joinnow.live/webinars/:shortId/registration-information');
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl_handle);
curl_close($curl_handle);
echo $response;
?>
<?php
$request = new HttpRequest('https://api.joinnow.live/webinars/:shortId/registration-information', HttpRequest::METH_GET);
try {
$request->send();
echo $request->getResponseCode();
echo $request->getResponseBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
The above command returns JSON structured like this:
{
"id": "a9831b",
"title": "Test Webinar",
"timezone_id": "America/Phoenix",
"start_date": "2019-01-02T19:00:00.000Z",
"type": "automated",
"upcoming_times": [
"2019-01-03T16:00:00.000Z",
"2019-01-04T11:00:00.000Z",
"2019-01-05T19:00:00.000Z"
],
"registrationPages": [],
"javascript": [],
"eventTrackingPixels": [],
"sms_reminders": true,
"registration_enabled": true,
"registrationCSS": null,
"embedLayout": "simple-0",
"embedCSS": null,
"gdpr": null,
"gaNumber": null,
"thankYouRedirect": null,
"exitPopup": true,
"duration": 6186.33
}
GET https://api.joinnow.live/webinars/:shortId/registration-information
URL Parameters
Parameter | Type | Description |
---|---|---|
shortId | string |
The short, 6-character ID of the webinar |
Response Body
Attribute | Type | Description |
---|---|---|
id | string |
The short, 6-character ID of the webinar |
title | string |
The title of the webinar |
timezone_id | string |
The timezone ID - one of the TZ database names |
start_date | datetime |
Start datetime of the webinar, in ISO 8601 format |
type | string |
One of: automated , replay , live , or hybrid |
upcoming_times | array |
Array consisting of upcoming datetimes in ISO 8601 format |
registrationPages | array |
Array of RegistrationPage objects |
javascript | array |
Array of WebinarJavascript objects |
eventTrackingPixels | array |
Array of EventTrackingPixel objects |
sms_reminders | bool |
Whether to offer SMS reminders to leads |
registration_enabled | bool |
If false , will redirect any leads that land on the registration page to the login screen |
registrationCSS | string |
Identifier for uploaded Registration CSS file |
embedLayout | string |
Selected layout of embedded registration form. One of: simple-0 , simple-1 , simple-2 , styled-0 , styled-1 , styled-2 . |
embedCSS | string |
Identifier for uploaded Embedded Registration CSS file |
gdpr | object or null |
Object containing instructional_content and consent_text for obtaining GDPR consent from registrants. |
gaNumber | string |
Google Analytics Account (UA) Number. |
thankYouRedirect | string or null |
URL to redirect registrants to after a successful registration, after landing on the Thank You page. |
exitPopup | bool |
Whether to show a registration modal when a lead's cursor leaves the window. |
duration | float |
The duration of the webinar, used in some registration pages. |
Register For A Webinar
const request = new XMLHttpRequest();
const url='https://api.joinnow.live/webinars/:shortId/registration';
const postData = JSON.stringify({
start_time: '2019-01-18T12:00:00.000Z',
name: 'Test Name',
email: 'test@example.com',
customFields: {
country: 'US',
state: 'AZ',
},
});
request.open('POST', url);
request.setRequestHeader('Content-Type', 'application/json');
request.send(postData);
request.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
console.log(JSON.parse(request.responseText));
}
};
const https = require('https');
const postData = JSON.stringify({
start_time: '2019-01-18T12:00:00.000Z',
name: 'Test Name',
email: 'test@example.com',
customFields: {
country: 'US',
state: 'AZ',
},
});
const options = {
hostname: 'api.joinnow.live',
port: 443,
path: '/webinars/:shortId/registration',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length,
},
};
const req = https.request(options, res => {
let data = '';
// A chunk of data has been received.
res.on('data', chunk => {
data += chunk;
});
// The whole response has been received. Print out the result.
res.on('end', () => {
console.log(JSON.parse(data));
});
});
req.on('error', e => {
console.error(e);
});
req.write(postData);
req.end();
<?php
$data = json_encode([
'start_time' => '2019-01-18T12:00:00.000Z',
'name' => 'Test Name',
'email' => 'test@example.com',
'customFields' => {
'country' => 'US',
'state' => 'AZ,
},
]);
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, 'https://api.joinnow.live/webinars/:shortId/registration');
curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data),
]);
$response = curl_exec($curl_handle);
curl_close($curl_handle);
echo $response;
?>
<?php
$data = json_encode([
'start_time' => '2019-01-18T12:00:00.000Z',
'name' => 'Test Name',
'email' => 'test@example.com',
'customFields' => {
'country' => 'US',
'state' => 'AZ,
},
]);
$request = new HttpRequest('https://api.joinnow.live/webinars/:shortId/registration', HttpRequest::METH_POST);
$request->addHeaders([
'Content-Type' => 'application/json',
'Content-Length' => strlen($data);
]);
$request->addRawPostData($data);
try {
$request->send();
echo $request->getResponseCode();
echo $request->getResponseBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
The above command returns JSON structured like this:
{
"id": "7db6cc8f-3ca3-4db6-a66c-94f98cc577a8",
"webinar_id": "917f1507-a9ab-45cb-aa6a-50caf411d9ee",
"start_time": "2019-01-05T22:23:41.000Z",
"created_at": "2019-01-04T22:25:15.334Z",
"replay_start_time": "2019-01-06T02:23:51.300Z",
"replay_end_time": "2019-01-08T02:23:51.300Z",
"end_time": null,
"short_id": "78195e",
"live_video_url": null,
"display_start_time": "2019-01-05T22:23:41.000Z",
"webinar_short_id": "f25d67",
"attendee": {
"instance_id": "7db6cc8f-3ca3-4db6-a66c-94f98cc577a8",
"ip_address": "172.18.0.14",
"name": "Test Name",
"nickname": "TestName",
"email": "test@example.com",
"email_lower": "test@example.com",
"registration_page_id": "5ab0cc48-057c-48f8-a76b-3372ad853ad5",
"short_id": "cf9c73",
"sms_number": "",
"link_parameters": {},
"timezone_id": "America/Phoenix",
"gdpr_consent": false,
"custom_fields": {
"country": "US",
"state": "AZ"
},
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
"created_at": "2019-01-04T22:25:15.334Z",
"id": "f7328cbc-7e5e-418b-814d-ce40adda5998",
"blocked": false
}
}
POST https://api.joinnow.live/webinars/:shortId/registration
URL Parameters
Parameter | Type | Description |
---|---|---|
shortId | string |
The short, 6-character ID of the webinar |
Request Body Parameters
Parameter | Type | Description |
---|---|---|
start_time | datetime |
Required. The start time of the event for which the user is registering, in ISO 8601 format. |
name | string |
The registrant's name. If no name is provided, the attendee will appear as 'Guest-######' in webinar interactions. |
string |
Required. The registrant's email address. | |
yesterdays_now | bool |
If true, the registration is for a "Watch Yesterday's Webinar Now" event. |
registration_page_id | string |
Identifier of the registration page from which the user registered. |
sms_number | string |
Phone number for sending SMS reminders. |
timezone | string or null |
The registrant's timezone - one of the TZ database names |
gdprConsentReceived | bool |
Whether the registrant has given GDPR consent. |
linkParams | object |
Object containing any marketing parameters (v1, v2, v3, v4, v5) or UTM parameters (utm_source, utm_medium, utm_campaign, utm_term, utm_content) and their values |
customFields | object |
Object containing any additional registration information about the attendee. These values will be validated against the webinar's registration field configuration |
Webhooks
Creating a Webhook Endpoint
const app = require('express')();
const bodyParser = require('body-parser');
app.post('/webhook', bodyParser.raw({ type: 'application/json' }), (request, response) => {
let values;
try {
values = JSON.parse(request.body);
} catch (err) {
response.status(400).send(`Webhook Error: ${err.message}`);
}
switch (values.event) {
case 'ping':
// Respond with the authentication challenge
response.send(values.challenge);
break;
case 'register':
const attendeevalues = values.data;
// Handle attendee data
break;
case 'clickCta':
const attendeevalues = values.data;
const ctaId = values.eventParams.ctaId;
const ctaName = values.eventParams.ctaName;
// Handle other event types
default:
// Unexpected event type
return response.status(201).end();
}
response.json({ received: true });
});
app.listen(8000, () => console.log('Running on port 8000'));
<?php
$payload = @file_get_contents('php://input');
$values = json_decode($payload);
// Handle the event
switch ($values->event) {
case 'ping':
// Respond with the authentication challenge
echo $values->challenge;
break;
case 'register':
$attendeeData = $values->data;
// Handle attendee data
break;
case 'clickCta':
$attendeeData = $values->data;
$ctaId = $values->eventParams->ctaId;
$ctaName = $values->eventParams->ctaName;
// Handle attendee data
// Handle other events
default:
// Unexpected event type
http_response_code(201);
exit();
}
http_response_code(200);
Webhook data is sent as JSON in the POST request body. Type of event, event parameters, and attendee values are included in the request and can be used however you like, after being decoded from JSON.
Create a webhook endpoint on your website in whichever manner works best for you. With a NodeJS framework like Express, you would add a new route with the endpoint URL. With PHP, you might create a new .php file to handle the requests.
StealthSeminar expects that webhook endpoints will respond within 10 seconds of receiving the request payload. If your service takes longer than that to reply, then StealthSeminar terminates the connection and the request is considered failed. If your endpoint needs more time to process the webhook payload, consider offloading the work to a background worker like Resque (Ruby), RQ (Python), or RabbitMQ (Java).
Request Body Parameters
Parameter | Type | Description |
---|---|---|
event | string |
The type of event that was triggered |
eventParams | object |
An object of event parameters, such as minutes , ctaId , and ctaName |
data | object |
An object of values representing the attendee. These values can be renamed and reconfigured differently for each webinar. |
challenge | string |
A special value only sent with the ping event. The endpoint must send the challenge back as a response in order to validate the webhook endpoint. |
Attendee Data Values
Parameter | Type | Description |
---|---|---|
string |
The email address of the attendee | |
name | string |
The full name of the attendee |
first_name | string |
The first name of the attendee |
middle_name | string |
The middle name of the attendee, if any |
last_name | string |
The last name of the attendee |
sms_number | string |
The attendee's SMS number |
title | string |
The title of the webinar |
autologin_id | string |
An ID that can be used to automatically log the attendee into the event |
event_id | string |
The ID of the webinar |
webinar_datetime_utc | date |
The start time of the event in the UTC timezone. The format can be configured. |
webinar_datetime_for_viewer | date |
The start time of the event in the attendee's timezone. The format can be configured. |
event | string |
The type of event that triggered this data to be sent |
browser | string |
The browser that the attendee registered for the webinar from |
os | string |
The operating system that the attendee registered for the webinar from |
device | string |
The device that the attendee registered for the webinar from |
gdpr_consent_received | boolean |
Whether or not the attendee had given GDPR consent |
replay_id | string |
The ID for the webinar replay |
v1 | string |
The custom URL parameter configured for v1 |
v2 | string |
The custom URL parameter configured for v2 |
v3 | string |
The custom URL parameter configured for v3 |
v4 | string |
The custom URL parameter configured for v4 |
v5 | string |
The custom URL parameter configured for v5 |
utm_source | string |
The UTM source URL parameter |
utm_medium | string |
The UTM medium URL parameter |
utm_campaign | string |
The UTM campaign URL parameter |
utm_term | string |
The UTM term URL parameter |
utm_content | string |
The UTM content URL parameter |
Additional fields can be added to each webinar using the Registration Fields section. These fields will be added to the data
object. Each field can be renamed in the webhook plugin configuration.
Webhook Events
Event | Parameters | Description |
---|---|---|
ping | Sent when setting up the webhook endpoint | |
register | Sent when an attendee registers for the webinar | |
attend | Sent when an attendee attends the webinar | |
missWebinar | Sent when an attendee does not attend a webinar they registered for | |
attendReplay | Sent when an attendee watches a replay of a webinar | |
conversion | Sent when a conversion is recorded for a webinar | |
replayAvailable | Sent when a replay for a webinar becomes available | |
replayLastChance | Sent 4 hours before a replay for a webinar stops being available | |
viewCta | { ctaId: integer } |
Sent when an attendee views a CTA on a webinar |
clickCta | { ctaId: integer } |
Sent when an attendee clicks a CTA on a webinar |
joinAfter | { minutes: integer } |
Sent when an attendee arrives after a certain point in a webinar |
stayUntil | { minutes: integer } |
Sent when an attendee views a webinar beyond a certain point |
leaveBefore | { minutes: integer } |
Sent when an attendee leaves a webinar before a certain point |
fiveMinutesPrior | Sent 5 minutes before the start of a webinar | |
fifteenMinutesPrior | Sent 15 minutes before the start of a webinar | |
oneHourPrior | Sent 1 hour before the start of a webinar | |
threeHoursPrior | Sent 3 hours before the start of a webinar | |
sixHoursPrior | Sent 6 hours before the start of a webinar | |
twentyFourHoursPrior | Sent 24 hours before the start of a webinar | |
fortyEightHoursPrior | Sent 48 hours before the start of a webinar |
Objects
RegistrationPage Object
Attribute | Type | Description |
---|---|---|
id | string |
Identifier in UUID format. |
webinar_id | string |
UUID of the webinar. |
template_id | string |
UUID of the template used to create the registration page. |
template | object |
Object containing information about the template that the page was made from |
name | string |
Name of the registration page. Primarily used for split-testing. |
form | object |
Object containing all of the form content. |
active | bool |
Whether the registration page should be used. Primarily used for split-testing. |
deleted_at | datetime or null |
Timestamp when the registration page was marked as archived or deleted. |
WebinarJavascript Object
Attribute | Type | Description |
---|---|---|
id | int |
Integer identifier |
webinar_id | string |
UUID of the webinar. |
page | string |
The page that the javascript snippet will be run. One of: registration , thank_you , countdown , viewing , complete |
location | string |
The location in the HTML where the javascript snippet will be inserted and run. One of: inside_head , after_head , bottom |
javascript | string |
Javascript snippet. |
EventTrackingPixel Object
Attribute | Type | Description |
---|---|---|
id | int |
Integer identifier |
webinar_id | string |
UUID of the webinar. |
page | string |
The page that the tracking pixel will be placed on. One of: registration , thank_you , countdown , viewing , complete |
location | string |
The location in the HTML where the tracking pixel will be inserted. One of: inside_head , after_head , bottom |
content | string |
Tracking pixel HTML. |