{"id":18728623,"url":"https://github.com/rubyonworld/strava-ruby-client","last_synced_at":"2025-10-09T13:35:52.525Z","repository":{"id":174008167,"uuid":"542166008","full_name":"RubyOnWorld/strava-ruby-client","owner":"RubyOnWorld","description":"Unlike other clients, including strava-api-v3, provides complete OAuth refresh token flow support, webhooks support, a richer first class interface to Strava models, conversion helpers for distance, time and elevation, natively supports pagination, implements more consistent error handling and is built with thorough test coverage using actual Strava data.","archived":false,"fork":false,"pushed_at":"2022-09-27T18:37:45.000Z","size":575,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-19T20:31:58.665Z","etag":null,"topics":["api","client","oauth","ruby","strava","token"],"latest_commit_sha":null,"homepage":"","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/RubyOnWorld.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","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,"zenodo":null},"funding":{"github":["dblock"]}},"created_at":"2022-09-27T15:46:58.000Z","updated_at":"2022-09-27T22:36:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"98070522-c20f-4e60-95bd-38e5dded8cfa","html_url":"https://github.com/RubyOnWorld/strava-ruby-client","commit_stats":null,"previous_names":["rubyonworld/strava-ruby-client"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/RubyOnWorld/strava-ruby-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fstrava-ruby-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fstrava-ruby-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fstrava-ruby-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fstrava-ruby-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RubyOnWorld","download_url":"https://codeload.github.com/RubyOnWorld/strava-ruby-client/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RubyOnWorld%2Fstrava-ruby-client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001479,"owners_count":26083102,"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","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["api","client","oauth","ruby","strava","token"],"created_at":"2024-11-07T14:22:22.016Z","updated_at":"2025-10-09T13:35:52.520Z","avatar_url":"https://github.com/RubyOnWorld.png","language":"Ruby","funding_links":["https://github.com/sponsors/dblock"],"categories":[],"sub_categories":[],"readme":"# Strava Ruby Client\n\n[![Gem Version](https://badge.fury.io/rb/strava-ruby-client.svg)](https://badge.fury.io/rb/strava-ruby-client)\n[![Test](https://github.com/dblock/strava-ruby-client/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/dblock/strava-ruby-client/actions/workflows/test.yml)\n\nA complete Ruby client for the [Strava API v3](https://developers.strava.com).\n\nUnlike other clients, including [strava-api-v3](https://github.com/jaredholdcroft/strava-api-v3), provides complete OAuth refresh token flow support, webhooks support, a richer first class interface to Strava models, conversion helpers for distance, time and elevation, natively supports pagination, implements more consistent error handling and is built with thorough test coverage using actual Strava data.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Activities](#activities)\n    - [Create an Activity](#create-an-activity)\n    - [Get Activity](#get-activity)\n    - [List Activity Photos](#list-activity-photos)\n    - [List Activity Comments](#list-activity-comments)\n    - [List Activity Kudoers](#list-activity-kudoers)\n    - [List Activity Laps](#list-activity-laps)\n    - [List Athlete Activities](#list-athlete-activities)\n    - [Get Activity Zones](#get-activity-zones)\n    - [Update Activity](#update-activity)\n  - [Athletes](#athletes)\n    - [Get Authenticated Athlete](#get-authenticated-athlete)\n    - [Get Zones](#get-zones)\n    - [Get Athlete Stats](#get-athlete-stats)\n    - [Update Athlete](#update-athlete)\n  - [Clubs](#clubs)\n    - [List Club Activities](#list-club-activities)\n    - [List Club Events](#list-club-events)\n    - [List Club Administrators](#list-club-administrators)\n    - [Get Club](#get-club)\n    - [List Club Members](#list-club-members)\n    - [List Athlete Clubs](#list-athlete-clubs)\n  - [Gears](#gears)\n    - [Get Equipment](#get-equipment)\n  - [Routes](#routes)\n    - [Export Route GPX](#export-route-gpx)\n    - [Export Route TCX](#export-route-tcx)\n    - [Get Route](#get-route)\n    - [List Athlete Routes](#list-athlete-routes)\n  - [Running Races](#running-races)\n    - [Get Running Race](#get-running-race)\n  - [Segment Efforts](#segment-efforts)\n    - [List Segment Efforts](#list-segment-efforts)\n    - [Get Segment Effort](#get-segment-effort)\n  - [Segments](#segments)\n    - [Explore Segments](#explore-segments)\n    - [List Starred Segments](#list-starred-segments)\n    - [Get Segment](#get-segment)\n    - [Star Segment](#star-segment)\n  - [Streams](#streams)\n    - [Get Activity Streams](#get-activity-streams)\n    - [Get Segment Effort Streams](#get-segment-effort-streams)\n    - [Get Segment Streams](#get-segment-streams)\n  - [Uploads](#uploads)\n    - [Upload Activity](#upload-activity)\n    - [Get Upload](#get-upload)\n  - [Pagination](#pagination)\n  - [OAuth](#oauth)\n    - [OAuth Workflow](#oauth-workflow)\n    - [Deauthorize](#deauthorize)\n    - [Command Line OAuth Workflow](#command-line-oauth-workflow)\n  - [Webhooks](#webhooks)\n- [Configuration](#configuration)\n  - [Web Client Options](#web-client-options)\n  - [API Client Options](#api-client-options)\n  - [OAuth Client Options](#oauth-client-options)\n  - [Webhooks Client Options](#webhooks-client-options)\n- [Errors](#errors)\n- [Tools](#tools)\n  - [Strava OAuth Token](#strava-oauth-token)\n- [Users](#users)\n- [Resources](#resources)\n- [Upgrading](#upgrading)\n- [Contributing](#contributing)\n- [Copyright and License](#copyright-and-license)\n\n## Installation\n\nAdd to Gemfile.\n\n```\ngem 'strava-ruby-client'\n```\n\nRun `bundle install`.\n\n## Usage\n\nUse an access token obtained from [My API Application](https://www.strava.com/settings/api) in the Strava UI, the [strava-oauth-token tool](#strava-oauth-token) or the [OAuth Workflow](#oauth) in your application.\n\n```ruby\nclient = Strava::Api::Client.new(\n  access_token: \"12345678987654321\"\n)\n```\n\n### Activities\n\n#### Create an Activity\n\nCreates a manual activity for an athlete.\n\n```ruby\nactivity = client.create_activity(\n  name: 'Afternoon Run',\n  sport_type: 'Run',\n  start_date_local: Time.now,\n  elapsed_time: 1234, # in seconds\n  description: 'Test run.',\n  distance: 1000 # in meters\n)\n\nactivity.name # =\u003e 'Afternoon Run'\nactivity.strava_url # =\u003e 'https://www.strava.com/activities/1982980795'\n```\n\nSee [Strava::Models::Activity](lib/strava/models/activity.rb) for all available properties.\n\n#### Get Activity\n\nReturns the given activity that is owned by the authenticated athlete.\n\n```ruby\nactivity = client.activity(1982980795)\n\nactivity.name # =\u003e 'Afternoon Run'\nactivity.strava_url # =\u003e 'https://www.strava.com/activities/1982980795'\n```\n\nSee [Strava::Models::Activity](lib/strava/models/activity.rb) for all available properties.\n\nUse `map.summary_polyline` and combine with [polylines](https://github.com/joshuaclayton/polylines) to parse the activity map and to construct a Google maps URL with start and end markers.\n\n```ruby\nmap = activity.map # =\u003e Strava::Models::Map\n\ndecoded_summary_polyline = Polylines::Decoder.decode_polyline(map.summary_polyline)\nstart_latlng = decoded_summary_polyline[0]\nend_latlng = decoded_summary_polyline[-1]\n\ngoogle_maps_api_key = ENV['GOOGLE_STATIC_MAPS_API_KEY']\n\ngoogle_image_url = \"https://maps.googleapis.com/maps/api/staticmap?maptype=roadmap\u0026path=enc:#{map.summary_polyline}\u0026key=#{google_maps_api_key}\u0026size=800x800\u0026markers=color:yellow|label:S|#{start_latlng[0]},#{start_latlng[1]}\u0026markers=color:green|label:F|#{end_latlng[0]},#{end_latlng[1]}\"\n```\n\nSee [Strava::Models::Map](lib/strava/models/map.rb) for all available properties.\n\n#### List Activity Photos\n\nReturns the photos on the given activity. This API is undocumented.\n\n```ruby\nphotos = client.activity_photos(1982980795) # =\u003e Array[Strava::Models::Photo]\n\nphoto = photos.first # =\u003e Strava::Models::Photo\n\nphoto.id # =\u003e nil\nphoto.unique_id # =\u003e '65889142-538D-4EE5-96F5-3DC3B773B1E3'\nphoto.urls # =\u003e { '0' =\u003e 'https://dgtzuqphqg23d.cloudfront.net/eb4DMJ2hJW3k_g9URZEMfaJ8rZfHagrNlZRuEZz0osU-29x64.jpg' }\nphoto.athlete_id # =\u003e 26_462_176\nphoto.activity_id # =\u003e 1_946_417_534\nphoto.activity_name # =\u003e 'TCS NYC Marathon 2018'\nphoto.created_at # =\u003e Time\nphoto.uploaded_at # =\u003e Time\nphoto.sizes # =\u003e { '0' =\u003e [29, 64] }\nphoto.default_photo # =\u003e false\n```\n\nSee [Strava::Models::Photo](lib/strava/models/photo.rb) for all available properties.\n\n#### List Activity Comments\n\nReturns the comments on the given activity.\n\n```ruby\ncomments = client.activity_comments(1982980795) # =\u003e Array[Strava::Models::Comment]\n\ncomment = comments.first # =\u003e Strava::Models::Comment\n\ncomment.text # =\u003e 'Молодчина!'\ncomment.athlete.username # =\u003e 'zolotov'\n```\n\nSee [Strava::Models::Comment](lib/strava/models/comment.rb) for all available properties.\n\n#### List Activity Kudoers\n\nReturns the athletes who kudoed an activity identified by an identifier.\n\n```ruby\nkudoers = client.activity_kudos(1982980795) # =\u003e Array[Strava::Models::Athlete]\n\nkodoer = kudoers.first # =\u003e Strava::Models::Athlete\n\nkudoer.username # =\u003e 'zolotov'\n```\n\nSee [Strava::Models::Athlete](lib/strava/models/athlete.rb) for all available properties.\n\n#### List Activity Laps\n\nReturns the laps of an activity identified by an identifier.\n\n```ruby\nlaps = client.activity_laps(1982980795) # =\u003e Array[Strava::Models::Lap]\n\nlap = laps.first # =\u003e Strava::Models::Lap\n\nlap.name # =\u003e 'Lap 1'\n```\n\nSee [Strava::Models::Lap](lib/strava/models/lap.rb) for all available properties.\n\n#### List Athlete Activities\n\nReturns the currently logged-in athlete's activities.\n\n```ruby\nactivities = client.athlete_activities # =\u003e Array[Strava::Models::Activity]\n\nactivity = activities.first # =\u003e Strava::Models::Activity\n\nactivity.name # =\u003e 'NYC TCS Marathon 2018'\nactivity.strava_url # =\u003e 'https://www.strava.com/activities/1477353766'\nactivity.type_emoji # =\u003e '🏃'\nactivity.sport_type_emoji # =\u003e '🏃'\nactivity.distance_s # =\u003e '42.2km'\nactivity.moving_time_in_hours_s # =\u003e '3h38m5s'\nactivity.elapsed_time_in_hours_s # =\u003e '3h42m13s'\nactivity.pace_s # =\u003e '5m15s/km'\nactivity.pace_per_mile_s # =\u003e '8m28s/mi'\nactivity.speed_s # =\u003e '11.4km/h'\nactivity.miles_per_hour_s # =\u003e '7.1mph'\nactivity.total_elevation_gain_s # =\u003e '270.9m'\nactivity.total_elevation_gain_in_feet_s # =\u003e '888.8ft'\n```\n\nSee [Strava::Models::Activity](lib/strava/models/activity.rb), [Strava::Models::Mixins::Distance](lib/strava/models/mixins/distance.rb), [Strava::Models::Mixins::Elevation](lib/strava/models/mixins/elevation.rb) and [Strava::Models::Mixins::Time](lib/strava/models/mixins/time.rb) for all available properties.\n\n#### Get Activity Zones\n\nReturns the zones of a given activity.\n\n```ruby\nzones = client.activity_zones(1982980795) # =\u003e Array[Strava::Models::ActivityZone]\n\nzone = zones.first # =\u003e Strava::Models::ActivityZone\nzones.type # =\u003e 'heartrate'\n\ndistribution_buckets = activity_zone.distribution_buckets # =\u003e Array[Strava::Models::TimedZoneRange]\n\ndistribution_bucket = distribution_buckets.first # =\u003e Strava::Models::TimedZoneRange\n\ndistribution_bucket.min # =\u003e 0\ndistribution_bucket.max # =\u003e 123\ndistribution_bucket.time # =\u003e 20\n```\n\nSee [Strava::Models::ActivityZone](lib/strava/models/activity_zone.rb) and [Strava::Models::TimedZoneRange](lib/strava/models/timed_zone_range.rb) for all available properties.\n\n#### Update Activity\n\nUpdate an activity.\n\n```ruby\nactivity = client.update_activity(\n  id: 1982980795,\n  name: 'Afternoon Run (Updated)',\n  sport_type: 'Run',\n  description: 'It was cold.'\n)\n\nactivity.name # =\u003e 'Afternoon Run (Updated)'\nactivity.strava_url # =\u003e 'https://www.strava.com/activities/1982980795'\n```\n\n### Athletes\n\n#### Get Authenticated Athlete\n\nReturns the currently authenticated athlete.\n\n```ruby\nclient.athlete # =\u003e Strava::Models::Athlete\n```\n\nSee [Strava::Models::Athlete](lib/strava/models/athlete.rb) for all available properties.\n\n#### Get Zones\n\nReturns the the authenticated athlete's heart rate and power zones.\n\n```ruby\nathlete_zones = client.athlete_zones # =\u003e Strava::Models::Zones\n\nheart_rate = athlete_zones.heart_rate # =\u003e Strava::Models::HeartRateZoneRanges\nheart_rate.custom_zone # =\u003e false\n\nzone = heart_rate.zones.first # =\u003e Strava::Models::ZoneRange\nzone.min # =\u003e 0\nzone.max # =\u003e 123\n```\n\nSee [Strava::Models::Zones](lib/strava/models/zones.rb), [Strava::Models::HeartRateZoneRanges](lib/strava/models/heart_rate_zone_ranges.rb), [Strava::Models::PowerZoneRanges](lib/strava/models/power_zone_ranges.rb) and [Strava::Models::ZoneRange](lib/strava/models/zone_range.rb) for all available properties.\n\n#### Get Athlete Stats\n\nReturns the activity stats of an athlete.\n\n```ruby\nathlete_stats = client.athlete_stats(26462176) # =\u003e Strava::Models::ActivityStats\n\nrecent_run_totals = athlete_stats.recent_ride_totals # =\u003e Strava::Models::ActivityTotal\n\nrecent_run_totals.count # =\u003e 7\nrecent_run_totals.distance # =\u003e 78049.90087890625\nrecent_run_totals.distance_s # =\u003e '78.05km'\nrecent_run_totals.moving_time # =\u003e 25647\nrecent_run_totals.moving_time_in_hours_s # =\u003e '7h7m27s'\nrecent_run_totals.elapsed_time # =\u003e 26952\nrecent_run_totals.elapsed_time_in_hours_s # =\u003e '7h29m12s'\nrecent_run_totals.elevation_gain # =\u003e 595.4644241333008\nrecent_run_totals.total_elevation_gain_s # =\u003e '595.5m'\nrecent_run_totals.achievement_count # =\u003e 19\n```\n\nSee [Strava::Models::ActivityStats](lib/strava/models/activity_stats.rb) and [Strava::Models::ActivityTotal](lib/strava/models/activity_total.rb) for all available properties.\n\n#### Update Athlete\n\nUpdate the currently authenticated athlete.\n\n```ruby\nathlete = client.update_athlete(weight: 90.1) # =\u003e Strava::Models::Athlete\n```\n\nSee [Strava::Models::Athlete](lib/strava/models/athlete.rb) for all available returned properties.\n\n### Clubs\n\n#### List Club Activities\n\nRetrieve recent activities from members of a specific club.\n\n```ruby\nactivities = client.club_activities(108605) # =\u003e Array[Strava::Models::Activity]\n\nactivity = activities.first # =\u003e Strava::Models::Activity\n\nactivity.name # =\u003e 'Afternoon Run'\n```\n\nSee [Strava::Models::Activity](lib/strava/models/activity.rb) for all available properties. Note that Strava does not return activity or athlete ID via this API.\n\n#### List Club Events\n\nRetrieve recent Events from a specific club.\n\n```ruby\nevents = client.club_events(108605) # =\u003e Array[Strava::Models::ClubEvent]\n\nevent = events.first # =\u003e Strava::Models::ClubEvent\n\nevent.title # =\u003e 'First Group Event Ever! Yippieh!'\n```\n\nSee [Strava::Models::ClubEvent](lib/strava/models/club_event.rb) for all available properties.\n\n#### List Club Administrators\n\nReturns a list of the administrators of a given club.\n\n```ruby\nadmins = client.club_admins(108605) # =\u003e Array[Strava::Models::ClubAdmin]\n\nadmin = admins.first # =\u003e Strava::Models::ClubAdmin\nadmin.name # =\u003e 'Peter Ciaccia'\n```\n\nSee [Strava::Models::ClubAdmin](lib/strava/models/club_admin.rb) for all available properties.\n\n#### Get Club\n\nReturns a given club using its identifier.\n\n```ruby\nclub = client.club(108605) # =\u003e Strava::Models::Club\n\nclub.name # =\u003e 'NYRR'\n```\n\nSee [Strava::Models::Club](lib/strava/models/club.rb) for all available properties.\n\n#### List Club Members\n\nReturns a list of the members of a given club.\n\n```ruby\nmembers = client.club_members(108605) # =\u003e Array[Strava::Models::ClubMember]\n\nmember = members.first # =\u003e Strava::Models::ClubMember\nmember.name # =\u003e 'Peter Ciaccia'\n```\n\nSee [Strava::Models::ClubMember](lib/strava/models/club_member.rb) for all available properties.\n\n#### List Athlete Clubs\n\nReturns a list of the clubs whose membership includes the authenticated athlete.\n\n```ruby\nclubs = client.athlete_clubs # =\u003e Array[Strava::Models::Club]\n\nclub = clubs.first # =\u003e Strava::Models::Club\n\nactivity.name # =\u003e 'NYRR'\nactivity.strava_url # =\u003e 'https://www.strava.com/clubs/nyrr'\n```\n\nSee [Strava::Models::Club](lib/strava/models/club.rb) for all available properties.\n\n### Gears\n\n#### Get Equipment\n\nReturns an equipment using its identifier.\n\n```ruby\ngear = client.gear(id: 'b2338517') # =\u003e Strava::Models::Gear\n\ngear.id # =\u003e 'b2338517'\ngear.name # =\u003e 'Trek'\ngear.distance # =\u003e 380939.0\ngear.distance_s # =\u003e '380.94km'\ngear.brand_name # =\u003e 'Trek'\ngear.model_name # =\u003e 'Madone'\ngear.description # =\u003e 'white'\ngear.primary # =\u003e 'false'\ngear.frame_type # =\u003e '3'\ngear.weight # =\u003e '9'\ngear.retired # =\u003e 'false'\n```\n\nSee [Strava::Models::Gear](lib/strava/models/gear.rb) for all available properties.\n\n### Routes\n\n#### Export Route GPX\n\nReturns [GPS Exchange Format](https://en.wikipedia.org/wiki/GPS_Exchange_Format) (GPX) data of the route. Combine with [multi_xml](https://github.com/sferik/multi_xml) or [gpx](https://github.com/dougfales/gpx) to parse it.\n\n```ruby\ndata = client.export_route_gpx(16341573) # =\u003e String\n\nrequire 'multi_xml'\nxml = MultiXml.parse(data) # =\u003e parsed GPX\n\nrequire 'gpx'\ngpx = GPX::GPXFile.new(gpx_data: data) # =\u003e GPX::GPXFile\n\ngpx.name # =\u003e 'Lower Manhattan Loop'\ngpx.description # =\u003e 'My usual long run when I am too lazy to go to Central Park.'\ngpx.tracks # =\u003e Array[GPX::Track]\n```\n\n#### Export Route TCX\n\nReturns a [Training Center XML](https://en.wikipedia.org/wiki/Training_Center_XML) (TCX) data of the route. Combine with [multi_xml](https://github.com/sferik/multi_xml) to parse it.\n\n```ruby\ndata = client.export_route_tcx(16341573) # =\u003e String\n\nrequire 'multi_xml'\nxml = MultiXml.parse(data) # =\u003e parsed TCX\n```\n\n#### Get Route\n\nReturns a route using its identifier.\n\n```ruby\nroute = client.route(16341573) # =\u003e Strava::Models::Route\n\nroute.name # =\u003e 'Lower Manhattan Loop'\nroute.description # =\u003e 'My usual long run when I am too lazy to go to Central Park.'\n```\n\nSee [Strava::Models::Route](lib/strava/models/route.rb) for all available properties.\n\n#### List Athlete Routes\n\nReturns a list of the routes by athlete ID.\n\n```ruby\nroutes = client.athlete_routes(26462176) # =\u003e Array[Strava::Models::Route]\n\nroute = routes.first # =\u003e Strava::Models::Route\n\nroute.name # =\u003e 'Lower Manhattan Loop'\nroute.description # =\u003e 'My usual long run when I am too lazy to go to Central Park.'\nroute.moving_time_in_hours_s # =\u003e '1h21m5s'\n```\n\nSee [Strava::Models::Route](lib/strava/models/route.rb) for all available properties.\n\n### Running Races\n\n#### Get Running Race\n\nReturns a running race for a given identifier.\n\n```ruby\nrunning_race = client.running_race(1577) # =\u003e Strava::Models::RunningRace\n\nrunning_race.name # =\u003e 'Walt Disney World Marathon 10k'\nrunning_race.distance # =\u003e 10_000.0\nrunning_race.distance_s # =\u003e '10km'\nrunning_race.city # =\u003e 'Orlando'\nrunning_race.state # =\u003e 'FL'\nrunning_race.country # =\u003e 'United States'\nrunning_race.strava_url # =\u003e 'https://www.strava.com/running-races/2018-walt-disney-world-marathon-10k'\nrunning_race.website_url # =\u003e 'https://www.rundisney.com/disneyworld-marathon/'\n```\n\nSee [Strava::Models::RunningRace](lib/strava/models/running_race.rb) for all available properties.\n\n### Segment Efforts\n\n#### List Segment Efforts\n\nReturns a set of the authenticated athlete's segment efforts for a given segment.\n\n```ruby\nsegment_efforts = client.segment_efforts(1109718)\n\nsegment_effort = segment_efforts.first # =\u003e Strava::Models::SegmentEffort\n\nsegment_effort.name # =\u003e 'E 14th St Climb'\nsegment_effort.activity # =\u003e Strava::Models::Activity\nsegment_effort.athlete # =\u003e Strava::Models::Athlete\nsegment_effort.elapsed_time # =\u003e 116\nsegment_effort.distance # =\u003e 398.6\nsegment_effort.distance_s # =\u003e '0.4km'\nsegment_effort.average_heartrate # =\u003e 152.2\nsegment_effort.max_heartrate # =\u003e 158.0\n\nsegment_effort.achievements # =\u003e Enumerable\n\nachievement = segment_effort.achievements.first # =\u003e Strava::Models::Achievement\nachievement.rank # =\u003e 1\nachievement.type # =\u003e 'pr'\nachievement.type_id # =\u003e 3\n```\n\nSee [Strava::Models::SegmentEffort](lib/strava/models/segment_effort.rb) and [Strava::Models::Achievement](lib/strava/models/achievement.rb) for all available properties.\n\n#### Get Segment Effort\n\nReturns a segment effort from an activity that is owned by the authenticated athlete.\n\n```ruby\nsegment_effort = client.segment_effort(41494197089) # =\u003e Strava::Models::SegmentEffort\n\nsegment_effort.name # =\u003e 'E 14th St Climb'\nsegment_effort.activity # =\u003e Strava::Models::Activity\nsegment_effort.elapsed_time # =\u003e 116\n\nsegment_stats = segment_effort.athlete_segment_stats # =\u003e Strava::Models::SegmentStats\nsegment_stats.pr_elapsed_time # =\u003e 116\nsegment_stats.elapsed_time_in_hours_s # =\u003e '1m56s'\nsegment_stats.pr_date # =\u003e Date\nsegment_stats.effort_count # =\u003e 3\n```\n\nSee [Strava::Models::SegmentEffort](lib/strava/models/segment_effort.rb) and [Strava::Models::SegmentStats](lib/strava/models/segment_stats.rb) for all available properties.\n\n### Segments\n\n#### Explore Segments\n\nReturns the top 10 segments matching a specified query.\n\n```ruby\nsegments = client.explore_segments(bounds: [36.372975, -94.220234, 36.415949, -94.183670], activity_type: 'running')\n\nsegment = segments.first # =\u003e Strava::Models::ExplorerSegment\nsegment.name # =\u003e 'Compton Gardens hill'\nsegment.avg_grade # =\u003e 4.6\nsegment.start_latlng # =\u003e [36.377702, -94.207242]\nsegment.end_latlng # =\u003e [36.375948, -94.207689]\nsegment.elev_difference # =\u003e 9.6\n```\n\nSee [Strava::Models::ExplorerSegment](lib/strava/models/explorer_segment.rb) for all available properties.\n\n#### List Starred Segments\n\nList of the authenticated athlete's starred segments.\n\n```ruby\nsegments = client.starred_segments\n\nsegment = segments.first # =\u003e Strava::Models::Segment\n\nsegment.pr_time # =\u003e 256\nsegment.elapsed_time_in_hours_s # =\u003e '4m16s'\nsegment.starred_date # =\u003e Time\nsegment.athlete_pr_effort # =\u003e Strava::Models::SegmentEffort\n```\n\nSee [Strava::Models::Segment](lib/strava/models/segment.rb) and [Strava::Models::SegmentEffort](lib/strava/models/segment_effort.rb) for all available properties.\n\n#### Get Segment\n\nReturns the specified segment.\n\n```ruby\nsegment = client.segment(1109718) # =\u003e Strava::Models::Segment\n\nsegment.name # =\u003e 'E 14th St Climb'\nsegment.city # =\u003e 'New York'\nsegment.state # =\u003e 'NY'\nsegment.country # =\u003e 'United States'\nsegment.map # =\u003e Strava::Models::Map\nsegment.effort_count # =\u003e 750\nsegment.athlete_count # =\u003e 206\nsegment.star_count # =\u003e 1\nsegment.athlete_segment_stats # =\u003e Strava::Models::SegmentStats\n```\n\nSee [Strava::Models::Segment](lib/strava/models/segment.rb) for all available properties.\n\n#### Star Segment\n\nStars/unstars the given segment for the authenticated athlete.\n\n```ruby\nsegment = client.star_segment(50272077110, starred: true) # =\u003e Strava::Models::Segment\n\nsegment.name # =\u003e 'E 14th St Climb'\nsegment.starred # =\u003e true\n```\n\nSee [Strava::Models::Segment](lib/strava/models/segment.rb) for all available properties.\n\n### Streams\n\nStream APIs can return various streams by key(s).\n\n```ruby\nstreams = client.segment_streams(1109718, keys: %w[distance latlng altitude]) # =\u003e Strava::Models::StrewamSet\n\nstreams.distance # =\u003e Strava::Models::Stream\nstreams.latlng # =\u003e Strava::Models::Stream\nstreams.altitude # =\u003e Strava::Models::Stream\n```\n\n#### Get Activity Streams\n\nReturns the given activity's streams.\n\n```ruby\nstreams = client.activity_streams(1946417534) # =\u003e Strava::Models::StreamSet\n\ndistance = streams.distance # =\u003e Strava::Models::Stream\ndistance.original_size # =\u003e 13_129\ndistance.resolution # =\u003e 'high'\ndistance.series_type # =\u003e 'distance'\ndistance.data # =\u003e Array[Float]\n```\n\nSee [Strava::Models::StreamSet](lib/strava/models/stream_set.rb) and [Strava::Models::Stream](lib/strava/models/stream.rb) for all available properties.\n\n#### Get Segment Effort Streams\n\nReturns a set of streams for a segment effort completed by the authenticated athlete.\n\n```ruby\nstreams = client.segment_effort_streams(41494197089)\n\ndistance = streams.distance # =\u003e Strava::Models::Stream\ndistance.original_size # =\u003e 117\ndistance.resolution # =\u003e 'high'\ndistance.series_type # =\u003e 'distance'\ndistance.data # =\u003e Array[Float]\n```\n\nSee [Strava::Models::StreamSet](lib/strava/models/stream_set.rb) and [Strava::Models::Stream](lib/strava/models/stream.rb) for all available properties.\n\n#### Get Segment Streams\n\nReturns the given segment's streams.\n\n```ruby\nstreams = client.segment_streams(1109718) # =\u003e Strava::Models::StreamSet\n\ndistance = streams.distance # =\u003e Strava::Models::Stream\ndistance.original_size # =\u003e 32\ndistance.resolution # =\u003e 'high'\ndistance.series_type # =\u003e 'distance'\ndistance.data # =\u003e Array[Float]\n```\n\nSee [Strava::Models::StreamSet](lib/strava/models/stream_set.rb) and [Strava::Models::Stream](lib/strava/models/stream.rb) for all available properties.\n\n### Uploads\n\n#### Upload Activity\n\nUploads a new data file to create an activity from.\n\n```ruby\nupload = client.create_upload(\n  file: Faraday::UploadIO.new('17611540601.tcx', 'application/tcx+xml'),\n  name: 'Uploaded Activity',\n  description: 'Uploaded by strava-ruby-client.',\n  data_type: 'tcx',\n  external_id: 'strava-ruby-client-upload-1'\n) # =\u003e Strava::Models::Upload\n\nupload.id # =\u003e 2136460097\nupload.external_id # =\u003e 'strava-ruby-client-upload-1.tcx'\nupload.error # =\u003e nil\nupload.status # =\u003e 'Your activity is still being processed.'\nupload.activity_id # =\u003e nil\n```\n\nSee [Strava::Models::Upload](lib/strava/models/upload.rb) for all available properties.\n\n#### Get Upload\n\nReturns an upload for a given identifier.\n\n```ruby\nupload = client.upload(2136460097) # =\u003e Strava::Models::Upload\n\nupload.id # =\u003e 2_136_460_097\nupload.external_id # =\u003e 'strava-ruby-client-upload-1.tcx'\nupload.error # =\u003e nil\nupload.status # =\u003e 'Your activity is ready.'\nupload.activity_id # =\u003e 1_998_557_443\n```\n\nSee [Strava::Models::Upload](lib/strava/models/upload.rb) for all available properties.\n\n### Pagination\n\nSome Strava APIs, including [athlete-activities](#list-athlete-activities) support pagination when supplying an optional `page` and `per_page` parameter. By default the client retrieves one page of data, which Strava currently defaults to 30 items. You can paginate through more data by supplying a block and an optional `per_page` parameter. The underlying implementation makes page-sized calls and increments the `page` argument.\n\n```ruby\nclient.athlete_activities(per_page: 30) do |activity|\n  activity # =\u003e Strava::Models::Activity\nend\n```\n\n### OAuth\n\n#### OAuth Workflow\n\nObtain a redirect URL using an instance of `Strava::OAuth::Client`.\n\n```ruby\nclient = Strava::OAuth::Client.new(\n  client_id: \"12345\",\n  client_secret: \"12345678987654321\"\n)\n\nredirect_url = client.authorize_url(\n  redirect_uri: 'https://example.com/oauth',\n  approval_prompt: 'force',\n  response_type: 'code',\n  scope: 'activity:read_all',\n  state: 'magic'\n)\n```\n\nOnce the user is redirected to your application, perform a token exchange to obtain a refresh and access token.\n\n```ruby\nresponse = client.oauth_token(code: '1234556789901234567890')\n\nresponse # =\u003e Strava::Models::Token\n\nresponse.access_token # access token\nresponse.refresh_token # refresh token\nresponse.expires_at # timestamp when the access token expires\nresponse.athlete # =\u003e Strava::Models::Athlete\n```\n\nSee [Strava authentication documentation](https://developers.strava.com/docs/authentication/), [Strava::Models::Token](lib/strava/models/token.rb) and [Strava::Models::Athlete](lib/strava/models/athlete.rb) for all available properties in the response.\n\nIf the access token is expired, refresh it before making any requests. You will get back all new tokens.\n\n```ruby\nresponse = client.oauth_token(\n  refresh_token: '...',\n  grant_type: 'refresh_token'\n)\n\nresponse.access_token # =\u003e String, new access token\nresponse.refresh_token # =\u003e String, new refresh token\nresponse.expires_at # =\u003e Time, new timestamp when the access token expires\n```\n\n#### Deauthorize\n\nRevoke access to an athlete's data using an instance of `Strava::API::Client`.\n\n```ruby\nauthorization = client.deauthorize\n\nauthorization.access_token # =\u003e String, access token being revoked\n```\n\n#### Command Line OAuth Workflow\n\nThe OAuth process is web-based and you cannot obtain a token from a Strava client ID and secret without user intervention. You can, however, start a local web server to handle the OAuth redirect and open a browser from the command-line.\n\nSee [strava-oauth-token](/bin/strava-oauth-token) or [strava-ruby-cli](https://github.com/dblock/strava-ruby-cli) for an example.\n\n### Webhooks\n\nStrava provides a [Webhook Event API](https://developers.strava.com/docs/webhooks/).\n\nA complete example that handles subscription creation, deletion and handling can be found in [strava-webhooks](bin/strava-webhooks). Run `strava-webhooks` to see current registrations, `strava-webhooks handle` to run an HTTP server that handles both challenges and event data, `strava-webhooks create [url]` to create a new subscription and `strava-webhooks delete [id]` to delete it.\n\nBefore creating a webhook subscription you must implement and run an HTTP server that will handle a `GET` challenge at the subscription URL.\n\n```ruby\nchallenge = Strava::Webhooks::Models::Challenge.new(request.query)\nraise 'Bad Request' unless challenge.verify_token == 'token'\nresponse.content_type = 'application/json'\nresponse.body = challenge.response.to_json\n```\n\nSee [Strava::Webhooks::Models::Challenge](lib/strava/webhooks/models/challenge.rb) for details.\n\nAn existing subscription must be handled in the same HTTP server's `POST` request to the subscription URL.\n\n```ruby\nevent = Strava::Webhooks::Models::Event.new(JSON.parse(request.body))\n\nevent # =\u003e Strava::Webhooks::Models::Event\nevent.object_type # =\u003e 'activity'\nevent.object_id # =\u003e 1991813808\nevent.aspect_type # =\u003e 'update'\nevent.updates # =\u003e { 'sport_type' =\u003e 'Walk' }\nevent.owner_id # =\u003e 29323238\nevent.subscription_id # =\u003e 131302\nevent.event_time # =\u003e DateTime\n```\n\nSee [Strava::Webhooks::Models::Event](lib/strava/webhooks/models/event.rb) for details.\n\nSubscriptions can be created, listed and deleted.\n\nCreate a client.\n\n```ruby\nclient = Strava::Webhooks::Client.new(\n  client_id: \"12345\",\n  client_secret: \"12345678987654321\"\n)\n```\n\nCreate a subscription.\n\n```ruby\nsubscription = client.create_push_subscription(callback_url: 'http://example.com/strava', verify_token: 'token')\n\nsubscription # =\u003e Strava::Webhooks::Models::Subscription\nsubscription.id # =\u003e 131300\nsubscription.callback_url # =\u003e 'http://example.com/strava'\n```\n\nSee [Strava::Webhooks::Models::Subscription](lib/strava/webhooks/models/subscription.rb) for details.\n\nList an existing subscription. Strava seems to only allow one.\n\n```ruby\nsubscriptions = client.push_subscriptions\n\nsubscription = subscriptions.first # =\u003e Strava::Webhooks::Models::Subscription\nsubscription.id # =\u003e 131300\nsubscription.callback_url # =\u003e 'http://example.com/strava'\n```\n\nDelete an existing subscription.\n\n```ruby\nclient.delete_push_subscription(131300) # =\u003e nil\n```\n\n## Configuration\n\n### Web Client Options\n\nYou can configure web client options used in the OAuth and API clients, globally.\n\n```ruby\nStrava::Web::Client.configure do |config|\n  config.user_agent = 'Strava Ruby Client/1.0'\nend\n```\n\nThe following settings are supported.\n\n| setting      | description                                           |\n| ------------ | ----------------------------------------------------- |\n| user_agent   | User-agent, defaults to _Strava Ruby Client/version_. |\n| proxy        | Optional HTTP proxy.                                  |\n| ca_path      | Optional SSL certificates path.                       |\n| ca_file      | Optional SSL certificates file.                       |\n| logger       | Optional `Logger` instance that logs HTTP requests.   |\n| timeout      | Optional open/read timeout in seconds.                |\n| open_timeout | Optional connection open timeout in seconds.          |\n\n### API Client Options\n\nThe API client inherits web client options and provides additional application configuration. These can be configured globally or for a client instance.\n\n```ruby\nStrava::API.configure do |config|\n  config.access_token = \"...\" # Strava access token\nend\n```\n\n```ruby\nclient = Strava::API::Client.new(\n  access_token: \"...\",\n  user_agent: \"...\"\n)\n```\n\nThe following settings are supported.\n\n| setting      | description                                         |\n| ------------ | --------------------------------------------------- |\n| access_token | Access token to pass in the `Authorization` header. |\n| endpoint     | Defaults to `https://www.strava.com/api/v3`.        |\n\n### OAuth Client Options\n\nThe OAuth client inherits web client options and provides additional application configuration. These can be configured globally or for a client instance.\n\n```ruby\nStrava::OAuth.configure do |config|\n  config.client_id = \"...\" # Strava client ID\n  config.client_secret = \"...\" # Strava client secret\nend\n```\n\n```ruby\nclient = Strava::OAuth::Client.new(\n  client_id: \"...\",\n  client_secret: \"...\",\n  user_agent: \"...\"\n)\n```\n\nThe following settings are supported.\n\n| setting       | description                                 |\n| ------------- | ------------------------------------------- |\n| client_id     | Application client ID.                      |\n| client_secret | Application client secret.                  |\n| endpoint      | Defaults to `https://www.strava.com/oauth`. |\n\n### Webhooks Client Options\n\nThe Webhooks client inherits web client options and provides additional application configuration. These can be configured globally or for a client instance.\n\n```ruby\nStrava::Webhooks.configure do |config|\n  config.client_id = \"...\" # Strava client ID\n  config.client_secret = \"...\" # Strava client secret\nend\n```\n\n```ruby\nclient = Strava::Webhooks::Client.new(\n  client_id: \"...\",\n  client_secret: \"...\",\n  user_agent: \"...\"\n)\n```\n\nThe following settings are supported.\n\n| setting       | description                                  |\n| ------------- | -------------------------------------------- |\n| client_id     | Application client ID.                       |\n| client_secret | Application client secret.                   |\n| endpoint      | Defaults to `https://www.strava.com/api/v3`. |\n\n## Errors\n\nAll errors that return HTTP codes 400-600 result in either `Faraday::ResourceNotFound`, `Faraday::ConnectionFailed` or [Strava::Errors::Fault](lib/strava/errors/fault.rb) exceptions.\n\n```ruby\nbegin\n  client.oauth_token(code: 'invalid')\nrescue Strava::Errors::Fault =\u003e e\n  e.message # =\u003e Bad Request\n  e.errors # =\u003e [{ 'code' =\u003e 'invalid', 'field' =\u003e 'code', 'resource' =\u003e 'RequestToken' }]\n  e.headers # =\u003e { \"status\" =\u003e \"403 Bad Request\", \"x-ratelimit-limit\" =\u003e \"600,30000\", \"x-ratelimit-usage\" =\u003e \"314,27536\" }\nend\n```\n\n## Tools\n\nFor a complete set of command-line tools, check out [strava-ruby-cli](https://github.com/dblock/strava-ruby-cli) built on top of this gem.\n\n### Strava OAuth Token\n\nUse [strava-oauth-token](bin/strava-oauth-token) to obtain a token from the command-line. This will open a new browser window, navigate to Strava, request the appropriate permissions, then handle OAuth in a local redirect. The token type, refresh token, access token and token expiration will be displayed in the browser.\n\n```bash\n$ STRAVA_CLIENT_ID=... STRAVA_CLIENT_SECRET=... strava-oauth-token\n```\n\n## Users\n\n- [Slava: Strava integration with Slack](https://slava.playplay.io), [source](https://github.com/dblock/slack-strava).\n- [Jekyll Blog at run.dblock.org](https://run.dblock.org), [source](https://github.com/dblock/run.dblock.org)\n- [Secret Strava](https://steele.blue/secret-strava/), [source](https://github.com/mattdsteele/secret-strava)\n\n## Resources\n\n- [Strava API Documentation](https://developers.strava.com)\n- [Writing a New Strava API Ruby Client](https://code.dblock.org/2018/11/27/writing-a-new-strava-api-ruby-client.html)\n- [Dealing with Strava API OAuth Token Migration](https://code.dblock.org/2018/11/17/dealing-with-strava-api-token-migration.html)\n- [Auto-Publishing Strava Runs to Github Pages](https://code.dblock.org/2018/02/17/auto-publishing-strava-runs-to-github-pages.html)\n- [Strava Command-Line Client](https://github.com/dblock/strava-ruby-cli)\n\n## Upgrading\n\nSee [UPGRADING](UPGRADING.md).\n\n## Contributing\n\nSee [CONTRIBUTING](CONTRIBUTING.md).\n\n## Copyright and License\n\nCopyright (c) 2018, [Daniel Doubrovkine](https://twitter.com/dblockdotorg) and [Contributors](CHANGELOG.md).\n\nThis project is licensed under the [MIT License](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubyonworld%2Fstrava-ruby-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubyonworld%2Fstrava-ruby-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubyonworld%2Fstrava-ruby-client/lists"}