Create post and send via email using Admin API

I’m trying to use the admin api and Javascript client to load an HTML post and send it via email. I can add a post, but the API documentation is unclear about how to schedule it to be send as email in the Javascript client. Here is the relevant text in the docs:

To send a post by email, the newsletter query parameter must be passed when publishing or scheduling the post, containing the newsletter’s slug.

Does this mean that I cannot do this from within the client and must use the endpoint? It’s not clear.

In cases like this, it’s time “use the source, Luke!”.

The source for the Admin API shows that the edit() method has an undocumented second parameter that accepts query parameters:

So that’s where you can adding the query params for newsletter mailings described here:

@mjw Where can documentation patches for the JavaScript Admin API be submitted to document the second parameter for “edit()” calls? I looked in the SDK repo, but there’s no mention there of where the docs are stored. Then I found the “docs” repo and saw that it is archived, but there’s mention in that archived README of where to update the docs instead.

@markstos Thanks for doing the research :smile: The docs themselves are in a private repo, but I think you could add this as an issue in the SDK. It’s also on my radar now, so I’ll work on updating the docs to reflect this option!

If something’s missing from the docs in the future, you can message me on the Forum, too!

1 Like

Thanks for this, and being able to send the query params this way would help. Syntactically, how would I do this? I’m using requests in Python. Thanks for any guidance.

If you are unsure how to add a query string to a request in Python, I suggest trying the official JavaScript SDK instead.

Thanks. I have some JS code that successfully posts via the API , makes status published, and includes the query string params. But it won’t send out via email on the Admin API, despite the query string being included (I think).

Does this make sense to you? And thanks again.

var html = '<p>Testing email sending through API</p>'

api.posts.add({
    title: 'Testing Email Sending Through API',
    html: html,
    status: 'published',
    }, {
    source: 'html',
    newsletter: 'default-newsletter',
    }
    );

I have tried to modify and email existing posts, as well as send new posts via email, and neither version of the code sends the email. I can modify properties, but not send anything via email. I can obviously send via email manually.

Update

Okay, I got it to work. I had to post the entry first, and then modify its status to published with the edit function, and then add the query string params. Thanks for your help.

1 Like

Hi @timbenz, may I know what is the sequence of requests you made to post and send email using the admin API please? What is the sequence of POST and PUT requests? Thank you in advance.

Update
With lots of trial and error I got it to work.
Step 1: Send a POST request without “status” in the body. This creates a draft.
Step 2: Send a PUT request to the post_id url, with “status” being “published” and the newsletter parameters.

Python

body = {"posts": [{
            "title": title
            "html": html
        }]}
params = {"source": "html"}
requests.post(f"https://{domain}/ghost/api/admin/posts/", json=body, headers=headers, params=params)

body = {"posts": [{
            "updated_at": datetime.datetime.utcnow().isoformat()[:-6] + '000Z',
            "status": "published"
}]}
params = {"newsletter": "default-newsletter", "email_segment": "all"}
requests.put(f"https://{domain}/ghost/api/admin/posts/{post_id}", json=body, headers=headers, params=params)
1 Like

Thanks to everyone who contributed above. I still spent an hour wrangling with it (probably because I was convinced I should be able to do it in one step…)

Here’s what works (it’s not one step). Using the Admin API SDK, which makes it super easy. Eventually.

And code below:

async function pushPostToGhost(HTML) {
  const api = new GhostAdminAPI({
    url: process.env.GHOST_API_URL,
    version: "v5.0",
    key: process.env.GHOST_ADMIN_API_KEY
    });
// Change to when you actually want the email sent...  
    let schedule_time = moment().add(1, 'minutes').format('YYYY-MM-DDTHH:mm:ssZ');

    let post = {
      title: `Spiffy title`,
      html: `
      ${HTML}
      `,
      status: 'draft',
      tags: ['#some-tag'],
      email_only: true
      
    }
    let response = await api.posts.add(post, {source: 'html'});
    let edit = await api.posts.edit({
      id: response.id, 
      updated_at: response.updated_at, 
      email_only: true, 
      status: 'scheduled', 
      published_at: schedule_time
      }, {newsletter: 'default-newsletter', email_segment: 'all'
    });
      
    return edit; 
}
1 Like