Repository: google/go-github
Pull request #1400 (2020-01-28 04:27:38)

Move the GitHub Teams API
Fixes: #1387.

weeco: I think this PR is missing (some?) of the new Team API endpoints e. g. fetching a team by it's slug `GET /orgs/:org/teams/:team_slug`, see: https://developer.github.com/changes/2020-01-21-moving-the-team-api-endpoints/
gmlewis: Thank you, @weeco - I've made a list in #1387 so we can hopefully keep track of the changes needed, and the ones that are implemented, as we review the PR(s).
atorr: @weeco - I will go ahead and take a look again.  As for the particular endpoint you referenced the implementation for that should be in github/teams.go on line [119](https://github.com/atorr/go-github/blob/60a41cf33f4e1bed91fb1bf357e8905aed317433/github/teams.go#L119).   Is that what you are referring to?  
atorr: New changes in.  Had missed the link to the blog post and went a bit overboard.  Will work to pay more attention to what needs to be changed.  Thank you all for your patience on this!  
weeco: Is there any chance to get that merged/released soonish?
gmlewis: Hi @weeco - this repo is maintained by volunteers and it is difficult to tell when people will have time to review PRs, so I don't have an ETA for you.

I suggest that if you need something right away, you fork the repo and pull in the PR(s) that you need and work off of that.

Thank you for your patience.
gmlewis: Thank you, @wesleimp!
Merging.

Patch:
diff --git a/github/teams.go b/github/teams.go
index 1f86ef96..cfb814e7 100644
--- a/github/teams.go
+++ b/github/teams.go
@@ -97,11 +97,11 @@ func (s *TeamsService) ListTeams(ctx context.Context, org string, opts *ListOpti
 	return teams, resp, nil
 }
 
-// GetTeam fetches a team by ID.
+// GetTeamByID fetches a team, given a specified organization ID, by ID.
 //
-// GitHub API docs: https://developer.github.com/v3/teams/#get-team
-func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Response, error) {
-	u := fmt.Sprintf("teams/%v", team)
+// GitHub API docs: https://developer.github.com/v3/teams/#get-team-by-name
+func (s *TeamsService) GetTeamByID(ctx context.Context, orgID, teamID int64) (*Team, *Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID)
 	req, err := s.client.NewRequest("GET", u, nil)
 	if err != nil {
 		return nil, nil, err
@@ -116,7 +116,7 @@ func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Respons
 	return t, resp, nil
 }
 
-// GetTeamBySlug fetches a team by slug.
+// GetTeamBySlug fetches a team, given a specified organization name, by slug.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#get-team-by-name
 func (s *TeamsService) GetTeamBySlug(ctx context.Context, org, slug string) (*Team, *Response, error) {
@@ -212,11 +212,11 @@ func copyNewTeamWithoutParent(team *NewTeam) *newTeamNoParent {
 	}
 }
 
-// EditTeam edits a team.
+// EditTeamByID edits a team, given an organization ID, selected by ID.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#edit-team
-func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam, removeParent bool) (*Team, *Response, error) {
-	u := fmt.Sprintf("teams/%v", id)
+func (s *TeamsService) EditTeamByID(ctx context.Context, orgID, teamID int64, team NewTeam, removeParent bool) (*Team, *Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID)
 
 	var req *http.Request
 	var err error
@@ -239,11 +239,51 @@ func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam, rem
 	return t, resp, nil
 }
 
-// DeleteTeam deletes a team.
+// EditTeamBySlug edits a team, given an organization name, by slug.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#edit-team
+func (s *TeamsService) EditTeamBySlug(ctx context.Context, org, slug string, team NewTeam, removeParent bool) (*Team, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v", org, slug)
+
+	var req *http.Request
+	var err error
+	if removeParent {
+		teamRemoveParent := copyNewTeamWithoutParent(&team)
+		req, err = s.client.NewRequest("PATCH", u, teamRemoveParent)
+	} else {
+		req, err = s.client.NewRequest("PATCH", u, team)
+	}
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(Team)
+	resp, err := s.client.Do(ctx, req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, nil
+}
+
+// DeleteTeamByID deletes a team referenced by ID.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#delete-team
+func (s *TeamsService) DeleteTeamByID(ctx context.Context, orgID, teamID int64) (*Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// DeleteTeamBySlug deletes a team reference by slug.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#delete-team
-func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, error) {
-	u := fmt.Sprintf("teams/%v", team)
+func (s *TeamsService) DeleteTeamBySlug(ctx context.Context, org, slug string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v", org, slug)
 	req, err := s.client.NewRequest("DELETE", u, nil)
 	if err != nil {
 		return nil, err
@@ -252,11 +292,35 @@ func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, e
 	return s.client.Do(ctx, req, nil)
 }
 
-// ListChildTeams lists child teams for a team.
+// ListChildTeamsByParentID lists child teams for a parent team given parent ID.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams
+func (s *TeamsService) ListChildTeamsByParentID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/teams", orgID, teamID)
+	u, err := addOptions(u, opts)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var teams []*Team
+	resp, err := s.client.Do(ctx, req, &teams)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return teams, resp, nil
+}
+
+// ListChildTeamsByParentSlug lists child teams for a parent team given parent slug.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams
-func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opts *ListOptions) ([]*Team, *Response, error) {
-	u := fmt.Sprintf("teams/%v/teams", teamID)
+func (s *TeamsService) ListChildTeamsByParentSlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/teams", org, slug)
 	u, err := addOptions(u, opts)
 	if err != nil {
 		return nil, nil, err
@@ -276,11 +340,11 @@ func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opts *L
 	return teams, resp, nil
 }
 
-// ListTeamRepos lists the repositories that the specified team has access to.
+// ListTeamReposByID lists the repositories given a team ID that the specified team has access to.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos
-func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opts *ListOptions) ([]*Repository, *Response, error) {
-	u := fmt.Sprintf("teams/%v/repos", team)
+func (s *TeamsService) ListTeamReposByID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/repos", orgID, teamID)
 	u, err := addOptions(u, opts)
 	if err != nil {
 		return nil, nil, err
@@ -304,13 +368,65 @@ func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opts *List
 	return repos, resp, nil
 }
 
-// IsTeamRepo checks if a team manages the specified repository. If the
+// ListTeamReposBySlug lists the repositories given a team slug that the specified team has access to.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos
+func (s *TeamsService) ListTeamReposBySlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Repository, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/repos", org, slug)
+	u, err := addOptions(u, opts)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when topics API fully launches.
+	headers := []string{mediaTypeTopicsPreview}
+	req.Header.Set("Accept", strings.Join(headers, ", "))
+
+	var repos []*Repository
+	resp, err := s.client.Do(ctx, req, &repos)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repos, resp, nil
+}
+
+// IsTeamRepoByID checks if a team, given its ID, manages the specified repository. If the
+// repository is managed by team, a Repository is returned which includes the
+// permissions team has for that repo.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository
+func (s *TeamsService) IsTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Repository, *Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	headers := []string{mediaTypeOrgPermissionRepo}
+	req.Header.Set("Accept", strings.Join(headers, ", "))
+
+	repository := new(Repository)
+	resp, err := s.client.Do(ctx, req, repository)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return repository, resp, nil
+}
+
+// IsTeamRepoBySlug checks if a team, given its slug, manages the specified repository. If the
 // repository is managed by team, a Repository is returned which includes the
 // permissions team has for that repo.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository
-func (s *TeamsService) IsTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Repository, *Response, error) {
-	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+func (s *TeamsService) IsTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Repository, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo)
 	req, err := s.client.NewRequest("GET", u, nil)
 	if err != nil {
 		return nil, nil, err
@@ -341,13 +457,13 @@ type TeamAddTeamRepoOptions struct {
 	Permission string `json:"permission,omitempty"`
 }
 
-// AddTeamRepo adds a repository to be managed by the specified team. The
-// specified repository must be owned by the organization to which the team
+// AddTeamRepoByID adds a repository to be managed by the specified team given the team ID.
+// The specified repository must be owned by the organization to which the team
 // belongs, or a direct fork of a repository owned by the organization.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo
-func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) {
-	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo)
 	req, err := s.client.NewRequest("PUT", u, opts)
 	if err != nil {
 		return nil, err
@@ -356,13 +472,43 @@ func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string
 	return s.client.Do(ctx, req, nil)
 }
 
-// RemoveTeamRepo removes a repository from being managed by the specified
-// team. Note that this does not delete the repository, it just removes it
-// from the team.
+// AddTeamRepoBySlug adds a repository to be managed by the specified team given the team slug.
+// The specified repository must be owned by the organization to which the team
+// belongs, or a direct fork of a repository owned by the organization.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo
+func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo)
+	req, err := s.client.NewRequest("PUT", u, opts)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveTeamRepoByID removes a repository from being managed by the specified
+// team given the team ID. Note that this does not delete the repository, it
+// just removes it from the team.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo
-func (s *TeamsService) RemoveTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Response, error) {
-	u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
+func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveTeamRepoBySlug removes a repository from being managed by the specified
+// team given the team slug. Note that this does not delete the repository, it
+// just removes it from the team.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo
+func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo)
 	req, err := s.client.NewRequest("DELETE", u, nil)
 	if err != nil {
 		return nil, err
@@ -394,11 +540,35 @@ func (s *TeamsService) ListUserTeams(ctx context.Context, opts *ListOptions) ([]
 	return teams, resp, nil
 }
 
-// ListTeamProjects lists the organization projects for a team.
+// ListTeamProjectsByID lists the organization projects for a team given the team ID.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects
+func (s *TeamsService) ListTeamProjectsByID(ctx context.Context, orgID, teamID int64) ([]*Project, *Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/projects", orgID, teamID)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeProjectsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	var projects []*Project
+	resp, err := s.client.Do(ctx, req, &projects)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return projects, resp, nil
+}
+
+// ListTeamProjectsBySlug lists the organization projects for a team given the team slug.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects
-func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*Project, *Response, error) {
-	u := fmt.Sprintf("teams/%v/projects", teamID)
+func (s *TeamsService) ListTeamProjectsBySlug(ctx context.Context, org, slug string) ([]*Project, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/projects", org, slug)
 
 	req, err := s.client.NewRequest("GET", u, nil)
 	if err != nil {
@@ -418,12 +588,36 @@ func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*P
 	return projects, resp, nil
 }
 
-// ReviewTeamProjects checks whether a team has read, write, or admin
+// ReviewTeamProjectsByID checks whether a team, given its ID, has read, write, or admin
+// permissions for an organization project.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project
+func (s *TeamsService) ReviewTeamProjectsByID(ctx context.Context, orgID, teamID, projectID int64) (*Project, *Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID)
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeProjectsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	projects := &Project{}
+	resp, err := s.client.Do(ctx, req, &projects)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return projects, resp, nil
+}
+
+// ReviewTeamProjectsBySlug checks whether a team, given its slug, has read, write, or admin
 // permissions for an organization project.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project
-func (s *TeamsService) ReviewTeamProjects(ctx context.Context, teamID, projectID int64) (*Project, *Response, error) {
-	u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
+func (s *TeamsService) ReviewTeamProjectsBySlug(ctx context.Context, org, slug string, projectID int64) (*Project, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID)
 	req, err := s.client.NewRequest("GET", u, nil)
 	if err != nil {
 		return nil, nil, err
@@ -454,13 +648,13 @@ type TeamProjectOptions struct {
 	Permission *string `json:"permission,omitempty"`
 }
 
-// AddTeamProject adds an organization project to a team. To add a project to a team or
-// update the team's permission on a project, the authenticated user must have admin
-// permissions for the project.
+// AddTeamProjectByID adds an organization project to a team given the team ID.
+// To add a project to a team or update the team's permission on a project, the
+// authenticated user must have admin permissions for the project.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project
-func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) {
-	u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
+func (s *TeamsService) AddTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID)
 	req, err := s.client.NewRequest("PUT", u, opts)
 	if err != nil {
 		return nil, err
@@ -473,15 +667,57 @@ func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int
 	return s.client.Do(ctx, req, nil)
 }
 
-// RemoveTeamProject removes an organization project from a team. An organization owner or
-// a team maintainer can remove any project from the team. To remove a project from a team
-// as an organization member, the authenticated user must have "read" access to both the team
-// and project, or "admin" access to the team or project.
+// AddTeamProjectBySlug adds an organization project to a team given the team slug.
+// To add a project to a team or update the team's permission on a project, the
+// authenticated user must have admin permissions for the project.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project
+func (s *TeamsService) AddTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64, opts *TeamProjectOptions) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID)
+	req, err := s.client.NewRequest("PUT", u, opts)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeProjectsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveTeamProjectByID removes an organization project from a team given team ID.
+// An organization owner or a team maintainer can remove any project from the team.
+// To remove a project from a team as an organization member, the authenticated user
+// must have "read" access to both the team and project, or "admin" access to the team
+// or project.
+// Note: This endpoint removes the project from the team, but does not delete it.
+//
+// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project
+func (s *TeamsService) RemoveTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64) (*Response, error) {
+	u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID)
+	req, err := s.client.NewRequest("DELETE", u, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	acceptHeaders := []string{mediaTypeProjectsPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
+
+	return s.client.Do(ctx, req, nil)
+}
+
+// RemoveTeamProjectBySlug removes an organization project from a team given team slug.
+// An organization owner or a team maintainer can remove any project from the team.
+// To remove a project from a team as an organization member, the authenticated user
+// must have "read" access to both the team and project, or "admin" access to the team
+// or project.
 // Note: This endpoint removes the project from the team, but does not delete it.
 //
 // GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project
-func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, projectID int64) (*Response, error) {
-	u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID)
+func (s *TeamsService) RemoveTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64) (*Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID)
 	req, err := s.client.NewRequest("DELETE", u, nil)
 	if err != nil {
 		return nil, err


Test patch:
diff --git a/github/teams_test.go b/github/teams_test.go
index ce7ece54..414ad78e 100644
--- a/github/teams_test.go
+++ b/github/teams_test.go
@@ -15,7 +15,6 @@ import (
 	"reflect"
 	"strings"
 	"testing"
-	"time"
 )
 
 func TestTeamsService_ListTeams(t *testing.T) {
@@ -48,46 +47,44 @@ func TestTeamsService_ListTeams_invalidOrg(t *testing.T) {
 	testURLParseError(t, err)
 }
 
-func TestTeamsService_GetTeam(t *testing.T) {
+func TestTeamsService_GetTeamByID(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p", "ldap_dn":"cn=n,ou=groups,dc=example,dc=com", "parent":null}`)
 	})
 
-	team, _, err := client.Teams.GetTeam(context.Background(), 1)
+	team, _, err := client.Teams.GetTeamByID(context.Background(), 1, 1)
 	if err != nil {
-		t.Errorf("Teams.GetTeam returned error: %v", err)
+		t.Errorf("Teams.GetTeamByID returned error: %v", err)
 	}
 
 	want := &Team{ID: Int64(1), Name: String("n"), Description: String("d"), URL: String("u"), Slug: String("s"), Permission: String("p"), LDAPDN: String("cn=n,ou=groups,dc=example,dc=com")}
 	if !reflect.DeepEqual(team, want) {
-		t.Errorf("Teams.GetTeam returned %+v, want %+v", team, want)
+		t.Errorf("Teams.GetTeamByID returned %+v, want %+v", team, want)
 	}
 }
 
-func TestTeamsService_GetTeam_nestedTeams(t *testing.T) {
+func TestTeamsService_GetTeamByID_notFound(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/2", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p",
-		"parent": {"id":2, "name":"n", "description": "d", "parent": null}}`)
+		w.WriteHeader(http.StatusNotFound)
 	})
 
-	team, _, err := client.Teams.GetTeam(context.Background(), 1)
-	if err != nil {
-		t.Errorf("Teams.GetTeam returned error: %v", err)
+	team, resp, err := client.Teams.GetTeamByID(context.Background(), 1, 2)
+	if err == nil {
+		t.Errorf("Expected HTTP 404 response")
 	}
-
-	want := &Team{ID: Int64(1), Name: String("n"), Description: String("d"), URL: String("u"), Slug: String("s"), Permission: String("p"),
-		Parent: &Team{ID: Int64(2), Name: String("n"), Description: String("d")},
+	if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
+		t.Errorf("Teams.GetTeamByID returned status %d, want %d", got, want)
 	}
-	if !reflect.DeepEqual(team, want) {
-		t.Errorf("Teams.GetTeam returned %+v, want %+v", team, want)
+	if team != nil {
+		t.Errorf("Teams.GetTeamByID returned %+v, want nil", team)
 	}
 }
 
@@ -177,13 +174,13 @@ func TestTeamsService_CreateTeam_invalidOrg(t *testing.T) {
 	testURLParseError(t, err)
 }
 
-func TestTeamsService_EditTeam(t *testing.T) {
+func TestTeamsService_EditTeamByID(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
 	input := NewTeam{Name: "n", Privacy: String("closed")}
 
-	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) {
 		v := new(NewTeam)
 		json.NewDecoder(r.Body).Decode(v)
 
@@ -195,25 +192,25 @@ func TestTeamsService_EditTeam(t *testing.T) {
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
-	team, _, err := client.Teams.EditTeam(context.Background(), 1, input, false)
+	team, _, err := client.Teams.EditTeamByID(context.Background(), 1, 1, input, false)
 	if err != nil {
-		t.Errorf("Teams.EditTeam returned error: %v", err)
+		t.Errorf("Teams.EditTeamByID returned error: %v", err)
 	}
 
 	want := &Team{ID: Int64(1)}
 	if !reflect.DeepEqual(team, want) {
-		t.Errorf("Teams.EditTeam returned %+v, want %+v", team, want)
+		t.Errorf("Teams.EditTeamByID returned %+v, want %+v", team, want)
 	}
 }
 
-func TestTeamsService_EditTeam_RemoveParent(t *testing.T) {
+func TestTeamsService_EditTeamByID_RemoveParent(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
 	input := NewTeam{Name: "n", Privacy: String("closed")}
 	var body string
 
-	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) {
 		v := new(NewTeam)
 		buf, err := ioutil.ReadAll(r.Body)
 		if err != nil {
@@ -230,7 +227,75 @@ func TestTeamsService_EditTeam_RemoveParent(t *testing.T) {
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
-	team, _, err := client.Teams.EditTeam(context.Background(), 1, input, true)
+	team, _, err := client.Teams.EditTeamByID(context.Background(), 1, 1, input, true)
+	if err != nil {
+		t.Errorf("Teams.EditTeamByID returned error: %v", err)
+	}
+
+	want := &Team{ID: Int64(1)}
+	if !reflect.DeepEqual(team, want) {
+		t.Errorf("Teams.EditTeamByID returned %+v, want %+v", team, want)
+	}
+
+	if want := `{"name":"n","parent_team_id":null,"privacy":"closed"}` + "\n"; body != want {
+		t.Errorf("Teams.EditTeamByID body = %+v, want %+v", body, want)
+	}
+}
+
+func TestTeamsService_EditTeamBySlug(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	input := NewTeam{Name: "n", Privacy: String("closed")}
+
+	mux.HandleFunc("/orgs/o/teams/s", func(w http.ResponseWriter, r *http.Request) {
+		v := new(NewTeam)
+		json.NewDecoder(r.Body).Decode(v)
+
+		testMethod(t, r, "PATCH")
+		if !reflect.DeepEqual(v, &input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprint(w, `{"id":1}`)
+	})
+
+	team, _, err := client.Teams.EditTeamBySlug(context.Background(), "o", "s", input, false)
+	if err != nil {
+		t.Errorf("Teams.EditTeamBySlug returned error: %v", err)
+	}
+
+	want := &Team{ID: Int64(1)}
+	if !reflect.DeepEqual(team, want) {
+		t.Errorf("Teams.EditTeamBySlug returned %+v, want %+v", team, want)
+	}
+}
+
+func TestTeamsService_EditTeamBySlug_RemoveParent(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	input := NewTeam{Name: "n", Privacy: String("closed")}
+	var body string
+
+	mux.HandleFunc("/orgs/o/teams/s", func(w http.ResponseWriter, r *http.Request) {
+		v := new(NewTeam)
+		buf, err := ioutil.ReadAll(r.Body)
+		if err != nil {
+			t.Errorf("Unable to read body: %v", err)
+		}
+		body = string(buf)
+		json.NewDecoder(bytes.NewBuffer(buf)).Decode(v)
+
+		testMethod(t, r, "PATCH")
+		if !reflect.DeepEqual(v, &input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprint(w, `{"id":1}`)
+	})
+
+	team, _, err := client.Teams.EditTeamBySlug(context.Background(), "o", "s", input, true)
 	if err != nil {
 		t.Errorf("Teams.EditTeam returned error: %v", err)
 	}
@@ -245,47 +310,83 @@ func TestTeamsService_EditTeam_RemoveParent(t *testing.T) {
 	}
 }
 
-func TestTeamsService_DeleteTeam(t *testing.T) {
+func TestTeamsService_DeleteTeamByID(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/organizations/1/team/1", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+	})
+
+	_, err := client.Teams.DeleteTeamByID(context.Background(), 1, 1)
+	if err != nil {
+		t.Errorf("Teams.DeleteTeamByID returned error: %v", err)
+	}
+}
+
+func TestTeamsService_DeleteTeamBySlug(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/orgs/o/teams/s", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
 	})
 
-	_, err := client.Teams.DeleteTeam(context.Background(), 1)
+	_, err := client.Teams.DeleteTeamBySlug(context.Background(), "o", "s")
 	if err != nil {
-		t.Errorf("Teams.DeleteTeam returned error: %v", err)
+		t.Errorf("Teams.DeleteTeamBySlug returned error: %v", err)
 	}
 }
 
-func TestTeamsService_ListChildTeams(t *testing.T) {
+func TestTeamsService_ListChildTeamsByParentID(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1/teams", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/2/teams", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":2}]`)
 	})
 
 	opt := &ListOptions{Page: 2}
-	teams, _, err := client.Teams.ListChildTeams(context.Background(), 1, opt)
+	teams, _, err := client.Teams.ListChildTeamsByParentID(context.Background(), 1, 2, opt)
 	if err != nil {
-		t.Errorf("Teams.ListTeams returned error: %v", err)
+		t.Errorf("Teams.ListChildTeamsByParentID returned error: %v", err)
 	}
 
 	want := []*Team{{ID: Int64(2)}}
 	if !reflect.DeepEqual(teams, want) {
-		t.Errorf("Teams.ListTeams returned %+v, want %+v", teams, want)
+		t.Errorf("Teams.ListChildTeamsByParentID returned %+v, want %+v", teams, want)
 	}
 }
 
-func TestTeamsService_ListTeamRepos(t *testing.T) {
+func TestTeamsService_ListChildTeamsByParentSlug(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1/repos", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/orgs/o/teams/s/teams", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testFormValues(t, r, values{"page": "2"})
+		fmt.Fprint(w, `[{"id":2}]`)
+	})
+
+	opt := &ListOptions{Page: 2}
+	teams, _, err := client.Teams.ListChildTeamsByParentSlug(context.Background(), "o", "s", opt)
+	if err != nil {
+		t.Errorf("Teams.ListChildTeamsByParentSlug returned error: %v", err)
+	}
+
+	want := []*Team{{ID: Int64(2)}}
+	if !reflect.DeepEqual(teams, want) {
+		t.Errorf("Teams.ListChildTeamsByParentSlug returned %+v, want %+v", teams, want)
+	}
+}
+
+func TestTeamsService_ListTeamReposByID(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/organizations/1/team/1/repos", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		wantAcceptHeaders := []string{mediaTypeTopicsPreview}
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
@@ -294,96 +395,192 @@ func TestTeamsService_ListTeamRepos(t *testing.T) {
 	})
 
 	opt := &ListOptions{Page: 2}
-	members, _, err := client.Teams.ListTeamRepos(context.Background(), 1, opt)
+	members, _, err := client.Teams.ListTeamReposByID(context.Background(), 1, 1, opt)
 	if err != nil {
-		t.Errorf("Teams.ListTeamRepos returned error: %v", err)
+		t.Errorf("Teams.ListTeamReposByID returned error: %v", err)
 	}
 
 	want := []*Repository{{ID: Int64(1)}}
 	if !reflect.DeepEqual(members, want) {
-		t.Errorf("Teams.ListTeamRepos returned %+v, want %+v", members, want)
+		t.Errorf("Teams.ListTeamReposByID returned %+v, want %+v", members, want)
 	}
 }
 
-func TestTeamsService_IsTeamRepo_true(t *testing.T) {
+func TestTeamsService_ListTeamReposBySlug(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/orgs/o/teams/s/repos", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		wantAcceptHeaders := []string{mediaTypeTopicsPreview}
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
+		testFormValues(t, r, values{"page": "2"})
+		fmt.Fprint(w, `[{"id":1}]`)
+	})
+
+	opt := &ListOptions{Page: 2}
+	members, _, err := client.Teams.ListTeamReposBySlug(context.Background(), "o", "s", opt)
+	if err != nil {
+		t.Errorf("Teams.ListTeamReposBySlug returned error: %v", err)
+	}
+
+	want := []*Repository{{ID: Int64(1)}}
+	if !reflect.DeepEqual(members, want) {
+		t.Errorf("Teams.ListTeamReposBySlug returned %+v, want %+v", members, want)
+	}
+}
+
+func TestTeamsService_IsTeamRepoByID_true(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		wantAcceptHeaders := []string{mediaTypeOrgPermissionRepo}
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
+		fmt.Fprint(w, `{"id":1}`)
+	})
+
+	repo, _, err := client.Teams.IsTeamRepoByID(context.Background(), 1, 1, "owner", "repo")
+	if err != nil {
+		t.Errorf("Teams.IsTeamRepoByID returned error: %v", err)
+	}
+
+	want := &Repository{ID: Int64(1)}
+	if !reflect.DeepEqual(repo, want) {
+		t.Errorf("Teams.IsTeamRepoByID returned %+v, want %+v", repo, want)
+	}
+}
+
+func TestTeamsService_IsTeamRepoBySlug_true(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/org/teams/slug/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		wantAcceptHeaders := []string{mediaTypeOrgPermissionRepo}
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
-	repo, _, err := client.Teams.IsTeamRepo(context.Background(), 1, "o", "r")
+	repo, _, err := client.Teams.IsTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo")
 	if err != nil {
-		t.Errorf("Teams.IsTeamRepo returned error: %v", err)
+		t.Errorf("Teams.IsTeamRepoBySlug returned error: %v", err)
 	}
 
 	want := &Repository{ID: Int64(1)}
 	if !reflect.DeepEqual(repo, want) {
-		t.Errorf("Teams.IsTeamRepo returned %+v, want %+v", repo, want)
+		t.Errorf("Teams.IsTeamRepoBySlug returned %+v, want %+v", repo, want)
+	}
+}
+
+func TestTeamsService_IsTeamRepoByID_false(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		w.WriteHeader(http.StatusNotFound)
+	})
+
+	repo, resp, err := client.Teams.IsTeamRepoByID(context.Background(), 1, 1, "owner", "repo")
+	if err == nil {
+		t.Errorf("Expected HTTP 404 response")
+	}
+	if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
+		t.Errorf("Teams.IsTeamRepoByID returned status %d, want %d", got, want)
+	}
+	if repo != nil {
+		t.Errorf("Teams.IsTeamRepoByID returned %+v, want nil", repo)
 	}
 }
 
-func TestTeamsService_IsTeamRepo_false(t *testing.T) {
+func TestTeamsService_IsTeamRepoBySlug_false(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/orgs/org/teams/slug/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		w.WriteHeader(http.StatusNotFound)
 	})
 
-	repo, resp, err := client.Teams.IsTeamRepo(context.Background(), 1, "o", "r")
+	repo, resp, err := client.Teams.IsTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo")
 	if err == nil {
 		t.Errorf("Expected HTTP 404 response")
 	}
 	if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
-		t.Errorf("Teams.IsTeamRepo returned status %d, want %d", got, want)
+		t.Errorf("Teams.IsTeamRepoByID returned status %d, want %d", got, want)
 	}
 	if repo != nil {
-		t.Errorf("Teams.IsTeamRepo returned %+v, want nil", repo)
+		t.Errorf("Teams.IsTeamRepoByID returned %+v, want nil", repo)
 	}
 }
 
-func TestTeamsService_IsTeamRepo_error(t *testing.T) {
+func TestTeamsService_IsTeamRepoByID_error(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		http.Error(w, "BadRequest", http.StatusBadRequest)
 	})
 
-	repo, resp, err := client.Teams.IsTeamRepo(context.Background(), 1, "o", "r")
+	repo, resp, err := client.Teams.IsTeamRepoByID(context.Background(), 1, 1, "owner", "repo")
 	if err == nil {
 		t.Errorf("Expected HTTP 400 response")
 	}
 	if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want {
-		t.Errorf("Teams.IsTeamRepo returned status %d, want %d", got, want)
+		t.Errorf("Teams.IsTeamRepoByID returned status %d, want %d", got, want)
 	}
 	if repo != nil {
-		t.Errorf("Teams.IsTeamRepo returned %+v, want nil", repo)
+		t.Errorf("Teams.IsTeamRepoByID returned %+v, want nil", repo)
 	}
 }
 
-func TestTeamsService_IsTeamRepo_invalidOwner(t *testing.T) {
+func TestTeamsService_IsTeamRepoBySlug_error(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/org/teams/slug/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		http.Error(w, "BadRequest", http.StatusBadRequest)
+	})
+
+	repo, resp, err := client.Teams.IsTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo")
+	if err == nil {
+		t.Errorf("Expected HTTP 400 response")
+	}
+	if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want {
+		t.Errorf("Teams.IsTeamRepoBySlug returned status %d, want %d", got, want)
+	}
+	if repo != nil {
+		t.Errorf("Teams.IsTeamRepoBySlug returned %+v, want nil", repo)
+	}
+}
+
+func TestTeamsService_IsTeamRepoByID_invalidOwner(t *testing.T) {
 	client, _, _, teardown := setup()
 	defer teardown()
 
-	_, _, err := client.Teams.IsTeamRepo(context.Background(), 1, "%", "r")
+	_, _, err := client.Teams.IsTeamRepoByID(context.Background(), 1, 1, "%", "r")
 	testURLParseError(t, err)
 }
 
-func TestTeamsService_AddTeamRepo(t *testing.T) {
+func TestTeamsService_IsTeamRepoBySlug_invalidOwner(t *testing.T) {
+	client, _, _, teardown := setup()
+	defer teardown()
+
+	_, _, err := client.Teams.IsTeamRepoBySlug(context.Background(), "o", "s", "%", "r")
+	testURLParseError(t, err)
+}
+
+func TestTeamsService_AddTeamRepoByID(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
 	opt := &TeamAddTeamRepoOptions{Permission: "admin"}
 
-	mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
 		v := new(TeamAddTeamRepoOptions)
 		json.NewDecoder(r.Body).Decode(v)
 
@@ -395,55 +592,125 @@ func TestTeamsService_AddTeamRepo(t *testing.T) {
 		w.WriteHeader(http.StatusNoContent)
 	})
 
-	_, err := client.Teams.AddTeamRepo(context.Background(), 1, "o", "r", opt)
+	_, err := client.Teams.AddTeamRepoByID(context.Background(), 1, 1, "owner", "repo", opt)
 	if err != nil {
-		t.Errorf("Teams.AddTeamRepo returned error: %v", err)
+		t.Errorf("Teams.AddTeamRepoByID returned error: %v", err)
 	}
 }
 
-func TestTeamsService_AddTeamRepo_noAccess(t *testing.T) {
+func TestTeamsService_AddTeamRepoBySlug(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
+	opt := &TeamAddTeamRepoOptions{Permission: "admin"}
+
+	mux.HandleFunc("/orgs/org/teams/slug/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
+		v := new(TeamAddTeamRepoOptions)
+		json.NewDecoder(r.Body).Decode(v)
+
+		testMethod(t, r, "PUT")
+		if !reflect.DeepEqual(v, opt) {
+			t.Errorf("Request body = %+v, want %+v", v, opt)
+		}
+
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	_, err := client.Teams.AddTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo", opt)
+	if err != nil {
+		t.Errorf("Teams.AddTeamRepoBySlug returned error: %v", err)
+	}
+}
+
+func TestTeamsService_AddTeamRepoByID_noAccess(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PUT")
+		w.WriteHeader(http.StatusUnprocessableEntity)
+	})
+
+	_, err := client.Teams.AddTeamRepoByID(context.Background(), 1, 1, "owner", "repo", nil)
+	if err == nil {
+		t.Errorf("Expcted error to be returned")
+	}
+}
+
+func TestTeamsService_AddTeamRepoBySlug_noAccess(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/org/teams/slug/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "PUT")
 		w.WriteHeader(http.StatusUnprocessableEntity)
 	})
 
-	_, err := client.Teams.AddTeamRepo(context.Background(), 1, "o", "r", nil)
+	_, err := client.Teams.AddTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo", nil)
 	if err == nil {
 		t.Errorf("Expcted error to be returned")
 	}
 }
 
-func TestTeamsService_AddTeamRepo_invalidOwner(t *testing.T) {
+func TestTeamsService_AddTeamRepoByID_invalidOwner(t *testing.T) {
+	client, _, _, teardown := setup()
+	defer teardown()
+
+	_, err := client.Teams.AddTeamRepoByID(context.Background(), 1, 1, "%", "r", nil)
+	testURLParseError(t, err)
+}
+
+func TestTeamsService_AddTeamRepoBySlug_invalidOwner(t *testing.T) {
 	client, _, _, teardown := setup()
 	defer teardown()
 
-	_, err := client.Teams.AddTeamRepo(context.Background(), 1, "%", "r", nil)
+	_, err := client.Teams.AddTeamRepoBySlug(context.Background(), "o", "s", "%", "r", nil)
 	testURLParseError(t, err)
 }
 
-func TestTeamsService_RemoveTeamRepo(t *testing.T) {
+func TestTeamsService_RemoveTeamRepoByID(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/organizations/1/team/1/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	_, err := client.Teams.RemoveTeamRepoByID(context.Background(), 1, 1, "owner", "repo")
+	if err != nil {
+		t.Errorf("Teams.RemoveTeamRepoByID returned error: %v", err)
+	}
+}
+
+func TestTeamsService_RemoveTeamRepoBySlug(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/orgs/org/teams/slug/repos/owner/repo", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
 		w.WriteHeader(http.StatusNoContent)
 	})
 
-	_, err := client.Teams.RemoveTeamRepo(context.Background(), 1, "o", "r")
+	_, err := client.Teams.RemoveTeamRepoBySlug(context.Background(), "org", "slug", "owner", "repo")
 	if err != nil {
-		t.Errorf("Teams.RemoveTeamRepo returned error: %v", err)
+		t.Errorf("Teams.RemoveTeamRepoBySlug returned error: %v", err)
 	}
 }
 
-func TestTeamsService_RemoveTeamRepo_invalidOwner(t *testing.T) {
+func TestTeamsService_RemoveTeamRepoByID_invalidOwner(t *testing.T) {
+	client, _, _, teardown := setup()
+	defer teardown()
+
+	_, err := client.Teams.RemoveTeamRepoByID(context.Background(), 1, 1, "%", "r")
+	testURLParseError(t, err)
+}
+
+func TestTeamsService_RemoveTeamRepoBySlug_invalidOwner(t *testing.T) {
 	client, _, _, teardown := setup()
 	defer teardown()
 
-	_, err := client.Teams.RemoveTeamRepo(context.Background(), 1, "%", "r")
+	_, err := client.Teams.RemoveTeamRepoBySlug(context.Background(), "o", "s", "%", "r")
 	testURLParseError(t, err)
 }
 
@@ -469,128 +736,95 @@ func TestTeamsService_ListUserTeams(t *testing.T) {
 	}
 }
 
-func TestTeamsService_ListPendingTeamInvitations(t *testing.T) {
+func TestTeamsService_ListProjectsByID(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/teams/1/invitations", func(w http.ResponseWriter, r *http.Request) {
+	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
+	mux.HandleFunc("/organizations/1/team/1/projects", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testFormValues(t, r, values{"page": "1"})
-		fmt.Fprint(w, `[
-				{
-    					"id": 1,
-    					"login": "monalisa",
-    					"email": "octocat@github.com",
-    					"role": "direct_member",
-    					"created_at": "2017-01-21T00:00:00Z",
-    					"inviter": {
-      						"login": "other_user",
-      						"id": 1,
-      						"avatar_url": "https://github.com/images/error/other_user_happy.gif",
-      						"gravatar_id": "",
-      						"url": "https://api.github.com/users/other_user",
-      						"html_url": "https://github.com/other_user",
-      						"followers_url": "https://api.github.com/users/other_user/followers",
-      						"following_url": "https://api.github.com/users/other_user/following/other_user",
-      						"gists_url": "https://api.github.com/users/other_user/gists/gist_id",
-      						"starred_url": "https://api.github.com/users/other_user/starred/owner/repo",
-      						"subscriptions_url": "https://api.github.com/users/other_user/subscriptions",
-      						"organizations_url": "https://api.github.com/users/other_user/orgs",
-      						"repos_url": "https://api.github.com/users/other_user/repos",
-      						"events_url": "https://api.github.com/users/other_user/events/privacy",
-      						"received_events_url": "https://api.github.com/users/other_user/received_events/privacy",
-      						"type": "User",
-      						"site_admin": false
-    					}
-  				}
-			]`)
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
+		fmt.Fprint(w, `[{"id":1}]`)
 	})
 
-	opt := &ListOptions{Page: 1}
-	invitations, _, err := client.Teams.ListPendingTeamInvitations(context.Background(), 1, opt)
-	if err != nil {
-		t.Errorf("Teams.ListPendingTeamInvitations returned error: %v", err)
-	}
-
-	createdAt := time.Date(2017, time.January, 21, 0, 0, 0, 0, time.UTC)
-	want := []*Invitation{
-		{
-			ID:        Int64(1),
-			Login:     String("monalisa"),
-			Email:     String("octocat@github.com"),
-			Role:      String("direct_member"),
-			CreatedAt: &createdAt,
-			Inviter: &User{
-				Login:             String("other_user"),
-				ID:                Int64(1),
-				AvatarURL:         String("https://github.com/images/error/other_user_happy.gif"),
-				GravatarID:        String(""),
-				URL:               String("https://api.github.com/users/other_user"),
-				HTMLURL:           String("https://github.com/other_user"),
-				FollowersURL:      String("https://api.github.com/users/other_user/followers"),
-				FollowingURL:      String("https://api.github.com/users/other_user/following/other_user"),
-				GistsURL:          String("https://api.github.com/users/other_user/gists/gist_id"),
-				StarredURL:        String("https://api.github.com/users/other_user/starred/owner/repo"),
-				SubscriptionsURL:  String("https://api.github.com/users/other_user/subscriptions"),
-				OrganizationsURL:  String("https://api.github.com/users/other_user/orgs"),
-				ReposURL:          String("https://api.github.com/users/other_user/repos"),
-				EventsURL:         String("https://api.github.com/users/other_user/events/privacy"),
-				ReceivedEventsURL: String("https://api.github.com/users/other_user/received_events/privacy"),
-				Type:              String("User"),
-				SiteAdmin:         Bool(false),
-			},
-		}}
+	projects, _, err := client.Teams.ListTeamProjectsByID(context.Background(), 1, 1)
+	if err != nil {
+		t.Errorf("Teams.ListTeamProjectsByID returned error: %v", err)
+	}
 
-	if !reflect.DeepEqual(invitations, want) {
-		t.Errorf("Teams.ListPendingTeamInvitations returned %+v, want %+v", invitations, want)
+	want := []*Project{{ID: Int64(1)}}
+	if !reflect.DeepEqual(projects, want) {
+		t.Errorf("Teams.ListTeamProjectsByID returned %+v, want %+v", projects, want)
 	}
 }
 
-func TestTeamsService_ListProjects(t *testing.T) {
+func TestTeamsService_ListProjectsBySlug(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
 	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
-	mux.HandleFunc("/teams/1/projects", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/orgs/o/teams/s/projects", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
 
-	projects, _, err := client.Teams.ListTeamProjects(context.Background(), 1)
+	projects, _, err := client.Teams.ListTeamProjectsBySlug(context.Background(), "o", "s")
 	if err != nil {
-		t.Errorf("Teams.ListTeamProjects returned error: %v", err)
+		t.Errorf("Teams.ListTeamProjectsBySlug returned error: %v", err)
 	}
 
 	want := []*Project{{ID: Int64(1)}}
 	if !reflect.DeepEqual(projects, want) {
-		t.Errorf("Teams.ListTeamProjects returned %+v, want %+v", projects, want)
+		t.Errorf("Teams.ListTeamProjectsBySlug returned %+v, want %+v", projects, want)
 	}
 }
 
-func TestTeamsService_ReviewProjects(t *testing.T) {
+func TestTeamsService_ReviewProjectsByID(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
 	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
-	mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
-	project, _, err := client.Teams.ReviewTeamProjects(context.Background(), 1, 1)
+	project, _, err := client.Teams.ReviewTeamProjectsByID(context.Background(), 1, 1, 1)
 	if err != nil {
-		t.Errorf("Teams.ReviewTeamProjects returned error: %v", err)
+		t.Errorf("Teams.ReviewTeamProjectsByID returned error: %v", err)
 	}
 
 	want := &Project{ID: Int64(1)}
 	if !reflect.DeepEqual(project, want) {
-		t.Errorf("Teams.ReviewTeamProjects returned %+v, want %+v", project, want)
+		t.Errorf("Teams.ReviewTeamProjectsByID returned %+v, want %+v", project, want)
 	}
 }
 
-func TestTeamsService_AddTeamProject(t *testing.T) {
+func TestTeamsService_ReviewProjectsBySlug(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
+	mux.HandleFunc("/orgs/o/teams/s/projects/1", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
+		fmt.Fprint(w, `{"id":1}`)
+	})
+
+	project, _, err := client.Teams.ReviewTeamProjectsBySlug(context.Background(), "o", "s", 1)
+	if err != nil {
+		t.Errorf("Teams.ReviewTeamProjectsBySlug returned error: %v", err)
+	}
+
+	want := &Project{ID: Int64(1)}
+	if !reflect.DeepEqual(project, want) {
+		t.Errorf("Teams.ReviewTeamProjectsBySlug returned %+v, want %+v", project, want)
+	}
+}
+
+func TestTeamsService_AddTeamProjectByID(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
@@ -599,7 +833,7 @@ func TestTeamsService_AddTeamProject(t *testing.T) {
 	}
 
 	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
-	mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/organizations/1/team/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "PUT")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 
@@ -612,26 +846,71 @@ func TestTeamsService_AddTeamProject(t *testing.T) {
 		w.WriteHeader(http.StatusNoContent)
 	})
 
-	_, err := client.Teams.AddTeamProject(context.Background(), 1, 1, opt)
+	_, err := client.Teams.AddTeamProjectByID(context.Background(), 1, 1, 1, opt)
+	if err != nil {
+		t.Errorf("Teams.AddTeamProjectByID returned error: %v", err)
+	}
+}
+
+func TestTeamsService_AddTeamProjectBySlug(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	opt := &TeamProjectOptions{
+		Permission: String("admin"),
+	}
+
+	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
+	mux.HandleFunc("/orgs/o/teams/s/projects/1", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PUT")
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
+
+		v := &TeamProjectOptions{}
+		json.NewDecoder(r.Body).Decode(v)
+		if !reflect.DeepEqual(v, opt) {
+			t.Errorf("Request body = %+v, want %+v", v, opt)
+		}
+
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	_, err := client.Teams.AddTeamProjectBySlug(context.Background(), "o", "s", 1, opt)
+	if err != nil {
+		t.Errorf("Teams.AddTeamProjectBySlug returned error: %v", err)
+	}
+}
+
+func TestTeamsService_RemoveTeamProjectByID(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
+	mux.HandleFunc("/organizations/1/team/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
+		w.WriteHeader(http.StatusNoContent)
+	})
+
+	_, err := client.Teams.RemoveTeamProjectByID(context.Background(), 1, 1, 1)
 	if err != nil {
-		t.Errorf("Teams.AddTeamProject returned error: %v", err)
+		t.Errorf("Teams.RemoveTeamProjectByID returned error: %v", err)
 	}
 }
 
-func TestTeamsService_RemoveTeamProject(t *testing.T) {
+func TestTeamsService_RemoveTeamProjectBySlug(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
 	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
-	mux.HandleFunc("/teams/1/projects/1", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/orgs/o/teams/s/projects/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
 		w.WriteHeader(http.StatusNoContent)
 	})
 
-	_, err := client.Teams.RemoveTeamProject(context.Background(), 1, 1)
+	_, err := client.Teams.RemoveTeamProjectBySlug(context.Background(), "o", "s", 1)
 	if err != nil {
-		t.Errorf("Teams.RemoveTeamProject returned error: %v", err)
+		t.Errorf("Teams.RemoveTeamProjectBySlug returned error: %v", err)
 	}
 }