Verify membership with API calls

I’m trying to verify supporter status with API calls. So far I got to receiving a token (identity.memberships scope). It works for my user, but does not work for any other user, returning 401

curl -s --request GET --url https://www.patreon.com/api/oauth2/v2/identity?include=memberships.campaign\&fields%5Bmember%5D=patron_status --header 'authorization: Bearer xxxxxxx'
{
    "errors":[
        {
            "code":1,
            "code_name":"Unauthorized",
            "detail":"The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.",
            "id":"586cfb60-603a-417a-a69e-5e4757752c44",
            "status":"401",
            "title":"Unauthorized"
        }
    ]
}

To be clear, same call works just fine if I log in as myself, even if I issue a token with correct scope and everything.

I can see from the docs that I can’t access user’s pledges without some interaction from Patreon, even if users allow it. But I can’t even get a user ID to verify against list of my patrons… Are there other ways of doing it which doesn’t require manual approval from the Patreon administration?

P.S.
I do not have PHP or Wordpress, it’s a web app which can make simple fetch requests.

This would happen due to any number of things, ranging from using different version clients with different version endpoints and/or calls, or as much as not having permission to an include that you are requesting, or an include/relationship not being present in the resource you are requesting.

First step would be to make sure you are using a v2 client with v2 calls to v2 endpoints. Then checking if scopes are present. All scopes should be in creator’s token, for others you need to request it during authorization/token creation. Then checking includes and relationships for that resource would help.

I have same workflow for 2 users, one is myself, another is test user. When I do it myself, everything works, another user - it doesn’t.
And flow is very straightforward, unless you help me spot some error, it is following:
Browser:

https://www.patreon.com/oauth2/authorize?client_id=l4YlAvUnfrNrTk9uiupqgnAb3PxDIScWv_FU2f5GVrCiyxEIJCeALuxzLB9R335s&scope=identity.memberships&allow_signup=false&response_type=code&redirect_uri=https://supporters.solar2d.workers.dev/patreon-callback

Note that requested scope is identity.memberships

Then on Server two requests, one to get token from code, another is actual request. So, I’m getting token just fine, but request fails if user is anyone except me.

I have client version set to V2. I’m not sure where creator’s token fits in here.

        const body = {
            client_id: "l4YlAvUnfrNrTk9uiupqgnAb3PxDIScWv_FU2f5GVrCiyxEIJCeALuxzLB9R335s",
            client_secret: "...............",
            code: code,
            grant_type: "authorization_code",
            redirect_uri: "https://supporters.solar2d.workers.dev/patreon-callback",
        };
        const init = {
            body: new URLSearchParams(Object.entries(body)).toString(),
            method: "POST",
            headers: {
                "content-type": "application/x-www-form-urlencoded",
                accept: "application/json",
            },
        };
        const response = await fetch("https://www.patreon.com/api/oauth2/token", init);
        const results = await response.json();
        if (results.error)
            return new Response("Patreon Error: " + (results.error_description || results.error), {
                status: 500,
            });
        results.site = "patreon";

        const ptResponse = await fetch("https://www.patreon.com/api/oauth2/v2/identity?include=memberships.campaign&fields%5Bmember%5D=patron_status", {
            method: "GET",
            headers: {
                accept: "application/json",
                Authorization: `Bearer ${results.access_token}`,
            },
        });

I finally figured it out. Finally!
Basically, add identity to scope. Just having identity.memberships is not enough for some reason
That’s that.

1 Like

Yeah all scopes must be explicitly requested with api v2.