[metadata]
description: You can generate a user access token for your GitHub App in order to attribute app activity to a user.
google-site-verification: c1kuD-K2HIVF635lypcsWPoD4kilo5-jA_wBFyT4uMY
og:image: https://docs.github.com/assets/cb-345/images/social-cards/apps.png
og:site_name: GitHub Docs
og:title: Generating a user access token for a GitHub App - GitHub Docs
og:type: article
og:url: https://docs-internal.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app
page-document-type: article
path-article: apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app
path-language: en
path-product: apps
path-version: free-pro-team@latest
status: 200
twitter:card: summary
twitter:description: You can generate a user access token for your GitHub App in order to attribute app activity to a user.
twitter:domain: docs-internal.github.com
twitter:image: https://docs.github.com/assets/cb-345/images/social-cards/apps.png
twitter:title: Generating a user access token for a GitHub App - GitHub Docs
twitter:url: https://docs-internal.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app
viewport: width=device-width, initial-scale=1

[document-links]
About GitHub Marketplace for apps: /en/apps/github-marketplace/github-marketplace-overview/about-github-marketplace-for-apps
About authentication: /en/apps/creating-github-apps/authenticating-with-a-github-app/about-authentication-with-a-github-app
About creating apps: /en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps
About marketplace badges: /en/apps/github-marketplace/github-marketplace-overview/about-marketplace-badges
About the user authorization callback URL: /en/apps/creating-github-apps/registering-a-github-app/about-the-user-authorization-callback-url
About using apps: /en/apps/using-github-apps/about-using-github-apps
About writing GitHub App code: /en/apps/creating-github-apps/writing-code-for-a-github-app/about-writing-code-for-a-github-app
Activate optional features: /en/apps/maintaining-github-apps/activating-optional-features-for-github-apps
Activate optional features: /en/apps/oauth-apps/maintaining-oauth-apps/activating-optional-features-for-oauth-apps
Activating optional features for GitHub Apps: /en/apps/maintaining-github-apps/activating-optional-features-for-github-apps
App manifest: /en/apps/sharing-github-apps/registering-a-github-app-from-a-manifest
App query parameters: /en/apps/sharing-github-apps/registering-a-github-app-using-url-parameters
Approve new permissions: /en/apps/using-github-apps/approving-updated-permissions-for-a-github-app
Apps: /en/apps
Ask the GitHub community: https://github.com/orgs/community/discussions
Authenticate as an app: /en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app
Authenticate as an installation: /en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation
Authenticate in Actions workflow: /en/apps/creating-github-apps/authenticating-with-a-github-app/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow
Authenticate on behalf of users: /en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-with-a-github-app-on-behalf-of-a-user
Authenticate with a GitHub App: /en/apps/creating-github-apps/authenticating-with-a-github-app
Authenticate with an OAuth app: /en/apps/oauth-apps/building-oauth-apps/authenticating-to-the-rest-api-with-an-oauth-app
Authorize: /en/apps/using-github-apps/authorizing-github-apps
Authorizing OAuth apps: /en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps
Authorizing OAuth apps: /en/apps/oauth-apps/using-oauth-apps/authorizing-oauth-apps
Best practices for creating a GitHub App: /en/apps/creating-github-apps/about-creating-github-apps/best-practices-for-creating-a-github-app
Best practices: /en/apps/creating-github-apps/about-creating-github-apps/best-practices-for-creating-a-github-app
Best practices: /en/apps/oauth-apps/building-oauth-apps/best-practices-for-creating-an-oauth-app
Billing customers: /en/apps/github-marketplace/selling-your-app-on-github-marketplace/billing-customers
Blog: https://github.blog
Build CI checks: /en/apps/creating-github-apps/writing-code-for-a-github-app/building-ci-checks-with-a-github-app
Build a "Login" button: /en/apps/creating-github-apps/writing-code-for-a-github-app/building-a-login-with-github-button-with-a-github-app
Build a CLI: /en/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app
Building a "Login with GitHub" button with a GitHub App: /en/apps/creating-github-apps/writing-code-for-a-github-app/building-a-login-with-github-button-with-a-github-app
Building a CLI with a GitHub App: /en/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app
Callback URLs: /en/apps/creating-github-apps/registering-a-github-app/about-the-user-authorization-callback-url
Contact support: https://support.github.com
Create custom badges: /en/apps/oauth-apps/building-oauth-apps/creating-a-custom-badge-for-your-oauth-app
Creating GitHub Apps: /en/apps/creating-github-apps
Creating an OAuth app: /en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app
Custom badge: /en/apps/creating-github-apps/registering-a-github-app/creating-a-custom-badge-for-your-github-app
Customer experience best practice: /en/apps/github-marketplace/creating-apps-for-github-marketplace/customer-experience-best-practices-for-apps
Delete your app: /en/apps/maintaining-github-apps/deleting-a-github-app
Delete your listing: /en/apps/github-marketplace/listing-an-app-on-github-marketplace/deleting-your-app-listing-from-github-marketplace
Deleting an OAuth app: /en/apps/oauth-apps/maintaining-oauth-apps/deleting-an-oauth-app
Draft an app listing: /en/apps/github-marketplace/listing-an-app-on-github-marketplace/drafting-a-listing-for-your-app
Expert services: https://services.github.com
Expiring user-to-server access tokens for GitHub Apps: https://developer.github.com/changes/2020-04-30-expiring-user-to-server-access-tokens-for-github-apps
Generate a JWT: /en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app
Generate a user access token: /en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app
Generate an installation access token: /en/apps/creating-github-apps/authenticating-with-a-github-app/generating-an-installation-access-token-for-a-github-app
GitHub App managers: /en/apps/maintaining-github-apps/about-github-app-managers
GitHub App versus other options: /en/apps/creating-github-apps/about-creating-github-apps/deciding-when-to-build-a-github-app
GitHub Apps & OAuth apps: /en/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps
GitHub Docs: /en
Handling plan changes: /en/apps/github-marketplace/using-the-github-marketplace-api-in-your-app/handling-plan-changes
Home: /en
Install app organization: /en/apps/oauth-apps/using-oauth-apps/installing-an-oauth-app-in-your-organization
Install app personal account: /en/apps/oauth-apps/using-oauth-apps/installing-an-oauth-app-in-your-personal-account
Install from Marketplace for org: /en/apps/using-github-apps/installing-a-github-app-from-github-marketplace-for-your-organizations
Install from Marketplace for user: /en/apps/using-github-apps/installing-a-github-app-from-github-marketplace-for-your-personal-account
Install from third party: /en/apps/using-github-apps/installing-a-github-app-from-a-third-party
Install your own app: /en/apps/using-github-apps/installing-your-own-github-app
Learn how to contribute: /contributing
Listing requirements: /en/apps/github-marketplace/creating-apps-for-github-marketplace/requirements-for-listing-an-app
Make a contribution: https://github.com/github/docs/blob/main/content/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app.md
Manage allowed IP addresses: /en/apps/maintaining-github-apps/managing-allowed-ip-addresses-for-a-github-app
Manage private keys: /en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps
Migrate from OAuth apps: /en/apps/creating-github-apps/about-creating-github-apps/migrating-oauth-apps-to-github-apps
Modify app settings: /en/apps/maintaining-github-apps/modifying-a-github-app-registration
Modifying a GitHub App registration: /en/apps/maintaining-github-apps/modifying-a-github-app-registration
Modifying a GitHub App registration: /en/apps/maintaining-github-apps/modifying-a-github-app-registration#navigating-to-your-github-app-settings
Modifying an OAuth app: /en/apps/oauth-apps/maintaining-oauth-apps/modifying-an-oauth-app
New purchases & free trials: /en/apps/github-marketplace/using-the-github-marketplace-api-in-your-app/handling-new-purchases-and-free-trials
OAuth 2.0 Device Authorization Grant: https://datatracker.ietf.org/doc/html/rfc8628
OAuth 2.0 and OIDC Discovery documents: /en/apps/github-authentication-discovery-endpoints
Overview: /en/apps/overview
PKCE RFC: https://datatracker.ietf.org/doc/html/rfc7636
Permissions: /en/apps/creating-github-apps/registering-a-github-app/choosing-permissions-for-a-github-app
Plan cancellations: /en/apps/github-marketplace/using-the-github-marketplace-api-in-your-app/handling-plan-cancellations
Pricing plans for apps: /en/apps/github-marketplace/selling-your-app-on-github-marketplace/pricing-plans-for-github-marketplace-apps
Pricing: https://github.com/pricing
Privacy policy: /en/site-policy/privacy-policies/github-privacy-statement
Privacy: /en/site-policy/privacy-policies/github-privacy-statement
Privileged apps: /en/apps/oauth-apps/using-oauth-apps/privileged-oauth-apps
Privileged apps: /en/apps/using-github-apps/privileged-github-apps
Publisher verification: /en/apps/github-marketplace/github-marketplace-overview/applying-for-publisher-verification-for-your-organization
Quickstart: /en/apps/creating-github-apps/writing-code-for-a-github-app/quickstart
REST API endpoints for GitHub App installations: /en/rest/apps/installations
REST API: /en/apps/github-marketplace/using-the-github-marketplace-api-in-your-app/rest-endpoints-for-the-github-marketplace-api
Rate limits for GitHub Apps: /en/apps/creating-github-apps/registering-a-github-app/rate-limits-for-github-apps
Rate limits: /en/apps/creating-github-apps/registering-a-github-app/rate-limits-for-github-apps
Rate limits: /en/apps/oauth-apps/building-oauth-apps/rate-limits-for-oauth-apps
Receive payment: /en/apps/github-marketplace/selling-your-app-on-github-marketplace/receiving-payment-for-app-purchases
Refresh user access tokens: /en/apps/creating-github-apps/authenticating-with-a-github-app/refreshing-user-access-tokens
Refreshing user access tokens: /en/apps/creating-github-apps/authenticating-with-a-github-app/refreshing-user-access-tokens
Register a GitHub App: /en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app
Request for org: /en/apps/using-github-apps/requesting-a-github-app-from-your-organization-owner
Respond to webhooks: /en/apps/creating-github-apps/writing-code-for-a-github-app/building-a-github-app-that-responds-to-webhook-events
Review OAuth apps: /en/apps/oauth-apps/using-oauth-apps/reviewing-your-authorized-oauth-apps
Review installations: /en/apps/using-github-apps/reviewing-and-modifying-installed-github-apps
Review your authorizations: /en/apps/using-github-apps/reviewing-and-revoking-authorization-of-github-apps
SAML and GitHub Apps: /en/enterprise-cloud@latest/apps/using-github-apps/saml-and-github-apps
Scopes for OAuth apps: /en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps
Security best practice: /en/apps/github-marketplace/creating-apps-for-github-marketplace/security-best-practices-for-apps-on-github-marketplace
Set listing pricing plans: /en/apps/github-marketplace/listing-an-app-on-github-marketplace/setting-pricing-plans-for-your-listing
Setup URL: /en/apps/creating-github-apps/registering-a-github-app/about-the-setup-url
Share with GHES: /en/apps/sharing-github-apps/making-your-github-app-available-for-github-enterprise-server
Share your app: /en/apps/sharing-github-apps/sharing-your-github-app
Status: https://www.githubstatus.com/
Submit your listing: /en/apps/github-marketplace/listing-an-app-on-github-marketplace/submitting-your-listing-for-publication
Suspend an installation: /en/apps/maintaining-github-apps/suspending-a-github-app-installation
Terms: /en/site-policy/github-terms/github-terms-of-service
Testing your app: /en/apps/github-marketplace/using-the-github-marketplace-api-in-your-app/testing-your-app
Third-party applications: /en/apps/oauth-apps/using-oauth-apps/connecting-with-third-party-applications
Token expiration and revocation: /en/authentication/keeping-your-account-and-data-secure/token-expiration-and-revocation
Transfer ownership: /en/apps/maintaining-github-apps/transferring-ownership-of-a-github-app
Transfer ownership: /en/apps/oauth-apps/maintaining-oauth-apps/transferring-ownership-of-an-oauth-app
Troubleshoot authorization: /en/apps/oauth-apps/maintaining-oauth-apps/troubleshooting-authorization-request-errors
Troubleshoot token request: /en/apps/oauth-apps/maintaining-oauth-apps/troubleshooting-oauth-app-access-token-request-errors
Verifying your email address: /en/account-and-profile/how-tos/email-preferences/verifying-your-email-address
View listing metrics: /en/apps/github-marketplace/creating-apps-for-github-marketplace/viewing-metrics-for-your-listing
View listing transactions: /en/apps/github-marketplace/creating-apps-for-github-marketplace/viewing-transactions-for-your-listing
Visibility: /en/apps/creating-github-apps/registering-a-github-app/making-a-github-app-public-or-private
Webhook events and payloads: /en/webhooks/webhook-events-and-payloads#github_app_authorization
Webhook events: /en/apps/github-marketplace/using-the-github-marketplace-api-in-your-app/webhook-events-for-the-github-marketplace-api
Webhooks for plan changes: /en/apps/github-marketplace/listing-an-app-on-github-marketplace/configuring-a-webhook-to-notify-you-of-plan-changes
Webhooks: /en/apps/creating-github-apps/registering-a-github-app/using-webhooks-with-github-apps
Write listing descriptions: /en/apps/github-marketplace/listing-an-app-on-github-marketplace/writing-a-listing-description-for-your-app
https:/ / github.com/ login/ device: https://github.com/login/device
https://github.com/login/device: https://github.com/login/device

[content]
Generating a user access token for a GitHub App - GitHub Docs
Skip to main content
GitHub Docs
Version:
Free, Pro, & Team
Search or ask Copilot
Search or ask
Copilot
Select language: current language is English
Search or ask Copilot
Search or ask
Copilot
Open menu
Collapse sidebar
Expand sidebar
Scroll breadcrumbs left
Home
Apps
Creating GitHub Apps
Authenticate with a GitHub App
Generate a user access token
Scroll breadcrumbs right
Apps
Overview
Using GitHub Apps
About using apps
Install from Marketplace for user
Install from Marketplace for org
Install from third party
Install your own app
Request for org
Authorize
Approve new permissions
Review your authorizations
Review installations
Privileged apps
Creating GitHub Apps
About creating GitHub Apps
About creating apps
GitHub App versus other options
Best practices
Migrate from OAuth apps
Registering a GitHub App
Register a GitHub App
Callback URLs
Setup URL
Permissions
Webhooks
Visibility
Rate limits
Custom badge
Authenticate with a GitHub App
About authentication
Authenticate as an app
Authenticate as an installation
Authenticate on behalf of users
Manage private keys
Generate a JWT
Generate an installation access token
Generate a user access token
Refresh user access tokens
Authenticate in Actions workflow
Writing code for a GitHub App
About writing GitHub App code
Quickstart
Respond to webhooks
Build a "Login" button
Build a CLI
Build CI checks
Sharing GitHub Apps
Share your app
Share with GHES
App manifest
App query parameters
Maintaining GitHub Apps
Modify app settings
Activate optional features
GitHub App managers
Manage allowed IP addresses
Suspend an installation
Transfer ownership
Delete your app
GitHub Marketplace
Overview
About GitHub Marketplace for apps
About marketplace badges
Publisher verification
Create Marketplace apps
Listing requirements
Security best practice
Customer experience best practice
View listing metrics
View listing transactions
Marketplace API usage
REST API
Webhook events
Testing your app
New purchases & free trials
Handling plan changes
Plan cancellations
List an app on the Marketplace
Draft an app listing
Write listing descriptions
Set listing pricing plans
Webhooks for plan changes
Submit your listing
Delete your listing
Sell apps on the Marketplace
Pricing plans for apps
Billing customers
Receive payment
OAuth apps
Using OAuth apps
Install app personal account
Install app organization
Authorizing OAuth apps
Review OAuth apps
Third-party applications
Privileged apps
Building OAuth apps
GitHub Apps & OAuth apps
Rate limits
Creating an OAuth app
Authenticate with an OAuth app
Authorizing OAuth apps
Scopes for OAuth apps
Create custom badges
Best practices
Maintaining OAuth apps
Modifying an OAuth app
Activate optional features
Transfer ownership
Troubleshoot authorization
Troubleshoot token request
Deleting an OAuth app
OAuth 2.0 and OIDC Discovery documents
Generating a user access token for a GitHub App
You can generate a user access token for your GitHub App in order to attribute app activity to a user.
Copy as Markdown
In this article
About user access tokens
Using the web application flow to generate a user access token
Using the device flow to generate a user access token
Generating a user access token when a user installs your app
Using a refresh token to generate a user access token
Troubleshooting
About user access tokens
Note
User access tokens that expire are currently an optional feature and are subject to change. To opt in or out of the token expiration feature, see
Activating optional features for GitHub Apps
. For more information, see
Expiring user-to-server access tokens for GitHub Apps
.
If a user reports that they cannot see resources owned by their organization after authorizing your GitHub App and the organization uses SAML SSO, instruct the user to start an active SAML session for their organization before reauthorizing. For more information, see
SAML and GitHub Apps
in the GitHub Enterprise Cloud documentation.
A user access token is a type of OAuth token. Unlike a traditional OAuth token, the user access token does not use scopes. Instead, it uses fine-grained permissions. A user access token only has permissions that both the user and the app have. For example, if the app was granted permission to write the contents of a repository, but the user can only read the contents, then the user access token can only read the contents.
Similarly, a user access token can only access resources that both the user and app can access. For example, if an app is granted access to repository
A
and
B
, and the user can access repository
B
and
C
, the user access token can access repository
B
but not
A
or
C
. You can use the REST API to check which installations and which repositories within an installation a user access token can access. For more information, see
GET /user/installations
and
GET /user/installations/{installation_id}/repositories
in
REST API endpoints for GitHub App installations
.
When you make API requests with a user access token, the rate limits for user access tokens apply. For more information, see
Rate limits for GitHub Apps
.
By default, the user access token expires after 8 hours. You can use a refresh token to regenerate a user access token. For more information, see
Refreshing user access tokens
.
Users can revoke their authorization of a GitHub App. For more information, see
Token expiration and revocation
. If a user revokes their authorization of a GitHub App, the app will receive the
github_app_authorization
webhook. GitHub Apps cannot unsubscribe from this event. If your app receives this webhook, you should stop calling the API on behalf of the user who revoked the token. If your app continues to use a revoked access token, it will receive the
401 Bad Credentials
error. For more information about this webhook, see
Webhook events and payloads
.
You should keep user access tokens and refresh tokens secure. For more information, see
Best practices for creating a GitHub App
.
Using the web application flow to generate a user access token
If your app runs in the browser, you should use the web application flow to generate a user access token. For a tutorial about using the web application flow, see
Building a "Login with GitHub" button with a GitHub App
.
Direct the user to this URL, and add any necessary query parameters from the following list of parameters:
https://github.com/login/oauth/authorize
. For example, this URL specifies the
client_id
and
state
parameters:
https://github.com/login/oauth/authorize?client_id=12345&state=abcdefg
.
Query parameter
Type
Required?
Description
client_id
string
Required
The client ID for your GitHub App. The client ID is different from the app ID. You can find the client ID on the settings page for your app. For more information about navigating to the settings page for your GitHub App, see
Modifying a GitHub App registration
.
redirect_uri
string
Strongly recommended
The URL in your application where users will be sent after authorization. This must be a match to one of the URLs you provided as a "Callback URL" in your app's settings and can't contain any additional parameters. For more information, see
About the user authorization callback URL
.
state
string
Strongly recommended
When specified, the value should contain a random string to protect against forgery attacks, and it can also contain any other arbitrary data.
code_challenge
string
Strongly recommended
Used to secure the authentication flow with PKCE (Proof Key for Code Exchange). Required if
code_challenge_
method
is included. Must be a 43 character SHA-256 hash of a random string generated by the client. See the
PKCE RFC
for more details about this security extension.
code_challenge_
method
string
Strongly recommended
Used to secure the authentication flow with PKCE (Proof Key for Code Exchange). Required if
code_challenge
is included. Must be
S256
- the
plain
code challenge method is not supported.
login
string
Optional
When specified, the web application flow will prompt users with a specific account they can use for signing in and authorizing your app.
allow_signup
boolean
Optional
Whether unauthenticated users will be offered an option to sign up for GitHub during the OAuth flow. The default is
true
. Use
false
when a policy prohibits signups.
prompt
string
Optional
Forces the account picker to appear if set to
select_account
. The account picker will also appear if the application has a non-HTTP redirect URI or if the user has multiple accounts signed in.
If the user accepts your authorization request, GitHub will redirect the user to one of the callback URLs in your app settings, and provide a
code
query parameter you can use in the next step to create a user access token. If you specified
redirect_uri
in the previous step, that callback URL will be used. Otherwise, the first callback URL on your app's settings page will be used.
If you specified the
state
parameter in the previous step, GitHub will also include a
state
parameter. If the
state
parameter does not match the
state
parameter that you sent in the previous step, the request cannot be trusted, and the web application flow should be aborted.
Exchange the
code
from the previous step for a user access token by making a
POST
request to this URL, along with the following query parameters:
https://github.com/login/oauth/access_token
Query parameter
Type
Description
client_id
string
Required.
The client ID for your GitHub App. The client ID is different from the app ID. You can find the client ID on the settings page for your app. For more information about navigating to the settings page for your GitHub App, see
Modifying a GitHub App registration
.
client_secret
string
Required.
The client secret for your GitHub App. You can generate a client secret on the settings page for your app.
code
string
Required.
The code you received in the previous step.
redirect_uri
string
The URL in your application where users will be sent after authorization. This must match one of the URLs you provided as a "Callback URL" when setting up your GitHub App. For more information, see
About the user authorization callback URL
.
code_verifier
string
Strongly recommended.
Used to secure the authentication flow with PKCE (Proof Key for Code Exchange). Required if
code_challenge
was sent during the user authorization. Must be the original value used to generate the
code_challenge
in the authorization request. This can be stored in a cookie alongside the
state
parameter or in a session variable during authentication, depending on your application architecture.
repository_id
string
The ID of a single repository that the user access token can access. If the GitHub App or user cannot access the repository, this will be ignored. Use this parameter to restrict the access of the user access token further.
GitHub will give a response that includes the following parameters:
Response parameter
Type
Description
access_token
string
The user access token. The token starts with
ghu_
.
expires_in
integer
The number of seconds until
access_token
expires. If you disabled expiration of user access tokens, this parameter will be omitted. The value will always be
28800
(8 hours).
refresh_token
string
The refresh token. If you disabled expiration of user access tokens, this parameter will be omitted. The token starts with
ghr_
.
refresh_token_
expires_in
integer
The number of seconds until
refresh_token
expires. If you disabled expiration of user access tokens, this parameter will be omitted. The value will always be
15897600
(6 months).
scope
string
The scopes that the token has. This value will always be an empty string. Unlike a traditional OAuth token, the user access token is limited to the permissions that both your app and the user have.
token_type
string
The type of token. The value will always be
bearer
.
Use the user access token from the previous step to make API requests on behalf of the user. Include the user access token in the
Authorization
header of an API request. For example:
curl --request GET \ --url "https://api.github.com/user" \ --header "Accept: application/vnd.github+json" \ --header "Authorization: Bearer USER_ACCESS_TOKEN" \ --header "X-GitHub-Api-Version: 2026-03-10"
Using the device flow to generate a user access token
If your app is headless or does not have access to a browser, you should use the device flow to generate a user access token. For example, CLI tools, simple Raspberry Pis, and desktop applications should use the device flow. For a tutorial that uses device flow, see
Building a CLI with a GitHub App
.
Before you can use the device flow, you must first enable it in your app's settings. For more information on enabling device flow, see
Modifying a GitHub App registration
.
The device flow uses the
OAuth 2.0 Device Authorization Grant
.
Send a
POST
request to
https://github.com/login/device/code
along with a
client_id
query parameter. The client ID is different from the app ID. You can find the client ID on the settings page for your app. For more information about navigating to the settings page for your GitHub App, see
Modifying a GitHub App registration
.
GitHub will give a response that includes the following query parameters:
Response parameter
Type
Description
device_code
string
A verification code that is used to verify the device. This code is 40 characters long.
user_code
string
A verification code that your application should display so that the user can enter the code in a browser. This code is 8 characters with a hyphen in the middle. For example,
WDJB-MJHT
.
verification_uri
string
The URL where users need to enter their
user_code
. The URL is:
https:/
/
github.com/
login/
device
.
expires_in
integer
The number of seconds before the
device_code
and
user_code
expire. The default is 900 seconds (15 minutes).
interval
integer
The minimum number of seconds that must pass before you can make a new access token request (
POST https:/
/
github.com/
login/
oauth/
access_token
) to complete the device authorization. If you make a request before this interval passes, then you will hit the rate limit and receive a
slow_down
error. The default is 5 seconds.
Prompt the user to enter the
user_code
from the previous step at
https://github.com/login/device
.
If the user does not enter the code before the
expires_in
time passes, the code will be invalid. In this case, you should restart the device flow.
Poll
POST https://github.com/login/oauth/access_token
along with the
client_id
,
device_code
, and
grant_type
query parameters (described below) until the device and user codes expire or the user has successfully authorized the app by entering the
user_code
.
Query parameter
Type
Description
client_id
string
Required.
The client ID for your GitHub App.
device_code
string
Required.
The device verification code you received in the previous step.
grant_type
string
Required.
The grant type must be
urn:ietf:params:oauth:grant-type:device_
code
.
repository_id
string
The ID of a single repository that the user access token can access. If the GitHub App or user cannot access the repository, this will be ignored. Use this parameter to restrict the access of the user access token further.
Do not poll this endpoint at a higher frequency than the frequency indicated by
interval
. If you do, you will hit the rate limit and receive a
slow_down
error. The
slow_down
error response adds 5 seconds to the last
interval
.
Until the user enters the code, GitHub will respond with a 200 status and an
error
response query parameter.
Error name
Description
authorization_
pending
This error occurs when the authorization request is pending and the user hasn't entered the user code yet. The app is expected to keep polling the
POST https:/
/
github.com/
login/
oauth/
access_token
at a frequency no faster than the frequency specified by
interval
.
slow_down
When you receive the
slow_down
error, 5 extra seconds are added to the minimum
interval
or timeframe required between your requests using
POST https:/
/
github.com/
login/
oauth/
access_token
. For example, if the starting interval required at least 5 seconds between requests and you get a
slow_down
error response, you must now wait a minimum of 10 seconds before making a new request for a token. The error response includes the new
interval
that you must use.
expired_token
If the device code expired, then you will see the
token_expired
error. You must make a new request for a device code.
unsupported_grant_
type
The grant type must be
urn:ietf:params:oauth:grant-type:device_
code
and included as an input parameter when you poll the OAuth token request
POST https:/
/
github.com/
login/
oauth/
access_token
.
incorrect_client_
credentials
For the device flow, you must pass your app's client ID, which you can find on your app settings page. The client ID is different from the app ID and client secret.
incorrect_device_
code
The
device_code
provided is not valid.
access_denied
When a user clicks cancel during the authorization process, you'll receive an
access_denied
error, and the user won't be able to use the verification code again.
device_flow_disabled
Device flow has not been enabled in the app's settings. For more information on enabling device flow, see
Modifying a GitHub App registration
.
Once the user has entered the
user_code
, GitHub will give a response that includes the following query parameters:
Response parameter
Type
Description
access_token
string
The user access token. The token starts with
ghu_
.
expires_in
integer
The number of seconds until
access_token
expires. If you disabled expiration of user access tokens, this parameter will be omitted. The value will always be
28800
(8 hours).
refresh_token
string
The refresh token. If you disabled expiration of user access tokens, this parameter will be omitted. The token starts with
ghr_
.
refresh_token_
expires_in
integer
The number of seconds until
refresh_token
expires. If you disabled expiration of user access tokens, this parameter will be omitted. The value will always be
15897600
(6 months).
scope
string
The scopes that the token has. This value will always be an empty string. Unlike a traditional OAuth token, the user access token is limited to the permissions that both your app and the user have.
token_type
string
The type of token. The value will always be
bearer
.
Use the user access token from the previous step to make API requests on behalf of the user. Include the user access token in the
Authorization
header of an API request. For example:
curl --request GET \ --url "https://api.github.com/user" \ --header "Accept: application/vnd.github+json" \ --header "Authorization: Bearer USER_ACCESS_TOKEN" \ --header "X-GitHub-Api-Version: 2026-03-10"
Generating a user access token when a user installs your app
If you select
Request user authorization (OAuth) during installation
in your app settings, GitHub will start the web application flow immediately after a user installs your app.
You can generate a user access token with this method regardless of whether the app is installed on a user account or an organization account. However, if the app was installed on an organization account, you will need to use the web application flow or device flow to generate a user access token for other users in the organization.
When a user installs your app, GitHub will redirect the user to
https://github.com/login/oauth/authorize?client_id=CLIENT_ID
, where
CLIENT_ID
is the client ID of your app.
If the user accepts your authorization request, GitHub will redirect the user to the first callback URL in your app settings, and provide a
code
query parameter.
If you want to control which callback URL is used, do not select
Request user authorization (OAuth) during installation
. Instead, direct users through the full web application flow and specify the
redirect_uri
parameter.
Exchange the
code
from the previous step for a user access token by making a
POST
request to this URL, along with the following query parameters:
https://github.com/login/oauth/access_token
Query parameter
Type
Description
client_id
string
Required.
The client ID for your GitHub App. The client ID is different from the app ID. You can find the client ID on the settings page for your app. For more information about navigating to the settings page for your GitHub App, see
Modifying a GitHub App registration
.
client_secret
string
Required.
The client secret for your GitHub App. You can generate a client secret on the settings page for your app.
code
string
Required.
The code you received in the previous step.
redirect_uri
string
The URL in your application where users will be sent after authorization. This must match one of the URLs you provided as a "Callback URL" when setting up your GitHub App. For more information, see
About the user authorization callback URL
.
code_verifier
string
Strongly recommended.
Used to secure the authentication flow with PKCE (Proof Key for Code Exchange). Required if
code_challenge
was sent during the user authorization. Must be the original value used to generate the
code_challenge
in the authorization request. This can be stored in a cookie alongside the
state
parameter or in a session variable during authentication, depending on your application architecture.
repository_id
string
The ID of a single repository that the user access token can access. If the GitHub App or user cannot access the repository, this will be ignored. Use this parameter to restrict the access of the user access token further.
GitHub will give a response that includes the following parameters:
Response parameter
Type
Description
access_token
string
The user access token. The token starts with
ghu_
.
expires_in
integer
The number of seconds until
access_token
expires. If you disabled expiration of user access tokens, this parameter will be omitted. The value will always be
28800
(8 hours).
refresh_token
string
The refresh token. If you disabled expiration of user access tokens, this parameter will be omitted. The token starts with
ghr_
.
refresh_token_
expires_in
integer
The number of seconds until
refresh_token
expires. If you disabled expiration of user access tokens, this parameter will be omitted. The value will always be
15897600
(6 months).
scope
string
The scopes that the token has. This value will always be an empty string. Unlike a traditional OAuth token, the user access token is limited to the permissions that both your app and the user have.
token_type
string
The type of token. The value will always be
bearer
.
Use the user access token from the previous step to make API requests on behalf of the user. Include the user access token in the
Authorization
header of an API request. For example:
curl --request GET \ --url "https://api.github.com/user" \ --header "Accept: application/vnd.github+json" \ --header "Authorization: Bearer USER_ACCESS_TOKEN" \ --header "X-GitHub-Api-Version: 2026-03-10"
Using a refresh token to generate a user access token
By default, user access tokens expires after 8 hours. If you receive a user access token with an expiration, you will also receive a refresh token. The refresh token expire after 6 months. You can use this refresh token to regenerate a user access token. For more information, see
Refreshing user access tokens
.
GitHub strongly encourages you to use user access tokens that expire. If you previously opted out of using user access tokens that expire but want to re-enable this feature, see
Activating optional features for GitHub Apps
.
Troubleshooting
The following sections outline some errors you may receive when generating a user access token.
Incorrect client credentials
If the
client_id
or
client_secret
that you specify are incorrect, you will receive an
incorrect_client_credentials
error.
To resolve this error, make sure to use the correct credentials for your GitHub App. You can find the client ID and client secret on the settings page for your GitHub App. For more information about navigating to your GitHub App settings page, see
Modifying a GitHub App registration
.
Redirect URI mismatch
If you specify a
redirect_uri
that doesn't match one of the callback URLs in your GitHub App registration, you will receive a
redirect_uri_mismatch
error.
To resolve this error, either provide a
redirect_uri
that matches one of the callback URLs for your GitHub App registration, or omit this parameter to default to the first callback URL that is listed on your GitHub App registration. For more information, see
About the user authorization callback URL
.
Bad verification code
If you are using device flow and the verification code (
device_code
) that you specified is incorrect, expired, or doesn't match the value that you received from the initial request to
https://github.com/login/device/code
, you will receive a
bad_verification_code
error.
To resolve this error, you should start the device flow again to get a new code. For more information, see
Using the device flow to generate a user access token
.
Bad refresh token
If the refresh token that you specified is invalid or expired, you will receive a
bad_refresh_token
error.
To resolve this error, you must restart the web application flow or device flow to get a new user access token and refresh token. You will only receive a refresh token if your GitHub App has opted in to expiring user access tokens. For more information, see
Refreshing user access tokens
.
Unsupported grant type
When you request a user access token via the device flow, the
grant_type
parameter must be
urn:ietf:params:oauth:grant-type:device_code
. When you refresh a user access token by using a refresh token, the
grant_type
parameter must be
refresh_token
. If you don't use the correct grant type, you will receive an
unsupported_grant_type
error.
Unverified user email
If the user for whom you are trying to generate a user access token has not verified their primary email address with GitHub, you will receive an
unverified_user_email
error.
To resolve this error, prompt the user to verify the primary email address on their GitHub account. For more information, see
Verifying your email address
.
Help and support
Did you find what you needed?
Yes
No
Privacy policy
Help us make these docs great!
All GitHub docs are open source. See something that's wrong or unclear? Submit a pull request.
Make a contribution
Learn how to contribute
Still need help?
Ask the GitHub community
Contact support
Legal
©
2026
GitHub, Inc.
Terms
Privacy
Status
Pricing
Expert services
Blog
