diff --git a/README.md b/README.md
index d4db13e..ae415a7 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
go.strava
=========
-Go.strava provides a complete, **including upload,** wrapper library for the [Strava V3 API](http://strava.github.com/api).
+Go.strava provides a complete, **including upload,** wrapper library for the [Strava V3 API](https://developers.strava.com/docs/reference/).
Structs are defined for all the basic types such as athletes, activities and leaderboards. Functions are
provided to fetch all these values.
-**Please note:** Every effort is made to keep the [API Documentation](http://strava.github.com/api)
+**Please note:** Every effort is made to keep the [API Documentation](https://developers.strava.com)
up to date, however this package may lag behind. If this is impacting your development,
please file an [issue](https://github.com/strava/go.strava/issues) and it will be addressed as soon as possible.
@@ -14,12 +14,12 @@ please file an [issue](https://github.com/strava/go.strava/issues) and it will b
Find the new Strava V3 API at https://github.com/strava/developers.strava.com/. You can generate Go client following the [Client code section](https://github.com/strava/developers.strava.com/#client-code). This repository is no longer getting updated and may be removed in the near future.
#### To install
-
- go get github.com/strava/go.strava
+
+ go get github.com/strava/go.strava
#### To use, imports as package name `strava`:
- import "github.com/strava/go.strava"
+ import "github.com/strava/go.strava"
[![Build Status](https://travis-ci.org/strava/go.strava.png?branch=master)](https://travis-ci.org/strava/go.strava)
@@ -42,31 +42,31 @@ Find the new Strava V3 API at https://github.com/strava/developers.strava.com/.
Make sure to check out the source code as it provides many helpful comments.
* #### [segment_example.go](examples/segment_example.go)
- This example shows how to pull segment descriptions and leaderboards. To run:
+ This example shows how to pull segment descriptions and leaderboards. To run:
- cd $GOPATH/src/github.com/strava/go.strava/examples
- go run segment_example.go -token=
+ cd $GOPATH/src/github.com/strava/go.strava/examples
+ go run segment_example.go -token=
- A sample access token can be found on the [API settings page](https://strava.com/settings/api).
+ A sample access token can be found on the [API settings page](https://strava.com/settings/api).
* #### [oauth_example.go](examples/oauth_example.go)
- This example shows how to use `OAuthCallbackHandler` to simplify the OAuth2 token exchange,
- as well as how to handle the errors that might occur. To run:
+ This example shows how to use `OAuthCallbackHandler` to simplify the OAuth2 token exchange,
+ as well as how to handle the errors that might occur. To run:
- cd $GOPATH/src/github.com/strava/go.strava/examples
- go run oauth_example.go -id= -secret=
+ cd $GOPATH/src/github.com/strava/go.strava/examples
+ go run oauth_example.go -id= -secret=
- Visit http://localhost:8080/ in your favorite web browser
+ Visit http://localhost:8080/ in your favorite web browser
- Your client id and client secret can be found on the [API settings page](https://strava.com/settings/api).
+ Your client id and client secret can be found on the [API settings page](https://strava.com/settings/api).
* #### [upload.go](examples/upload.go)
- This example shows how to upload data to Strava. It will upload a random GPX file. To run:
+ This example shows how to upload data to Strava. It will upload a random GPX file. To run:
- cd $GOPATH/src/github.com/strava/go.strava/examples
- go run upload.go -token=
+ cd $GOPATH/src/github.com/strava/go.strava/examples
+ go run upload.go -token=
- The access token must have 'write' permissions which must be created using the OAuth flow, see the above example.
+ The access token must have 'write' permissions which must be created using the OAuth flow, see the above example.
Service Documentation
@@ -76,34 +76,34 @@ Below is a overview of how the library works, followed by examples for all the d
1. All requests should start by creating a client that defines the access token to be used:
- client := strava.NewClient("", optionalHttpClient)
+ client := strava.NewClient("", optionalHttpClient)
- The library will use the http.DefaultClient by default. If the default client is unavailable,
- like in the app engine environment for example, you can pass one in as the second parameter.
+ The library will use the http.DefaultClient by default. If the default client is unavailable,
+ like in the app engine environment for example, you can pass one in as the second parameter.
2. Then a service must be defined that represents a given API request endpoint, for example:
- service := strava.NewClubsService(client)
+ service := strava.NewClubsService(client)
3. Required parameters are passed on call creation, optional parameters are added after, for example:
- call := service.ListMembers(clubId).Page(2).PerPage(50)
+ call := service.ListMembers(clubId).Page(2).PerPage(50)
4. To actually execute the call, run `Do()` on it:
- members, err := call.Do()
- if e, ok := err.(*strava.Error); ok {
- // this is a strava provided error
- } else {
- // regular error, could be internet connectivity problems
- }
+ members, err := call.Do()
+ if e, ok := err.(*strava.Error); ok {
+ // this is a strava provided error
+ } else {
+ // regular error, could be internet connectivity problems
+ }
- This will return members 50-100 of the given clubs. All of these things can be chained together like so:
+ This will return members 50-100 of the given clubs. All of these things can be chained together like so:
- members, err := strava.NewClubsService(strava.NewClient(token)).
- ListMembers(clubId).
- PerPage(100).
- Do()
+ members, err := strava.NewClubsService(strava.NewClient(token)).
+ ListMembers(clubId).
+ PerPage(100).
+ Do()
**Polyline decoding**
Activities and segments come with summary polylines encoded using the
@@ -131,20 +131,20 @@ Related objects:
[OAuthAuthenticator](https://godoc.org/github.com/strava/go.strava#OAuthAuthenticator),
[AuthorizationResponse](https://godoc.org/github.com/strava/go.strava#AuthorizationResponse).
- authenticator := &strava.OAuthAuthenticator{
- CallbackURL: "http://yourdomain/strava/authorize",
- }
+ authenticator := &strava.OAuthAuthenticator{
+ CallbackURL: "http://yourdomain/strava/authorize",
+ }
- path, err := authenticator.CallbackPath()
- http.HandleFunc(path, authenticator.HandlerFunc(oAuthSuccess, oAuthFailure))
+ path, err := authenticator.CallbackPath()
+ http.HandleFunc(path, authenticator.HandlerFunc(oAuthSuccess, oAuthFailure))
- func oAuthSuccess(auth *strava.AuthorizationResponse, w http.ResponseWriter, r *http.Request) {
- // Success
- }
+ func oAuthSuccess(auth *strava.AuthorizationResponse, w http.ResponseWriter, r *http.Request) {
+ // Success
+ }
- func oAuthFailure(err error, w http.ResponseWriter, r *http.Request) {
- // Failure, or access was denied
- }
+ func oAuthFailure(err error, w http.ResponseWriter, r *http.Request) {
+ // Failure, or access was denied
+ }
For a more detailed example of how to handle OAuth authorization see [oauth_example.go](examples/oauth_example.go)
@@ -159,76 +159,76 @@ Related objects:
For the athlete associated with the access token, aka current athlete:
- service := strava.NewCurrentAthleteService(client)
+ service := strava.NewCurrentAthleteService(client)
- // returns a AthleteDetailed object
- athlete, err := service.Get().Do()
+ // returns a AthleteDetailed object
+ athlete, err := service.Get().Do()
- // returns a AthleteDetailed object
- athlete, err := service.Update().
- City(city).
- State(state).
- Country(country).
- Gender(gender).
- Weight(weight).
- Do()
+ // returns a AthleteDetailed object
+ athlete, err := service.Update().
+ City(city).
+ State(state).
+ Country(country).
+ Gender(gender).
+ Weight(weight).
+ Do()
- // returns a slice of ActivitySummary objects
- activities, err := service.ListActivities(athleteId).
- Page(page).
- PerPage(perPage).
- Before(before).
- After(after).
- Do()
+ // returns a slice of ActivitySummary objects
+ activities, err := service.ListActivities(athleteId).
+ Page(page).
+ PerPage(perPage).
+ Before(before).
+ After(after).
+ Do()
- // returns a slice of ActivitySummary objects
- activities, err := service.ListFriendsActivities(athleteId).
- Page(page).
- PerPage(perPage).
- Before(before).
- Do()
+ // returns a slice of ActivitySummary objects
+ activities, err := service.ListFriendsActivities(athleteId).
+ Page(page).
+ PerPage(perPage).
+ Before(before).
+ Do()
- // returns a slice of AthleteSummary objects
- friends, err := service.ListFriends().Page(page).PerPage(perPage).Do()
-
- // returns a slice of AthleteSummary objects
- followers, err := service.ListFollowers().Page(page).PerPage(perPage).Do()
+ // returns a slice of AthleteSummary objects
+ friends, err := service.ListFriends().Page(page).PerPage(perPage).Do()
+
+ // returns a slice of AthleteSummary objects
+ followers, err := service.ListFollowers().Page(page).PerPage(perPage).Do()
- // returns a slice of ClubSummary objects
- clubs, err := service.ListClubs().Do()
+ // returns a slice of ClubSummary objects
+ clubs, err := service.ListClubs().Do()
- // returns a slice of PersonalSegmentSummary objects
- segments, err := service.ListStarredSegments().Do()
+ // returns a slice of PersonalSegmentSummary objects
+ segments, err := service.ListStarredSegments().Do()
For other athletes:
- service := strava.NewAthletesService(client)
+ service := strava.NewAthletesService(client)
- // returns a AthleteSummary object
- athlete, err := service.Get(athleteId).Do()
+ // returns a AthleteSummary object
+ athlete, err := service.Get(athleteId).Do()
- // returns a slice of AthleteSummary objects
- friends, err := service.ListFriends(athleteId).Page(page).PerPage(perPage).Do()
-
- // returns a slice of AthleteSummary objects
- followers, err := service.ListFollowers(athleteId).Page(page).PerPage(perPage).Do()
+ // returns a slice of AthleteSummary objects
+ friends, err := service.ListFriends(athleteId).Page(page).PerPage(perPage).Do()
+
+ // returns a slice of AthleteSummary objects
+ followers, err := service.ListFollowers(athleteId).Page(page).PerPage(perPage).Do()
- // returns a slice of AthleteSummary objects
- bothFollowing, err := service.ListBothFollowing(athleteId).Do()
+ // returns a slice of AthleteSummary objects
+ bothFollowing, err := service.ListBothFollowing(athleteId).Do()
- // returns an AthleteStats objects
- stats, err := service.Stats(athleteId).Do()
+ // returns an AthleteStats objects
+ stats, err := service.Stats(athleteId).Do()
- // returns a slice of SegmentEffortSummary objects
- efforts, err := service.ListKOMs(athleteId).Do()
+ // returns a slice of SegmentEffortSummary objects
+ efforts, err := service.ListKOMs(athleteId).Do()
- // returns a slice of ActivitySummary objects
- // athleteId must match authenticated athlete's
- activities, err := service.ListActivities(athleteId).Do()
+ // returns a slice of ActivitySummary objects
+ // athleteId must match authenticated athlete's
+ activities, err := service.ListActivities(athleteId).Do()
- // returns a slice of PersonalSegmentSummary objects
- segments, err := service.ListStarredSegments(athleteId).Do()
+ // returns a slice of PersonalSegmentSummary objects
+ segments, err := service.ListStarredSegments(athleteId).Do()
### Activities
@@ -244,39 +244,39 @@ Related objects:
Related constants:
[ActivityTypes](https://godoc.org/github.com/strava/go.strava#ActivityTypes).
- service := strava.NewActivitiesService(client)
+ service := strava.NewActivitiesService(client)
- // returns a AthleteDetailed if the activity is owned by the requesting user
- // or an ActivitySummary object otherwise.
- // The Type is defined by Activity.ResourceState, 3 for detailed, 2 for summary.
- activity, err := service.Get(activityId).
- IncludeAllEfforts().
- Do()
+ // returns a AthleteDetailed if the activity is owned by the requesting user
+ // or an ActivitySummary object otherwise.
+ // The Type is defined by Activity.ResourceState, 3 for detailed, 2 for summary.
+ activity, err := service.Get(activityId).
+ IncludeAllEfforts().
+ Do()
- // create a manual activity entry. To upload a file see Upload below.
- activity, err := service.Create(name, type, startDateLocal, elapsedTime).
- Description(description).
- Distance(distance).
- Do()
+ // create a manual activity entry. To upload a file see Upload below.
+ activity, err := service.Create(name, type, startDateLocal, elapsedTime).
+ Description(description).
+ Distance(distance).
+ Do()
- activity, err := service.Update(activityId).
- Name(name).
- Description(description).
- Type(ActivityTypes.Ride).
- Private(true).
- Communte(true).
- Trainer(false).
- Gear(gearId).
- Do()
+ activity, err := service.Update(activityId).
+ Name(name).
+ Description(description).
+ Type(ActivityTypes.Ride).
+ Private(true).
+ Communte(true).
+ Trainer(false).
+ Gear(gearId).
+ Do()
- // returns a slice of PhotoSummary objects
- photos, err := service.ListPhotos(activityId).Do()
+ // returns a slice of PhotoSummary objects
+ photos, err := service.ListPhotos(activityId).Do()
- // returns a slice of ZonesSummary objects
- zones, err := service.ListZones(activityId).Do()
+ // returns a slice of ZonesSummary objects
+ zones, err := service.ListZones(activityId).Do()
- // returns a slice of LapEffortSummary objects
- laps, err := service.ListLaps(activityId).Do()
+ // returns a slice of LapEffortSummary objects
+ laps, err := service.ListLaps(activityId).Do()
### Comments
@@ -284,39 +284,39 @@ Related objects:
[CommentDetailed](https://godoc.org/github.com/strava/go.strava#CommentDetailed),
[CommentSummary](https://godoc.org/github.com/strava/go.strava#CommentSummary).
- service := strava.NewActivityCommentsService(client, activityId)
+ service := strava.NewActivityCommentsService(client, activityId)
- // returns a slice of CommentSummary objects
- comments, err := service.List().
- Page(page).
- PerPage(perPage).
- IncludeMarkdown().
- Do()
+ // returns a slice of CommentSummary objects
+ comments, err := service.List().
+ Page(page).
+ PerPage(perPage).
+ IncludeMarkdown().
+ Do()
- // create a comment if your application has permission
- comment, err := service.Create("funny comment").Do()
+ // create a comment if your application has permission
+ comment, err := service.Create("funny comment").Do()
- // delete a comment if your application has permission
- comment, err := service.Delete(commentId).Do()
+ // delete a comment if your application has permission
+ comment, err := service.Delete(commentId).Do()
### Kudos
Related objects:
[AthleteSummary](https://godoc.org/github.com/strava/go.strava#AthleteSummary).
- service := strava.NewActivityKudosService(client, activityId)
+ service := strava.NewActivityKudosService(client, activityId)
- // returns a slice of AthleteSummary objects
- comments, err := service.List().
- Page(page).
- PerPage(perPage).
- Do()
+ // returns a slice of AthleteSummary objects
+ comments, err := service.List().
+ Page(page).
+ PerPage(perPage).
+ Do()
- // create/give a kudo
- comment, err := service.Create().Do()
+ // create/give a kudo
+ comment, err := service.Create().Do()
- // delete/take back a kudo
- comment, err := service.Delete().Do()
+ // delete/take back a kudo
+ comment, err := service.Delete().Do()
### Clubs
@@ -324,22 +324,22 @@ Related objects:
[ClubDetailed](https://godoc.org/github.com/strava/go.strava#ClubDetailed),
[ClubSummary](https://godoc.org/github.com/strava/go.strava#ClubSummary).
- service := strava.NewClubService(client)
+ service := strava.NewClubService(client)
- // returns a ClubDetailed object
- club, err := service.Get(clubId).Do()
+ // returns a ClubDetailed object
+ club, err := service.Get(clubId).Do()
- // returns a slice of AthleteSummary objects
- members, err := service.ListMembers(clubId).
- Page(page).
- PerPage(perPage).
- Do()
+ // returns a slice of AthleteSummary objects
+ members, err := service.ListMembers(clubId).
+ Page(page).
+ PerPage(perPage).
+ Do()
- // returns a slice of ActivitySummary objects
- activities, err := service.ListActivities(clubId).
- Page(page).
- PerPage(perPage).
- Do()
+ // returns a slice of ActivitySummary objects
+ activities, err := service.ListActivities(clubId).
+ Page(page).
+ PerPage(perPage).
+ Do()
### Gear
@@ -350,8 +350,8 @@ Related objects:
Related constants:
[FrameTypes](https://godoc.org/github.com/strava/go.strava#FrameTypes).
- // returns a GearDetailed object
- gear, err := strava.NewGearService(client).Get(gearId).Do()
+ // returns a GearDetailed object
+ gear, err := strava.NewGearService(client).Get(gearId).Do()
### Segments
@@ -370,38 +370,38 @@ Related constants:
[DateRanges](https://godoc.org/github.com/strava/go.strava#DateRanges),
[WeightClasses](https://godoc.org/github.com/strava/go.strava#WeightClasses).
- service := strava.NewSegmentsService(client)
-
- // returns a SegmentDetailed object
- segment, err := service.Get(segmentId).Do()
-
- // return list of segment efforts
- efforts, err := service.ListEfforts(segmentId).
- Page(page).
- PerPage(perPage).
- AthleteId(athleteId).
- DateRange(startDateLocal, endDateLocal).
- Do()
-
- // returns a SegmentLeaderboard object
- leaderboard, err := service.GetLeaderboard(segmentId).
- Page(page).
- PerPage(perPage).
- Gender(gender).
- AgeGroup(ageGroup).
- WeightClass(weightClass).
- Following().
- ClubId(clubId).
- DateRange(dateRange).
- ContextEntries(count).
- Do()
-
- // returns a slice of SegmentExplorerSegment
- segments, err := service.Explore(south, west, north, east).
- ActivityType(activityType).
- MinimumCategory(cat).
- MaximumCategory(cat).
- Do()
+ service := strava.NewSegmentsService(client)
+
+ // returns a SegmentDetailed object
+ segment, err := service.Get(segmentId).Do()
+
+ // return list of segment efforts
+ efforts, err := service.ListEfforts(segmentId).
+ Page(page).
+ PerPage(perPage).
+ AthleteId(athleteId).
+ DateRange(startDateLocal, endDateLocal).
+ Do()
+
+ // returns a SegmentLeaderboard object
+ leaderboard, err := service.GetLeaderboard(segmentId).
+ Page(page).
+ PerPage(perPage).
+ Gender(gender).
+ AgeGroup(ageGroup).
+ WeightClass(weightClass).
+ Following().
+ ClubId(clubId).
+ DateRange(dateRange).
+ ContextEntries(count).
+ Do()
+
+ // returns a slice of SegmentExplorerSegment
+ segments, err := service.Explore(south, west, north, east).
+ ActivityType(activityType).
+ MinimumCategory(cat).
+ MaximumCategory(cat).
+ Do()
### Segment Efforts
@@ -409,8 +409,8 @@ Related objects:
[SegmentEffortDetailed](https://godoc.org/github.com/strava/go.strava#SegmentEffortDetailed),
[SegmentEffortSummary](https://godoc.org/github.com/strava/go.strava#SegmentEffortSummary).
- // returns a SegmentEffortDetailed object
- segmentEffort, err := strava.NewSegmentEffortsService(client).Get(effortId).Do()
+ // returns a SegmentEffortDetailed object
+ segmentEffort, err := strava.NewSegmentEffortsService(client).Get(effortId).Do()
### Streams
@@ -426,29 +426,29 @@ Related objects:
Related constants:
[StreamTypes](https://godoc.org/github.com/strava/go.strava#StreamTypes).
- // Activity Streams
- // returns a StreamSet object
- strava.NewActivityStreamsService(client).
- Get(activityId, types).
- Resolution(resolution).
- SeriesType(seriesType).
- Do()
-
- // Segment Streams
- // returns a StreamSet object
- strava.NewSegmentStreamsService(client).
- Get(segmentId, types).
- Resolution(resolution).
- SeriesType(seriesType).
- Do()
-
- // SegmentEffort Streams
- // returns a StreamSet object
- strava.NewSegmentEffortStreamsService(client).
- Get(effortId, types).
- Resolution(resolution).
- SeriesType(seriesType).
- Do()
+ // Activity Streams
+ // returns a StreamSet object
+ strava.NewActivityStreamsService(client).
+ Get(activityId, types).
+ Resolution(resolution).
+ SeriesType(seriesType).
+ Do()
+
+ // Segment Streams
+ // returns a StreamSet object
+ strava.NewSegmentStreamsService(client).
+ Get(segmentId, types).
+ Resolution(resolution).
+ SeriesType(seriesType).
+ Do()
+
+ // SegmentEffort Streams
+ // returns a StreamSet object
+ strava.NewSegmentEffortStreamsService(client).
+ Get(effortId, types).
+ Resolution(resolution).
+ SeriesType(seriesType).
+ Do()
### Uploads
@@ -460,28 +460,28 @@ Related objects:
Related constants:
[FileDataTypes](https://godoc.org/github.com/strava/go.strava#FileDataTypes),
- service := strava.NewUploadsService(client)
-
- // returns a UploadDetailed object
- upload, err := service.Get(uploadId).
- Do()
-
- // returns a UploadSummary object
- // gzips the payload if not already done so,
- // use .Get(uploadId) to check progress on the upload and eventually get the activity id
- upload, err := service.Create(FileDataType, "filename", io.Reader).
- ActivityType(ActivityTypes.Ride).
- Name("name").
- Description("description").
- Private().
- Trainer().
- ExternalId("id").
- Do()
-
- // typical ways to create an io.Reader in Go
- fileReader, err := os.Open("file.go")
- byteReader, err := bytes.NewReader(binarydata)
- stringReader := strings.NewReader("stringdata")
+ service := strava.NewUploadsService(client)
+
+ // returns a UploadDetailed object
+ upload, err := service.Get(uploadId).
+ Do()
+
+ // returns a UploadSummary object
+ // gzips the payload if not already done so,
+ // use .Get(uploadId) to check progress on the upload and eventually get the activity id
+ upload, err := service.Create(FileDataType, "filename", io.Reader).
+ ActivityType(ActivityTypes.Ride).
+ Name("name").
+ Description("description").
+ Private().
+ Trainer().
+ ExternalId("id").
+ Do()
+
+ // typical ways to create an io.Reader in Go
+ fileReader, err := os.Open("file.go")
+ byteReader, err := bytes.NewReader(binarydata)
+ stringReader := strings.NewReader("stringdata")
Testing
-----------------------------
@@ -489,9 +489,9 @@ To test code using this package try the `StubResponseClient`.
This will stub the JSON returned by the Strava API. You'll need to
be familiar with raw JSON responses, so see the [Documentation](http://strava.github.io/api)
- client := strava.NewStubResponseClient(`[{"id": 1,"name": "Team Strava Cycling"}`, http.StatusOK)
- clubs, err := strava.NewClubsService(client).Get(1000)
+ client := strava.NewStubResponseClient(`[{"id": 1,"name": "Team Strava Cycling"}`, http.StatusOK)
+ clubs, err := strava.NewClubsService(client).Get(1000)
- clubs[0].Id == 1
+ clubs[0].Id == 1
This will return the club provided when creating the client even though you actually wanted club 1000.