WebinarJam

Gem Version CI

A dependency-free Ruby client for the WebinarJam / EverWebinar API.

Covers every documented endpoint:

Method Endpoint Purpose
#webinars POST /webinars List all published webinars
#webinar(id) POST /webinar Details for one webinar (schedules, URLs, presenters)
#countries POST /countries Countries and states/provinces reference for registration
#register(...) POST /register Register a user to a webinar
#registrants(...) POST /registrants List registrants and attendees
#unsubscribe(...) POST /unsubscribe Unsubscribe a lead from notifications

Installation

# Gemfile
gem "webinarjam"

Usage

require "webinarjam"

client = WebinarJam::Client.new(api_key: ENV["WEBINARJAM_API_KEY"])
# api_key: defaults to ENV["WEBINARJAM_API_KEY"], so this is equivalent:
client = WebinarJam::Client.new

# Or configure once, module-wide:
WebinarJam.configure { |config| config.api_key = "your-key" }
client = WebinarJam.client

# List all webinars
client.webinars
# => { status: "success", webinars: [{ webinar_id: 1, webinar_hash: "abcd1234", ... }] }

# Details for one webinar (schedule ids live here)
details = client.webinar(1)
schedule = details[:webinar][:schedules].first[:schedule]

# Register a user
client.register(
  webinar_id: 1,
  schedule: schedule,
  first_name: "Jane",
  email: "jane@example.com",
  # optional: last_name, country, state, timezone_id, ip_address,
  #           phone_country_code, phone, twilio_consent
)
# => { status: "success", user: { user_id: ..., live_room_url: ..., ... } }

# Registrants / attendees for one session (paginated)
listing = client.registrants(webinar_id: 1, schedule_id: schedule, search: "jane@example.com")
# => { status: "success", registrants: { current_page: 1, data: [{ lead_id: ..., email: ..., ... }] } }
# optional filters: attended_live, attended_replay, purchased, page,
#                   attended_live_timestamp, attended_replay_timestamp, date_range

# Unsubscribe a lead (lead id comes from #registrants)
client.unsubscribe(webinar_id: 1, lead_id: 818)
# => true (the API responds 204 No Content)

All responses are parsed JSON with symbolized keys.

Custom registration fields

Custom fields configured on the registration page are passed by their label (returned by #webinar under registration_custom_fields). Extra keyword arguments to #register are forwarded as-is:

client.register(
  webinar_id: 1, schedule: schedule, first_name: "Jane", email: "jane@example.com",
  company: "XYZ",                     # text custom field
  whereDidYouHearAboutUs: ["id_1"]    # dropdown custom field: pass option id(s)
)

EverWebinar

The EverWebinar API shares the same shape under a different path prefix:

client = WebinarJam::Client.new(product: :everwebinar)

EverWebinar's #register accepts two extra optional parameters, which the generic keyword passthrough covers:

client.register(
  webinar_id: 6, schedule: 55, first_name: "Jane", email: "jane@example.com",
  date: "2026-01-01 09:00",  # must match a session date returned by #webinar
  timezone: "GMT-5"          # e.g. "GMT+2", "GMT+4:30"
)

Errors and rate limiting

Every API failure raises a subclass of WebinarJam::Error:

  • WebinarJam::ConfigurationError — no API key provided.
  • WebinarJam::AuthenticationError — HTTP 401/403 (invalid API key).
  • WebinarJam::RateLimitError — HTTP 429. The API allows at most 20 calls per second per user.
  • WebinarJam::APIError — any other error, including 2xx responses whose body carries "status": "error". Exposes #http_status and #body.

Opt into automatic retries on 429 (exponential backoff: 0.5s, 1s, 2s, ...):

client = WebinarJam::Client.new(max_retries: 3)

Development

bundle install
bundle exec rspec              # unit specs + integration specs (VCR replay)
bundle exec rspec spec/webinarjam  # unit specs only
bin/console                    # IRB with the gem and .env loaded

Integration specs replay VCR cassettes committed under spec/fixtures/vcr_cassettes/ — no credentials needed. To re-record against the live API, put a real key in .env (WEBINARJAM_API_KEY=...) and run:

VCR_RECORD=all bundle exec rspec spec/integration

The API key is filtered out of cassettes (<API_KEY>), but recorded bodies still contain your account's webinar names and room URLs — review cassettes before publishing them anywhere.

License

MIT