pyrx-synapse

Gem Version License: MIT

Zero-dependency Ruby SDK for the PYRX Synapse customer engagement platform.

Requires Ruby 3.1+ (uses stdlib only: net/http, json, openssl).

Installation

Add to your Gemfile:

gem "pyrx-synapse"

Or install directly:

gem install pyrx-synapse

Quick Start

require "pyrx_synapse"

client = PyrxSynapse::Client.new(
  api_key: "psk_live_your_api_key",
  workspace_id: "your_workspace_id"
)

# Track an event
result = client.track(
  external_id: "user_123",
  event_name: "purchase_completed",
  attributes: {
    "order_id" => "ord_456",
    "amount" => 99.99,
    "currency" => "USD"
  }
)

# Identify a user
client.identify(
  external_id: "user_123",
  email: "jane@example.com",
  first_name: "Jane",
  last_name: "Doe",
  properties: { "plan" => "pro", "signup_source" => "website" },
  tags: ["paying", "beta-tester"]
)

# Send a transactional email
client.send_email(
  template_slug: "order-confirmation",
  to: {
    "user_id" => "user_123",
    "email" => "jane@example.com",
    "first_name" => "Jane"
  },
  attributes: {
    "order_id" => "ord_456",
    "items" => [{ "name" => "Widget", "price" => 99.99 }]
  }
)

Features

  • Event tracking (single and batch)
  • Contact management (CRUD, search, pagination)
  • Template management (CRUD, preview)
  • Transactional email sending
  • Webhook signature verification (Svix format)
  • Automatic retry with exponential backoff and jitter
  • Typed error classes for all API error types
  • Zero runtime dependencies (stdlib only)

Webhook Verification

event = PyrxSynapse.verify_webhook(
  request.body.read,
  {
    "svix-id" => request.headers["svix-id"],
    "svix-timestamp" => request.headers["svix-timestamp"],
    "svix-signature" => request.headers["svix-signature"]
  },
  ENV["SYNAPSE_WEBHOOK_SECRET"]
)

Error Handling

begin
  client.track(external_id: "user_123", event_name: "test")
rescue PyrxSynapse::SynapseRateLimitError => e
  sleep(e.retry_after)
  retry
rescue PyrxSynapse::SynapsePlanLimitError => e
  puts "Plan limit: #{e.limit_type} (#{e.current}/#{e.maximum})"
rescue PyrxSynapse::SynapseValidationError => e
  e.errors.each { |err| puts "#{err[:field]}: #{err[:message]}" }
rescue PyrxSynapse::SynapseAuthError => e
  puts "Auth error: #{e.message}"
rescue PyrxSynapse::SynapseError => e
  puts "API error: #{e.message} (#{e.status})"
end

Documentation

Full API reference and guides: synapse.pyrx.tech/developers/sdks/ruby

License

MIT