NAV Navbar
shell javascript python ruby php java
  • Introduction
  • API Libraries
  • Third Party Libraries
  • Clients and API Keys
  • OAuth
  • Errors
  • Resources
  • API Endpoints
  • More Data, Paging, and Sorting
  • Webhooks
  • APIv2: OAuth
  • APIv2: Resource Endpoints
  • APIv2: Webhook Endpoints
  • APIv2: Resources
  • External Services
  • FAQs
  • Introduction

    Welcome to the Patreon API!

    Get familiar with the Patreon API and tools using the tutorials and references below.

    Want more than a reference? For a broader overview and use cases, check our our developer portal.

    Make these docs better

    If you find any errors in our docs, we'd love to have you tell us! Submit an issue or a pull request github repo and we'll get them fixed up.

    API Libraries

    We've written some open source libraries to help you use our platform services. Our API follows the JSON:API spec which is pretty complex and these libraries make it a bit easier to work with.

    Python

    Get the package from PyPI, typically via pip:

    Install

    pip install patreon

    or

    echo "patreon" >> requirements.txt
    pip install -r requirements.txt

    Make sure that, however you install patreon, you install its dependencies as well

    View the source on github

    Javascript

    Available on npm

    Install

    npm install --save patreon

    View the source on github

    Ruby

    Get the gem from RubyGems

    Install

    gem install patreon

    View the source on github

    PHP

    Available on packagist

    Install

    composer require patreon/patreon

    View the source on github

    Java

    <dependency>
        <groupId>com.patreon</groupId>
        <artifactId>patreon</artifactId>
        <version>0.1.1</version>
    </dependency>
    

    Get the artifact from

    Maven

    View the source on github

    Third Party Libraries

    There are a number of third party libraries that the developer community has created. If you would like to add yours to this list, please email [email protected].

    Go

    View the source on github

    django-allauth

    Patreon is available as an OAuth backend in django-allauth.

    python-social-auth

    Patreon is available as an OAuth backend in python-social-auth.

    Clients and API Keys

    In order to authenticate with OAuth and interact with the Patreon API, you'll have to register your Client(s). This involves signing up on patreon.com and making a creator account.

    Register your client here

    Once you've registered a Client you'll have access to a:

    OAuth

    Patreon has an OAuth provider service — the technology that lets you log in to Medium with Twitter, log in to Disqus with Google+, and even login to Patreon with Facebook.

    Below, you’ll find steps explaining how to begin integrating with us. It assumes understanding in HTTP protocol and OAuth, and that you have administrative access & developer control of the server that you wish to integrate with Patreon.

    All API calls must be made via HTTPS.

    Step 1 - Registering Your Client

    To set up OAuth, you will need to register your client application on the Clients & API Keys page.

    Step 2 - Making the Log In Button

    Request [2]

    GET www.patreon.com/oauth2/authorize
        ?response_type=code
        &client_id=<your client id>
        &redirect_uri=<one of your redirect_uris that you provided in step 1>
        &scope=<optional list of requested scopes>
        &state=<optional string>
    
    

    Once your client is registered, you should create a “Log in with Patreon” and/or “Link your Patreon account” button on your site which directs users to the following URL:

    HTTPS Request

    GET www.patreon.com/oauth2/authorize

    Query Parameters

    Parameter Description
    response_type Required OAuth grant type. Set this to code.
    client_id Required Your client id
    redirect_uri Required One of your redirect_uris that you provided in step 1
    scope This optional parameter will default to users pledges-to-me my-campaign, which fetches user profile information, pledges to your creator, and your creator info. It will be displayed to the user in human-friendly terms when signing in with Patreon. If your client requires the ability to ask for pledges or campaign data of other users (not just your own campaign), please email [email protected], and we'll do our best to get back to you shortly.
    state This optional parameter will be transparently appended as a query parameter when redirecting to your redirect_uri. This should be used as CSRF, and can be used as session/user identification as well. E.g. https://www.patreon.com/oauth2/authorize?response_type=code&client_id=123&redirect_uri=https://www.mysite.com/custom-uri&state=their_session_id. On this page, users will be asked if they wish to grant your client access to their account info. When they grant or deny access, they will be redirected to the provided redirect_uri (so long as it is pre-registered with us).

    Step 3 - Handling OAuth Redirect

    Request [3]

    GET https://www.mysite.com/custom-uri
        ?code=<single use code>
        &state=<string>
    

    When the link in Step 2 redirects to the provided redirect_uri, e.g. https://www.mysite.com/custom-uri, it will bring extra HTTPS query parameters as follows (assuming the user granted your client access):

    Query Parameters

    Parameter Description
    code Used to fetch access tokens for the session that just signed in with Patreon.
    state Trasnparently appended from the state param you provided in your initial link in Step 2.

    Step 4 - Validating Receipt of the OAuth Token

    Request [4]

    POST www.patreon.com/api/oauth2/token
    
    code=<single use code, as passed in to GET route [2]>
    &grant_type=authorization_code
    &client_id=<your client id>
    &client_secret=<your client secret>
    &redirect_uri=<redirect_uri>
    

    Make sure to also include this header: Content-Type: application/x-www-form-urlencoded

    Your server should handle GET requests in Step 3 by performing the following request on the server (not as a redirect):

    which will return a JSON response of:

    {
        "access_token": <single use token>,
        "refresh_token": <single use token>,
        "expires_in": <token lifetime duration>,
        "scope": <token scopes>,
        "token_type": "Bearer"
    }
    

    to be stored on your server, one pair per user.

    Step 5 - Using the OAuth Token

    You may use the received access_token to make API calls. For example, a typical first usage of the new access_token would be to fetch the user's profile info, and either merge that into their existing account on your site, or make a new account for them. You could then use their pledge level to show or hide certain parts of your site.

    Step 6 - Resolving the OAuth Redirect

    To reiterate, requests [4] and [5] should be performed by your server (synchronously or asynchronously) in response to receiving the GET request in request [3].

    Once your calls are complete, you will have the user’s profile info and pledge level for your creator.

    If requests [4] and [5] were performed synchronously, then you can return a HTTPS 302 for their GET in request [3], redirecting to a page with appropriate success dialogs & profile information. If the requests in requests [4] and [5] are being performed asynchronously, your response to request [3] should probably contain AJAX code that will notify the user once requests [4] and [5] are completed.

    Step 7 - Keeping up to date

    <?php
    require_once('vendor/patreon/patreon/src/patreon.php');
    use Patreon\API;
    use Patreon\OAuth;
    // Get your current "Creator's Access Token" from https://www.patreon.com/portal/registration/register-clients
    $access_token = null;
    // Get your "Creator's Refesh Token" from https://www.patreon.com/portal/registration/register-clients
    $refresh_token = null;
    $api_client = new Patreon\API($access_token);
    
    // If the token doesn't work, get a newer one
    if ($campaign_response['errors']) {
        // Make an OAuth client
        // Get your Client ID and Secret from https://www.patreon.com/portal/registration/register-clients
        $client_id = null;
        $client_secret = null;
        $oauth_client = new Patreon\OAuth($client_id, $client_secret);
        // Get a fresher access token
        $tokens = $oauth_client->refresh_token($refresh_token, null);
        if ($tokens['access_token']) {
            $access_token = $tokens['access_token'];
            echo "Got a new access_token! Please overwrite the old one in this script with: " . $access_token . " and try again.";
        } else {
            echo "Can't recover from access failure\n";
            print_r($tokens);
        }
        return;
    }
    ?>
    

    Request [7]

    POST www.patreon.com/api/oauth2/token
        ?grant_type=refresh_token
        &refresh_token=<the user‘s refresh_token>
        &client_id=<your client id>
        &client_secret=<your client secret>
    

    which will return a JSON response of:

    {
        "access_token": <single use token>,
        "refresh_token": <single use token>,
        "expires_in": <token lifetime duration>,
        "scope": <token scopes>,
        "token_type": "Bearer"
    }
    

    and you should store this information just as before.

    Tokens are valid for up to one month after they are issued. During this period, you may refresh a user’s information using the API calls from step 4. If you wish to get up-to-date information after the token has expired, a new token may be issued to be used for the following month. To refresh a token, make a POST request to the token endpoint with a grant type of refresh_token, as in the example. You may also manually refresh the token on the appropriate client in your clients page.

    Errors

    The Patreon API uses the following error codes:

    Error Code Meaning
    400 Bad Request -- Something was wrong with your request (syntax, size too large, etc.)
    401 Unauthorized -- Authentication failed (bad API key, invalid OAuth token, incorrect scopes, etc.)
    403 Forbidden -- The requested is hidden for administrators only.
    404 Not Found -- The specified resource could not be found.
    405 Method Not Allowed -- You tried to access a resource with an invalid method.
    406 Not Acceptable -- You requested a format that isn't json.
    410 Gone -- The resource requested has been removed from our servers.
    429 Too Many Requests -- Slow down!
    500 Internal Server Error -- Our server ran into a problem while processing this request. Please try again later.
    503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

    Resources

    Our JSON responses follow the JSON:API standard, with the following structure for our three main resources (users, campaigns, and pledges):

    User

    {
      "type": "user"
      "id": <string>
      "attributes": {
        "first_name": <string>
        "last_name": <string>
        "full_name": <string>
        "vanity": <string>
        "email": <string>
        "about": <string>
        "facebook_id": <string>
        "image_url": <string>
        "thumb_url": <string>
        "youtube": <string>
        "twitter": <string>
        "facebook": <string>
        "created": <date>
        "url": <string>
        // optional properties
        "like_count": <int>
        "comment_count": <int>
      }
      "relationships": {
        "campaign": ...<campaign>...
      }
    }
    

    Campaign

    {
      "type": "campaign"
      "id": <string>
      "attributes": {
        "summary": <string>
        "creation_name": <string>
        "pay_per_name": <string>
        "one_liner": <string>
        "main_video_embed": <string>
        "main_video_url": <string>
        "image_small_url": <string>
        "image_url": <string>
        "thanks_video_url": <string>
        "thanks_embed": <string>
        "thanks_msg": <string>
        "is_monthly": <bool>
        "is_nsfw": <bool>
        "created_at": <date>
        "published_at": <date>
        "pledge_url": <string>
        "pledge_sum": <int>
        "patron_count": <int>
        "creation_count": <int>
        "outstanding_payment_amount_cents": <int>
      }
      "relationships": {
        "creator": ...<user>...
        "rewards": [ ...<reward>, <reward>, ... ]
        "goals": [ ...<goal>, <goal>, ... ]
        "pledges": [ ...<pledge>, <pledge>, ... ]
      }
    }
    
    

    Pledge

    {
      "type": "pledge"
      "id": <string>
      "attributes": {
        "amount_cents": <int>
        "created_at": <date>
        "declined_since": <date>
        "pledge_cap_cents": <int>
        "patron_pays_fees": <bool>
        // optional properties
        "total_historical_amount_cents": <int>
        "is_paused": <bool>
        "has_shipping_address": <bool>
      }
      "relationships": {
        "patron": ...<user>...
        "reward": ...<reward>...
        "creator": ...<user>...
        "address": ...<address>...
      }
    }
    

    API Endpoints

    To use a given access_token, send it in the Authorization HTTPS Header as follows:

    Authorization: Bearer <access_token>
    

    The three endpoints below are accessed using an OAuth client access_token obtained from the OAuth section. Please go there first if you do not yet have one.

    When performing an API request, the information you are allowed is determined by which access_token you are using. Please be sure to select your access_token appropriately. For example, if someone has granted your OAuth client access to their profile information, and you try to fetch it using your own Creator's Access Token instead of the one created when they granted your client access, you will instead just get your own profile information.

    During the transition period from APIv1 to APIv2, it is possible to use v2 scopes on v1 endpoints. If you do this, note that you may have more scope than you had in v1, and so the set of data returned will be much greater.

    Fetching a patron's profile info

    require 'patreon'
    
    class OAuthController < ApplicationController
      def redirect
        oauth_client = Patreon::OAuth.new(client_id, client_secret)
        tokens = oauth_client.get_tokens(params[:code], redirect_uri)
        access_token = tokens['access_token']
    
        api_client = Patreon::API.new(access_token)
        user_response = api_client.fetch_user()
        @user = user_response.data
        @pledge = @user.pledges ? @user.pledges[0] : nil
      end
    end
    
    import patreon
    from flask import request
    ...
    
    client_id = None      # Replace with your data
    client_secret = None  # Replace with your data
    creator_id = None     # Replace with your data
    
    @app.route('/oauth/redirect')
    def oauth_redirect():
        oauth_client = patreon.OAuth(client_id, client_secret)
        tokens = oauth_client.get_tokens(request.args.get('code'), '/oauth/redirect')
        access_token = tokens['access_token']
    
        api_client = patreon.API(access_token)
        user_response = api_client.fetch_user()
        user = user_response.data()
        pledges = user.relationship('pledges')
        pledge = pledges[0] if pledges and len(pledges) > 0 else None
    
    curl --request GET \
      --url https://www.patreon.com/api/oauth2/api/current_user \
      --header 'authorization: Bearer <access_token>'
    
    <?php
    
    use Patreon\API;
    use Patreon\OAuth;
    
    $client_id = null;      // Replace with your data
    $client_secret = null;  // Replace with your data
    $redirect_uri = null;   // Replace with your data
    
    $oauth_client = new Patreon\OAuth($client_id, $client_secret);
    $tokens = $oauth_client->get_tokens($_GET['code'], $redirect_uri);
    $access_token = $tokens['access_token'];
    $refresh_token = $tokens['refresh_token'];
    
    $api_client = new Patreon\API($access_token);
    $patron_response = $api_client->fetch_user();
    $patron = $patron_response->get('data');
    $pledge = null;
    if ($patron->has('relationships.pledges')) {
        $pledge = $patron->relationship('pledges')->get(0)->resolve($patron_response);
    }
    
    ?>
    
    import url from 'url'
    import patreonAPI, { oauth as patreonOAuth } from 'patreon'
    
    const CLIENT_ID = null     // Replace with your data
    const CLIENT_SECRET = null // Replace with your data
    const redirectURL = null   // Replace with your data
    
    const patreonOAuthClient = patreonOAuth(CLIENT_ID, CLIENT_SECRET)
    
    function handleOAuthRedirectRequest(request, response) {
        const oauthGrantCode = url.parse(request.url, true).query.code
    
        patreonOAuthClient
            .getTokens(oauthGrantCode, redirectURL)
            .then(tokensResponse => {
                const patreonAPIClient = patreonAPI(tokensResponse.access_token)
                return patreonAPIClient('/current_user')
            })
            .then(({ store }) => {
                response.end(store.findAll('user').map(user => user.serialize()))
            })
            .catch(err => {
                console.error('error!', err)
                response.end(err)
            })
    }
    
    //Get the raw json from the response. See for the expected format of the data
    var patreon_response = patreon_client('/current_user').then(function(result) {
      user_store = result.store
      const data = result.rawJson
      /*  data.data will contain the current_user, but there might be more users returned and loaded into the store.
       *  Get the id of the requested user, and find it in the store
       */
      const myUserId = data.data.id
      creator = user_store.find('user', myUserId)
    })
    
    import com.patreon.OAuth;
    import com.patreon.API;
    import org.json.JSONObject;
    import org.json.JSONArray;
    ...
    
    String clientID = null;        // Replace with your data
    String clientSecret = null;    // Replace with your data
    String creatorID = null;       // Replace with your data
    String redirectURI = null;     // Replace with your data
    String code = null;            // get from inbound HTTP request
    
    OAuth oauthClient = new OAuth(clientID, clientSecret);
    JSONObject tokens = oauthClient.getTokens(code, redirectURI);
    String accessToken = tokens.getString("access_token");
    
    API apiClient = new API(accessToken);
    JSONObject userResponse = apiClient.fetchUser();
    JSONObject user = userResponse.getJSONObject("data");
    JSONArray included = userResponse.getJSONArray("included");
    JSONObject pledge = null;
    if (included != null) {
       for (int i = 0; i < included.length(); i++) {
           JSONObject object = included.getJSONObject(i);
           if (object.getString("type").equals("pledge") && object.getJSONObject("relationships").getJSONObject("creator").getJSONObject("data").getString("id").equals(creatorID)) {
               pledge = object;
               break;
           }
       }
    }
    
       // use the user, pledge, and campaign objects as you desire
    

    Response:

    {
      "data": {
        "attributes": {
          "about": null,
          "created": "2017-10-20T21:36:23+00:00",
          "discord_id": null,
          "email": "[email protected]",
          "facebook": null,
          "facebook_id": null,
          "first_name": "Corgi",
          "full_name": "Corgi The Dev",
          "gender": 0,
          "has_password": true,
          "image_url": "https://c8.patreon.com/2/400/0000000",
          "is_deleted": false,
          "is_email_verified": false,
          "is_nuked": false,
          "is_suspended": false,
          "last_name": "The Dev",
          "social_connections": {
            "deviantart": null,
            "discord": null,
            "facebook": null,
            "reddit": null,
            "spotify": null,
            "twitch": null,
            "twitter": null,
            "youtube": null
          },
          "thumb_url": "https://c8.patreon.com/2/100/0000000",
          "twitch": null,
          "twitter": null,
          "url": "https://www.patreon.com/corgithedev",
          "vanity": "corgithedev",
          "youtube": null
        },
        "id": "0000000",
        "relationships": {
          "pledges": {
            "data": []
          }
        },
        "type": "user"
      },
      "links": {
        "self": "https://www.patreon.com/api/user/0000000"
      }
    }
    

    This endpoint returns a JSON representation of the user who granted your OAuth client an access_token. It is most typically used in the OAuth "Log in with Patreon flow" to create or update the patron's account info in your application.

    The Patreon JS library uses a data store pattern for storing inflated objects from the returned results of API calls. In some cases, especially if you have been granted the scopes for being a multi-campaign client or are opted-in to some API beta programs, the JS client calling /current_user will fetch the current user's campaign, as well as all the patron users connected to that campaign.

    This can result in the user store in the JS library having a larger list of users than expected for a call to /current_user, but the current user's user object will be in that list.

    HTTPS Request

    GET https://www.patreon.com/api/oauth2/api/current_user

    Fetch a creator profile and campaign info

    require 'patreon'
    
    access_token = nil  # Replace with your data
    
    api_client = Patreon::API.new(access_token)
    campaign_response = api_client.fetch_campaign()
    campaign = campaign_response.data[0]
    puts "campaign is", campaign
    user = campaign.creator
    puts "user is", user
    
    <?php
    
    use Patreon\API;
    use Patreon\OAuth;
    
    $access_token = null;   // Replace with your data
    
    $api_client = new Patreon\API($access_token);
    $campaign_response = $api_client->fetch_campaign();
    $campaign = $campaign_response->get('data')->get('0');
    echo "campaign is\n";
    print_r($campaign->asArray(true));
    $user = $campaign->relationship('creator')->resolve($campaign_response);
    echo "user is\n";
    print_r($user->asArray(true));
    
    import patreon
    
    access_token = None   # Replace with your creator access token
    
    api_client = patreon.API(access_token)
    campaign_response = api_client.fetch_campaign()
    campaign = campaign_response.data()[0]
    print('campaign is', campaign)
    user = campaign.relationship('creator')
    print('user is', user)
    
    curl --request GET \
      --url https://www.patreon.com/api/oauth2/api/current_user/campaigns \
      --header 'Authorization: Bearer <access_token>'
    
    import patreonAPI from 'patreon'
    
    const accessToken = null   // Replace with your creator access token
    
    const patreonAPIClient = patreonAPI(accessToken)
    patreonAPIClient('/current_user/campaigns')
        .then(({ store }) => {
            const user = store.findAll('user').map(user => user.serialize())
            console.log('user is', user)
            const campaign = store.findAll('campaign').map(campaign => campaign.serialize())
            console.log('campaign is', campaign)
        })
        .catch(err => {
            console.error('error!', err)
            response.end(err)
        })
    
    import com.patreon.OAuth;
    import com.patreon.API;
    import org.json.JSONObject;
    import org.json.JSONArray;
    ...
    
    String accessToken = null; // Replace with your data
    
    API apiClient = new API(accessToken);
    JSONObject campaignResponse = apiClient.fetchCampaign();
    JSONObject campaign = campaignResponse.getJSONObject("data");
    JSONArray included = userResponse.getJSONArray("included");
    JSONObject user = null;
    // This will get simplified in future versions of the library.
    // For now, we must denormalize the JSON:API response by hand.
    String userID = campaign .getJSONObject("relationships").getJSONObject("creator").getJSONObject("data").getString("id");
    if (included != null) {
       for (int i = 0; i < included.length(); i++) {
           JSONObject object = included.getJSONObject(i);
           if (object.getString("type").equals("user") && object.getJSONObject("relationships").getJSONObject("creator").getJSONObject("data").getString("id").equals(userID)) {
               user = object;
               break;
           }
       }
    }
    

    Response:

    {
      "data": [{
        "attributes": {
          "created_at": "2017-10-20T21:39:01+00:00",
          "creation_count": 0,
          "creation_name": "Documentation",
          "discord_server_id": null,
          "display_patron_goals": false,
          "earnings_visibility": "public",
          "image_small_url": null,
          "image_url": null,
          "is_charged_immediately": false,
          "is_monthly": false,
          "is_nsfw": false,
          "is_plural": false,
          "main_video_embed": null,
          "main_video_url": null,
          "one_liner": null,
          "outstanding_payment_amount_cents": 0,
          "patron_count": 0,
          "pay_per_name": null,
          "pledge_sum": 0,
          "pledge_url": "/bePatron?c=0000000",
          "published_at": "2017-10-20T21:49:31+00:00",
          "summary": null,
          "thanks_embed": null,
          "thanks_msg": null,
          "thanks_video_url": null
        },
        "id": "0000000",
        "relationships": {
          "creator": {
            "data": {
              "id": "1111111",
              "type": "user"
            },
            "links": {
              "related": "https://www.patreon.com/api/user/1111111"
            }
          },
          "goals": {
            "data": []
          },
          "rewards": {
            "data": [{
                "id": "-1",
                "type": "reward"
              },
              {
                "id": "0",
                "type": "reward"
              }
            ]
          }
        },
        "type": "campaign"
      }],
      "included": [{
          "attributes": {
            "about": null,
            "created": "2017-10-20T21:36:23+00:00",
            "discord_id": null,
            "email": "[email protected]",
            "facebook": null,
            "facebook_id": null,
            "first_name": "Corgi",
            "full_name": "Corgi The Dev",
            "gender": 0,
            "has_password": true,
            "image_url": "https://c8.patreon.com/2/400/1111111",
            "is_deleted": false,
            "is_email_verified": false,
            "is_nuked": false,
            "is_suspended": false,
            "last_name": "The Dev",
            "social_connections": {
              "deviantart": null,
              "discord": null,
              "facebook": null,
              "reddit": null,
              "spotify": null,
              "twitch": null,
              "twitter": null,
              "youtube": null
            },
            "thumb_url": "https://c8.patreon.com/2/100/1111111",
            "twitch": null,
            "twitter": null,
            "url": "https://www.patreon.com/drkthedev",
            "vanity": "drkthedev",
            "youtube": null
          },
          "id": "1111111",
          "relationships": {
            "campaign": {
              "data": {
                "id": "0000000",
                "type": "campaign"
              },
              "links": {
                "related": "https://www.patreon.com/api/campaigns/0000000"
              }
            }
          },
          "type": "user"
        },
        {
          "attributes": {
            "amount": 0,
            "amount_cents": 0,
            "created_at": null,
            "description": "Everyone",
            "id": "-1",
            "remaining": 0,
            "requires_shipping": false,
            "type": "reward",
            "url": null,
            "user_limit": null
          },
          "id": "-1",
          "relationships": {
            "creator": {
              "data": {
                "id": "1111111",
                "type": "user"
              },
              "links": {
                "related": "https://www.patreon.com/api/user/1111111"
              }
            }
          },
          "type": "reward"
        },
        {
          "attributes": {
            "amount": 1,
            "amount_cents": 1,
            "created_at": null,
            "description": "Patrons Only",
            "id": "0",
            "remaining": 0,
            "requires_shipping": false,
            "type": "reward",
            "url": null,
            "user_limit": null
          },
          "id": "0",
          "relationships": {
            "creator": {
              "data": {
                "id": "1111111",
                "type": "user"
              },
              "links": {
                "related": "https://www.patreon.com/api/user/1111111"
              }
            }
          },
          "type": "reward"
        }
      ]
    }
    

    This endpoint returns a JSON representation of the user's campaign, including its rewards and goals, and the pledges to it. If there are more than twenty pledges to the campaign, the first twenty will be returned, along with a link to the next page of pledges.

    HTTPS Request

    GET https://www.patreon.com/api/oauth2/api/current_user/campaigns

    Query Parameters

    Parameter Default Description
    includes rewards,creator,goals,pledges You can pass this rewards, creator, goals, or pledges

    Paging through a list of pledges

    require 'patreon'
    require 'uri'
    require 'cgi'
    
    access_token = nil # your Creator Access Token
    api_client = Patreon::API.new(access_token)
    
    # Get the campaign ID
    campaign_response = api_client.fetch_campaign()
    campaign_id = campaign_response.data[0].id
    
    # Fetch all pledges
    all_pledges = []
    cursor = nil
    while true do
        page_response = api_client.fetch_page_of_pledges(campaign_id, 25, cursor)
        all_pledges += page_response.data
        next_page_link = page_response.links[page_response.data]['next']
        if next_page_link
            parsed_query = CGI::parse(next_page_link)
            cursor = parsed_query['page[cursor]'][0]
        else
            break
        end
    end
    
    # Mapping to all patrons. Feel free to customize as needed.
    # As with all standard Ruby objects, (pledge.methods - Object.methods) will list the available attributes and relationships
    puts all_pledges.map{ |pledge| { full_name: pledge.patron.full_name, amount_cents: pledge.amount_cents } }
    
    import patreon
    
    access_token = nil # your Creator Access Token
    api_client = patreon.API(access_token)
    
    # Get the campaign ID
    campaign_response = api_client.fetch_campaign()
    campaign_id = campaign_response.data()[0].id()
    
    # Fetch all pledges
    all_pledges = []
    cursor = None
    while True:
        pledges_response = api_client.fetch_page_of_pledges(campaign_id, 25, cursor=cursor)
        pledges += pledges_response.data()
        cursor = api_client.extract_cursor(pledges_response)
        if not cursor:
            break
    
    // TODO: Needs a code example of pagination
    
    curl --request GET \
      --url https://www.patreon.com/api/oauth2/api/campaigns/<campaign_id>/pledges?include=patron.null \
      --header 'Authorization: Bearer <access_token>
    
    // TODO: get pagination example
    
    <?php
    
    use Patreon\API;
    use Patreon\OAuth;
    
    $access_token = null; // Your Creator Access Token
    
    $api_client = new Patreon\API($access_token);
    
    // Get your campaign data
    $campaign_response = $api_client->fetch_campaign();
    $campaign_id = $campaign_response->get('data.0.id');
    
    // get page after page of pledge data
    $all_pledges = [];
    $cursor = null;
    while (true) {
        $pledges_response = $api_client->fetch_page_of_pledges($campaign_id, 25, $cursor);
        // loop over the pledges to get e.g. their amount and user name
        foreach ($pledges_response->get('data')->getKeys() as $pledge_data_key) {
            $pledge_data = $pledges_response->get('data')->get($pledge_data_key);
            array_push($all_pledges, $pledge_data);
        }
        // get the link to the next page of pledges
        if (!$pledges_response->has('links.next')) {
            // if there's no next page, we're done!
            break;
        }
        $next_link = $pledges_response->get('links.next');
        // otherwise, parse out the cursor param
        $next_query_params = explode("?", $next_link)[1];
        parse_str($next_query_params, $parsed_next_query_params);
        $cursor = $parsed_next_query_params['page']['cursor'];
    }
    ?>
    

    Response:

    {
        "data": [
            {
                "attributes": {
                    "amount_cents": 100,
                    "created_at": "2016-07-25T20:59:52+00:00",
                    "declined_since": null,
                    "patron_pays_fees": false,
                    "pledge_cap_cents": null
                },
                "id": "2745627",
                "relationships": {
                    "patron": {
                        "data": {
                            "id": "111111",
                            "type": "user"
                        },
                        "links": {
                            "related": "https://www.patreon.com/api/user/111111"
                        }
                    },
                    "reward": {
                        "data": {
                            "id": "222222",
                            "type": "reward"
                        },
                        "links": {
                            "related": "https://www.patreon.com/api/rewards/222222"
                        }
                    }
                },
                "type": "pledge"
            }
        ],
        "included": [
            {
                "attributes": {
                    "about": "sample about text",
                    "created": "2015-01-15T07:25:51+00:00",
                    "email": "[email protected]",
                    "facebook": null,
                    "first_name": "Foo",
                    "full_name": "Foo Bar",
                    "gender": 1,
                    "image_url": "",
                    "is_email_verified": true,
                    "last_name": "Bar",
                    "social_connections": {
                        "deviantart": null,
                        "discord": null,
                        "facebook": null,
                        "reddit": null,
                        "spotify": null,
                        "twitch": null,
                        "twitter": null,
                        "youtube": null
                    },
                    "thumb_url": "",
                    "twitch": null,
                    "twitter": "foo",
                    "url": "https://www.patreon.com/foo",
                    "vanity": "foo",
                    "youtube": null
                },
                "id": "111111",
                "type": "user"
            },
            {
                "attributes": {
                    "amount_cents": 100,
                    "created_at": "2017-12-19T01:56:37.762679+00:00",
                    "description": "",
                    "discord_role_ids": None,
                    "edited_at": "2017-12-19T01:56:37.762679+00:00",
                    "image_url": None,
                    "patron_count": 1,
                    "post_count": None,
                    "published": True,
                    "published_at": "2017-12-19T01:56:37.762679+00:00",
                    "remaining": None,
                    "requires_shipping": False,
                    "title": "",
                    "unpublished_at": None,
                    "url": "/bePatron?c=12345&rid=222222",
                    "user_limit": None
                },
                "id": "222222",
                "type": "reward"
            }
        ],
        "links": {
            "first": "https://www.patreon.com/api/oauth2/api/campaigns/70261/pledges?page%5Bcount%5D=10&sort=created",
            "next": "https://www.patreon.com/api/oauth2/api/campaigns/70261/pledges?page%5Bcount%5D=10&sort=created&page%5Bcursor%5D=2017-08-21T20%3A16%3A49.258893%2B00%3A00"
        },
        "meta": {
            "count": 18
        }
    }
    

    This endpoint returns a JSON list of pledges to the provided campaign_id. They are sorted by the date the pledge was made, and provide relationship references to the user who made each respective pledge, as well as the reward tier pledged to.

    The API response will also contain a links field which may be used to fetch the next page of pledges, or go back to the first page.

    HTTPS Request

    GET https://www.patreon.com/api/oauth2/api/campaigns/<campaign_id>/pledges?include=patron.null

    Paging

    You may only fetch your own list of pledges. If you attempt to fetch another creator's pledge list, the API call will return an HTTPS 403. If you would like to create an application which can manage many creator's campaigns, please contact us at [email protected].

    More Data, Paging, and Sorting

    Requesting specific data

    https://www.patreon.com/api/oauth2/api/campaigns/<campaign_id>/pledges?include=reward&fields[pledge]=total_historical_amount_cents,is_paused
    

    Want to retrieve the patrons for your pledges, or the goals for a given campaign?

    To retrieve specific attributes or relationships other than the defaults, you can pass fields and include parameters respectively, each being comma-separated lists of attributes or resources. You can see which attributes or relationships are requestable on a given resource in the resources section.

    Requesting optional attributes

    To fetch an optional property (for example total_historical_amount_cents and is_paused on pledge), use the fields query params.

    GET https://www.patreon.com/api/oauth2/api/campaigns/<campaign_id>/pledges?fields[pledge]=total_historical_amount_cents,is_paused

    Restricting included resources

    By default, fetching or including a resource will follow that resource's relationship tree as well.

    For a more explicit approach, you may instead set json-api-use-default-includes=false, which will limit relationships to only those specifically included.

    Pagination and sorting

    https://www.patreon.com/api/oauth2/api/campaigns/<campaign_id>/pledges?page[count]=5&sort=-created&page[cursor]=2012-01-19
    

    Our API endpoints support pagination and sorting on some attributes.

    Parameter Description
    page[count] Maximum number of results returned
    sort Comma-separated attributes to sort by, in order of precedence. Each attribute can be prepended with - to indicate descending order. Currently, we support created and updated for pledges.
    page[cursor] From the sorted results, start returning where the first attribute in sort equals this value.

    The example URL on the right is for 5 pledges with max created before 2012-01-19, in reverse chronological order.

    The links field of the response body contains URLs of first, prev, next, and last pages if they exist.

    Webhooks

    Sample Webhook payload

    {
      "data": {
        "attributes": {
          "amount_cents": 250,
          "created_at": "2015-05-18T23:50:42+00:00",
          "declined_since": null,
          "patron_pays_fees": false,
          "pledge_cap_cents": null
        },
        "id": "1",
        "relationships": {
          "address": {
            "data": null
          },
          "card": {
            "data": null
          },
          "creator": {
            "data": {
              "id": "3024102",
              "type": "user"
            },
            "links": {
              "related": "https://www.patreon.com/api/user/3024102"
            }
          },
          "patron": {
            "data": {
              "id": "32187",
              "type": "user"
            },
            "links": {
              "related": "https://www.patreon.com/api/user/32187"
            }
          },
          "reward": {
            "data": {
              "id": "599336",
              "type": "reward"
            },
            "links": {
              "related": "https://www.patreon.com/api/rewards/599336"
            }
          }
        },
        "type": "pledge"
      },
      "included": [{ ** * Creator Object ** *
        },
        { ** * Patron Object ** *
        },
        { ** * Reward Object ** *
        },
      ]
    }
    

    Webhooks allow you to receive real-time updates from our servers. While there will eventually be many events about which you can be notified, we presently only support webhooks that trigger when you get a new patron, or an existing patron edits or deletes their pledge.

    By creating a webhook, you can specify a URL for us to send an HTTP POST to when one of these events occur. This POST request will contain the relevant data from the user action in JSON format. It will also have headers

    X-Patreon-Event: [trigger]
    X-Patreon-Signature: [message signature]

    where the message signature is the HEX digest of the message body HMAC signed (with MD5) using your webhook's secret viewable on the webhooks page. You can use this to verify us as the sender of the message.

    Triggers

    A trigger is an event type. The syntax of a trigger is [resource]:[action] (e.g. pledges:create). You can add or remove triggers for a webhook to listen to on the webhooks page.

    Trigger Description
    pledge:create Fires when a user pledges to a creator. This trigger fires even if the charge is declined or fraudulent. The pledge object is still created, even if the user is not a valid patron due to charge status.
    pledge:update Fires when a user edits their pledge. Notably, the pledge ID will change, because the underlying pledge object is different. The user id should be the primary key to reference.
    pledge:delete Fires when a user stops pledging or the pledge is cancelled altogether. Does not fire for pledge pausing, as the pledge still exists.

    Robust Retries

    To ensure that you can rely exclusively on webhooks data, we've put measures in place to make sure your server does not miss a single event.

    In case of failed delivery, perhaps due to network problems or server outages on your end, we will store the events and make sure none were lost until your server is back up. Over time, we’ll try to send them to you and re-try your server. The next successful call to your server will include all the past webhooks that accumulated.

    Our retry schedule is approximately as follows:

    You can also use our webhooks page to manually send yourself the queued messages.

    Programmatically Adding Webhooks

    In addition to manually adding webhooks, you can also create, read, update, delete and list webhooks with our API. This feature is currently in early beta. If you would like to know more please contact us at [email protected].

    APIv2: OAuth

    What's new?

    At a high level, the main differences between APIv1 and APIv2 are:

    1. The Pledges resource has been replaced by the Members resource. Members return more data about the relationship between a patron and a creator, including charge status and membership lifetime.
    2. All data attributes and relationships must be explicitly requested with the fields and include query params. In v1, the server would return certain attributes and relationships by default. Now, in v2, no data other than type and id will be returned for a resource unless it is requested.
    3. The scopes have been improved. We have reworked what scopes are available in the API to provide better access for developers and better security for our users.
    4. Developers can now create webhooks on campaigns on behalf of the creator, so your application can get real-time updates about a creator's campaign.

    What stays the same?

    1. Getting access to a Patreon user’s account via OAuth works much the same. Just make sure to request all required scopes.
    2. The client creator’s access token will automatically have all V2 scopes associated with it.
    3. We will not be deprecating APIv1 in the next year at least.

    Note to those with V1 tokens:

    You will be able to request tokens with any set of APIv2 scopes from your existing APIv1 client. If you choose to create an APIv2-specific client in the developer portal, that client will only be able to request V2 scopes.

    Scopes

    Scope Description
    identity Provides read access to data about the user. See the /identity endpoint documentation for details about what data is available.
    identity[email] Provides read access to the user’s email.
    identity.memberships Provides read access to the user’s memberships.
    campaigns Provides read access to basic campaign data. See the /campaign endpoint documentation for details about what data is available.
    w:campaigns.webhook Provides read, write, update, and delete access to the campaign’s webhooks created by the client.
    campaigns.members Provides read access to data about a campaign’s members. See the /members endpoint documentation for details about what data is available. Also allows the same information to be sent via webhooks created by your client.
    campaigns.members[email] Provides read access to the member’s email. Also allows the same information to be sent via webhooks created by your client.
    campaigns.members.address Provides read access to the member’s address, if an address was collected in the pledge flow. Also allows the same information to be sent via webhooks created by your client.

    Using APIv2 with APIv1

    During the transitionary period, when APIv1 and APIv2 are both available, it is possible to make requests against APIv1 endpoints with APIv2 clients and tokens. APIv2 has more controls around private information, so a fuller set of APIv2 scopes is needed to access V1 resources.

    V1 Scope V2 Scopes Required
    campaigns campaigns
    my-campaign campaigns
    pledges campaigns.members, campaigns.members[email], campaigns.members.address
    pledges-to-me identity.memberships
    users identity, identity[email]

    APIv2: Resource Endpoints

    With APIv2, all properties must be individually requested; there are no more default properties on resources.

    GET /api/oauth2/v2/identity

    Fetches the User resource.

    Top-level includes: memberships, campaign.

    This is the endpoint for accessing information about the current User with reference to the oauth token. With the basic scope of identity, you will receive the user’s public profile information. If you have the identity[email] scope, you will also get the user’s email address. You will not receive email address without that scope.

    // Sample response with email scope for https://www.patreon.com/api/oauth2/v2/identity?fields[user]=about,created,email,first_name,full_name,image_url,last_name,social_connections,thumb_url,url,vanity
    {
        "data": {
            "attributes":
                {
                    "about": "A Patreon Platform User",
                    "created": "2018-04-01T00:36:26+00:00",
                    "email": "[email protected]",
                    "first_name": "Platform",
                    "full_name": "Platform Team",
                    "image_url": "https://url.example",
                    "last_name": "Platform",
                    "social_connections": {
                        "deviantart": null,
                        "discord": null,
                        "facebook": null,
                        "reddit": null,
                        "spotify": null,
                        "twitch": null,
                        "twitter": {"user_id": "12345"},
                        "youtube": null
                    },
                    "thumb_url": "https://url.example",
                    "url": "https://www.patreon.com/example",
                    "vanity": "platform"
                },
            "id": "12345",
            "type": "user",
        },
    }
    

    You can request related data through includes, ie, /api/oauth2/v2/identity?include=memberships and /api/oauth2/v2/identity?include=campaign.

    GET /api/oauth2/v2/campaigns

    Requires the campaigns scope. Returns a list of Campaigns owned by the authorized user.

    Top-level includes: tiers, creator, benefits, goals.

    //Sample response for https://www.patreon.com/api/oauth2/v2/campaigns?fields[campaign]=created_at,creation_name,discord_server_id,image_small_url,image_url,is_charged_immediately,is_monthly,is_nsfw,main_video_embed,main_video_url,one_liner,one_liner,patron_count,pay_per_name,pledge_url,published_at,summary,thanks_embed,thanks_msg,thanks_video_url,has_rss,has_sent_rss_notify,rss_feed_title,rss_artwork_url,patron_count,discord_server_id,google_analytics_id,earnings_visibility
    {
        "data": [
            {
                "attributes": {
                    "created_at": "2018-05-04T23:34:08+00:00",
                    "creation_name": "online communities",
                    "discord_server_id": "1234567890",
                    "google_analytics_id": "1234567890",
                    "has_rss": true,
                    "has_sent_rss_notify": true,
                    "image_small_url": "https://example.url",
                    "image_url": "https://example.url",
                    "is_charged_immediately": false,
                    "is_monthly": false,
                    "is_nsfw": false,
                    "main_video_embed": null,
                    "main_video_url": "https://example.url",
                    "one_liner": null,
                    "patron_count": 2,
                    "pay_per_name": "creation",
                    "pledge_url": "/bePatron?c=1234560",
                    "published_at": "2018-05-09T17:12:01+00:00",
                    "rss_artwork_url": "https://example.url",
                    "rss_feed_title": "My custom feed",
                    "summary": "Putting the internet to work for creators.",
                    "thanks_embed": null,
                    "thanks_msg": null,
                    "thanks_video_url": null
                },
                "id": "1234560",
                "type": "campaign"
            }
        ],
        "meta": {
            "pagination": {
                "total": 1
            }
        }
    }
    

    GET /api/oauth2/v2/campaigns/{campaign_id}

    Requires the campaigns scope. The single resource endpoint returns information about a single Campaign, fetched by campaign ID.

    Top-level includes: tiers, creator, benefits, goals.

    //Sample response for https://www.patreon.com/api/oauth2/v2/campaigns/{campaign_id}?fields[campaign]=created_at,creation_name,discord_server_id,image_small_url,image_url,is_charged_immediately,is_monthly,_is_nswf,main_video_embed,main_video_url,one_liner,one_liner,patron_count,pay_per_name,pledge_url,published_at,summary,thanks_embed,thanks_msg,thanks_video_url
    {
        "data":
            {
                "attributes": {
                    "created_at": "2018-04-01T15:27:11+00:00",
                    "creation_name": "online communities",
                    "discord_server_id": "1234567890",
                    "image_small_url": "https://example.url",
                    "image_url": "https://example.url",
                    "is_charged_immediately": false,
                    "is_monthly": true,
                    "is_nsfw": false,
                    "main_video_embed": null,
                    "main_video_url": null,
                    "one_liner": null,
                    "patron_count": 1000,
                    "pay_per_name": "month",
                    "pledge_url": "/bePatron?c=12345",
                    "published_at": "2018-04-01T18:15:34+00:00",
                    "summary": "The most creator-first API",
                    "thanks_embed": "",
                    "thanks_msg": null,
                    "thanks_video_url": null,
                },
               "id": "12345",
               "type": "campaign"
            },
    }
    

    GET /api/oauth2/v2/campaigns/{campaign_id}/members

    Gets the Members for a given Campaign. Requires the campaigns.members scope.

    Top-level includes: address (requires campaign.members.address scope), campaign, currently_entitled_tiers, user.

    We recommend using currently_entitled_tiers to see exactly what a Member is entitled to, either as an include on the members list or on the member get.

    // Sample response for https://www.patreon.com/api/oauth2/v2/campaigns/{campaign_id}/members?include=currently_entitled_tiers,address&fields[member]=full_name,is_follower,last_charge_date,last_charge_status,lifetime_support_cents,currently_entitled_amount_cents,patron_status&fields[tier]=amount_cents,created_at,description,discord_role_ids,edited_at,patron_count,published,published_at,requires_shipping,title,url
    {
        "data": [
            {
                "attributes": {
                    "full_name": "Platform Team",
                    "is_follower": false,
                    "last_charge_date": "2018-04-01T21:28:06+00:00",
                    "last_charge_status": "Paid",
                    "lifetime_support_cents": 400,
                    "currently_entitled_amount_cents": 400,
                    "patron_status": "active_patron",
               },
               "id": "03ca69c3-ebea-4b9a-8fac-e4a837873254",
               "relationships": {
                    "address": {
                        "data": {
                            "id": "12345",
                            "type": "address"
                        }
                    },
                    "currently_entitled_tiers": {
                        "data": [{
                            "id": "54321",
                            "type": "tier",
                        }]
                    }
               },
               "type": "member",
            },
            ...other members...,
        ],
        "included": [
            {
                "attributes": {
                    "addressee": "Platform Team",
                    "city": "San Francisco",
                    "confirmed": true,
                    "confirmed_at": null,
                    "country": "US",
                    "created_at": "2018-06-03T16:23:38+00:00",
                    "line_1": "555 Main St",
                    "line_2": "",
                    "phone_number": null,
                    "postal_code": "94103",
                    "state": "CA"
                },
                "id": "12345",
                "type": "address"
            },{
            "attributes": {
                "amount_cents": 100,
                "created_at": "2018-04-01T04:15:41.403645+00:00",
                "description": "A tier",
                "discord_role_ids": ["1234567890"],
                "edited_at": "2018-04-01T02:55:36.963334+00:00",
                "patron_count": 32,
                "published": true,
                "published_at": "2018-04-01T02:55:36.938342+00:00",
                "requires_shipping": false,
                "title": "Patron",
                "url": "/bePatron?c=12345&rid=54321",
            },
            "id": "54321",
            "type": "tier",
        }],
        "links": {
            "next": "https://www.patreon.com/api/oauth2/v2/campaigns/{campaign_id}/members?page%5Bcursor%5D=12345678abcdefg",
        },
        "meta": {
            "pagination": {
                "cursors": {
                    "next": "12345678abcdefg"
                },
                "total": 100
            }
        }
    }
    

    GET /api/oauth2/v2/members/{id}

    Get a particular member by id. Requires the campaigns.members scope.

    Top-level includes: address (requires campaign.members.address scope), campaign, currently_entitled_tiers, user.

    We recommend using currently_entitled_tiers to see exactly what a member is entitled to, either as an include on the members list or on the member get.

    // Sample response for https://www.patreon.com/api/oauth2/v2/members/03ca69c3-ebea-4b9a-8fac-e4a837873254?fields[member]=full_name,is_follower,email,last_charge_date,last_charge_status,lifetime_support_cents,patron_status,currently_entitled_amount_cents,pledge_relationship_start,will_pay_amount_cents&fields%5Btier%5D=title&fields%5Buser%5D=full_name,hide_pledges
    {
        "data": {
            "attributes": {
                "full_name": "Platform Team",
                "email": "[email protected],
                "is_follower": false,
                "last_charge_date": "2018-04-01T21:28:06+00:00",
                "last_charge_status": "Paid",
                "lifetime_support_cents": 400,
                "patron_status": "active_patron",
                "currently_entitled_amount_cents": 100,
                "pledge_relationship_start": "2018-04-01T16:33:27.861405+00:00",
                "will_pay_amount_cents": 100},
           "id": "03ca69c3-ebea-4b9a-8fac-e4a837873254",
           "relationships": {
                "address": {
                    "data": {
                        "id": "123456",
                        "type": "address"
                    }
                },
                "currently_entitled_tiers": {
                    "data": [
                        {
                            "id": "99001122",
                            "type": "tier"
                        }
                    ]
                },
                "user": {
                    "data": {
                        "id": "654321",
                        "type": "user"
                    }
                }
           },
           "type": "member",
        },
        "included": [
            {
                "attributes": {
                    "addressee": "Platform Team",
                    "city": "San Francisco",
                    "confirmed": true,
                    "confirmed_at": null,
                    "country": "US",
                    "created_at": "2018-06-03T16:23:38+00:00",
                    "line_1": "555 Main St",
                    "line_2": "",
                    "phone_number": null,
                    "postal_code": "94103",
                    "state": "CA"
                },
                "id": "123456",
                "type": "address"
            },
            {
                "attributes": {
                    "full_name": "Platform Team",
                    "hide_pledges": false,
                },
                "id": "654321",
                "type": "user"
            },
            {
                "attributes": {
                    "title": "Tshirt Tier"
                },
                "id": "99001122",
                "type": "tier"
            }
        ]
    }
    

    APIv2: Webhook Endpoints

    GET /api/oauth2/v2/webhooks

    Get the Webhooks for the current user's Campaign created by the API client. You will only be able to see webhooks created by your client. Requires the w:campaigns.webhook scope.

    Top-level includes: client, campaign.

    // Sample response https://www.patreon.com/api/oauth2/v2/webhooks/?fields[webhook]=last_attempted_at,num_consecutive_times_failed,paused,secret,triggers,uri
    {
        "data": [
            {
                "attributes": {
                    "last_attempted_at": "2018-04-01T20:09:18+00:00",
                    "num_consecutive_times_failed": 0,
                    "paused": false,
                    "secret": "hereisaverycomplexsecret",
                    "triggers": [
                        "members:create",
                        "members:delete",
                        "members:update"
                    ],
                    "uri": "https://requestb.in/123456"},
                "id": "2793",
                "type": "webhook",
            },
        ],
    }
    

    POST /api/oauth2/v2/webhooks

    Create a Webhook on the current user’s campaign. Requires the w:campaigns.webhook scope.

    Triggers v2

    Trigger Cause
    members:create Triggered when a new member is created. Note that you may get more than one of these per patron if they delete and renew their membership. Member creation only occurs if there was no prior payment between patron and creator.
    members:update Triggered when the membership information is changed. Includes updates on payment charging events
    members:delete Triggered when a membership is deleted. Note that you may get more than one of these per patron if they delete and renew their membership. Deletion only occurs if no prior payment happened, otherwise pledge deletion is an update to member status.
    members:pledge:create Triggered when a new pledge is created for a member. This includes when a member is created through pledging, and when a follower becomes a patron.
    members:pledge:update Triggered when a member updates their pledge.
    members:pledge:delete Triggered when a member deletes their pledge.
    // Example POST Payload
    {
      "data": {
        "type": "webhook",
        "attributes": {
          "triggers": ["members:create", "members:update", "members:delete"],
          "uri": "https://www.example.com",
        },
        "relationships": {
          "campaign": {
            "data": {"type": "campaign", "id": "12345"},
          },
        },
      },
    }
    
    // Example API response
    {  
       "data":{  
          "attributes":{  
             "last_attempted_at": null,
             "paused":false,
             "num_consecutive_times_failed":0,
             "secret":"abcdefghiklmnopqrstuvwyz",
             "triggers":[
                "members:create",
                "members:update",
                "members:delete"
             ],
             "uri":"https://example.com/hooks/patreon"
          },
          "id":"3955",
          "type":"webhook"
       }
    }
    

    Webhook Responses

    When a webhook fires, the data will look something like this. Note that there will be a X-Patreon-Signature header, which is the HEX digest of the message body HMAC signed (with MD5) using your webhook's secret. We suggest you use this to verify authenticity of the webhook event. Webhook secrets should not be shared.

    {
      "data": {
        "attributes": {
          "currently_entitled_amount_cents": null,
          "full_name": "Platform",
          "is_follower": true,
          "last_charge_date": null,
          "last_charge_status": null,
          "lifetime_support_cents": 0,
          "note": "",
          "patron_status": null,
          "pledge_relationship_start": null
        },
        "id": "d485d5ac-6c82-42c6-9c08-c50cf01b73d7",
        "relationships": {
          "address": {
            "data": null
          },
          "campaign": {
            "data": {
              "id": "123456",
              "type": "campaign"
            }
          },
          "currently_entitled_tiers": {
            "data": []
          },
          "user": {
            "data": {
              "id": "987654321",
              "type": "user"
            }
          }
        },
        "type": "member"
      },
      "included": [
        ...campaign data...
        ...user data...
      ]
    }
    

    PATCH /api/oauth2/v2/webhooks/{id}

    Update a webhook with the given id, if the webhook was created by your client. Requires the w:campaigns.webhook scope.

    // Sample PATCH payload
    {
      "data": {
        "id": "1234567",
        "type": "webhook",
        "attributes": {
          "triggers": ["members:create", "members:delete"],
          "uri": "https://www.example2.com",
          "paused": "false" // <- do this if you’re attempting to send missed events, see NOTE in Example Webhook Payload
        }
      }
    }
    

    APIv2: Resources

    Address

    A User's shipping address.

    Address Attributes

    Attribute Type Description
    addressee string Full recipient name. Can be null.
    line_1 string First line of street address. Can be null.
    line_2 string Second line of street address. Can be null.
    postal_code string Postal or zip code. Can be null.
    city string City.
    state string State or province name. Can be null.
    country string Country.
    phone_number string Telephone number. Specified for non-US addresses. Can be null.
    created_at string (UTC ISO format) Datetime address was first created.
    confirmed boolean true if the address was confirmed after creation.
    confirmed_at string (UTC ISO format) When this address was last confirmed, set by confirmed action attribute. Can be null.

    Address Relationships

    Relationship Type Description
    user User
    campaigns array[Campaign]

    Benefit

    A benefit added to the Campaign, which can be added to a tier to be delivered to the patron.

    Benefit Attributes

    Attribute Type Description
    title string Benefit display title.
    description string Benefit display description. Can be null.
    benefit_type string Type of benefit, such as custom for creator-defined benefits. Can be null.
    rule_type string A rule type designation, such as eom_monthly or one_time_immediate. Can be null.
    created_at string (UTC ISO format) Datetime this benefit was created.
    delivered_deliverables_count integer Number of deliverables for this benefit that have been marked complete.
    not_delivered_deliverables_count integer Number of deliverables for this benefit that are due, for all dates.
    deliverables_due_today_count integer Number of deliverables for this benefit that are due today specifically.
    next_deliverable_due_date string (UTC ISO format) The next due date (after EOD today) for this benefit. Can be null.
    tiers_count integer Number of tiers containing this benefit.
    is_deleted boolean true if this benefit has been deleted.

    Benefit Relationships

    Relationship Type Description
    tiers array[Tier]
    deliverables array[Deliverable]
    campaign Campaign

    Campaign v2

    The creator's page, and the top-level object for accessing lists of members, tiers, etc.

    Campaign Attributes

    Attribute Type Description
    summary string The creator's summary of their campaign. Can be null.
    creation_name string The type of content the creator is creating, as in "vanity is creating creation_name". Can be null.
    pay_per_name string The thing which patrons are paying per, as in "vanity is making $1000 per pay_per_name". Can be null.
    one_liner string Pithy one-liner for this campaign, displayed on the creator page. Can be null.
    main_video_embed string Can be null.
    main_video_url string Can be null.
    image_url string Banner image URL for the campaign.
    image_small_url string URL for the campaign's profile image.
    thanks_video_url string URL for the video shown to patrons after they pledge to this campaign. Can be null.
    thanks_embed string Can be null.
    thanks_msg string Thank you message shown to patrons after they pledge to this campaign. Can be null.
    is_monthly boolean true if the campaign charges per month, false if the campaign charges per-post.
    has_rss boolean Whether this user has opted-in to rss feeds.
    has_sent_rss_notify boolean Whether or not the creator has sent a one-time rss notification email.
    rss_feed_title string The title of the campaigns rss feed.
    rss_artwork_url string The url for the rss album artwork. Can be null.
    is_nsfw boolean true if the creator has marked the campaign as containing nsfw content.
    is_charged_immediately boolean true if the campaign charges upfront, false otherwise. Can be null.
    created_at string (UTC ISO format) Datetime that the creator first began the campaign creation process. See published_at.
    published_at string (UTC ISO format) Datetime that the creator most recently published (made publicly visible) the campaign. Can be null.
    pledge_url string Relative (to patreon.com) URL for the pledge checkout flow for this campaign.
    patron_count integer Number of patrons pledging to this creator.
    discord_server_id string The ID of the external discord server that is linked to this campaign. Can be null.
    google_analytics_id string The ID of the Google Analytics tracker that the creator wants metrics to be sent to. Can be null.
    earnings_visibility string Controls the visibility of the total earnings in the campaign.

    Campaign Relationships

    Relationship Type Description
    tiers array[Tier]
    creator User
    benefits array[Benefit]
    goals array[Goal]

    Deliverable

    The record of whether or not a patron has been delivered the benefitthey are owed because of their member tier.

    Deliverable Attributes

    Attribute Type Description
    completed_at string (UTC ISO format) When the creator marked the deliverable as completed or fulfilled to the patron. Can be null.
    delivery_status string One of 'not_delivered', 'delivered', 'wont_deliver'.
    due_at string (UTC ISO format) When the deliverable is due to the patron.

    Deliverable Relationships

    Relationship Type Description
    campaign Campaign
    benefit Benefit
    member Member The member who has been granted the deliverable.
    user User The user who has been granted the deliverable. This user is the same as the member user.

    Goal

    A funding goal in USD set by a creator on a campaign.

    Goal Attributes

    Attribute Type Description
    amount_cents integer Goal amount in USD cents.
    title string Goal title.
    description string Goal description. Can be null.
    created_at string (UTC ISO format) When the goal was created for the campaign.
    reached_at string (UTC ISO format) When the campaign reached the goal. Can be null.
    completed_percentage integer Equal to (pledge_sum/goal amount)*100, helpful when a creator

    wants to hide their pledge sum but still wants their goals to be cash based

    Goal Relationships

    Relationship Type Description
    campaign Campaign The campaign trying to reach the goal

    Media

    A file uploaded to patreon.com, usually an image.

    Media Attributes

    Attribute Type Description
    file_name string File name.
    size_bytes integer Size of file in bytes.
    mimetype string Mimetype of uploaded file, eg: "application/jpeg".
    state string Upload availability state of the file.
    owner_type string Type of the resource that owns the file.
    owner_id string Ownership id (See also owner_type).
    owner_relationship string Ownership relationship type for multi-relationship medias.
    upload_expires_at string (UTC ISO format) When the upload URL expires.
    upload_url string The URL to perform a POST request to in order to upload the media file.
    upload_parameters string All the parameters that have to be added to the upload form request.
    download_url string The URL to download this media. Valid for 24 hours.
    created_at string (UTC ISO format) When the file was created.
    metadata string Metadata related to the file. Can be null.

    Member

    The record of a user's membership to a campaign. Remains consistent across months of pledging.

    Member Attributes

    Attribute Type Description
    patron_status string Can be null.
    is_follower boolean The user is not a pledging patron but has subscribed to updates about public posts.
    full_name string Full name of the member user.
    email string The member's email address. Requires the campaigns.members[email] scope.
    pledge_relationship_start string (UTC ISO format) Datetime of beginning of most recent pledge chainfrom this member to the campaign. Pledge updates do not change this value. Can be null.
    lifetime_support_cents integer The total amount that the member has ever paid to the campaign. 0 if never paid.
    currently_entitled_amount_cents integer The amount in cents that the member is entitled to.This includes a current pledge, or payment that covers the current payment period.
    last_charge_date string (UTC ISO format) Datetime of last attempted charge. null if never charged. Can be null.
    last_charge_status string The result of the last attempted charge. Possible values are ['Paid', 'Declined', 'Deleted', 'Pending', 'Refunded', 'Fraud', 'Other', null]. The only successful status is Paid. null if never charged. Can be null.
    note string The creator's notes on the member.
    will_pay_amount_cents integer The amount in cents the user will pay at the next pay cycle.

    Member Relationships

    Relationship Type Description
    address Address The member's shipping address that they entered for the campaign. Requires the campaign.members.address scope.
    campaign Campaign The campaign that the membership is for.
    currently_entitled_tiers array[Tier] The tiers that the member is entitled to. This includes a current pledge, or payment that covers the current payment period.
    user User The user who is pledging to the campaign.

    OAuthClient

    A client created by a developer, used for getting OAuth2 access tokens.

    OAuthClient Attributes

    Attribute Type Description
    client_secret string Secret token generated when you registered your client.
    name string Display name for your app.
    description string Details about client's functionality.
    author_name string Author name for app attribution.
    domain string Company domain, e.g. www.patreon.com.
    version integer Client API version, e.g 2 for APIv2.
    icon_url string Fully qualified url for your app icon, shown on oauth screen.
    privacy_policy_url string Fully qualified url to our privacy policy, linked on oauth screen. Can be null.
    tos_url string Terms of Service url for your app. Can be null.
    redirect_uris string Space-separated list of fully qualified uris that your oauth is trusted to redirect to after connection.
    default_scopes string Space-separated list of Patreon scopes you wish to associate with this oauth session.

    OAuthClient Relationships

    Relationship Type Description
    user User
    campaign Campaign

    Tier

    A membership level on a campaign, which can have benefits attached to it.

    Tier Attributes

    Attribute Type Description
    amount_cents integer Monetary amount associated with this tier (in U.S. cents).
    user_limit integer Maximum number of patrons this tier is limited to, if applicable. Can be null.
    remaining integer Remaining number of patrons who may subscribe, if there is a user_limit. Can be null.
    description string Tier display description.
    requires_shipping boolean true if this tier requires a shipping address from patrons.
    created_at string (UTC ISO format) Datetime this tier was created.
    url string Fully qualified URL associated with this tier.
    patron_count integer Number of patrons currently registered for this tier.
    post_count integer Number of posts published to this tier. Can be null.
    discord_role_ids string The discord role IDs granted by this tier. Can be null.
    title string Tier display title.
    image_url string Full qualified image URL associated with this tier. Can be null.
    edited_at string (UTC ISO format) Datetime tier was last modified.
    published boolean true if the tier is currently published.
    published_at string (UTC ISO format) Datetime this tier was last published. Can be null.
    unpublished_at string (UTC ISO format) Datetime tier was unpublished, while applicable. Can be null.

    Tier Relationships

    Relationship Type Description
    campaign Campaign The campaign the tier belongs to.
    tier_image Media The image file associated with the tier.
    benefits array[Benefit] The benefits attached to the tier, which are used for generating deliverables

    User v2

    The Patreon user, which can be both patron and creator.

    User Attributes

    Attribute Type Description
    email string The user's email address. Requires certain scopes to access. See the scopes section of this documentation.
    first_name string First name. Can be null.
    last_name string Last name. Can be null.
    full_name string Combined first and last name.
    is_email_verified boolean true if the user has confirmed their email. Requires certain scopes to access. See the scopes section of this documentation.
    vanity string The public "username" of the user. patreon.com/ goes to this user's creator page. Non-creator users might not have a vanity. Can be null.
    about string The user's about text, which appears on their profile. Can be null.
    image_url string The user's profile picture URL, scaled to width 400px.
    thumb_url string The user's profile picture URL, scaled to a square of size 100x100px.
    can_see_nsfw boolean true if this user can view nsfw content. Can be null.
    created string (UTC ISO format) Datetime of this user's account creation.
    url string URL of this user's creator or patron profile.
    like_count integer How many posts this user has liked.
    hide_pledges boolean true if the user has chosen to keep private which creators they pledge to. Can be null.
    social_connections object Mapping from user's connected app names to an object containing the external user id and a profile URL in the respective app.

    User Relationships

    Relationship Type Description
    memberships array[Member] Usually a zero or one-element array with the user's membership to the token creator's campaign, if they are a member. With the identity.memberships scope, this returns memberships to ALL campaigns the user is a member of.
    campaign Campaign

    Webhook

    Webhooks are fired based on events happening on a particular campaign.

    Webhook Attributes

    Attribute Type Description
    triggers collection List of events that will trigger this webhook.
    uri string Fully qualified uri where webhook will be sent (e.g. https://www.example.com/webhooks/incoming).
    paused boolean true if the webhook is paused as a result of repeated failed attempts to post to uri. Set to false to attempt to re-enable a previously failing webhook.
    last_attempted_at string (UTC ISO format) Last date that the webhook was attempted or used.
    num_consecutive_times_failed integer Number of times the webhook has failed consecutively, when in an error state.
    secret string Secret used to sign your webhook message body, so you can validate authenticity upon receipt.

    Webhook Relationships

    Relationship Type Description
    client OAuth-Client The client which created the webhook
    campaign Campaign The campaign whose events trigger the webhook.

    External Services

    We have an ever expanding set of external services that enable creators to manage and reward patrons in a flexible way.

    Zapier

    Zapier is an automation tool that connects your favorite apps, such as Gmail, Slack, MailChimp, and over 750 more. You can use the Patreon Zapier plugin to automate repetitive tasks without coding or relying on developers to build the integration.

    It's perfect for many of the use cases that would ordinarily require webhooks and has an ever expanding set of use cases. https://zapier.com/zapbook/patreon/

    Use cases

    Our Zapier plugin currently supports pledge activity (adds, updates and deletes). We plan to add more triggers in the future. If you would like to request a trigger, send the request to [email protected].

    Wordpress

    We have a wordpress plugin that allows creators to gate content on their wordpress page to patrons only. For more information check it out.

    FAQs

    Testing

    Testing of the API can be done by creating dummy accounts through the website. To test pledging, it can be useful to:

    1. Create a Patreon account with creator page and set it to "per post".
    2. Create another Patreon account and use it to pledge to the first account's page. A "per post" pledge will not incur any payments as long as it is cancelled before the end of the month.
    3. Use the API as needed.