vTilt
Why vTiltHow It WorksFeaturesFAQDocs
Docs / Elixir
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 guidesElixir

Elixir

Send vTilt events from any Elixir code by POSTing to the ingest API. Compatible with Phoenix, OTP releases, and stand-alone scripts.

There's no native Elixir SDK yet, but vTilt's wire format is a plain JSON POST so any Elixir code can emit events. Use this guide for non-Phoenix Elixir projects (OTP releases, scripts, Broadway pipelines). For Phoenix, see the dedicated Phoenix guide.

#1. Add dependencies

# mix.exs
defp deps do
  [
    {:req, "~> 0.5"},
    {:jason, "~> 1.4"},
  ]
end
elixir
# config/runtime.exs
config :my_app, :vtilt,
  token: System.fetch_env!("VTILT_TOKEN"),
  host: System.get_env("VTILT_HOST") || "https://www.vtilt.com"
elixir

#2. Capture module

# lib/my_app/vtilt.ex
defmodule MyApp.VTilt do
  require Logger

  @spec capture(String.t(), String.t(), map()) :: :ok
  def capture(distinct_id, event, properties \\ %{}) do
    cfg = Application.get_env(:my_app, :vtilt)

    Task.start(fn ->
      result = Req.post(
        cfg[:host] <> "/api/e",
        json: %{
          api_key: cfg[:token],
          event: event,
          distinct_id: distinct_id,
          properties: properties
        },
        receive_timeout: 2_000
      )

      case result do
        {:ok, _} -> :ok
        {:error, e} -> Logger.warning("vtilt capture failed: #{inspect(e)}")
      end
    end)

    :ok
  end

  def identify(distinct_id, properties) do
    capture(distinct_id, "$identify", %{"$set" => properties})
  end
end
elixir

#3. Capture events

MyApp.VTilt.identify("user_42", %{email: "alice@example.com", plan: "pro"})

MyApp.VTilt.capture("user_42", "purchase_completed", %{amount: 99.99, currency: "USD"})
elixir

#4. Broadway pipeline (recommended)

For high-throughput pipelines, batch captures through a Broadway producer to avoid hammering vTilt with individual requests.

defmodule MyApp.VTiltPipeline do
  use Broadway

  def handle_message(_, %Broadway.Message{data: {distinct_id, event, props}} = msg, _ctx) do
    MyApp.VTilt.capture(distinct_id, event, props)
    msg
  end
end
elixir

#Next steps

  • Phoenix integration guide — Phoenix-specific helpers + LiveView bridge.
  • Identify & alias — full identification model.
  • Event forwarding — fan events out to GA4, Meta CAPI, PostHog.
PreviousRubyIntegration guidesNextGoIntegration guides

On this page

  • 1. Add dependencies
  • 2. Capture module
  • 3. Capture events
  • 4. Broadway pipeline (recommended)
  • Next steps