Setting public previews via Admin API

I’m unable to set public previews via the Admin API for HTML posts.

It appears that this is set via the ‘<!--members-only-->’ HTML comment, however this is being ignored despite being correctly formatted in the request.

Discovered an earlier thread on this issue: Public previews via html admin-api publish

<h1>Test Post 1</h1>

<p>This is a public paragraph</p>
<p>This should be a members only paragraph, but it isn't :-)</p>

Checked some of the code on Github and there seems to be a parser for this comment, yet it doesn’t seem to be working:

Has anybody figured this out yet?

The parser you’ve linked to is for the beta editor, that’s not currently being used for the ?source=html route for creating posts but will be once the new editor comes out of beta.

The parsers for the original editor are in the kg-parser-plugins package which doesn’t have a paywall card parser. Happy to accept a PR for that :slight_smile:

Thanks for the response. Happy to try my hand at it. I can’t claim to be fully familiar with Ghost’s architecture.

Could you give me some pointers as to where I can get started? I’ve found my way here in the last few minutes:

Btw I’ve discovered another minor issue - the html parser seems incapable of handling independent <li> tags. Have used a workaround on our end to parse and wrap those <li> tags into a <ul> tag.

Hi! I also ran into the issue of setting the public preview. I resolved it by creating the post as ?source=html, getting the mobiledoc from ghost, adding the paywall marker as a card and inserting it before the right section, and then updating the mobiledoc.

After creating the post (from html), I call this function to make the first paragraph a preview. Sorry if this is a bit messy, but hope it helps!

function addPaywallAfterFirstParagraph(post, authorization) {
  let md = JSON.parse(post.mobiledoc);
  // Verify existence of, or add, a 'paywall' card:
  console.log(`Cards were: ${}.`)
  let i = => card[0] == 'paywall');
  if (i == -1) {['paywall', {}]);
    console.log(`Cards are now: ${}.`)
    i = - 1;
  console.log(`Paywall card index is ${i}.`);

  // If there is already a paywall section, stop.
  if (md.sections.findIndex(item => (item[0] == 10 && item[1] == i)) != -1) {
    console.log(`There is already a paywall section marker in post ${}.`);

  // We will add the card before the first index.
  let sectionIndex = 1;
  // Add paywall
  md.sections.splice(sectionIndex, 0, [10,i]);


  post.mobiledoc = JSON.stringify(md);
  return updatePost(post, authorization);

Glad to hear that the updated parser will handle the members-only comment.

I did a work-around to get this behavior by manipulating the mobiledoc directly.

From Ghost 5.62.0 and later if you have the beta editor enabled then ?source=html will pick up the <!--members-only--> comment and convert to a paywall card.


Thanks Kevin, but I’m not getting this to work. I use Ghost Pro and have enabled the beta editor (I see post_revisions and the lexical content when requesting posts now).

My intention is to insert the paywall after the first paragraph of a post. get the html of an existing post, add the comment after the first </p>, and then update the post.

I’m doing an update by using PUT and including ?source=html at the end of the url. But although other changes are accepted, the <!--members-only--> comment is still ignored. I have the same problem when POSTing a new post.

Do you have any advice?

This is now working just fine now that the editor is out of beta :+1: