Skip to content

Quickstart

Ahmed Abbas edited this page Jun 8, 2026 · 1 revision

Quickstart

Get the Convert Ruby SDK running and serving your first experiment. This page is the fast path; for the conceptual background read Quickstart Overview and How Convert Works first.

You need an SDK key from your Convert dashboard and Ruby 3.1 or newer. The gem has zero runtime dependencies (stdlib only).

The complete flow in one block

Build a client, create a per-visitor context, decide an experience, act on the result, track a conversion, and flush — every step is copy-pasteable:

require "convert_sdk"

# 1. Build ONE client at boot and reuse it for the life of the process.
#    Fetch mode: pass an sdk_key. Direct-data mode: pass a pre-fetched `data:`.
CONVERT_SDK = ConvertSdk.create(sdk_key: ENV.fetch("CONVERT_SDK_KEY"))

# 2. One context per visitor (per web request / per job). Cheap — no network,
#    no thread. The singleton client owns all shared state.
context = CONVERT_SDK.create_context("visitor-123", { "country" => "US" })

# 3. Decide an experience. Returns a BucketedVariation on a hit, or a Sentinel
#    on a miss — NEVER raises, NEVER a bare nil.
variation = context.run_experience("homepage-test")

# 4. Act on the result. `variation&.key` is the variation key on a hit and nil
#    on a miss (a Sentinel's #key is always nil), so a single `case` covers both.
case variation&.key
when nil          then render_default        # business miss — show the control
when "treatment"  then render_treatment
else                   render_variation(variation.key)
end

# 5. Track a conversion with revenue. Deduplicated per visitor per goal.
context.track_conversion("purchase", goal_data: { amount: 49.99, transaction_id: "tx-1" })

# 6. Flush queued events synchronously. In long-running servers the background
#    timer also drains; call flush explicitly before a process exits (Lambda/CLI).
CONVERT_SDK.flush

Step by step

  1. Build one client at boot. ConvertSdk.create is the single entry point — it builds the validated config, fetches the bucketing config synchronously, and fires the ready event. Build it once and assign it to a process-lifetime constant; never build a client per request. The only thing create may raise is an ArgumentError on misconfiguration. See Initialization.

  2. One context per visitor. create_context(visitor_id, attributes = nil) returns a fresh, independent Context. It is cheap — no network, no thread. A blank/nil visitor id logs an error and returns nil.

  3. Decide. run_experience(key) returns a frozen BucketedVariation on a hit or a Sentinel on a business miss. It never raises and never returns a bare nil. See Return Types & Sentinels.

  4. Branch on variation&.key. A Sentinel's #key is always nil, so case variation&.key falls through to the nil branch on a miss and exposes the real key on a hit — one branch handles both cases.

  5. Track conversions. track_conversion(goal_key, goal_data: nil, force_multiple_transactions: false) records a conversion, deduplicated per visitor per goal. Pass revenue/transaction data via goal_data: with snake_case keys (amount:, transaction_id:, …). See Tracking Conversions.

  6. Flush. flush (alias release_queues) delivers queued events synchronously. Long-running servers also drain via the background flush timer, so you do not need to flush per request. Short-lived processes (AWS Lambda, CLI) must flush explicitly before exit — see Fork Safety & Runtime Recipes.

Production wiring per runtime

Each runtime has a copy-pasteable recipe on the Fork Safety & Runtime Recipes page:

  • Rails (Puma cluster / Unicorn / Passenger) — fork-safe with zero config.
  • Sidekiq — singleton client + a shutdown flush.
  • AWS Lambda — timers off + a synchronous flush before the handler returns.
  • Plain CLI / rake — the automatic at_exit flush.

Next steps

Clone this wiki locally