Obtaining a member's `currently_entitled_tiers` in webhook payloads

I’m building a web app. I’d like to use v2 webhooks to get an update whenever a user becomes a member of my campaign, their membership expires, or they upgrade/downgrade their membership tier. I subscribed to the members:create, members:delete, and members:update triggers to accomplish this.

I ran a handful of webhook tests using Patreon’s developer portal. The only two attributes I need to track membership status are the user’s id and the id of the tier they selected. I already obtained all the campaign’s tiers in a separate API call. I expect to be able to access these attributes via payload['data']['id'] and payload['data']['relationships']['currently_entitled_tiers']['data'][0]['id'].

In the test payloads, payload['data']['id'] is null. I’m assuming this is a test-only thing and with real events that key will contain the user’s id. payload['data']['relationships']['currently_entitled_tiers'], on the other hand, doesn’t exist.

  1. Can I accomplish what I want with those three triggers only?
  2. Am I correct in assuming that non-test payloads will contain a user id?
  3. Is currently_entitled_tiers just missing in test payloads, or is that property not available in webhook payloads at all?
  4. If currently_entitled_tiers isn’t available in webhook payloads, what is the best way to get a member’s tier from the payload?

Just make a new Patreon account with a different email but the same payment info, then try pledging to your campaign from a low tier like $1. That way you can test your app.

All data may not be available in a webhook. For that reason, having a locally synced copy of your patrons and then matching the webhook info to the local patron data may be a better idea in most cases.

I’m aware that I can register a second account and spend money to test this, it’s just bizarre that I have to resort to that. I think my goals are very common, so I thought someone would have answers to my questions.

I already have a locally synced copy of all members. Obviously I can’t match the data in a webhook payload to local data if it’s a member:create event (that member wouldn’t exist in the local copy), or if there is no user id in the payload (there would be no criteria by which to perform the match). Also, my chief issue is the payload doesn’t have a currently_entitled_tiers.

The create event should have the user id:

https://docs.patreon.com/#webhook-responses

"user": {
        "data": {
          "id": "987654321",
          "type": "user"
        }
      }

It also should have ```currently_entitled_tiers. But not in the attributes section.

After some testing, I can confirm that member ID, user ID, and currently_entitled_tiers are present in webhook events. I put together a sample production payload below.

{
  "data": {
    "attributes": {
      "campaign_lifetime_support_cents": 16800,
      "currently_entitled_amount_cents": 0,
      "email": "johndoe@gmail.com",
      "full_name": "JohnDoe",
      "is_follower": false,
      "last_charge_date": "2023-01-18T02:55:46.000+00:00",
      "last_charge_status": "Paid",
      "lifetime_support_cents": 16800,
      "next_charge_date": "2023-02-01T08:00:00.000+00:00",
      "note": "",
      "patron_status": "former_patron",
      "pledge_cadence": 1,
      "pledge_relationship_start": "2020-06-21T19:24:35.015+00:00",
      "will_pay_amount_cents": 0
    },
    "id": "this-is-a-fake-member-id",
    "relationships": {
      "address": {
        "data": null
      },
      "campaign": {
        "data": {
          "id": "2222222",
          "type": "campaign"
        },
        "links": {
          "related": "https://www.patreon.com/api/oauth2/v2/campaigns/2222222"
        }
      },
      "currently_entitled_tiers": {
        "data": []
      },
      "user": {
        "data": {
          "id": "11111111",
          "type": "user"
        },
        "links": {
          "related": "https://www.patreon.com/api/oauth2/v2/user/11111111"
        }
      }
    },
    "type": "member"
  },
  "included": [
    {
      "attributes": {
        "created_at": "2020-06-15T22:46:15.000+00:00",
        "creation_name": "creating a Patreon Campaign",
        "discord_server_id": null,
        "google_analytics_id": null,
        "has_rss": false,
        "has_sent_rss_notify": false,
        "image_small_url": "https://c10.patreonusercontent.com/4/patreon-media/p/campaign/2222222/image-name.jpg?token-time=123123&token-hash=fake-hash",
        "image_url": "https://c10.patreonusercontent.com/4/patreon-media/p/campaign/2222222/image-name.jpg?token-time=123123&token-hash=fake-hash",
        "is_charged_immediately": false,
        "is_monthly": false,
        "is_nsfw": false,
        "main_video_embed": null,
        "main_video_url": null,
        "one_liner": null,
        "patron_count": 999,
        "pay_per_name": "episode",
        "pledge_url": "/join/patreoncampaign",
        "published_at": "2020-06-15T23:07:30.000+00:00",
        "rss_artwork_url": null,
        "rss_feed_title": null,
        "summary": "This is a Patreon campaign.",
        "thanks_embed": null,
        "thanks_msg": null,
        "thanks_video_url": null,
        "url": "https://www.patreon.com/patreoncampaign",
        "vanity": "patreoncampaign"
      },
      "id": "2222222",
      "type": "campaign"
    },
    {
      "attributes": {
        "about": null,
        "created": "2018-09-20T04:46:49.000+00:00",
        "first_name": "JohnDoe",
        "full_name": "JohnDoe",
        "hide_pledges": false,
        "image_url": "https://c8.patreon.com/2/200/11111111",
        "is_creator": false,
        "last_name": "",
        "like_count": 2,
        "social_connections": {
          "deviantart": null,
          "discord": null,
          "facebook": null,
          "google": null,
          "instagram": null,
          "reddit": null,
          "spotify": null,
          "twitch": null,
          "twitter": null,
          "vimeo": null,
          "youtube": null
        },
        "thumb_url": "https://c8.patreon.com/2/200/11111111",
        "url": "https://www.patreon.com/user?u=11111111",
        "vanity": null
      },
      "id": "11111111",
      "type": "user"
    }
  ],
  "links": {
    "self": "https://www.patreon.com/api/oauth2/v2/members/this-is-a-fake-member-id"
  }
}
1 Like

Thanks for this.

Working with the Patreon API has been such a bang your face against the wall event. I can’t believe someone got paid to do this. It’s such a nonsensical payload, with bloat information and none of the information ANY of us would want to be able to easily use.