NAV Navbar
javascript--browser javascript--node php--cURL php--HttpRequest

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.
email 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
email 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.