📊 umami-ruby – Ruby client for the Umami Analytics API
Tip
🚀 Ship your next Rails app 10x faster! I've built RailsFast, a production-ready Rails boilerplate template that comes with everything you need to launch a software business in days, not weeks. Go check it out!
umami-ruby is a comprehensive Ruby wrapper for the Umami Analytics API. Works with both Umami Cloud and self-hosted instances.
Installation
Add this line to your application's Gemfile:
gem 'umami-ruby'And then execute:
$ bundle install
Or install it yourself as:
$ gem install umami-ruby
Documentation
Full API documentation is available online or can be generated using YARD:
yard doc
yard serverConfiguration
You can put this config in a handy location within your Rails project, like config/initializers/umami.rb
For Umami Cloud
Umami.configure do |config|
config.access_token = "your_api_key"
# No need to specify uri_base - automatically uses https://api.umami.is
endFor Self-Hosted Umami Instances
# With an access token
Umami.configure do |config|
config.uri_base = "https://your-umami-instance.com"
config.access_token = "your_access_token"
end
# Or with username and password
Umami.configure do |config|
config.uri_base = "https://your-umami-instance.com"
config.credentials = {
username: "your_username",
password: "your_password"
}
endConfiguration Options
| Option | Description | Default |
|---|---|---|
access_token |
API key for Umami Cloud or access token for self-hosted | nil |
uri_base |
Base URL for self-hosted instances | Auto-detected |
credentials |
Hash with :username and :password for self-hosted |
nil |
request_timeout |
Request timeout in seconds | 120 |
# Example with custom timeout
Umami.configure do |config|
config.access_token = "your_api_key"
config.request_timeout = 60 # 60 seconds
endUsage
Basic Usage
client = Umami::Client.new
# Get current user info
me = client.me
# Get all websites
websites = client.websites
# Get a specific website
website = client.website("website_id")
# Verify token
token_info = client.verify_tokenWebsite Statistics
# Get website stats for a time range (timestamps in milliseconds)
stats = client.website_stats("website_id", {
startAt: 1656679719687,
endAt: 1656766119687
})
# Get active visitors (last 5 minutes)
active = client.website_active_visitors("website_id")
# Get pageviews with time grouping
pageviews = client.website_pageviews("website_id", {
startAt: 1656679719687,
endAt: 1656766119687,
unit: "day",
timezone: "America/Los_Angeles"
})
# Get metrics by type
metrics = client.website_metrics("website_id", {
startAt: 1656679719687,
endAt: 1656766119687,
type: "browser" # or: path, referrer, os, device, country, etc.
})
# Get realtime stats (last 30 minutes)
realtime = client.realtime("website_id")Sending Events
Send custom events to Umami for tracking. This is useful for server-side event tracking.
client = Umami::Client.new
# Send a basic event
client.send_event({
website: "your-website-id",
url: "/checkout",
hostname: "example.com",
name: "purchase_completed"
})
# Send an event with custom data
client.send_event({
website: "your-website-id",
url: "/checkout",
hostname: "example.com",
name: "purchase_completed",
language: "en-US",
screen: "1920x1080",
title: "Checkout - Example Store",
data: {
order_id: "12345",
total: 99.99,
currency: "USD"
}
})
# Send with a custom User-Agent (optional)
client.send_event(payload, user_agent: "MyApp/1.0")Important notes about send_event:
- No authentication token is sent (not required by the API)
- A
User-Agentheader is automatically included (required by Umami) - For Umami Cloud, requests go to
https://cloud.umami.is/api/send(different from other API calls) - For self-hosted, requests go to your configured
uri_base
Sessions
# Get sessions within a time range
sessions = client.website_sessions("website_id", {
startAt: 1656679719687,
endAt: 1656766119687,
page: 1,
pageSize: 20
})
# Get session statistics
stats = client.website_sessions_stats("website_id", {
startAt: 1656679719687,
endAt: 1656766119687
})
# Get individual session details
session = client.website_session("website_id", "session_id")
# Get session activity
activity = client.website_session_activity("website_id", "session_id", {
startAt: 1656679719687,
endAt: 1656766119687
})Events Data
# Get paginated event list with search
events = client.website_events_list("website_id", {
startAt: 1656679719687,
endAt: 1656766119687,
search: "click",
page: 1,
pageSize: 20
})
# Get event data aggregations
event_data = client.website_event_data_events("website_id", {
startAt: 1656679719687,
endAt: 1656766119687
})
# Get event statistics
stats = client.website_event_data_stats("website_id", {
startAt: 1656679719687,
endAt: 1656766119687
})Reports
# List reports (optionally filter by website and/or type)
all_reports = client.reports
website_reports = client.reports(websiteId: "website_id")
funnel_reports = client.reports(websiteId: "website_id", type: "funnel")
# Create a report
report = client.create_report({
websiteId: "website_id",
type: "funnel",
name: "Checkout Funnel",
parameters: {
startDate: "2024-01-01T00:00:00Z",
endDate: "2024-01-31T23:59:59Z"
}
})
# Run specialized reports
funnel = client.report_funnel({
websiteId: "website_id",
startDate: "2024-01-01T00:00:00Z",
endDate: "2024-01-31T23:59:59Z",
steps: [
{ type: "path", value: "/" },
{ type: "path", value: "/checkout" },
{ type: "path", value: "/thank-you" }
],
window: 7
})
retention = client.report_retention({
websiteId: "website_id",
startDate: "2024-01-01T00:00:00Z",
endDate: "2024-01-31T23:59:59Z",
timezone: "America/Los_Angeles"
})
# Available report types: attribution, breakdown, funnel, goal, journey, retention, revenue, utmReport types:
| Type | Description |
|---|---|
attribution |
Marketing channel attribution analysis |
breakdown |
Multi-dimensional data segmentation |
funnel |
Conversion funnel tracking |
goal |
Goal performance metrics |
journey |
User navigation path analysis |
retention |
Return visitor analysis |
revenue |
Revenue tracking and analysis |
utm |
UTM campaign parameter breakdown |
User & Team Management
# Get current user info
me = client.me
my_teams = client.my_teams(page: 1, pageSize: 10)
my_websites = client.my_websites(includeTeams: true)
# Team management
teams = client.teams
team = client.team("team_id")
client.create_team("My Team")
client.add_team_user("team_id", "user_id", "team-member")
# User management (admin only, self-hosted)
users = client.admin_users
client.create_user("username", "password", "user")Website Management
# Create a website
website = client.create_website({
name: "My Website",
domain: "example.com",
teamId: "optional-team-id"
})
# Update a website
client.update_website("website_id", {
name: "Updated Name",
shareId: "public-share-id"
})
# Reset website data
client.reset_website("website_id")
# Delete a website
client.delete_website("website_id")Available Methods
Authentication
-
verify_token- Verify the current authentication token
Me (Current User)
-
me- Get current user information -
my_teams(params)- Get user's teams (supports pagination) -
my_websites(params)- Get user's websites
Admin (Self-hosted only)
-
admin_users(params)- List all users -
admin_websites(params)- List all websites -
admin_teams(params)- List all teams
Users
-
create_user(username, password, role, id:)- Create a user -
user(user_id)- Get user by ID -
update_user(user_id, params)- Update user -
delete_user(user_id)- Delete user -
user_websites(user_id, params)- Get user's websites -
user_teams(user_id, params)- Get user's teams
Teams
-
teams(params)- List all teams -
create_team(name)- Create a team -
join_team(access_code)- Join a team -
team(team_id)- Get team by ID -
update_team(team_id, params)- Update team -
delete_team(team_id)- Delete team -
team_users(team_id, params)- List team members -
add_team_user(team_id, user_id, role)- Add user to team -
team_user(team_id, user_id)- Get team member -
update_team_user(team_id, user_id, role)- Update member role -
delete_team_user(team_id, user_id)- Remove user from team -
team_websites(team_id, params)- List team websites
Websites
-
websites(params)- List all websites -
create_website(params)- Create a website -
website(website_id)- Get website by ID -
update_website(website_id, params)- Update website -
delete_website(website_id)- Delete website -
reset_website(website_id)- Reset website data
Website Statistics
-
website_stats(website_id, params)- Get statistics -
website_active_visitors(website_id)- Get active visitors -
website_pageviews(website_id, params)- Get pageviews -
website_events(website_id, params)- Get events (time-series) -
website_events_series(website_id, params)- Get events series -
website_metrics(website_id, params)- Get metrics -
website_metrics_expanded(website_id, params)- Get expanded metrics
Sessions
-
website_sessions(website_id, params)- List sessions -
website_sessions_stats(website_id, params)- Get session stats -
website_sessions_weekly(website_id, params)- Get weekly breakdown -
website_session(website_id, session_id)- Get session details -
website_session_activity(website_id, session_id, params)- Get activity -
website_session_properties(website_id, session_id)- Get properties -
website_session_data_properties(website_id, params)- Get data properties -
website_session_data_values(website_id, params)- Get data values
Events
-
website_events_list(website_id, params)- List events (paginated) -
website_event_data(website_id, event_id)- Get event data -
website_event_data_events(website_id, params)- Get event aggregations -
website_event_data_fields(website_id, params)- Get event fields -
website_event_data_properties(website_id, params)- Get event properties -
website_event_data_values(website_id, params)- Get event values -
website_event_data_stats(website_id, params)- Get event statistics
Realtime
-
realtime(website_id)- Get realtime stats (last 30 minutes)
Links
-
links(params)- List all links -
link(link_id)- Get link by ID -
update_link(link_id, params)- Update link -
delete_link(link_id)- Delete link
Pixels
-
pixels(params)- List all pixels -
pixel(pixel_id)- Get pixel by ID -
update_pixel(pixel_id, params)- Update pixel -
delete_pixel(pixel_id)- Delete pixel
Reports
-
reports(params)- List all reports (filter bywebsiteId,type) -
create_report(params)- Create a report -
report(report_id)- Get report by ID -
update_report(report_id, params)- Update report -
delete_report(report_id)- Delete report -
report_attribution(params)- Run attribution report -
report_breakdown(params)- Run breakdown report -
report_funnel(params)- Run funnel report -
report_goals(params)- Run goals report -
report_journey(params)- Run journey report -
report_retention(params)- Run retention report -
report_revenue(params)- Run revenue report -
report_utm(params)- Run UTM report
Sending Events
-
send_event(payload, user_agent:)- Send tracking event
Error Handling
The gem defines several custom error classes:
begin
client.website("non-existent-id")
rescue Umami::NotFoundError => e
puts "Website not found: #{e.message}"
rescue Umami::ClientError => e
puts "Client error: #{e.message}"
rescue Umami::ServerError => e
puts "Server error: #{e.message}"
rescue Umami::AuthenticationError => e
puts "Authentication failed: #{e.message}"
rescue Umami::ConfigurationError => e
puts "Configuration error: #{e.message}"
rescue Umami::APIError => e
puts "API error: #{e.message}"
endError class hierarchy:
-
Umami::Error- Base error class-
Umami::ConfigurationError- Configuration issues -
Umami::AuthenticationError- Authentication failures -
Umami::APIError- API request failures-
Umami::NotFoundError- Resource not found (404) -
Umami::ClientError- Client errors (4xx) -
Umami::ServerError- Server errors (5xx)
-
-
Logging
The gem uses a logger that can be configured:
# Set log level
Umami.logger.level = Logger::DEBUG
# Use a custom logger
Umami.logger = Rails.loggerDevelopment
After checking out the repo, run bin/setup to install dependencies. Then, run bundle exec rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/rameerez/umami-ruby. Our code of conduct is: just be nice and make your mom proud of what you do and post online.
License
The gem is available as open source under the terms of the MIT License.