Invalid parameter for 'fields[memberships]' on type user: [None]

I got through all of the OAuth song and dance. Not without issues, but I got through it through trial and error, now I have the token and what not, and can start making calls to the API.

Alas, calling

https://www.patreon.com/api/oauth2/v2/identity?include=memberships&fields%5Bmemberships%5D=patron_status%2Clast_charge_status%2Ccurrently_entitled_amount_cents&fields%5Buser%5D=vanity%2Cfull_name%2Cimage_url

results in the following response:

{
   "code":1,
   "code_name":"ParameterInvalidOnType",
   "detail":"Invalid parameter for 'fields[memberships]' on type user: [None].",
   "id":"f43daad0-596f-5db3-950b-618af737a768",
   "status":"400",
   "title":"Invalid value for parameter 'fields[memberships]'."
}

and the code I’m using to call it is

  const identityUrl = new UrlBuilder(
    "https://www.patreon.com/api/oauth2/v2/identity"
  )
    .query("include", "memberships")
    .bracketQuery("fields[memberships]", [
      "patron_status",
      "last_charge_status",
      "currently_entitled_amount_cents",
    ])
    .bracketQuery("fields[user]", ["vanity", "full_name", "image_url"])
    .build();

  const identityResponse = await fetch(identityUrl, {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${oauthData.access_token}`,
    },
  });
  const identityData = await identityResponse.json();

with the UrlBuilder being simple

export class UrlBuilder {
  #url: URL;

  constructor(baseUrl: string) {
    this.#url = new URL(baseUrl);
  }

  queries(query: { [key: string]: string }): UrlBuilder {
    for (const key in query) {
      this.#url.searchParams.append(key, query[key]);
    }
    return this;
  }

  query(name: string, value: string): UrlBuilder {
    this.#url.searchParams.append(name, value.toString());
    return this;
  }

  bracketQuery(name: string, values: string[]): UrlBuilder {
    const key = name; //.replace("[", "%5B").replace("]", "%5D");
    const val = values.join(",");
    return this.query(key, val);
  }

  build() {
    return this.#url.toString();
  }
}

I did try encoding the URL and even replacing the brackets manually, as you can see, but it always ends up with the % itself being escaped to %5, so %5D and %5B end up as %55D and %55B. I thought maybe the URL gets escaped automatically, so I tried getting rid of the escaping, but no cigar.

So far, all of my attempts — be it escaping, manually replacing brackets, not escaping, or anything else, have been failures.

Apparently the solution was to use fields[member] instead of fields[memberships]

Now I just need to find out how to use the data I retrieve to check if the user is a patreon of my campaign, and I’m good lol

1 Like

If you request memberships and DON’T have the identity.memberships scope, you will receive data about the user’s membership to your campaign. If you DO have the scope, you will receive data about all of the user’s memberships, to all the campaigns they’re members of.

2 Likes