Repository: google/go-github
Pull request #852 (2018-02-14 17:33:31)

Add app_id to the Installation struct
Implements https://github.com/google/go-github/issues/851

An InstallationID is different from an AppID. This PR adds an additional field
so that we can query the GitHub application ID given its installation ID.

The `app_id` field is returned during installation and creation events.
It is also returned in the https://developer.github.com/v3/apps/#get-a-single-installation endpoint.

googlebot: Thanks for your pull request.  It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

:memo: **Please visit <https://cla.developers.google.com/> to sign.**

Once you've signed, please reply here (e.g. `I signed it!`) and we'll verify.  Thanks.

---

- If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address on your commit.  Check [your existing CLA data](https://cla.developers.google.com/clas) and verify that your [email is set on your git commits](https://help.github.com/articles/setting-your-email-in-git/).
- If your company signed a CLA, they designated a Point of Contact who decides which employees are authorized to participate. You may need to contact the Point of Contact for your company and ask to be added to the group of authorized contributors. If you don't know who your Point of Contact is, direct the project maintainer to go/cla#troubleshoot. The email used to register you as an authorized contributor must be the email used for the Git commit.
- In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again. If the bot doesn't comment, it means it doesn't think anything has changed.

<!-- need_sender_cla -->
sridharavinash: I signed it!
googlebot: CLAs look good, thanks!

<!-- ok -->

Patch:
diff --git a/README.md b/README.md
index e829bdd3..e035faea 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ access different parts of the GitHub API. For example:
 client := github.NewClient(nil)
 
 // list all organizations for user "willnorris"
-orgs, _, err := client.Organizations.List(ctx, "willnorris", nil)
+orgs, _, err := client.Organizations.List(context.Background(), "willnorris", nil)
 ```
 
 Some API methods have optional parameters that can be passed. For example:
@@ -32,13 +32,21 @@ client := github.NewClient(nil)
 
 // list public repositories for org "github"
 opt := &github.RepositoryListByOrgOptions{Type: "public"}
-repos, _, err := client.Repositories.ListByOrg(ctx, "github", opt)
+repos, _, err := client.Repositories.ListByOrg(context.Background(), "github", opt)
 ```
 
 The services of a client divide the API into logical chunks and correspond to
 the structure of the GitHub API documentation at
 https://developer.github.com/v3/.
 
+NOTE: Using the [context](https://godoc.org/context) package, one can easily
+pass cancelation signals and deadlines to various services of the client for
+handling a request. In case there is no context available, then `context.Background()`
+can be used as a starting point.
+
+For more sample code snippets, head over to the
+[example](https://github.com/google/go-github/tree/master/example) directory.
+
 ### Authentication ###
 
 The go-github library does not directly handle authentication. Instead, when
diff --git a/example/simple/main.go b/example/simple/main.go
new file mode 100644
index 00000000..64a2e6f5
--- /dev/null
+++ b/example/simple/main.go
@@ -0,0 +1,40 @@
+// Copyright 2017 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The simple command demonstrates a simple functionality which
+// prompts the user for a GitHub username and lists all the public
+// organization memberships of the specified username.
+package main
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/google/go-github/github"
+)
+
+// Fetch all the public organizations' membership of a user.
+//
+func FetchOrganizations(username string) ([]*github.Organization, error) {
+	client := github.NewClient(nil)
+	orgs, _, err := client.Organizations.List(context.Background(), username, nil)
+	return orgs, err
+}
+
+func main() {
+	var username string
+	fmt.Print("Enter GitHub username: ")
+	fmt.Scanf("%s", &username)
+
+	organizations, err := FetchOrganizations(username)
+	if err != nil {
+		fmt.Printf("Error: %v\n", err)
+		return
+	}
+
+	for i, organization := range organizations {
+		fmt.Printf("%v. %v\n", i+1, organization.GetLogin())
+	}
+}
diff --git a/github/apps_installation.go b/github/apps_installation.go
index af85cb87..5a424ff1 100644
--- a/github/apps_installation.go
+++ b/github/apps_installation.go
@@ -13,6 +13,7 @@ import (
 // Installation represents a GitHub Apps installation.
 type Installation struct {
 	ID              *int64  `json:"id,omitempty"`
+	AppID           *int64  `json:"app_id,omitempty"`
 	Account         *User   `json:"account,omitempty"`
 	AccessTokensURL *string `json:"access_tokens_url,omitempty"`
 	RepositoriesURL *string `json:"repositories_url,omitempty"`
diff --git a/github/doc.go b/github/doc.go
index 4ba03cb3..9f12400d 100644
--- a/github/doc.go
+++ b/github/doc.go
@@ -30,6 +30,13 @@ The services of a client divide the API into logical chunks and correspond to
 the structure of the GitHub API documentation at
 https://developer.github.com/v3/.
 
+NOTE: Using the https://godoc.org/context package, one can easily
+pass cancelation signals and deadlines to various services of the client for
+handling a request. In case there is no context available, then context.Background()
+can be used as a starting point.
+
+For more sample code snippets, head over to the https://github.com/google/go-github/tree/master/example directory.
+
 Authentication
 
 The go-github library does not directly handle authentication. Instead, when
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 30b76739..32306121 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -1324,6 +1324,30 @@ func (c *CreateEvent) GetSender() *User {
 	return c.Sender
 }
 
+// GetEmail returns the Email field if it's non-nil, zero value otherwise.
+func (c *CreateOrgInvitationOptions) GetEmail() string {
+	if c == nil || c.Email == nil {
+		return ""
+	}
+	return *c.Email
+}
+
+// GetInviteeID returns the InviteeID field if it's non-nil, zero value otherwise.
+func (c *CreateOrgInvitationOptions) GetInviteeID() int64 {
+	if c == nil || c.InviteeID == nil {
+		return 0
+	}
+	return *c.InviteeID
+}
+
+// GetRole returns the Role field if it's non-nil, zero value otherwise.
+func (c *CreateOrgInvitationOptions) GetRole() string {
+	if c == nil || c.Role == nil {
+		return ""
+	}
+	return *c.Role
+}
+
 // GetInstallation returns the Installation field.
 func (d *DeleteEvent) GetInstallation() *Installation {
 	if d == nil {
@@ -2684,6 +2708,14 @@ func (i *Installation) GetAccount() *User {
 	return i.Account
 }
 
+// GetAppID returns the AppID field if it's non-nil, zero value otherwise.
+func (i *Installation) GetAppID() int64 {
+	if i == nil || i.AppID == nil {
+		return 0
+	}
+	return *i.AppID
+}
+
 // GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
 func (i *Installation) GetHTMLURL() string {
 	if i == nil || i.HTMLURL == nil {
@@ -2804,6 +2836,14 @@ func (i *Invitation) GetID() int64 {
 	return *i.ID
 }
 
+// GetInvitationTeamURL returns the InvitationTeamURL field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetInvitationTeamURL() string {
+	if i == nil || i.InvitationTeamURL == nil {
+		return ""
+	}
+	return *i.InvitationTeamURL
+}
+
 // GetInviter returns the Inviter field.
 func (i *Invitation) GetInviter() *User {
 	if i == nil {
@@ -2828,6 +2868,14 @@ func (i *Invitation) GetRole() string {
 	return *i.Role
 }
 
+// GetTeamCount returns the TeamCount field if it's non-nil, zero value otherwise.
+func (i *Invitation) GetTeamCount() int {
+	if i == nil || i.TeamCount == nil {
+		return 0
+	}
+	return *i.TeamCount
+}
+
 // GetAssignee returns the Assignee field.
 func (i *Issue) GetAssignee() *User {
 	if i == nil {
@@ -5212,6 +5260,14 @@ func (p *Project) GetName() string {
 	return *p.Name
 }
 
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *Project) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
 // GetNumber returns the Number field if it's non-nil, zero value otherwise.
 func (p *Project) GetNumber() int {
 	if p == nil || p.Number == nil {
@@ -5292,6 +5348,14 @@ func (p *ProjectCard) GetID() int64 {
 	return *p.ID
 }
 
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *ProjectCard) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
 // GetNote returns the Note field if it's non-nil, zero value otherwise.
 func (p *ProjectCard) GetNote() string {
 	if p == nil || p.Note == nil {
@@ -5404,6 +5468,14 @@ func (p *ProjectColumn) GetName() string {
 	return *p.Name
 }
 
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *ProjectColumn) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
 // GetProjectURL returns the ProjectURL field if it's non-nil, zero value otherwise.
 func (p *ProjectColumn) GetProjectURL() string {
 	if p == nil || p.ProjectURL == nil {
@@ -6980,6 +7052,14 @@ func (r *Reaction) GetID() int64 {
 	return *r.ID
 }
 
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *Reaction) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
 // GetUser returns the User field.
 func (r *Reaction) GetUser() *User {
 	if r == nil {
@@ -7140,6 +7220,14 @@ func (r *ReleaseAsset) GetName() string {
 	return *r.Name
 }
 
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *ReleaseAsset) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
 // GetSize returns the Size field if it's non-nil, zero value otherwise.
 func (r *ReleaseAsset) GetSize() int {
 	if r == nil || r.Size == nil {
@@ -8500,6 +8588,14 @@ func (r *RepositoryRelease) GetName() string {
 	return *r.Name
 }
 
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetNodeID() string {
+	if r == nil || r.NodeID == nil {
+		return ""
+	}
+	return *r.NodeID
+}
+
 // GetPrerelease returns the Prerelease field if it's non-nil, zero value otherwise.
 func (r *RepositoryRelease) GetPrerelease() bool {
 	if r == nil || r.Prerelease == nil {
diff --git a/github/github.go b/github/github.go
index f3eadce9..6d45e4aa 100644
--- a/github/github.go
+++ b/github/github.go
@@ -99,9 +99,6 @@ const (
 	// https://developer.github.com/changes/2017-07-17-update-topics-on-repositories/
 	mediaTypeTopicsPreview = "application/vnd.github.mercy-preview+json"
 
-	// https://developer.github.com/changes/2017-07-26-team-review-request-thor-preview/
-	mediaTypeTeamReviewPreview = "application/vnd.github.thor-preview+json"
-
 	// https://developer.github.com/v3/apps/marketplace/
 	mediaTypeMarketplacePreview = "application/vnd.github.valkyrie-preview+json"
 
@@ -113,6 +110,9 @@ const (
 
 	// https://developer.github.com/changes/2017-12-19-graphql-node-id/
 	mediaTypeGraphQLNodeIDPreview = "application/vnd.github.jean-grey-preview+json"
+
+	// https://developer.github.com/changes/2018-01-25-organization-invitation-api-preview/
+	mediaTypeOrganizationInvitationPreview = "application/vnd.github.dazzler-preview+json"
 )
 
 // A Client manages communication with the GitHub API.
diff --git a/github/orgs_members.go b/github/orgs_members.go
index d0ea6a98..fb1957e6 100644
--- a/github/orgs_members.go
+++ b/github/orgs_members.go
@@ -297,3 +297,74 @@ func (s *OrganizationsService) ListPendingOrgInvitations(ctx context.Context, or
 	}
 	return pendingInvitations, resp, nil
 }
+
+// CreateOrgInvitationOptions specifies the parameters to the OrganizationService.Invite
+// method.
+type CreateOrgInvitationOptions struct {
+	// GitHub user ID for the person you are inviting. Not required if you provide Email.
+	InviteeID *int64 `json:"invitee_id,omitempty"`
+	// Email address of the person you are inviting, which can be an existing GitHub user.
+	// Not required if you provide InviteeID
+	Email *string `json:"email,omitempty"`
+	// Specify role for new member. Can be one of:
+	// * admin - Organization owners with full administrative rights to the
+	// 	 organization and complete access to all repositories and teams.
+	// * direct_member - Non-owner organization members with ability to see
+	//   other members and join teams by invitation.
+	// * billing_manager - Non-owner organization members with ability to
+	//   manage the billing settings of your organization.
+	// Default is "direct_member".
+	Role   *string `json:"role"`
+	TeamID []int64 `json:"team_ids"`
+}
+
+// CreateOrgInvitation invites people to an organization by using their GitHub user ID or their email address.
+// In order to create invitations in an organization,
+// the authenticated user must be an organization owner.
+//
+// https://developer.github.com/v3/orgs/members/#create-organization-invitation
+func (s *OrganizationsService) CreateOrgInvitation(ctx context.Context, org string, opt *CreateOrgInvitationOptions) ([]*Invitation, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/invitations", org)
+
+	req, err := s.client.NewRequest("POST", u, opt)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeOrganizationInvitationPreview)
+
+	var invitations []*Invitation
+	resp, err := s.client.Do(ctx, req, &invitations)
+	if err != nil {
+		return nil, resp, err
+	}
+	return invitations, resp, nil
+}
+
+// ListOrgInvitationTeams lists all teams associated with an invitation. In order to see invitations in an organization,
+// the authenticated user must be an organization owner.
+//
+// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-organization-invitation-teams
+func (s *OrganizationsService) ListOrgInvitationTeams(ctx context.Context, org, invitationID string, opt *ListOptions) ([]*Team, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/invitations/%v/teams", org, invitationID)
+	u, err := addOptions(u, opt)
+	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 this API fully launches.
+	req.Header.Set("Accept", mediaTypeOrganizationInvitationPreview)
+
+	var orgInvitationTeams []*Team
+	resp, err := s.client.Do(ctx, req, &orgInvitationTeams)
+	if err != nil {
+		return nil, resp, err
+	}
+	return orgInvitationTeams, resp, nil
+}
diff --git a/github/orgs_teams.go b/github/orgs_teams.go
index c1457108..b3cc9f07 100644
--- a/github/orgs_teams.go
+++ b/github/orgs_teams.go
@@ -53,9 +53,11 @@ type Invitation struct {
 	Login *string `json:"login,omitempty"`
 	Email *string `json:"email,omitempty"`
 	// Role can be one of the values - 'direct_member', 'admin', 'billing_manager', 'hiring_manager', or 'reinstate'.
-	Role      *string    `json:"role,omitempty"`
-	CreatedAt *time.Time `json:"created_at,omitempty"`
-	Inviter   *User      `json:"inviter,omitempty"`
+	Role              *string    `json:"role,omitempty"`
+	CreatedAt         *time.Time `json:"created_at,omitempty"`
+	Inviter           *User      `json:"inviter,omitempty"`
+	TeamCount         *int       `json:"team_count,omitempty"`
+	InvitationTeamURL *string    `json:"invitation_team_url,omitempty"`
 }
 
 func (i Invitation) String() string {
diff --git a/github/projects.go b/github/projects.go
index 22061363..409ed4a2 100644
--- a/github/projects.go
+++ b/github/projects.go
@@ -8,6 +8,7 @@ package github
 import (
 	"context"
 	"fmt"
+	"strings"
 )
 
 // ProjectsService provides access to the projects functions in the
@@ -26,6 +27,7 @@ type Project struct {
 	Number    *int       `json:"number,omitempty"`
 	CreatedAt *Timestamp `json:"created_at,omitempty"`
 	UpdatedAt *Timestamp `json:"updated_at,omitempty"`
+	NodeID    *string    `json:"node_id,omitempty"`
 
 	// The User object that generated the project.
 	Creator *User `json:"creator,omitempty"`
@@ -45,8 +47,9 @@ func (s *ProjectsService) GetProject(ctx context.Context, id int64) (*Project, *
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	project := &Project{}
 	resp, err := s.client.Do(ctx, req, project)
@@ -83,8 +86,9 @@ func (s *ProjectsService) UpdateProject(ctx context.Context, id int64, opt *Proj
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	project := &Project{}
 	resp, err := s.client.Do(ctx, req, project)
@@ -120,6 +124,7 @@ type ProjectColumn struct {
 	ProjectURL *string    `json:"project_url,omitempty"`
 	CreatedAt  *Timestamp `json:"created_at,omitempty"`
 	UpdatedAt  *Timestamp `json:"updated_at,omitempty"`
+	NodeID     *string    `json:"node_id,omitempty"`
 }
 
 // ListProjectColumns lists the columns of a GitHub Project for a repo.
@@ -137,8 +142,9 @@ func (s *ProjectsService) ListProjectColumns(ctx context.Context, projectID int6
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	columns := []*ProjectColumn{}
 	resp, err := s.client.Do(ctx, req, &columns)
@@ -159,8 +165,9 @@ func (s *ProjectsService) GetProjectColumn(ctx context.Context, id int64) (*Proj
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	column := &ProjectColumn{}
 	resp, err := s.client.Do(ctx, req, column)
@@ -189,8 +196,9 @@ func (s *ProjectsService) CreateProjectColumn(ctx context.Context, projectID int
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	column := &ProjectColumn{}
 	resp, err := s.client.Do(ctx, req, column)
@@ -211,8 +219,9 @@ func (s *ProjectsService) UpdateProjectColumn(ctx context.Context, columnID int6
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	column := &ProjectColumn{}
 	resp, err := s.client.Do(ctx, req, column)
@@ -275,6 +284,7 @@ type ProjectCard struct {
 	Creator    *User      `json:"creator,omitempty"`
 	CreatedAt  *Timestamp `json:"created_at,omitempty"`
 	UpdatedAt  *Timestamp `json:"updated_at,omitempty"`
+	NodeID     *string    `json:"node_id,omitempty"`
 
 	// The following fields are only populated by Webhook events.
 	ColumnID *int64 `json:"column_id,omitempty"`
@@ -295,8 +305,9 @@ func (s *ProjectsService) ListProjectCards(ctx context.Context, columnID int64,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	cards := []*ProjectCard{}
 	resp, err := s.client.Do(ctx, req, &cards)
@@ -317,8 +328,9 @@ func (s *ProjectsService) GetProjectCard(ctx context.Context, columnID int64) (*
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	card := &ProjectCard{}
 	resp, err := s.client.Do(ctx, req, card)
@@ -352,8 +364,9 @@ func (s *ProjectsService) CreateProjectCard(ctx context.Context, columnID int64,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	card := &ProjectCard{}
 	resp, err := s.client.Do(ctx, req, card)
@@ -374,8 +387,9 @@ func (s *ProjectsService) UpdateProjectCard(ctx context.Context, cardID int64, o
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	card := &ProjectCard{}
 	resp, err := s.client.Do(ctx, req, card)
diff --git a/github/pulls.go b/github/pulls.go
index 31d492ee..6df85c78 100644
--- a/github/pulls.go
+++ b/github/pulls.go
@@ -29,6 +29,7 @@ type PullRequest struct {
 	UpdatedAt           *time.Time `json:"updated_at,omitempty"`
 	ClosedAt            *time.Time `json:"closed_at,omitempty"`
 	MergedAt            *time.Time `json:"merged_at,omitempty"`
+	Labels              []*Label   `json:"labels,omitempty"`
 	User                *User      `json:"user,omitempty"`
 	Merged              *bool      `json:"merged,omitempty"`
 	Mergeable           *bool      `json:"mergeable,omitempty"`
diff --git a/github/pulls_reviewers.go b/github/pulls_reviewers.go
index 15b47be3..a1d78531 100644
--- a/github/pulls_reviewers.go
+++ b/github/pulls_reviewers.go
@@ -32,9 +32,6 @@ func (s *PullRequestsService) RequestReviewers(ctx context.Context, owner, repo
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamReviewPreview)
-
 	r := new(PullRequest)
 	resp, err := s.client.Do(ctx, req, r)
 	if err != nil {
@@ -59,9 +56,6 @@ func (s *PullRequestsService) ListReviewers(ctx context.Context, owner, repo str
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamReviewPreview)
-
 	reviewers := new(Reviewers)
 	resp, err := s.client.Do(ctx, req, reviewers)
 	if err != nil {
@@ -81,8 +75,5 @@ func (s *PullRequestsService) RemoveReviewers(ctx context.Context, owner, repo s
 		return nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeTeamReviewPreview)
-
 	return s.client.Do(ctx, req, nil)
 }
diff --git a/github/reactions.go b/github/reactions.go
index b276ff3e..19b533f3 100644
--- a/github/reactions.go
+++ b/github/reactions.go
@@ -8,6 +8,7 @@ package github
 import (
 	"context"
 	"fmt"
+	"strings"
 )
 
 // ReactionsService provides access to the reactions-related functions in the
@@ -19,8 +20,9 @@ type ReactionsService service
 // Reaction represents a GitHub reaction.
 type Reaction struct {
 	// ID is the Reaction ID.
-	ID   *int64 `json:"id,omitempty"`
-	User *User  `json:"user,omitempty"`
+	ID     *int64  `json:"id,omitempty"`
+	User   *User   `json:"user,omitempty"`
+	NodeID *string `json:"node_id,omitempty"`
 	// Content is the type of reaction.
 	// Possible values are:
 	//     "+1", "-1", "laugh", "confused", "heart", "hooray".
@@ -58,8 +60,9 @@ func (s *ReactionsService) ListCommentReactions(ctx context.Context, owner, repo
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var m []*Reaction
 	resp, err := s.client.Do(ctx, req, &m)
@@ -84,8 +87,9 @@ func (s ReactionsService) CreateCommentReaction(ctx context.Context, owner, repo
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	m := &Reaction{}
 	resp, err := s.client.Do(ctx, req, m)
@@ -111,8 +115,9 @@ func (s *ReactionsService) ListIssueReactions(ctx context.Context, owner, repo s
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var m []*Reaction
 	resp, err := s.client.Do(ctx, req, &m)
@@ -137,8 +142,9 @@ func (s ReactionsService) CreateIssueReaction(ctx context.Context, owner, repo s
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	m := &Reaction{}
 	resp, err := s.client.Do(ctx, req, m)
@@ -164,8 +170,9 @@ func (s *ReactionsService) ListIssueCommentReactions(ctx context.Context, owner,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var m []*Reaction
 	resp, err := s.client.Do(ctx, req, &m)
@@ -190,8 +197,9 @@ func (s ReactionsService) CreateIssueCommentReaction(ctx context.Context, owner,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	m := &Reaction{}
 	resp, err := s.client.Do(ctx, req, m)
@@ -217,8 +225,9 @@ func (s *ReactionsService) ListPullRequestCommentReactions(ctx context.Context,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var m []*Reaction
 	resp, err := s.client.Do(ctx, req, &m)
@@ -243,8 +252,9 @@ func (s ReactionsService) CreatePullRequestCommentReaction(ctx context.Context,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeReactionsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	m := &Reaction{}
 	resp, err := s.client.Do(ctx, req, m)
diff --git a/github/repos_projects.go b/github/repos_projects.go
index 770ffc76..97a045f6 100644
--- a/github/repos_projects.go
+++ b/github/repos_projects.go
@@ -8,6 +8,7 @@ package github
 import (
 	"context"
 	"fmt"
+	"strings"
 )
 
 // ProjectListOptions specifies the optional parameters to the
@@ -34,8 +35,9 @@ func (s *RepositoriesService) ListProjects(ctx context.Context, owner, repo stri
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	var projects []*Project
 	resp, err := s.client.Do(ctx, req, &projects)
@@ -56,8 +58,9 @@ func (s *RepositoriesService) CreateProject(ctx context.Context, owner, repo str
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeProjectsPreview)
+	// TODO: remove custom Accept headers when APIs fully launch.
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	project := &Project{}
 	resp, err := s.client.Do(ctx, req, project)
diff --git a/github/repos_releases.go b/github/repos_releases.go
index 7ad2b278..bca0f08d 100644
--- a/github/repos_releases.go
+++ b/github/repos_releases.go
@@ -36,6 +36,7 @@ type RepositoryRelease struct {
 	ZipballURL      *string        `json:"zipball_url,omitempty"`
 	TarballURL      *string        `json:"tarball_url,omitempty"`
 	Author          *User          `json:"author,omitempty"`
+	NodeID          *string        `json:"node_id,omitempty"`
 }
 
 func (r RepositoryRelease) String() string {
@@ -56,6 +57,7 @@ type ReleaseAsset struct {
 	UpdatedAt          *Timestamp `json:"updated_at,omitempty"`
 	BrowserDownloadURL *string    `json:"browser_download_url,omitempty"`
 	Uploader           *User      `json:"uploader,omitempty"`
+	NodeID             *string    `json:"node_id,omitempty"`
 }
 
 func (r ReleaseAsset) String() string {
@@ -77,6 +79,9 @@ func (s *RepositoriesService) ListReleases(ctx context.Context, owner, repo stri
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
 	var releases []*RepositoryRelease
 	resp, err := s.client.Do(ctx, req, &releases)
 	if err != nil {
@@ -115,6 +120,9 @@ func (s *RepositoriesService) getSingleRelease(ctx context.Context, url string)
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
 	release := new(RepositoryRelease)
 	resp, err := s.client.Do(ctx, req, release)
 	if err != nil {
@@ -134,6 +142,9 @@ func (s *RepositoriesService) CreateRelease(ctx context.Context, owner, repo str
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
 	r := new(RepositoryRelease)
 	resp, err := s.client.Do(ctx, req, r)
 	if err != nil {
@@ -153,6 +164,9 @@ func (s *RepositoriesService) EditRelease(ctx context.Context, owner, repo strin
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
 	r := new(RepositoryRelease)
 	resp, err := s.client.Do(ctx, req, r)
 	if err != nil {
@@ -189,6 +203,9 @@ func (s *RepositoriesService) ListReleaseAssets(ctx context.Context, owner, repo
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
 	var assets []*ReleaseAsset
 	resp, err := s.client.Do(ctx, req, &assets)
 	if err != nil {
@@ -208,6 +225,9 @@ func (s *RepositoriesService) GetReleaseAsset(ctx context.Context, owner, repo s
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
 	asset := new(ReleaseAsset)
 	resp, err := s.client.Do(ctx, req, asset)
 	if err != nil {
@@ -231,7 +251,10 @@ func (s *RepositoriesService) DownloadReleaseAsset(ctx context.Context, owner, r
 	if err != nil {
 		return nil, "", err
 	}
-	req.Header.Set("Accept", defaultMediaType)
+
+	// TODO: remove custom Accept header when APIs fully launch.
+	acceptHeaders := []string{defaultMediaType, mediaTypeGraphQLNodeIDPreview}
+	req.Header.Set("Accept", strings.Join(acceptHeaders, ", "))
 
 	s.client.clientMu.Lock()
 	defer s.client.clientMu.Unlock()
@@ -272,6 +295,9 @@ func (s *RepositoriesService) EditReleaseAsset(ctx context.Context, owner, repo
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
 	asset := new(ReleaseAsset)
 	resp, err := s.client.Do(ctx, req, asset)
 	if err != nil {
@@ -318,6 +344,9 @@ func (s *RepositoriesService) UploadReleaseAsset(ctx context.Context, owner, rep
 		return nil, nil, err
 	}
 
+	// TODO: remove custom Accept header when this API fully launches.
+	req.Header.Set("Accept", mediaTypeGraphQLNodeIDPreview)
+
 	asset := new(ReleaseAsset)
 	resp, err := s.client.Do(ctx, req, asset)
 	if err != nil {


Test patch:
diff --git a/github/apps_test.go b/github/apps_test.go
index f306e1a9..d1ebde48 100644
--- a/github/apps_test.go
+++ b/github/apps_test.go
@@ -66,7 +66,7 @@ func TestAppsService_ListInstallations(t *testing.T) {
 			"page":     "1",
 			"per_page": "2",
 		})
-		fmt.Fprint(w, `[{"id":1}]`)
+		fmt.Fprint(w, `[{"id":1, "app_id":1}]`)
 	})
 
 	opt := &ListOptions{Page: 1, PerPage: 2}
@@ -75,7 +75,7 @@ func TestAppsService_ListInstallations(t *testing.T) {
 		t.Errorf("Apps.ListInstallations returned error: %v", err)
 	}
 
-	want := []*Installation{{ID: Int64(1)}}
+	want := []*Installation{{ID: Int64(1), AppID: Int64(1)}}
 	if !reflect.DeepEqual(installations, want) {
 		t.Errorf("Apps.ListInstallations returned %+v, want %+v", installations, want)
 	}
@@ -88,7 +88,7 @@ func TestAppsService_GetInstallation(t *testing.T) {
 	mux.HandleFunc("/app/installations/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", mediaTypeIntegrationPreview)
-		fmt.Fprint(w, `{"id":1}`)
+		fmt.Fprint(w, `{"id":1, "app_id":1}`)
 	})
 
 	installation, _, err := client.Apps.GetInstallation(context.Background(), 1)
@@ -96,7 +96,7 @@ func TestAppsService_GetInstallation(t *testing.T) {
 		t.Errorf("Apps.GetInstallation returned error: %v", err)
 	}
 
-	want := &Installation{ID: Int64(1)}
+	want := &Installation{ID: Int64(1), AppID: Int64(1)}
 	if !reflect.DeepEqual(installation, want) {
 		t.Errorf("Apps.GetInstallation returned %+v, want %+v", installation, want)
 	}
@@ -113,7 +113,7 @@ func TestAppsService_ListUserInstallations(t *testing.T) {
 			"page":     "1",
 			"per_page": "2",
 		})
-		fmt.Fprint(w, `{"installations":[{"id":1}]}`)
+		fmt.Fprint(w, `{"installations":[{"id":1, "app_id":1}]}`)
 	})
 
 	opt := &ListOptions{Page: 1, PerPage: 2}
@@ -122,7 +122,7 @@ func TestAppsService_ListUserInstallations(t *testing.T) {
 		t.Errorf("Apps.ListUserInstallations returned error: %v", err)
 	}
 
-	want := []*Installation{{ID: Int64(1)}}
+	want := []*Installation{{ID: Int64(1), AppID: Int64(1)}}
 	if !reflect.DeepEqual(installations, want) {
 		t.Errorf("Apps.ListUserInstallations returned %+v, want %+v", installations, want)
 	}
diff --git a/github/orgs_members_test.go b/github/orgs_members_test.go
index 7b5cba85..83a63535 100644
--- a/github/orgs_members_test.go
+++ b/github/orgs_members_test.go
@@ -400,7 +400,9 @@ func TestOrganizationsService_ListPendingOrgInvitations(t *testing.T) {
       						"received_events_url": "https://api.github.com/users/other_user/received_events/privacy",
       						"type": "User",
       						"site_admin": false
-    					}
+						},
+						"team_count": 2,
+						"invitation_team_url": "https://api.github.com/organizations/2/invitations/1/teams"	  	
   				}
 			]`)
 	})
@@ -438,9 +440,96 @@ func TestOrganizationsService_ListPendingOrgInvitations(t *testing.T) {
 				Type:              String("User"),
 				SiteAdmin:         Bool(false),
 			},
+			TeamCount:         Int(2),
+			InvitationTeamURL: String("https://api.github.com/organizations/2/invitations/1/teams"),
 		}}
 
 	if !reflect.DeepEqual(invitations, want) {
 		t.Errorf("Organizations.ListPendingOrgInvitations returned %+v, want %+v", invitations, want)
 	}
 }
+
+func TestOrganizationsService_CreateOrgInvitation(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+	input := &CreateOrgInvitationOptions{
+		Email: String("octocat@github.com"),
+		Role:  String("direct_member"),
+		TeamID: []int64{
+			12,
+			26,
+		},
+	}
+
+	mux.HandleFunc("/orgs/o/invitations", func(w http.ResponseWriter, r *http.Request) {
+		v := new(CreateOrgInvitationOptions)
+		json.NewDecoder(r.Body).Decode(v)
+
+		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeOrganizationInvitationPreview)
+		if !reflect.DeepEqual(v, input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprintln(w, `[{"email": "octocat@github.com"}]`)
+
+	})
+
+	invitations, _, err := client.Organizations.CreateOrgInvitation(context.Background(), "o", input)
+	if err != nil {
+		t.Errorf("Organizations.CreateOrgInvitation returned error: %v", err)
+	}
+
+	want := []*Invitation{{Email: String("octocat@github.com")}}
+	if !reflect.DeepEqual(invitations, want) {
+		t.Errorf("Organizations.ListPendingOrgInvitations returned %+v, want %+v", invitations, want)
+	}
+}
+
+func TestOrganizationsService_ListOrgInvitationTeams(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/o/invitations/22/teams", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testFormValues(t, r, values{"page": "1"})
+		testHeader(t, r, "Accept", mediaTypeOrganizationInvitationPreview)
+		fmt.Fprint(w, `[
+			{
+				"id": 1,
+				"url": "https://api.github.com/teams/1",
+				"name": "Justice League",
+				"slug": "justice-league",
+				"description": "A great team.",
+				"privacy": "closed",
+				"permission": "admin",
+				"members_url": "https://api.github.com/teams/1/members{/member}",
+				"repositories_url": "https://api.github.com/teams/1/repos"
+			  }
+			]`)
+	})
+
+	opt := &ListOptions{Page: 1}
+	invitations, _, err := client.Organizations.ListOrgInvitationTeams(context.Background(), "o", "22", opt)
+	if err != nil {
+		t.Errorf("Organizations.ListOrgInvitationTeams returned error: %v", err)
+	}
+
+	want := []*Team{
+		{
+			ID:              Int64(1),
+			URL:             String("https://api.github.com/teams/1"),
+			Name:            String("Justice League"),
+			Slug:            String("justice-league"),
+			Description:     String("A great team."),
+			Privacy:         String("closed"),
+			Permission:      String("admin"),
+			MembersURL:      String("https://api.github.com/teams/1/members{/member}"),
+			RepositoriesURL: String("https://api.github.com/teams/1/repos"),
+		},
+	}
+
+	if !reflect.DeepEqual(invitations, want) {
+		t.Errorf("Organizations.ListOrgInvitationTeams returned %+v, want %+v", invitations, want)
+	}
+}
diff --git a/github/projects_test.go b/github/projects_test.go
index 9cb12aaa..d31ebce2 100644
--- a/github/projects_test.go
+++ b/github/projects_test.go
@@ -11,6 +11,7 @@ import (
 	"fmt"
 	"net/http"
 	"reflect"
+	"strings"
 	"testing"
 )
 
@@ -20,9 +21,10 @@ func TestProjectsService_UpdateProject(t *testing.T) {
 
 	input := &ProjectOptions{Name: "Project Name", Body: "Project body.", State: "open"}
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "PATCH")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		v := &ProjectOptions{}
 		json.NewDecoder(r.Body).Decode(v)
@@ -48,9 +50,10 @@ func TestProjectsService_GetProject(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
@@ -84,9 +87,10 @@ func TestProjectsService_ListProjectColumns(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/1/columns", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -107,9 +111,10 @@ func TestProjectsService_GetProjectColumn(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/columns/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
@@ -130,9 +135,10 @@ func TestProjectsService_CreateProjectColumn(t *testing.T) {
 
 	input := &ProjectColumnOptions{Name: "Column Name"}
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/1/columns", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		v := &ProjectColumnOptions{}
 		json.NewDecoder(r.Body).Decode(v)
@@ -160,9 +166,10 @@ func TestProjectsService_UpdateProjectColumn(t *testing.T) {
 
 	input := &ProjectColumnOptions{Name: "Column Name"}
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/columns/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "PATCH")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		v := &ProjectColumnOptions{}
 		json.NewDecoder(r.Body).Decode(v)
@@ -226,9 +233,10 @@ func TestProjectsService_ListProjectCards(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/columns/1/cards", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -249,9 +257,10 @@ func TestProjectsService_GetProjectCard(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/columns/cards/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
@@ -275,9 +284,10 @@ func TestProjectsService_CreateProjectCard(t *testing.T) {
 		ContentType: "Issue",
 	}
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/columns/1/cards", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		v := &ProjectCardOptions{}
 		json.NewDecoder(r.Body).Decode(v)
@@ -308,9 +318,10 @@ func TestProjectsService_UpdateProjectCard(t *testing.T) {
 		ContentType: "Issue",
 	}
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/projects/columns/cards/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "PATCH")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		v := &ProjectCardOptions{}
 		json.NewDecoder(r.Body).Decode(v)
diff --git a/github/pulls_reviewers_test.go b/github/pulls_reviewers_test.go
index 48a3bf0c..7c550e1b 100644
--- a/github/pulls_reviewers_test.go
+++ b/github/pulls_reviewers_test.go
@@ -20,7 +20,6 @@ func TestRequestReviewers(t *testing.T) {
 	mux.HandleFunc("/repos/o/r/pulls/1/requested_reviewers", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
 		testBody(t, r, `{"reviewers":["octocat","googlebot"],"team_reviewers":["justice-league","injustice-league"]}`+"\n")
-		testHeader(t, r, "Accept", mediaTypeTeamReviewPreview)
 		fmt.Fprint(w, `{"number":1}`)
 	})
 
@@ -41,7 +40,6 @@ func TestRemoveReviewers(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/pulls/1/requested_reviewers", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "DELETE")
-		testHeader(t, r, "Accept", mediaTypeTeamReviewPreview)
 		testBody(t, r, `{"reviewers":["octocat","googlebot"],"team_reviewers":["justice-league"]}`+"\n")
 	})
 
@@ -57,7 +55,6 @@ func TestListReviewers(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/pulls/1/requested_reviewers", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeTeamReviewPreview)
 		fmt.Fprint(w, `{"users":[{"login":"octocat","id":1}],"teams":[{"id":1,"name":"Justice League"}]}`)
 	})
 
diff --git a/github/reactions_test.go b/github/reactions_test.go
index 2a43a8b8..5342b18a 100644
--- a/github/reactions_test.go
+++ b/github/reactions_test.go
@@ -9,6 +9,7 @@ import (
 	"context"
 	"net/http"
 	"reflect"
+	"strings"
 	"testing"
 )
 
@@ -16,9 +17,10 @@ func TestReactionsService_ListCommentReactions(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		w.WriteHeader(http.StatusOK)
 		w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
@@ -37,9 +39,10 @@ func TestReactionsService_CreateCommentReaction(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		w.WriteHeader(http.StatusCreated)
 		w.Write([]byte(`{"id":1,"user":{"login":"l","id":2},"content":"+1"}`))
@@ -59,9 +62,10 @@ func TestReactionsService_ListIssueReactions(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/issues/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		w.WriteHeader(http.StatusOK)
 		w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
@@ -80,9 +84,10 @@ func TestReactionsService_CreateIssueReaction(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/issues/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		w.WriteHeader(http.StatusCreated)
 		w.Write([]byte(`{"id":1,"user":{"login":"l","id":2},"content":"+1"}`))
@@ -102,9 +107,10 @@ func TestReactionsService_ListIssueCommentReactions(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/issues/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		w.WriteHeader(http.StatusOK)
 		w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
@@ -123,9 +129,10 @@ func TestReactionsService_CreateIssueCommentReaction(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/issues/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		w.WriteHeader(http.StatusCreated)
 		w.Write([]byte(`{"id":1,"user":{"login":"l","id":2},"content":"+1"}`))
@@ -145,9 +152,10 @@ func TestReactionsService_ListPullRequestCommentReactions(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/pulls/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		w.WriteHeader(http.StatusOK)
 		w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
@@ -166,9 +174,10 @@ func TestReactionsService_CreatePullRequestCommentReaction(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeReactionsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/pulls/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeReactionsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		w.WriteHeader(http.StatusCreated)
 		w.Write([]byte(`{"id":1,"user":{"login":"l","id":2},"content":"+1"}`))
diff --git a/github/repos_projects_test.go b/github/repos_projects_test.go
index c0392254..4a585040 100644
--- a/github/repos_projects_test.go
+++ b/github/repos_projects_test.go
@@ -11,6 +11,7 @@ import (
 	"fmt"
 	"net/http"
 	"reflect"
+	"strings"
 	"testing"
 )
 
@@ -18,9 +19,10 @@ func TestRepositoriesService_ListProjects(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/projects", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -43,9 +45,10 @@ func TestRepositoriesService_CreateProject(t *testing.T) {
 
 	input := &ProjectOptions{Name: "Project Name", Body: "Project body."}
 
+	acceptHeaders := []string{mediaTypeProjectsPreview, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/projects", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 
 		v := &ProjectOptions{}
 		json.NewDecoder(r.Body).Decode(v)
diff --git a/github/repos_releases_test.go b/github/repos_releases_test.go
index 126a4284..65331198 100644
--- a/github/repos_releases_test.go
+++ b/github/repos_releases_test.go
@@ -24,6 +24,7 @@ func TestRepositoriesService_ListReleases(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/releases", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -45,6 +46,7 @@ func TestRepositoriesService_GetRelease(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/releases/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		fmt.Fprint(w, `{"id":1,"author":{"login":"l"}}`)
 	})
 
@@ -65,6 +67,7 @@ func TestRepositoriesService_GetLatestRelease(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/releases/latest", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		fmt.Fprint(w, `{"id":3}`)
 	})
 
@@ -85,6 +88,7 @@ func TestRepositoriesService_GetReleaseByTag(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/releases/tags/foo", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		fmt.Fprint(w, `{"id":13}`)
 	})
 
@@ -110,6 +114,7 @@ func TestRepositoriesService_CreateRelease(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "POST")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -138,6 +143,7 @@ func TestRepositoriesService_EditRelease(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "PATCH")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -174,6 +180,7 @@ func TestRepositoriesService_ListReleaseAssets(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/releases/1/assets", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		testFormValues(t, r, values{"page": "2"})
 		fmt.Fprint(w, `[{"id":1}]`)
 	})
@@ -195,6 +202,7 @@ func TestRepositoriesService_GetReleaseAsset(t *testing.T) {
 
 	mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		fmt.Fprint(w, `{"id":1}`)
 	})
 
@@ -212,9 +220,10 @@ func TestRepositoriesService_DownloadReleaseAsset_Stream(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{defaultMediaType, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", defaultMediaType)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		w.Header().Set("Content-Type", "application/octet-stream")
 		w.Header().Set("Content-Disposition", "attachment; filename=hello-world.txt")
 		fmt.Fprint(w, "Hello World")
@@ -238,9 +247,10 @@ func TestRepositoriesService_DownloadReleaseAsset_Redirect(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{defaultMediaType, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", defaultMediaType)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		http.Redirect(w, r, "/yo", http.StatusFound)
 	})
 
@@ -258,9 +268,10 @@ func TestRepositoriesService_DownloadReleaseAsset_APIError(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
+	acceptHeaders := []string{defaultMediaType, mediaTypeGraphQLNodeIDPreview}
 	mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
-		testHeader(t, r, "Accept", defaultMediaType)
+		testHeader(t, r, "Accept", strings.Join(acceptHeaders, ", "))
 		w.WriteHeader(http.StatusNotFound)
 		fmt.Fprint(w, `{"message":"Not Found","documentation_url":"https://developer.github.com/v3"}`)
 	})
@@ -291,6 +302,7 @@ func TestRepositoriesService_EditReleaseAsset(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(v)
 
 		testMethod(t, r, "PATCH")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}
@@ -329,6 +341,7 @@ func TestRepositoriesService_UploadReleaseAsset(t *testing.T) {
 		testMethod(t, r, "POST")
 		testHeader(t, r, "Content-Type", "text/plain; charset=utf-8")
 		testHeader(t, r, "Content-Length", "12")
+		testHeader(t, r, "Accept", mediaTypeGraphQLNodeIDPreview)
 		testFormValues(t, r, values{"name": "n"})
 		testBody(t, r, "Upload me !\n")