{"id":14955755,"url":"https://github.com/rameerez/umami-ruby","last_synced_at":"2026-02-03T03:14:10.904Z","repository":{"id":249671985,"uuid":"832220533","full_name":"rameerez/umami-ruby","owner":"rameerez","description":"⚪️ Ruby wrapper for the Umami analytics API","archived":false,"fork":false,"pushed_at":"2024-07-25T19:59:13.000Z","size":119,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-09T06:52:03.676Z","etag":null,"topics":["analytics","google-analytics","ruby","ruby-on-rails","umami","umami-analytics","web-analytics","web-development"],"latest_commit_sha":null,"homepage":"https://rameerez.github.io/umami-ruby/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rameerez.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-22T15:03:23.000Z","updated_at":"2025-07-04T09:14:37.000Z","dependencies_parsed_at":"2024-07-22T17:12:22.596Z","dependency_job_id":"bac6e8a6-cbb5-4045-bd93-59475982f41d","html_url":"https://github.com/rameerez/umami-ruby","commit_stats":{"total_commits":14,"total_committers":2,"mean_commits":7.0,"dds":0.0714285714285714,"last_synced_commit":"ff7833de82acb8fabb148c87077c630f1d5e1636"},"previous_names":["rameerez/umami-ruby"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rameerez/umami-ruby","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rameerez%2Fumami-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rameerez%2Fumami-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rameerez%2Fumami-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rameerez%2Fumami-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rameerez","download_url":"https://codeload.github.com/rameerez/umami-ruby/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rameerez%2Fumami-ruby/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264851643,"owners_count":23673270,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","google-analytics","ruby","ruby-on-rails","umami","umami-analytics","web-analytics","web-development"],"created_at":"2024-09-24T13:11:40.677Z","updated_at":"2026-02-03T03:14:10.898Z","avatar_url":"https://github.com/rameerez.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📊 `umami-ruby` – Ruby client for the Umami Analytics API\n\n[![Gem Version](https://badge.fury.io/rb/umami-ruby.svg)](https://badge.fury.io/rb/umami-ruby) [![Build Status](https://github.com/rameerez/umami-ruby/workflows/Tests/badge.svg)](https://github.com/rameerez/umami-ruby/actions)\n\n\u003e [!TIP]\n\u003e **🚀 Ship your next Rails app 10x faster!** I've built **[RailsFast](https://railsfast.com/?ref=umami-ruby)**, 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](https://railsfast.com/?ref=umami-ruby)!\n\n`umami-ruby` is a comprehensive Ruby wrapper for the [Umami Analytics API](https://umami.is/docs/api). Works with both Umami Cloud and self-hosted instances.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'umami-ruby'\n```\n\nAnd then execute:\n\n```\n$ bundle install\n```\n\nOr install it yourself as:\n\n```\n$ gem install umami-ruby\n```\n\n## Documentation\n\nFull API documentation is available [online](https://rameerez.github.io/umami-ruby/) or can be generated using YARD:\n\n```bash\nyard doc\nyard server\n```\n\n## Configuration\n\nYou can put this config in a handy location within your Rails project, like `config/initializers/umami.rb`\n\n### For Umami Cloud\n\n```ruby\nUmami.configure do |config|\n  config.access_token = \"your_api_key\"\n  # No need to specify uri_base - automatically uses https://api.umami.is\nend\n```\n\n### For Self-Hosted Umami Instances\n\n```ruby\n# With an access token\nUmami.configure do |config|\n  config.uri_base = \"https://your-umami-instance.com\"\n  config.access_token = \"your_access_token\"\nend\n\n# Or with username and password\nUmami.configure do |config|\n  config.uri_base = \"https://your-umami-instance.com\"\n  config.credentials = {\n    username: \"your_username\",\n    password: \"your_password\"\n  }\nend\n```\n\n### Configuration Options\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `access_token` | API key for Umami Cloud or access token for self-hosted | `nil` |\n| `uri_base` | Base URL for self-hosted instances | Auto-detected |\n| `credentials` | Hash with `:username` and `:password` for self-hosted | `nil` |\n| `request_timeout` | Request timeout in seconds | `120` |\n\n```ruby\n# Example with custom timeout\nUmami.configure do |config|\n  config.access_token = \"your_api_key\"\n  config.request_timeout = 60  # 60 seconds\nend\n```\n\n## Usage\n\n### Basic Usage\n\n```ruby\nclient = Umami::Client.new\n\n# Get current user info\nme = client.me\n\n# Get all websites\nwebsites = client.websites\n\n# Get a specific website\nwebsite = client.website(\"website_id\")\n\n# Verify token\ntoken_info = client.verify_token\n```\n\n### Website Statistics\n\n```ruby\n# Get website stats for a time range (timestamps in milliseconds)\nstats = client.website_stats(\"website_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687\n})\n\n# Get active visitors (last 5 minutes)\nactive = client.website_active_visitors(\"website_id\")\n\n# Get pageviews with time grouping\npageviews = client.website_pageviews(\"website_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687,\n  unit: \"day\",\n  timezone: \"America/Los_Angeles\"\n})\n\n# Get metrics by type\nmetrics = client.website_metrics(\"website_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687,\n  type: \"browser\"  # or: path, referrer, os, device, country, etc.\n})\n\n# Get realtime stats (last 30 minutes)\nrealtime = client.realtime(\"website_id\")\n```\n\n### Sending Events\n\nSend custom events to Umami for tracking. This is useful for server-side event tracking.\n\n```ruby\nclient = Umami::Client.new\n\n# Send a basic event\nclient.send_event({\n  website: \"your-website-id\",\n  url: \"/checkout\",\n  hostname: \"example.com\",\n  name: \"purchase_completed\"\n})\n\n# Send an event with custom data\nclient.send_event({\n  website: \"your-website-id\",\n  url: \"/checkout\",\n  hostname: \"example.com\",\n  name: \"purchase_completed\",\n  language: \"en-US\",\n  screen: \"1920x1080\",\n  title: \"Checkout - Example Store\",\n  data: {\n    order_id: \"12345\",\n    total: 99.99,\n    currency: \"USD\"\n  }\n})\n\n# Send with a custom User-Agent (optional)\nclient.send_event(payload, user_agent: \"MyApp/1.0\")\n```\n\n**Important notes about `send_event`:**\n- No authentication token is sent (not required by the API)\n- A `User-Agent` header is automatically included (required by Umami)\n- For Umami Cloud, requests go to `https://cloud.umami.is/api/send` (different from other API calls)\n- For self-hosted, requests go to your configured `uri_base`\n\n### Sessions\n\n```ruby\n# Get sessions within a time range\nsessions = client.website_sessions(\"website_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687,\n  page: 1,\n  pageSize: 20\n})\n\n# Get session statistics\nstats = client.website_sessions_stats(\"website_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687\n})\n\n# Get individual session details\nsession = client.website_session(\"website_id\", \"session_id\")\n\n# Get session activity\nactivity = client.website_session_activity(\"website_id\", \"session_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687\n})\n```\n\n### Events Data\n\n```ruby\n# Get paginated event list with search\nevents = client.website_events_list(\"website_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687,\n  search: \"click\",\n  page: 1,\n  pageSize: 20\n})\n\n# Get event data aggregations\nevent_data = client.website_event_data_events(\"website_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687\n})\n\n# Get event statistics\nstats = client.website_event_data_stats(\"website_id\", {\n  startAt: 1656679719687,\n  endAt: 1656766119687\n})\n```\n\n### Reports\n\n```ruby\n# List reports (optionally filter by website and/or type)\nall_reports = client.reports\nwebsite_reports = client.reports(websiteId: \"website_id\")\nfunnel_reports = client.reports(websiteId: \"website_id\", type: \"funnel\")\n\n# Create a report\nreport = client.create_report({\n  websiteId: \"website_id\",\n  type: \"funnel\",\n  name: \"Checkout Funnel\",\n  parameters: {\n    startDate: \"2024-01-01T00:00:00Z\",\n    endDate: \"2024-01-31T23:59:59Z\"\n  }\n})\n\n# Run specialized reports\nfunnel = client.report_funnel({\n  websiteId: \"website_id\",\n  startDate: \"2024-01-01T00:00:00Z\",\n  endDate: \"2024-01-31T23:59:59Z\",\n  steps: [\n    { type: \"path\", value: \"/\" },\n    { type: \"path\", value: \"/checkout\" },\n    { type: \"path\", value: \"/thank-you\" }\n  ],\n  window: 7\n})\n\nretention = client.report_retention({\n  websiteId: \"website_id\",\n  startDate: \"2024-01-01T00:00:00Z\",\n  endDate: \"2024-01-31T23:59:59Z\",\n  timezone: \"America/Los_Angeles\"\n})\n\n# Available report types: attribution, breakdown, funnel, goal, journey, retention, revenue, utm\n```\n\n**Report types:**\n| Type | Description |\n|------|-------------|\n| `attribution` | Marketing channel attribution analysis |\n| `breakdown` | Multi-dimensional data segmentation |\n| `funnel` | Conversion funnel tracking |\n| `goal` | Goal performance metrics |\n| `journey` | User navigation path analysis |\n| `retention` | Return visitor analysis |\n| `revenue` | Revenue tracking and analysis |\n| `utm` | UTM campaign parameter breakdown |\n\n### User \u0026 Team Management\n\n```ruby\n# Get current user info\nme = client.me\nmy_teams = client.my_teams(page: 1, pageSize: 10)\nmy_websites = client.my_websites(includeTeams: true)\n\n# Team management\nteams = client.teams\nteam = client.team(\"team_id\")\nclient.create_team(\"My Team\")\nclient.add_team_user(\"team_id\", \"user_id\", \"team-member\")\n\n# User management (admin only, self-hosted)\nusers = client.admin_users\nclient.create_user(\"username\", \"password\", \"user\")\n```\n\n### Website Management\n\n```ruby\n# Create a website\nwebsite = client.create_website({\n  name: \"My Website\",\n  domain: \"example.com\",\n  teamId: \"optional-team-id\"\n})\n\n# Update a website\nclient.update_website(\"website_id\", {\n  name: \"Updated Name\",\n  shareId: \"public-share-id\"\n})\n\n# Reset website data\nclient.reset_website(\"website_id\")\n\n# Delete a website\nclient.delete_website(\"website_id\")\n```\n\n## Available Methods\n\n### Authentication\n- `verify_token` - Verify the current authentication token\n\n### Me (Current User)\n- `me` - Get current user information\n- `my_teams(params)` - Get user's teams (supports pagination)\n- `my_websites(params)` - Get user's websites\n\n### Admin (Self-hosted only)\n- `admin_users(params)` - List all users\n- `admin_websites(params)` - List all websites\n- `admin_teams(params)` - List all teams\n\n### Users\n- `create_user(username, password, role, id:)` - Create a user\n- `user(user_id)` - Get user by ID\n- `update_user(user_id, params)` - Update user\n- `delete_user(user_id)` - Delete user\n- `user_websites(user_id, params)` - Get user's websites\n- `user_teams(user_id, params)` - Get user's teams\n\n### Teams\n- `teams(params)` - List all teams\n- `create_team(name)` - Create a team\n- `join_team(access_code)` - Join a team\n- `team(team_id)` - Get team by ID\n- `update_team(team_id, params)` - Update team\n- `delete_team(team_id)` - Delete team\n- `team_users(team_id, params)` - List team members\n- `add_team_user(team_id, user_id, role)` - Add user to team\n- `team_user(team_id, user_id)` - Get team member\n- `update_team_user(team_id, user_id, role)` - Update member role\n- `delete_team_user(team_id, user_id)` - Remove user from team\n- `team_websites(team_id, params)` - List team websites\n\n### Websites\n- `websites(params)` - List all websites\n- `create_website(params)` - Create a website\n- `website(website_id)` - Get website by ID\n- `update_website(website_id, params)` - Update website\n- `delete_website(website_id)` - Delete website\n- `reset_website(website_id)` - Reset website data\n\n### Website Statistics\n- `website_stats(website_id, params)` - Get statistics\n- `website_active_visitors(website_id)` - Get active visitors\n- `website_pageviews(website_id, params)` - Get pageviews\n- `website_events(website_id, params)` - Get events (time-series)\n- `website_events_series(website_id, params)` - Get events series\n- `website_metrics(website_id, params)` - Get metrics\n- `website_metrics_expanded(website_id, params)` - Get expanded metrics\n\n### Sessions\n- `website_sessions(website_id, params)` - List sessions\n- `website_sessions_stats(website_id, params)` - Get session stats\n- `website_sessions_weekly(website_id, params)` - Get weekly breakdown\n- `website_session(website_id, session_id)` - Get session details\n- `website_session_activity(website_id, session_id, params)` - Get activity\n- `website_session_properties(website_id, session_id)` - Get properties\n- `website_session_data_properties(website_id, params)` - Get data properties\n- `website_session_data_values(website_id, params)` - Get data values\n\n### Events\n- `website_events_list(website_id, params)` - List events (paginated)\n- `website_event_data(website_id, event_id)` - Get event data\n- `website_event_data_events(website_id, params)` - Get event aggregations\n- `website_event_data_fields(website_id, params)` - Get event fields\n- `website_event_data_properties(website_id, params)` - Get event properties\n- `website_event_data_values(website_id, params)` - Get event values\n- `website_event_data_stats(website_id, params)` - Get event statistics\n\n### Realtime\n- `realtime(website_id)` - Get realtime stats (last 30 minutes)\n\n### Links\n- `links(params)` - List all links\n- `link(link_id)` - Get link by ID\n- `update_link(link_id, params)` - Update link\n- `delete_link(link_id)` - Delete link\n\n### Pixels\n- `pixels(params)` - List all pixels\n- `pixel(pixel_id)` - Get pixel by ID\n- `update_pixel(pixel_id, params)` - Update pixel\n- `delete_pixel(pixel_id)` - Delete pixel\n\n### Reports\n- `reports(params)` - List all reports (filter by `websiteId`, `type`)\n- `create_report(params)` - Create a report\n- `report(report_id)` - Get report by ID\n- `update_report(report_id, params)` - Update report\n- `delete_report(report_id)` - Delete report\n- `report_attribution(params)` - Run attribution report\n- `report_breakdown(params)` - Run breakdown report\n- `report_funnel(params)` - Run funnel report\n- `report_goals(params)` - Run goals report\n- `report_journey(params)` - Run journey report\n- `report_retention(params)` - Run retention report\n- `report_revenue(params)` - Run revenue report\n- `report_utm(params)` - Run UTM report\n\n### Sending Events\n- `send_event(payload, user_agent:)` - Send tracking event\n\n## Error Handling\n\nThe gem defines several custom error classes:\n\n```ruby\nbegin\n  client.website(\"non-existent-id\")\nrescue Umami::NotFoundError =\u003e e\n  puts \"Website not found: #{e.message}\"\nrescue Umami::ClientError =\u003e e\n  puts \"Client error: #{e.message}\"\nrescue Umami::ServerError =\u003e e\n  puts \"Server error: #{e.message}\"\nrescue Umami::AuthenticationError =\u003e e\n  puts \"Authentication failed: #{e.message}\"\nrescue Umami::ConfigurationError =\u003e e\n  puts \"Configuration error: #{e.message}\"\nrescue Umami::APIError =\u003e e\n  puts \"API error: #{e.message}\"\nend\n```\n\n**Error class hierarchy:**\n- `Umami::Error` - Base error class\n  - `Umami::ConfigurationError` - Configuration issues\n  - `Umami::AuthenticationError` - Authentication failures\n  - `Umami::APIError` - API request failures\n    - `Umami::NotFoundError` - Resource not found (404)\n    - `Umami::ClientError` - Client errors (4xx)\n    - `Umami::ServerError` - Server errors (5xx)\n\n## Logging\n\nThe gem uses a logger that can be configured:\n\n```ruby\n# Set log level\nUmami.logger.level = Logger::DEBUG\n\n# Use a custom logger\nUmami.logger = Rails.logger\n```\n\n## Development\n\nAfter 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.\n\nTo install this gem onto your local machine, run `bundle exec rake install`.\n\n## Contributing\n\nBug 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.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frameerez%2Fumami-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frameerez%2Fumami-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frameerez%2Fumami-ruby/lists"}