Skip to content

WordPress com and Jetpack

Arun Prakash edited this page Nov 3, 2026 · 1 revision

WordPress.com and Jetpack

Sites hosted on WordPress.com, and self-hosted sites connected through Jetpack, are reached through https://public-api.wordpress.com/wp/v2/sites/<site> instead of the site's own /wp-json. WordpressClient.forWordpressCom builds a client for that address. Every interface (posts, pages, media, categories, ...) works the same as on a self-hosted site.

final client = WordpressClient.forWordpressCom(
  site: 'example.wordpress.com',   // a custom domain or the numeric site ID also work
  accessToken: token.accessToken,  // leave out to read public content only
);

final posts = (await client.posts.list(ListPostRequest(perPage: 5))).dataOrThrow();

site may also be a full URL (https://example.wordpress.com/); only its host is used. Routes in other namespaces (wpcom/v2, a plugin's) go to /<namespace>/sites/<site>/... on the same host, so client.resource(..., namespace: ...) works there too.

client.siteUrl returns https://<site> when the site is given as a domain.

Get a token (OAuth2)

  1. Register an app at developer.wordpress.com/apps. Note the client ID and the redirect URL. The client secret is only needed for the code flow.
  2. Send the user to the approval page.
  3. Read the token from the redirect.

Implicit flow (apps without a server)

final state = randomString();   // your own random value

final url = WordpressComOAuth.authorizeUrl(
  clientId: '12345',
  redirectUri: Uri.parse('myapp://oauth'),
  responseType: WordpressComResponseType.token,
  state: state,
  // blog: 'example.wordpress.com',  preselect a site
  // scope: 'global',                access to all of the user's sites
);

// open `url` in a browser or with flutter_web_auth_2, then:
final token = WordpressComOAuth.tokenFromRedirect(redirect, expectedState: state);
if (token == null) {
  // the user said no, or the state did not match
}

tokenFromRedirect reads both the fragment (#access_token=...) and the query. It returns null when there is no token or expectedState differs.

Code flow (with a server)

Use responseType: WordpressComResponseType.code (the default). The redirect carries ?code=.... Exchange it on a server you control, since it needs the client secret:

final token = await WordpressComOAuth.exchangeCode(
  clientId: '12345',
  clientSecret: secret,            // never ship this in an app
  redirectUri: Uri.parse('https://example.com/oauth'),
  code: code,
);

It throws a DioException when WordPress.com refuses the code.

The token

WordpressComToken has accessToken, tokenType, blogId, blogUrl, scope and expiresIn. Its toString hides the token. Keep it in secure storage, see Integration with Storage Packages.

Bearer tokens elsewhere

accessToken is sent as Authorization: Bearer <token> through BearerTokenAuth. Use the same class for any site or proxy that accepts a static bearer token:

b.withDefaultAuthorization(WordpressAuth.bearer(token))

See Authorization.

Limits

  • WordPress.com does not support Application Passwords or the JWT plugins on hosted sites; use OAuth2.
  • Some core routes and plugins are not available on every WordPress.com plan.
  • WPGraphQL and the Abilities API are only there if the site runs those plugins (Business plan or Jetpack sites).

Clone this wiki locally