vTilt
Why vTiltHow It WorksFeaturesFAQDocs
Docs / Ruby
Quick startEvent forwarding
MCP server
Guides
OverviewAuthenticationOAuthAgent skills (prompts)AI intelligenceGoogle Ads
Client setup
CursorClaude DesktopVS CodeCodex
Realtime
Debug ViewRealtime Dashboard
Integration guides
Frontend frameworks
Next.jsNuxt.jsVue.jsReactReact RouterRemixGatsbySvelte / SvelteKitAstroAngularTanStack StartDocusaurus
Backend frameworks
NestJSHonoCloudflare WorkersDjangoFlaskLaravelPhoenixRuby on Rails
Backend languages
PythonPHPRubyElixirGoJava.NET / C#Rust
Stack guides
Vue + PHP
SDK
Browser SDK
InstallScript bundlesEvent trackingAutocaptureIdentify & aliasWeb VitalsSession recordingChat widgetFeature readinessRemote configurationReverse proxyDebug logging
Node SDK
Install & setupCapture, identify & aliasContext & shutdown

Documentation

vTilt
Quick startEvent forwarding

MCP server

Realtime

Debug ViewRealtime Dashboard

Integration guides

PythonPHPRubyElixirGoJava.NET / C#Rust

SDK

DocsIntegration guidesRuby

Ruby

Send vTilt events from any Ruby code (Sinatra, scripts, Sidekiq jobs) by POSTing to the ingest API.

There's no native Ruby SDK yet, but vTilt's wire format is a plain JSON POST so any Ruby code can emit events. Use this guide for non-Rails Ruby projects (Sinatra, Roda, plain Ruby scripts, Sidekiq workers). For Rails, see the dedicated Ruby on Rails guide.

#1. Configure

# .env
VTILT_TOKEN=YOUR_PROJECT_TOKEN
VTILT_HOST=https://www.vtilt.com
text

#2. Capture helper

A small client built on Net::HTTP. No third-party gems required. Swap in Faraday or HTTP.rb if you want a richer client.

# lib/vtilt.rb
require 'net/http'
require 'json'

module Vtilt
  TOKEN = ENV.fetch('VTILT_TOKEN')
  HOST  = ENV.fetch('VTILT_HOST', 'https://www.vtilt.com')

  def self.capture(distinct_id:, event:, properties: {})
    uri = URI.join(HOST, '/api/e')

    Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https', open_timeout: 2, read_timeout: 2) do |http|
      req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json')
      req.body = {
        api_key: TOKEN,
        event: event,
        distinct_id: distinct_id,
        properties: properties,
      }.to_json
      http.request(req)
    end
  rescue StandardError
    # never raise on analytics
  end

  def self.identify(distinct_id:, properties:)
    capture(distinct_id: distinct_id, event: '$identify', properties: { '$set' => properties })
  end
end
ruby

#3. Capture events

require_relative 'lib/vtilt'

Vtilt.identify(distinct_id: 'user_42', properties: { email: 'alice@example.com', plan: 'pro' })

Vtilt.capture(
  distinct_id: 'user_42',
  event: 'purchase_completed',
  properties: { amount: 99.99, currency: 'USD' },
)
ruby

#4. Sidekiq worker (recommended)

Run captures in Sidekiq so analytics never blocks the user-facing response.

class VtiltCaptureWorker
  include Sidekiq::Worker

  def perform(distinct_id, event, properties = {})
    Vtilt.capture(distinct_id: distinct_id, event: event, properties: properties)
  end
end

VtiltCaptureWorker.perform_async('user_42', 'subscription_renewed', { 'plan' => 'pro' })
ruby

#Next steps

  • Ruby on Rails integration guide — Rails-specific helpers + application layout.
  • Identify & alias — full identification model.
  • Event forwarding — fan events out to GA4, Meta CAPI, PostHog.
PreviousPHPIntegration guidesNextElixirIntegration guides

On this page

  • 1. Configure
  • 2. Capture helper
  • 3. Capture events
  • 4. Sidekiq worker (recommended)
  • Next steps