OAuth2 authentication
OAuth2 lets applications securely access WordPress.com and Jetpack sites without needing users’ passwords. It provides fine-grained control over what each app can access.
OAuth2 lets apps request only the specific permissions they need through “scopes”. When users authorize an app, they can see and control exactly what access they’re granting.
Users sign in with their WordPress.com account and can approve or deny the requested permissions, maintaining control over their data while safely connecting apps.
Looking for code examples? Check out the WordPress.com REST API Examples repository, which contains sample projects demonstrating OAuth authentication and API usage in various programming languages and frameworks. The repository includes examples of both OAuth-based authentication for user-authorized operations and Application Password authentication for direct API endpoint access.
Prerequisites
Before developing your OAuth2 application, you need to have a WordPress.com application registered with the following data:
- Client ID: Identifies your application
- Client Secret: Authenticates your application (keep secure)
- Redirect URI: Where users return after authorization
You can obtain these credentials through the WordPress.com Applications Manager.
Use this form to register a new WordPress.com Application
OAuth2 endpoints
If you’re new to OAuth2, you can learn more at https://oauth.net/. For WordPress.com integration, you need to understand the core OAuth2 endpoints available under the https://public-api.wordpress.com/oauth2/
namespace. These endpoints work consistently for both WordPress.com sites and Jetpack-connected sites.
Authorization Endpoint
Endpoint: https://public-api.wordpress.com/oauth2/authorize
Method: GET (via user redirect)
This is where the OAuth2 flow begins. Users are presented with an authorization interface to review and approve the permissions your application is requesting. The endpoint validates your application credentials, redirect URI, and generates secure authorization codes for token exchange.
Required Parameters:
client_id
: Your application’s client IDredirect_uri
: Must match registered redirect URIresponse_type
: “code” for Authorization Code Flow or “token” for Implicit Flow
Optional Parameters:
scope
: Space-separated permissions (defaults to single-blog access)state
: Recommended for CSRF protectionblog
: Specific blog URL or ID for single-site access
Example Authorization URL (Authorization Code Flow):
https://public-api.wordpress.com/oauth2/authorize?client_id=12345&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback&response_type=code&scope=posts%20media&state=abc123xyz
Example Authorization URL (Implicit Flow):
https://public-api.wordpress.com/oauth2/authorize?client_id=12345&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback&response_type=token&scope=posts%20media&state=abc123xyz
Example Authorization URL (Specific Blog):
https://public-api.wordpress.com/oauth2/authorize?client_id=12345&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback&response_type=code&blog=yourblog.wordpress.com&scope=posts%20media&state=abc123xyz
Response/Action: After user approval, redirects to your redirect_uri with:
- Authorization Code Flow:
?code=AUTHORIZATION_CODE&state=YOUR_STATE
- Implicit Flow:
#access_token=TOKEN&expires_in=64800&token_type=bearer&site_id=BLOG_ID
- User denial:
?error=access_denied
Important Note: The redirect_uri parameter must exactly match the redirect URI registered when creating your application. Even minor differences (like missing trailing slashes) will cause the authorization to fail. This is a security measure to prevent malicious redirects.
Token Request Endpoint
Endpoint: https://public-api.wordpress.com/oauth2/token
Method: POST
This secure server-to-server endpoint handles two different grant types for obtaining access tokens. Choose the appropriate grant type based on your use case:
Authorization Code Grant (Production Use)
Use this grant type for all production applications. It exchanges authorization codes (received from user authorization) for access tokens while keeping your client secret secure.
Required Parameters:
client_id
: Your application’s client IDclient_secret
: Your application’s client secretcode
: Authorization code from the authorization stepgrant_type
: Must be “authorization_code”redirect_uri
: Must match the authorization redirect URI
Example Request:
curl -X POST https://public-api.wordpress.com/oauth2/token \
-d "client_id=12345" \
-d "client_secret=your_client_secret" \
-d "code=received_authorization_code" \
-d "grant_type=authorization_code" \
-d "redirect_uri=https://yourapp.com/callback"
Password Grant (Development & Testing Only)
This grant type allows application owners to obtain tokens directly using their WordPress.com credentials, bypassing the user authorization flow.
Use Password Grant For:
- Testing API endpoints during development
- Automated testing where user authorization simulation is impractical
- Personal development on your own WordPress.com sites
Security Restrictions:
- Only works with your own WordPress.com credentials (not other users’)
- Requires exposing credentials in your code
- Bypasses OAuth2’s user consent and security benefits
- Never use in production applications
Required Parameters:
client_id
: Your application’s client IDclient_secret
: Your application’s client secretgrant_type
: Must be “password”username
: Your WordPress.com usernamepassword
: Your WordPress.com password (or Application Password if 2FA enabled)
Example Request:
curl -X POST https://public-api.wordpress.com/oauth2/token \
-d "client_id=12345" \
-d "client_secret=your_client_secret" \
-d "grant_type=password" \
-d "username=your_username" \
-d "password=your_password_or_app_password"
Two-Factor Authentication: If you have 2FA enabled, create an Application Password in your WordPress.com Account Settings and use that instead of your regular password.
Migration Path: Start with Password Grant for development convenience, but implement Authorization Code Flow before launching to production. Think of Password Grant as a development shortcut that must be replaced with proper user authorization in live applications.
Token Response Format (Both Grant Types):
{
"access_token": "YOUR_API_TOKEN",
"blog_id": "blog_id_number",
"blog_url": "https://yourblog.wordpress.com",
"token_type": "bearer"
}
Token Information Endpoint
Endpoint: https://public-api.wordpress.com/oauth2/token-info
Method: GET
Provides secure token validation and inspection. Returns detailed information about tokens, including user ID, blog ID, and scope permissions. Essential for verifying token authenticity, especially when tokens are transmitted between systems or in mobile applications.
Required Parameters:
client_id
: Your application’s client IDtoken
: The access token to validate
Example Request:
GET https://public-api.wordpress.com/oauth2/token-info?client_id=12345&token=your_access_token_here
Example CURL Request:
curl "https://public-api.wordpress.com/oauth2/token-info?client_id=12345&token=your_access_token_here"
Response Format (Valid Token):
{
"client_id": "12345",
"user_id": "123456789",
"blog_id": "987654321",
"scope": "posts,media"
}
Response (Invalid Token): Returns an error if the token was not authorized for your application or is invalid.
Authentication Endpoint
Endpoint: https://public-api.wordpress.com/oauth2/authenticate
Method: GET (via user redirect)
A specialized endpoint for WordPress.com Connect applications that only need basic user identity verification. Optimized for “Login with WordPress.com” functionality, designed for identity verification rather than content management.
Required Parameters:
client_id
: Your application’s client IDredirect_uri
: Must match registered redirect URIresponse_type
: Use “code” for secure server-side exchange
Optional Parameters:
scope
: Typically “auth” for basic profile accessstate
: Recommended for CSRF protection
Example Authentication URL:
https://public-api.wordpress.com/oauth2/authenticate?client_id=12345&redirect_uri=https%3A%2F%2Fyourapp.com%2Fauth-callback&response_type=code&scope=auth&state=random_secure_string
Response/Action: After user approval, redirects to your redirect_uri with an authorization code. Exchange this code at the token endpoint to receive a token with limited scope, typically providing access only to:
Available API Access:
/me/
endpoint for basic user profile information- User identity verification data (ID, username, email, avatar_URL, verified status)
OAuth2 Workflows
WordPress.com supports two main OAuth2 workflows, each designed for different application types and security requirements:
Authorization Code Flow (Recommended)
The Authorization Code Flow is the standard OAuth2 workflow for server-side applications where you can securely store client secrets. This flow provides the highest security by exchanging an authorization code for an access token through a secure server-to-server request.
Security advantage: The client secret never appears in client-side code, and access tokens are obtained through authenticated server requests.
Implicit Flow (Legacy)
The Implicit Flow was designed for browser-based applications where the access token is returned directly in the URL fragment. However, this approach is now considered less secure and has been largely deprecated in favor of more secure alternatives like PKCE (Proof Key for Code Exchange).
Important: We recommend using the Authorization Code Flow whenever possible for enhanced security.
OAuth2 Scopes and Permissions
OAuth2’s power lies in its granular permission system. When requesting authorization, you specify scopes that define exactly what your application can access.
Available Scopes
- users: View user information
- sites: View general site information and options
- posts: View and manage posts
- comments: View and manage post comments
- taxonomy: View and manage tags and categories
- follow: Follow and unfollow blogs
- sharing: Connect social media services
- freshly-pressed: View Freshly Pressed posts
- notifications: View and manage user notifications
- insights: View analytics for your application
- read: Manage and view Reader subscriptions
- stats: View site statistics
- media: Manage site media
- menus: View and manage site menus
- batch: Batch multiple GET requests
- videos: View video information
Special Scopes
- global: Grants comprehensive access to user data across all WordPress.com services and connected sites
- auth: Limited scope providing access only to the
/me/
endpoint for basic authentication flows. See WordPress.com Connect for more related info.
Scope Best Practices
Always follow the principle of least privilege:
// Request only necessary permissions
const scopes = 'posts,media'; // Not 'global' unless truly needed
Implementing OAuth2 Authentication
Step 1: Authorization Request
Direct users to the authorization endpoint with the required parameters:
Required Parameters
client_id
: Your application’s client IDredirect_uri
: Must match the URI registered in your application settingsresponse_type
: Use “code” for Authorization Code Flow or “token” for Implicit Flow
Optional Parameters
blog
: Specific blog URL or ID for single-site accessscope
: Space-separated list of requested permissionsstate
: Recommended security parameter to prevent CSRF attacks
Example Authorization URL
const authUrl = `https://public-api.wordpress.com/oauth2/authorize?` +
`client_id=${clientId}&` +
`redirect_uri=${encodeURIComponent(redirectUri)}&` +
`response_type=code&` +
`scope=posts,media&` +
`state=${secureRandomString}`;
// // Redirect user to authorization
window.location.href = authUrl;
Step 2: Authorization Code Exchange
After user authorization, you’ll receive (at the redirect_url location) an authorization code that must be exchanged for an access token.
Server-Side Token Exchange
Make a POST request to the token endpoint:
$curl = curl_init( 'https://public-api.wordpress.com/oauth2/token' );
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_POSTFIELDS, array(
'client_id' => $your_client_id,
'redirect_uri' => $your_redirect_url,
'client_secret' => $your_client_secret_key,
'code' => $_GET['code'], // The authorization code
'grant_type' => 'authorization_code'
) );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1);
$auth = curl_exec( $curl );
$secret = json_decode( $auth );
$access_token = $secret->access_token;
Successful Response
{
"access_token": "YOUR_API_TOKEN",
"blog_id": "blog_id_number",
"blog_url": "https://yourblog.wordpress.com",
"token_type": "bearer"
}
Step 3: Making Authenticated API Calls
Use the Bearer token in the Authorization header for all API requests:
$access_token = 'YOUR_API_TOKEN';
$curl = curl_init( 'https://public-api.wordpress.com/rest/v1/me/' );
curl_setopt( $curl, CURLOPT_HTTPHEADER, array( 'Authorization: Bearer ' . $access_token ) );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 );
$response = curl_exec( $curl );
Advanced OAuth2 Features
Token Scope Management
Different token scopes provide different access levels:
- Single-blog tokens: Grant access to one specific blog
- Global tokens: Provide access to all user’s WordPress.com and connected Jetpack sites
- User-specific endpoints: Some endpoints (likes, follows) work across blogs with any user token
Client-Side (Implicit) OAuth
For client-side applications, tokens can be returned in the URL fragment using the Implicit Flow:
https://yourapp.com/callback#access_token=TOKEN&expires_in=64800&token_type=bearer&site_id=BLOG_ID
Important considerations:
- Tokens currently expire after two weeks
- Use the expires_in value to handle token refresh
- Suitable only for public clients where secrets cannot be stored securely
Token Validation and Management
Managing OAuth2 tokens properly is crucial for a robust application. This includes validating tokens, handling API responses, and gracefully managing token expiration or insufficient permissions.
Token Information Endpoint
Verify token authenticity using the token info endpoint:
GET https://public-api.wordpress.com/oauth2/token-info?client_id=your_client_id&token=your_token
Valid response:
{
"client_id": "your_client_id",
"user_id": "user_id_number",
"blog_id": "blog_id_number",
"scope": "posts,media"
}
Development and Testing
Testing with Password Grant (Client Owners Only)
Application owners can use the password grant to get the authentication token:
$curl = curl_init( 'https://public-api.wordpress.com/oauth2/token' );
curl_setopt( $curl, CURLOPT_POST, true );
curl_setopt( $curl, CURLOPT_POSTFIELDS, array(
'client_id' => $your_client_id,
'client_secret' => $your_client_secret_key,
'grant_type' => 'password',
'username' => $your_wpcom_username,
'password' => $your_wpcom_password, // Use Application Password if 2FA enabled
) );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1);
$auth = curl_exec( $curl );
$auth = json_decode( $auth );
$access_token = $auth->access_token;
Important: This method requires an Application Password if two-factor authentication is enabled.
Security Best Practices and Error Handling
Implementation Guidelines
- State Parameter Validation: Always validate the state parameter to prevent CSRF attacks
- Secure Token Storage: Store access tokens securely using appropriate encryption
- Minimum Scope Requests: Request only the permissions your application actually needs
- Clear User Communication: Explain why specific permissions are required
- Proper Error Handling: Handle authorization failures, token expiration, and scope changes gracefully
HTTPS Requirements
All OAuth2 communications must use HTTPS to protect tokens and authorization codes during transmission.
Token Management
- Store access tokens securely on the server side
- Implement appropriate token refresh mechanisms
- Provide clear documentation about token lifecycle
- Handle token expiration gracefully in your application
Error Handling
Common OAuth2 errors and their meanings:
- access_denied: User declined authorization
- invalid_client: Invalid client credentials
- invalid_grant: Invalid or expired authorization code
- invalid_scope: Requested scope is invalid or unavailable
Always implement comprehensive error handling to provide users with clear feedback when authorization issues occur.
Conclusion
OAuth2 provides a secure, user-friendly authentication method for WordPress.com integrations. By implementing proper scope management, security practices, and error handling, you can build applications that respect user privacy while providing powerful functionality. The granular permission system ensures users maintain control over their data while enabling your application to deliver valuable features.
For complete API endpoint documentation and additional examples, visit the WordPress.com REST API Reference.
Last updated: October 01, 2025