Cannot create member with API

url: skill-speed.ghost.io
API version: 5.0
Hosted: on Ghost platform

I want my Next.js website to have a button which creates members.

The problem is when I make the POST, I get an error:

 {
      message: 'Request not understood error, cannot save member.',
      context: "No root key ('members') provided.",
      type: 'BadRequestError',
      details: null,
      property: null,
      help: null,
      code: null,
      id: '2db3b970-d68d-11ee-8b3b-41aef59088a6',
      ghostErrorCode: null
    }

I don’t understand what the root key is. As you will see, I make sure the members property is in the request payload.

Here’s my snippet of the button submit-handler:

'use server'

import jwt from 'jsonwebtoken'

const APIKEY = "API KEY"

const clickHandler = async () => {
  const [id, secret] =
    APIKEY.split(
      ':',
    )

  // Create the token (including decoding secret)
  const token = jwt.sign({}, Buffer.from(secret, 'hex'), {
    keyid: id,
    algorithm: 'HS256',
    expiresIn: '5m',
    audience: `/admin/`,
  })

  const url = 'https://skill-speed.ghost.io/ghost/api/admin/members'
  const headers = { Authorization: `Ghost ${token}` }
  const payload = {
    members: [
      {
        email: 'jayrey.go@gmail.com',
      },
    ],
  }

  const result = await fetch(url, {
    body: JSON.stringify(payload),
    headers,
    method: 'POST',
  })

  const body = await result.json()
  console.log(`clickHandler -- res`, body)
}

export default clickHandler

Two thoughts, both guesses.

  1. Looks like a validation error. My best trick for dealing with undocumented & unstable endpoints (which is the members API) is to do what I’m trying to do in the Ghost dashboard and watch the network calls with F12. So, creating a member in the Ghost dashboard, I see a POST request to /ghost/api/admin/members/?include=newsletters%2Clabels, with the following content:
{
  "members": [
    {
      "name": "rando",
      "email": "myemailaddress@gmail.com",
      "note": "",
      "subscriptions": [],
      "subscribed": true,
      "email_count": 0,
      "email_opened_count": 0,
      "email_open_rate": null,
      "avatar_image": null,
      "tiers": [],
      "newsletters": [],
      "labels": []
    }
  ]
}

My best is that the API probably wants newsletters or subscriptions or subscribed passed in. I’d try duplicating the network call above and see if it starts working, then you can trim back unnecessary fields from a point where things work.

If that doesn’t work, go on to #2 below…

  1. Some endpoints don’t work without cookie credentials. For example, JWT authentication doesn’t work with the endpoint for impersonation links. You could try sending an admin cookie instead and see if the problem vanishes.
1 Like

Thanks for the help.

I viewed the network request from my dev environment. And I saw that the content type was wrong. I needed to ensure the Content Type was application/json

The issue is now solved

1 Like