API call from Make.com error 400 - Update a member

Hi everyone,

I am not sure if this is a Make.com error or a Ghost error.

In Make.com there is no “update a member” module, so I have to use API call module.

However, when I try a PUT request to a specific member ID, I get the error:

The operation failed with an error. [400] InternalServerError An unexpected error occurred, please try again. Unexpected token u in JSON at position 0
This is the Ghost API call module:

When I run it to test, i put a member ID such as 99f008e08544200016c0525 so that URL part gets filled. But I get a 400 error.

400 Error

(the member id of the screenshot does exists on the test website)

My goal is to update the subscription status of a member. In this moment there is no body, I still have to write the JSON code for that.

Does Make authenticate with the Admin API key?

Yes, In Ghost I went to Integrations/Custom and added Make. In Make I added a Ghost connection via API: (admin API key and integration ID).

I added the body of my API call so it is clearer. I am subscribing the member to a newsletter and adding a label to it. Now the error tells me about a 353 JSON line but where it is?

Hmm. Watch me think out loud and hopefully solve your problem… :thinking:

Sometimes an error about not being able to parse JSON is because you’ve got an error in your JSON, but sometimes it’s just that the server is throwing an error and not returning JSON as a result. [In this situation, if it’s possible to get Make to return the raw result of the query, that might be useful. I don’t use Make, so I don’t know if it is.]

Most of the Ghost API endpoints are pretty good about throwing a 422 error if it’s an authentication problem, so that’s probably not it.

v3 is really old. That’s a bit suspicious.

My go-to answer in this situation is to do the action I want in the admin panel, and see what happens by watching the browser’s network tab (F12 to get there). In my experience, this is THE best way to figure out what an endpoint is expecting. (Sure, you could decipher the source code, but this is faster and gives you a working example.) We’re looking for both what endpoint the admin panel is using AND for what the payload is.

Here’s where the call to add a label goes:
{myadmindomain}/ghost/api/admin/members/{mymemberid}/?include=newsletters%2Clabels

It’s a PUT. OK, so is yours.

Here’s the payload:

{
  "members": [
    {
      "id": "67b91ac4e1b44f03c40341de",
      "name": "Totally Fake Cathy",
      "email": "catsarisky+fake@gmail.com",
      "note": "",
      "created_at": "2025-02-22T00:31:00.000Z",
      "subscriptions": [],
      "attribution": {
        "id": "67b91942e1b44f03c40341b8",
        "type": "post",
        "url": "https://www.spectralwebservices.com/blog/comments-and-accessibility/",
        "title": "Comments and accessibility",
        "referrer_source": "Direct",
        "referrer_medium": null,
        "referrer_url": null
      },
      "subscribed": true,
      "email_count": 5,
      "email_opened_count": 1,
      "email_open_rate": 20,
      "avatar_image": "https://www.gravatar.com/avatar/1b97422e5224d2b15e565619da7c9fb1?s=250&r=g&d=blank",
      "tiers": [],
      "email_suppression": {
        "suppressed": false,
        "info": null
      },
      "newsletters": [
        {
          "id": "674216a5b6a9b829161458c6",
          "name": "Spectral Web Services Newsletter",
          "slug": "default-newsletter-2",
          "description": "Subscribe to receive our new blog posts by email. Quasi-weekly, mostly focused on Ghost. Unsubscribe any time.",
          "sender_name": "Cathy @ Spectral Web Services ",
          "sender_email": null,
          "sender_reply_to": "newsletter",
          "status": "active",
          "subscribe_on_signup": true,
          "visibility": "members",
          "sort_order": 0,
          "feedback_enabled": true,
          "header_image": null,
          "show_header_icon": true,
          "show_header_title": false,
          "show_header_name": true,
          "show_post_title_section": true,
          "show_excerpt": true,
          "show_comment_cta": true,
          "show_subscription_details": true,
          "show_latest_posts": true,
          "title_font_category": "sans_serif",
          "title_alignment": "center",
          "show_feature_image": false,
          "body_font_category": "sans_serif",
          "background_color": "light",
          "border_color": null,
          "title_color": null,
          "footer_content": null,
          "show_badge": true
        }
      ],
      "labels": [
        {
          "name": "still fake",
          "slug": null
        }
      ]
    }
  ]
}

I’m 100% sure you don’t need all of that. The admin panel generally sends the whole user when updating one field. You probably just the bits you want to change. Which seems like what you have, and you probably have enough details for both newsletters and labels for those changes to work. (When I tried again with an existing label, I saw the label ID also, so no concerns there.)

OK, so the payload looks OK. Let’s get back to the URL. You’re both not hitting the same endpoint, AND you’re missing the querystring on the url ?include=newsletters%2Clabels . Either of those could be the problem.

Why don’t you try updating your endpoint to include that querystring (and remove the v3 while you’re at it, and see if that fixes things?

Aside to anyone following along: The one issue with duplicating what the admin panel is doing is that it’s using cookie authentication. So there’s a possibility you’ll find an endpoint that works fine with the admin panel but doesn’t work with your authentication token because it only takes a cookie. If you’re exactly duplicating the admin panel call and it’s failing, either your token generation is messed up (check that by hitting an endpoint that you know works with a token), or you have found one of those cookie-only endpoints.

Mmmm. Cookies.
:cookie: :fortune_cookie:

Professor Cathy out!

Hi Cathy, that’s a good advice of yours, however I now get a 404 error when I use the URL found in the Network tab. Also in that tab I can’t see any PUT, all of them are GET (I changed in Make to try, doesn’t work anyway).

Hence, trying with /ghost/api/admin/members/{idofmember}/?include=newsletters%2Clabels I get a 404, also without ?include=newsletters%2Clabels.

I then reverted to Ghost API docs “update a member” and as they say there, I used /admin/members/{memberid}/ and the error I got is 400.

In the meantime I decided to not update the labels but active newsletters only, so my settings are as follows:

Settings

and the error is 400 - internal server error from Ghost

Error

The raw make.com input is
[ { "url": "/admin/members/{67fa6771f14289000195fdf1}/", "body": "{\n \"members\": [\n {\n \"newsletters\": [\n {\n \"id\": \"67c9b991159234000122c01e\"\n \"status\": \"active\"\n }\n ]\n }\n ]\n}", "method": "PUT", "headers": [ { "key": "Content-Type", "value": "application/json" } ] } ]

While the output is: [ null ]

Why I get the 400 error if I follow the documentation?

I solved. I tried with their example:

{
“members”: [
{
“name”: “Jamie II”
}
]
}

What I did is removing the {} from the id and using their example. Also removing the v3 as Cathy suggested. It worked!

1 Like