LatticeStripe.Billing.MeterEventStream (LatticeStripe v1.7.9)

Copy Markdown View Source

Stripe v2 Billing Meter Event Stream — high-throughput session-token API.

Unlike other LatticeStripe modules, MeterEventStream bypasses the standard Client request pipeline. The v2 event stream uses a different authentication model (short-lived session tokens instead of API keys) and a different host (meter-events.stripe.com instead of api.stripe.com). This module calls client.transport.request/1 directly with the appropriate headers.

Two-Step Usage

  1. Create a session (uses your API key, returns a 15-minute token):

    = MeterEventStream.create_session(client)

  2. Send event batches within the session (uses the session token):

    events = [ %{"event_name" => "api_call", "payload" => %{"stripe_customer_id" => "cus_123", "value" => "1"}}, %{"event_name" => "api_call", "payload" => %{"stripe_customer_id" => "cus_456", "value" => "3"}} ]

    } = MeterEventStream.send_events(client, session, events)

Session Expiry

Sessions expire 15 minutes after creation. send_events/4 checks session.expires_at before each call and returns {:error, :session_expired} immediately if the session has expired — saving a network round-trip.

If the server returns a 401 with code billing_meter_event_session_expired (e.g., due to clock skew), it is also normalized to {:error, :session_expired}.

There is no automatic session renewal. Call create_session/2 again to obtain a fresh session.

Differences from v1 MeterEvent

Aspectv1 MeterEvent.create/3v2 MeterEventStream.send_events/4
AuthAPI key (Bearer)Session token (Bearer)
Hostapi.stripe.commeter-events.stripe.com
Encodingform-urlencodedJSON
BatchSingle eventUp to 100 events
ResponseReturns event objectReturns empty %{}

See guides/metering.md for the complete metering guide including v1 and v2 patterns.

Summary

Functions

Create a short-lived meter event stream session.

Send a batch of meter events within an active session.

Functions

create_session(client, opts \\ [])

Create a short-lived meter event stream session.

Returns a %Session{} struct containing an authentication_token valid for 15 minutes. Pass this session to send_events/4 to send event batches.

Opts

  • :timeout — HTTP request timeout in milliseconds (default: client.timeout)

Return value

  • {:ok, %Session{}} — session created successfully
  • {:error, %Error{}} — Stripe API error or connection error

Example

{:ok, session} = MeterEventStream.create_session(client)
# session.authentication_token is the bearer credential for send_events/4
# session.expires_at is a Unix timestamp (created + 900 seconds)

send_events(client, session, events, opts \\ [])

@spec send_events(
  LatticeStripe.Client.t(),
  LatticeStripe.Billing.MeterEventStream.Session.t(),
  [map()],
  keyword()
) ::
  {:ok, map()} | {:error, :session_expired} | {:error, LatticeStripe.Error.t()}

Send a batch of meter events within an active session.

Params

  • client%Client{} (used for transport, json_codec, finch, timeout)
  • session%Session{} from create_session/2
  • events — non-empty list of event maps, each with:
    • "event_name" (required) — must match a Billing.Meter.event_name
    • "payload" (required) — map with customer mapping key and value
    • "identifier" (optional) — deduplication UUID
    • "timestamp" (optional) — Unix timestamp or ISO 8601 string

Opts

  • :timeout — HTTP request timeout in milliseconds (default: client.timeout)

Return value

  • {:ok, %{}} — events accepted (fire-and-forget; no per-event response)
  • {:error, :session_expired} — session token has expired (client-side or server-side)
  • {:error, %Error{}} — Stripe API error, validation error, or connection error

Example

events = [
  %{"event_name" => "api_call", "payload" => %{"stripe_customer_id" => "cus_123", "value" => "1"}}
]

case MeterEventStream.send_events(client, session, events) do
  {:ok, %{}} -> :sent
  {:error, :session_expired} -> # create a new session
  {:error, %Error{} = err} -> # handle error
end