# Table of Contents
- [API Reference](#api-reference)
- [Email Protection | Cloudflare](#email-protection-cloudflare)
---
# API Reference
[NAV ](#)

* [Introduction](#introduction)
* [Welcome to the Patreon API!](#welcome-to-the-patreon-api)
* [Make these docs better](#make-these-docs-better)
* [API Libraries](#api-libraries)
* [Python](#python)
* [Javascript](#javascript)
* [Ruby](#ruby)
* [PHP](#php)
* [Java](#java)
* [Third Party Libraries](#third-party-libraries)
* [Go](#go)
* [django-allauth](#django-allauth)
* [python-social-auth](#python-social-auth)
* [Clients and API Keys](#clients-and-api-keys)
* [OAuth](#oauth)
* [Step 1 - Registering Your Client](#step-1-registering-your-client)
* [Step 2 - Making the Log In Button](#step-2-making-the-log-in-button)
* [Step 3 - Handling OAuth Redirect](#step-3-handling-oauth-redirect)
* [Step 4 - Validating Receipt of the OAuth Token](#step-4-validating-receipt-of-the-oauth-token)
* [Step 5 - Using the OAuth Token](#step-5-using-the-oauth-token)
* [Step 6 - Resolving the OAuth Redirect](#step-6-resolving-the-oauth-redirect)
* [Step 7 - Keeping up to date](#step-7-keeping-up-to-date)
* [Errors](#errors)
* [Rate Limits](#rate-limits)
* [APIv2: OAuth](#apiv2-oauth)
* [What's new?](#what-39-s-new)
* [What stays the same?](#what-stays-the-same)
* [Note to those with V1 tokens:](#note-to-those-with-v1-tokens)
* [Scopes](#scopes)
* [Using APIv2 with APIv1](#using-apiv2-with-apiv1)
* [APIv2: Resource Endpoints](#apiv2-resource-endpoints)
* [GET /api/oauth2/v2/identity](#get-api-oauth2-v2-identity)
* [GET /api/oauth2/v2/campaigns](#get-api-oauth2-v2-campaigns)
* [GET /api/oauth2/v2/campaigns/{campaign\_id}](#get-api-oauth2-v2-campaigns-campaign_id)
* [GET /api/oauth2/v2/campaigns/{campaign\_id}/members](#get-api-oauth2-v2-campaigns-campaign_id-members)
* [GET /api/oauth2/v2/members/{id}](#get-api-oauth2-v2-members-id)
* [GET /api/oauth2/v2/campaigns/{campaign\_id}/posts](#get-api-oauth2-v2-campaigns-campaign_id-posts)
* [GET /api/oauth2/v2/posts/{id}](#get-api-oauth2-v2-posts-id)
* [APIv2: Webhook Endpoints](#apiv2-webhook-endpoints)
* [GET /api/oauth2/v2/webhooks](#get-api-oauth2-v2-webhooks)
* [POST /api/oauth2/v2/webhooks](#post-api-oauth2-v2-webhooks)
* [Triggers v2](#triggers-v2)
* [Webhook Responses](#webhook-responses)
* [PATCH /api/oauth2/v2/webhooks/{id}](#patch-api-oauth2-v2-webhooks-id)
* [APIv2: Resources](#apiv2-resources)
* [Address](#address)
* [Benefit](#benefit)
* [Campaign v2](#campaign-v2)
* [Deliverable](#deliverable)
* [Goal](#goal)
* [Media](#media)
* [Member](#member)
* [OAuthClient](#oauthclient)
* [Pledge Event](#pledge-event)
* [Post v2](#post-v2)
* [Tier](#tier)
* [User v2](#user-v2)
* [Webhook](#webhook)
* [Resources](#resources)
* [User](#user)
* [Campaign](#campaign)
* [Pledge](#pledge)
* [API Endpoints](#api-endpoints)
* [Fetching a patron's profile info](#fetching-a-patron-39-s-profile-info)
* [Fetch a creator profile and campaign info](#fetch-a-creator-profile-and-campaign-info)
* [Paging through a list of pledges](#paging-through-a-list-of-pledges)
* [More Data, Paging, and Sorting](#more-data-paging-and-sorting)
* [Requesting specific data](#requesting-specific-data)
* [Pagination and sorting](#pagination-and-sorting)
* [Webhooks](#webhooks)
* [Triggers](#triggers)
* [Robust Retries](#robust-retries)
* [Programmatically Adding Webhooks](#programmatically-adding-webhooks)
* [External Services](#external-services)
* [Zapier](#zapier)
* [Wordpress](#wordpress)
* [FAQs](#faqs)
* [Testing](#testing)
* [Accessibility](#accessibility)
* [Sign Up for an API Key](https://www.patreon.com/portal/registration/register-clients)
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](https://www.patreon.com/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](https://github.com/Patreon/platform-documentation)
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](http://jsonapi.org)
which is pretty complex and these libraries make it a bit easier to work with.
Python
------
Get the package from [PyPI](https://pypi.org/project/patreon/)
, 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](https://github.com/Patreon/patreon-python)
Javascript
----------
Available on [npm](https://www.npmjs.com/package/patreon)
### Install
`npm install --save patreon`
View the source on [github](https://github.com/Patreon/patreon-js)
Ruby
----
Get the gem from [RubyGems](https://rubygems.org/gems/patreon)
### Install
`gem install patreon`
View the source on [github](https://github.com/Patreon/patreon-ruby)
PHP
---
Available on [packagist](https://packagist.org/packages/patreon/patreon)
### Install
`composer require patreon/patreon`
View the source on [github](https://github.com/Patreon/patreon-php)
Java
----
com.patreon
patreon
0.1.1
Get the artifact from
[Maven](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.patreon%22%20AND%20a%3A%22patreon%22)
View the source on [github](https://github.com/Patreon/patreon-java)
Third Party Libraries
=====================
There are a number of third party libraries that the developer community has created.
Go
--
View the source on [github](https://github.com/mxpv/patreon-go)
django-allauth
--------------
Patreon is available as an OAuth backend in [django-allauth](http://django-allauth.readthedocs.io/en/latest/installation.html)
.
python-social-auth
------------------
Patreon is available as an OAuth backend in [python-social-auth](http://python-social-auth-docs.readthedocs.io/en/latest/)
.
Clients and API Keys
====================
In order to authenticate with OAuth and interact with the Patreon API, you'll have to [register your Client(s)](https://www.patreon.com/portal/registration/register-clients)
. This involves signing up on patreon.com and making a [creator account](https://www.patreon.com/create-on-patreon)
.
Once you've registered a Client you'll have access to a:
* **Client ID** – Used to identify your application/tool with the client you registered.
* **Client Secret** – Used to authenticate your application/tool with the client you registered.
* **Creator's Access Token** – Which can be used to access the API in the context of the creator you account you made when registering a client.
* **Creator's Refresh Token** – Can be used to refresh new access tokens.
OAuth
=====
Patreon has an [OAuth](https://oauth.net/)
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](https://www.patreon.com/portal/registration/register-clients)
page.
Step 2 - Making the Log In Button
---------------------------------
> Request \[2\]
GET www.patreon.com/oauth2/authorize
?response_type=code
&client_id=
&redirect_uri=
&scope=
&state=
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_uri`s 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 contact us in [the developers forum](https://www.patreondevelopers.com/)
. |
| state | This optional parameter will be transparently appended as a query parameter when redirecting to your `redirect_uri`. This should be used as [CSRF](https://medium.com/@charithra/introduction-to-csrf-a329badfca49)
, 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=
&state=
When the link in [Step 2](#step-2-making-the-log-in-button)
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 | Transparently 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=
&grant_type=authorization_code
&client_id=
&client_secret=
&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](#step-3-handling-oauth-redirect)
by performing the following request on the server (not as a redirect):
> which will return a JSON response of:
{
"access_token": ,
"refresh_token": ,
"expires_in": ,
"scope": ,
"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](#api)
calls. For example, a typical first usage of the new `access_token` would be to [fetch the user's profile info](#fetch-your-own-profile-and-campaign-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
---------------------------
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=
&client_id=
&client_secret=
> which will return a JSON response of:
{
"access_token": ,
"refresh_token": ,
"expires_in": ,
"scope": ,
"token_type": "Bearer"
}
> and you should store this information just as before.
Tokens are valid for the duration specified by "expires\_in" field. 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. 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](https://www.patreon.com/portal/registration/register-clients)
.
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. |
Rate Limits
===========
Patreon implements rate limiting to enhance the security and reliability of its services. Requests are limited by client (100 requests per 2 seconds) and by token (100 requests per minute). Please note that refreshing a token will not reset the rate limits.
Rate limits are subject to change, and applications should handle HTTP 429 responses gracefully.
Responses for rate limited requests may optionally include the following response object. Treat all attributes in the response as optional. Use the `retry_after_seconds` value to determine when the next request can be made.
{
"errors": [\
{\
"code": null,\
"code_name": "RequestThrottled",\
"detail": "You have made too many attempts. Please try again later.",\
"id": "eb96e70d-909f-40cc-a3dc-e922cc90ea0a",\
"retry_after_seconds": 9,\
"status": "429",\
"title": "You have made too many attempts. Please try again later."\
}\
]
}
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](/#requesting-specific-data)
. 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. |
| campaigns.posts | Provides read access to the posts on a campaign. |
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. This is done by including the desired proprties in the fields parameter i.e.: `fields[address]=addressee,city`
GET /api/oauth2/v2/identity
---------------------------
Fetches the [User](/#user-v2)
resource.
Top-level `includes`: [`memberships`](/#member)
, [`campaign`](/#campaign-v2)
.
This is the endpoint for accessing information about the current [User](/#user-v2)
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.
Fields for each include must be explicitly requested i.e. `fields[campaign]=summary,is_monthly&fields[user]=full_name,email` but url encode the brackets i.e.`fields%5Bcampaign%5D=summary,is_monthly&fields%5Buser%5D=full_name,email`
// Sample response with email scope for (url decoded) 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": {
"email": "[email protected]",
"full_name": "Platform Team"
},
"id": "id",
"relationships": {
"campaign": {
"data": {
"id": "id",
"type": "campaign"
},
"links": {
"related": "https://www.patreon.com/api/oauth2/v2/campaigns/id"
}
}
},
"type": "user"
},
"included": [\
{\
"attributes": {\
"is_monthly": true,\
"summary": "Hi There"\
},\
"id": "id",\
"type": "campaign"\
}\
],
"links": {
"self": "https://www.patreon.com/api/oauth2/v2/user/id"
}
}
You can request related data through includes, ie, `/api/oauth2/v2/identity?include=memberships` and `/api/oauth2/v2/identity?include=campaign`.
* If you request [Campaign](/#campaign-v2)
and have the campaigns scope, you will receive information about the user’s [Campaign](/#campaign-v2)
.
* If you request [Campaign](/#campaign-v2)
and memberships, you will receive information about the user’s [memberships](/#member)
and the [Campaign](/#campaign-v2)
s they are [Member](/#member)
of, provided you have the `campaigns` and `identity.memberships` scopes.
* 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.
GET /api/oauth2/v2/campaigns
----------------------------
Requires the `campaigns` scope. Returns a list of [Campaign](/#campaign-v2)
s owned by the authorized user.
Top-level `includes`: [`tiers`](/#tier)
, [`creator`](/#user-v2)
, [`benefits`](/#benefit)
, [`goals`](/#goal)
.
Fields for each include must be explicitly requested i.e. `fields[tier]=currently_entitled_tiers` but url encode the brackets i.e.`fields%5Btier%5D=currently_entitled_tiers`
//Sample response for (url decoded) 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
{
"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](/#campaign-v2)
, fetched by campaign ID.
Top-level `includes`: [`tiers`](/#tier)
, [`creator`](/#user-v2)
, [`benefits`](/#benefit)
, [`goals`](/#goal)
.
Fields for each include must be explicitly requested i.e. `fields[campaign]=created_at,creation_name` but url encode the brackets i.e.`fields%5Bcampaign%5D=created_at,creation_name`
//Sample response for (url decoded) 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,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,
"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](/#member)
for a given [Campaign](/#campaign-v2)
. Requires the `campaigns.members` scope.
Top-level `includes`: [`address`](/#address)
(requires `campaigns.members.address` scope), [`campaign`](/#campaign-v2)
, [`currently_entitled_tiers`](/#tier)
, [`user`](/#user-v2)
, [`pledge_history`](/#pledge-event)
.
Fields for each include must be explicitly requested i.e. `fields[tier]=currently_entitled_tiers` but url encode the brackets i.e.`fields%5Btier%5D=currently_entitled_tiers`
We recommend using `currently_entitled_tiers` to see exactly what a [Member](/#member)
is entitled to, either as an include on the members list or on the member get.
Returns from this endpoint have 1000 results in one page. If pledge events are requested in includes, it has 500 results in one page. Do make sure to paginate your results by using next pagination cursor and cycle until there is no next page cursor in the API return.
// Sample response for (url decoded) 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&fields[address]=addressee,city,line_1,line_2,phone_number,postal_code,state
{
"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",\
"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=1231345&rid=54512321",\
},\
"id": "54321",\
"type": "tier",\
}],
"meta": {
"pagination": {
"cursors": {
"next": "12345678ab1231cdefg"
},
"total": 100
}
}
}
GET /api/oauth2/v2/members/{id}
-------------------------------
Get a particular member by id. Requires the `campaigns.members` scope.
Top-level `includes`: [`address`](/#address)
(requires `campaign.members.address` scope), [`campaign`](/#campaign-v2)
, [`currently_entitled_tiers`](/#tier)
, [`user`](/#user-v2)
.
Fields for each include must be explicitly requested i.e. `fields[address]=line_1,city` but url encode the brackets i.e.`fields%5Baddress%5D=line_1,city`
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 (url decoded) https://www.patreon.com/api/oauth2/v2/members/{member_id}?fields[address]=line_1,line_2,addressee,postal_code,city&fields[member]=full_name,is_follower,last_charge_date&include=address,user
{
"data": {
"attributes": {
"full_name": "first last",
"is_follower": false,
"last_charge_date": "2020-10-01T11:18:36.000+00:00"
},
"id": "123-456-789",
"relationships": {
"address": {
"data": {
"id": "123",
"type": "address"
},
"links": {
"related": "https://www.patreon.com/api/oauth2/v2/address/123"
}
},
"user": {
"data": {
"id": "123",
"type": "user"
},
"links": {
"related": "https://www.patreon.com/api/oauth2/v2/user/123"
}
}
},
"type": "member"
},
"included": [\
{\
"attributes": {\
"addressee": "123",\
"city": "city",\
"line_1": "line 1",\
"line_2": "Apt. 101",\
"postal_code": "123"\
},\
"id": "123",\
"type": "address"\
},\
{\
"attributes": {},\
"id": "123",\
"type": "user"\
}\
],
"links": {
"self": "https://www.patreon.com/api/oauth2/v2/members/123-456-789"
}
}
GET /api/oauth2/v2/campaigns/{campaign\_id}/posts
-------------------------------------------------
Get a list of all the [Posts](/#post-v2)
on a given [Campaign](/#campaign-v2)
by campaign ID. Requires the `campaigns.posts` scope.
GET /api/oauth2/v2/posts/{id}
-----------------------------
Get a particular [Post](/#post-v2)
by ID. Requires the `campaigns.posts` scope.
APIv2: Webhook Endpoints
========================
GET /api/oauth2/v2/webhooks
---------------------------
Get the [Webhooks](/#webhook)
for the current user's [Campaign](/#campaign-v2)
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`](/#oauthclient)
, [`campaign`](/#campaign-v2)
.
// 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](/#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 (upgrade, downgrade) their pledge. |
| members:pledge:delete | Triggered when a member deletes their pledge. |
| posts:publish | Triggered when a post is published on a campaign. |
| posts:update | Triggered when a post is updated on a campaign. |
| posts:delete | Triggered when a post is deleted on a campaign. |
// 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.`
* NOTE: If and only if `num_consecutive_times_failed` > 0, you have unsent events due to your webhook being unreachable on our last attempt. To send all your queued events, you can `PATCH /api/oauth2/v2/webhooks/{webhook_id}` with attribute `paused: false`. We’ll attempt to send you all unsent events and report back with your client’s response to us.
// 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 patron's shipping address.
### Address Attributes
| Attribute | Type | Description |
| --- | --- | --- |
| addressee | string | Full recipient name. Can be null. |
| city | string | City. |
| country | string | Country. |
| created\_at | string (UTC ISO format) | Datetime address was first created. |
| line\_1 | string | First line of street address. Can be null. |
| line\_2 | string | Second line of street address. Can be null. |
| phone\_number | string | Telephone number. Specified for non-US addresses. Can be null. |
| postal\_code | string | Postal or zip code. Can be null. |
| state | string | State or province name. Can be null. |
### Address Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| campaigns | array\[[Campaign](#campaign-v2)
\] | The campaigns that have access to the address. |
| user | [User](#user-v2) | The user this address belongs to. |
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 |
| --- | --- | --- |
| app\_external\_id | string | The third-party external ID this reward is associated with, if any. Can be null. |
| app\_meta | object | Any metadata the third-party app included with this benefit on creation. Can be null. |
| benefit\_type | string | Type of benefit, such as `custom` for creator-defined benefits. Can be null. |
| created\_at | string (UTC ISO format) | Datetime this benefit was created. |
| deliverables\_due\_today\_count | integer | Number of deliverables for this benefit that are due today specifically. |
| delivered\_deliverables\_count | integer | Number of deliverables for this benefit that have been marked complete. |
| description | string | Benefit display description. Can be null. |
| is\_deleted | boolean | `true` if this benefit has been deleted. |
| is\_ended | boolean | `true` if this benefit is no longer available to new patrons |
| is\_published | boolean | `true` if this benefit is ready to be fulfilled to patrons. |
| next\_deliverable\_due\_date | string (UTC ISO format) | The next due date (after EOD today) for this benefit. Can be null. |
| not\_delivered\_deliverables\_count | integer | Number of deliverables for this benefit that are due, for all dates. |
| rule\_type | string | A rule type designation, such as `eom_monthly` or `one_time_immediate`. Can be null. |
| tiers\_count | integer | Number of tiers containing this benefit. |
| title | string | Benefit display title. |
### Benefit Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| campaign | [Campaign](#campaign-v2) | The Campaign the benefit belongs to |
| campaign\_installation | Campaign-Installation | (Alpha) The campaign-app connection |
| deliverables | array\[[Deliverable](#deliverable)
\] | The Deliverables that have been generated by the Benefit |
| tiers | array\[[Tier](#tier)
\] | The Tiers the benefit has been added to. |
Campaign v2
-----------
The creator's page, and the top-level object for accessing lists of members, tiers, etc.
### Campaign v2 Attributes
| Attribute | Type | Description |
| --- | --- | --- |
| created\_at | string (UTC ISO format) | Datetime that the creator first began the campaign creation process. See `published_at`. |
| creation\_name | string | The type of content the creator is creating, as in "`vanity` is creating `creation_name`". Can be null. |
| 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. |
| 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. |
| image\_small\_url | string | URL for the campaign's profile image. |
| image\_url | string | Banner image URL for the campaign. |
| is\_charged\_immediately | boolean | `true` if the campaign charges upfront, `false` otherwise. Can be null. |
| is\_monthly | boolean | `true` if the campaign charges per month, `false` if the campaign charges per-post. |
| is\_nsfw | boolean | `true` if the creator has marked the campaign as containing nsfw content. |
| main\_video\_embed | string | Can be null. |
| main\_video\_url | string | Can be null. |
| one\_liner | string | Pithy one-liner for this campaign, displayed on the creator page. Can be null. |
| patron\_count | integer | Number of patrons having access to this creator. |
| pay\_per\_name | string | The thing which patrons are paying per, as in "`vanity` is making $1000 per `pay_per_name`". Can be null. |
| pledge\_url | string | Relative (to patreon.com) URL for the pledge checkout flow for this campaign. |
| published\_at | string (UTC ISO format) | Datetime that the creator most recently published (made publicly visible) the campaign. Can be null. |
| rss\_artwork\_url | string | The url for the rss album artwork. Can be null. |
| rss\_feed\_title | string | The title of the campaigns rss feed. |
| show\_earnings | boolean | Whether the campaign's total earnings are shown publicly |
| summary | string | The creator's summary of their 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. |
| thanks\_video\_url | string | URL for the video shown to patrons after they pledge to this campaign. Can be null. |
| url | string | A URL to access this campaign on patreon.com |
| vanity | string | The campaign's vanity. Can be null. |
### Campaign v2 Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| benefits | array\[[Benefit](#benefit)
\] | The campaign's benefits. |
| campaign\_installations | array\[Campaign-Installation\] | |
| categories | array\[Category\] | The campaign's categories. |
| creator | [User](#user-v2) | The campaign owner. |
| goals | array\[[Goal](#goal)
\] | \[DEPRECATED!\] The campaign's goals. Will always be empty. |
| tiers | array\[[Tier](#tier)
\] | The campaign's tiers. |
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 `delivered`, `not_delivered`, `wont_deliver`. |
| due\_at | string (UTC ISO format) | When the deliverable is due to the patron. |
### Deliverable Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| benefit | [Benefit](#benefit) | The Benefit the Deliverables were generated for. |
| campaign | [Campaign](#campaign-v2) | The Campaign the Deliverables were generated for. |
| member | [Member](#member) | The member who has been granted the deliverable. |
| user | [User](#user-v2) | 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. |
| completed\_percentage | integer | Equal to (pledge\_sum/goal amount)\*100, helpful when a creator |
| created\_at | string (UTC ISO format) | When the goal was created for the campaign. |
| description | string | Goal description. Can be null. |
| reached\_at | string (UTC ISO format) | When the campaign reached the goal. Can be null. |
| title | string | Goal title. |
wants to hide their pledge sum but still wants their goals to be cash based
### Goal Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| campaign | [Campaign](#campaign-v2) | The campaign trying to reach the goal |
Media
-----
A file uploaded to patreon.com, usually an image.
### Media Attributes
| Attribute | Type | Description |
| --- | --- | --- |
| created\_at | string (UTC ISO format) | When the file was created. |
| download\_url | string | The URL to download this media. Valid for 24 hours. |
| file\_name | string | File name. |
| image\_urls | object | The resized image URLs for this media. Valid for 2 weeks. |
| metadata | object | Metadata related to the file. Can be null. |
| mimetype | string | Mimetype of uploaded file, eg: "application/jpeg". |
| owner\_id | string | Ownership id (See also `owner_type`). |
| owner\_relationship | string | Ownership relationship type for multi-relationship medias. |
| owner\_type | string | Type of the resource that owns the file. |
| size\_bytes | integer | Size of file in bytes. |
| state | string | The state of the file. |
| upload\_expires\_at | string (UTC ISO format) | When the upload URL expires. |
| upload\_parameters | object | All the parameters that have to be added to the upload form request. |
| upload\_url | string | The URL to perform a POST request to in order to upload the media file. |
Member
------
The record of a user's membership to a campaign. Remains consistent across months of pledging.
### Member Attributes
| Attribute | Type | Description |
| --- | --- | --- |
| campaign\_lifetime\_support\_cents | integer | The total amount that the member has ever paid to the campaign in the campaign's currency. `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. |
| email | string | The member's email address. Requires the `campaigns.members[email]` scope. |
| full\_name | string | Full name of the member user. |
| is\_follower | boolean | \[DEPRECATED!\] The user is not a pledging patron but has subscribed to updates about public posts. This will always be false, following has been replaced by free membership. |
| is\_free\_trial | boolean | The user is in a free trial period. |
| is\_gifted | boolean | The user's membership is from a free gift |
| 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.The only successful status is `Paid`.`null` if never charged. One of `Paid`, `Declined`, `Deleted`, `Pending`, `Refunded`, `Fraud`, `Refunded by Patreon`, `Other`, `Partially Refunded`, `Free Trial`. Can be null. |
| lifetime\_support\_cents | integer | \[DEPRECATED!\] Use campaign\_lifetime\_support\_cents. The total amount that the member has ever paid to the campaign in the campaign's currency. `0` if never paid. |
| next\_charge\_date | string (UTC ISO format) | Datetime of next charge. `null` if annual pledge downgrade. Can be null. |
| note | string | The creator's notes on the member. |
| patron\_status | string | One of `active_patron`, `declined_patron`, `former_patron`. A null value indicates the member has never pledged. Can be null. |
| pledge\_cadence | integer | Number of months between charges. Can be null. |
| 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. |
| 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](#address) | The member's shipping address that they entered for the campaign.Requires the `campaign.members.address` scope. |
| campaign | [Campaign](#campaign-v2) | The campaign that the membership is for. |
| currently\_entitled\_tiers | array\[[Tier](#tier)
\] | The tiers that the member is entitled to. This includes a current pledge, or payment that covers the current payment period. |
| pledge\_history | array\[[Pledge Event](#pledge-event)
\] | The pledge history of the member |
| user | [User](#user-v2) | 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 |
| --- | --- | --- |
| author\_name | string | The author name provided during client setup. Can be null. |
| client\_secret | string | The client's secret. |
| default\_scopes | string | (Deprecated in APIv2) The client's default OAuth scopes for the authorization flow. |
| description | string | The description provided during client setup. |
| domain | string | The domain provided during client setup. Can be null. |
| icon\_url | string | The URL of the icon used in the OAuth authorization flow. Can be null. |
| name | string | The name provided during client setup. |
| privacy\_policy\_url | string | The URL of the privacy policy provided during client setup. Can be null. |
| redirect\_uris | string | The allowable redirect URIs for the OAuth authorization flow. |
| tos\_url | string | The URL of the terms of service provided during client setup. Can be null. |
| version | integer | The Patreon API version the client is targeting. |
| category | string | |
### OAuthClient Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| apps | array\[Platform App\] | (Alpha) The apps that this client controls. |
| campaign | [Campaign](#campaign-v2) | The campaign of the user who created the OAuth Client. |
| creator\_token | OAuth Token | The token of the user who created the client. |
| user | [User](#user-v2) | The user who created the OAuth Client. |
Pledge Event
------------
The record of a pledging action taken by the user, or that action's failure.
### Pledge Event Attributes
| Attribute | Type | Description |
| --- | --- | --- |
| amount\_cents | integer | Amount (in the currency in which the patron paid) of the underlying event. |
| currency\_code | string | ISO code of the currency of the event. |
| date | string (UTC ISO format) | The date which this event occurred. |
| pledge\_payment\_status | string | The payment status of the pledge. One of `queued`, `pending`, `valid`, `declined`, `fraud`, `disabled`. |
| payment\_status | string | Status of underlying payment. One of `Paid`, `Declined`, `Deleted`, `Pending`, `Refunded`, `Fraud`, `Refunded by Patreon`, `Other`, `Partially Refunded`, `Free Trial` |
| tier\_id | string | Id of the tier associated with the pledge. Can be null. |
| tier\_title | string | Title of the reward tier associated with the pledge. Can be null. |
| type | string | Event type. One of `pledge_start`, `pledge_upgrade`, `pledge_downgrade`, `pledge_delete`, `subscription` |
### Pledge Event Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| campaign | [Campaign](#campaign-v2) | The campaign being pledged to. |
| patron | [User](#user-v2) | The pledging user |
| tier | [Tier](#tier) | The tier associated with this pledge event. |
Post v2
-------
Content posted by a creator on a campaign page.
### Post v2 Attributes
| Attribute | Type | Description |
| --- | --- | --- |
| app\_id | integer | Platform app id. Can be null. |
| app\_status | string | Processing status of the post. Can be null. |
| content | string | Can be null. |
| embed\_data | object | An object containing embed data if media is embedded in the post,None if there is no embed |
| embed\_url | string | Embed media url Can be null. |
| is\_paid | boolean | True if the post incurs a bill as part of a pay-per-post campaign Can be null. |
| is\_public | boolean | True if the post is viewable by anyone,False if only patrons (or a subset of patrons) can view Can be null. |
| tiers | collection | The tier ids that the post is locked for if only patrons (or a subset of patrons) can view Can be null. |
| published\_at | string (UTC ISO format) | Datetime that the creator most recently published (made publicly visible) the post. Can be null. |
| title | string | Can be null. |
| url | string | A URL to access this post on patreon.com |
### Post v2 Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| user | [User](#user-v2) | The author of the post. |
| campaign | [Campaign](#campaign-v2) | The campaign that the membership is for. |
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). |
| created\_at | string (UTC ISO format) | Datetime this tier was created. |
| description | string | Tier display description. |
| discord\_role\_ids | collection | The discord role IDs granted by this tier. Can be null. |
| edited\_at | string (UTC ISO format) | Datetime tier was last modified. |
| image\_url | string | Full qualified image URL associated with this tier. Can be null. |
| patron\_count | integer | Number of patrons currently registered for this tier. |
| post\_count | integer | Number of posts published to this tier. Can be null. |
| published | boolean | `true` if the tier is currently published. |
| published\_at | string (UTC ISO format) | Datetime this tier was last published. Can be null. |
| remaining | integer | Remaining number of patrons who may subscribe, if there is a `user_limit`. Can be null. |
| requires\_shipping | boolean | `true` if this tier requires a shipping address from patrons. |
| title | string | Tier display title. |
| unpublished\_at | string (UTC ISO format) | Datetime tier was unpublished, while applicable. Can be null. |
| url | string | Fully qualified URL associated with this tier. |
| user\_limit | integer | Maximum number of patrons this tier is limited to, if applicable. Can be null. |
### Tier Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| benefits | array\[[Benefit](#benefit)
\] | The benefits attached to the tier, which are used for generating deliverables. |
| campaign | [Campaign](#campaign-v2) | The campaign the tier belongs to. |
| tier\_image | [Media](#media) | The image file associated with the tier. |
User v2
-------
The Patreon user, which can be both patron and creator.
### User v2 Attributes
| Attribute | Type | Description |
| --- | --- | --- |
| about | string | The user's about text, which appears on their profile. Can be null. |
| 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. |
| 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. |
| hide\_pledges | boolean | `true` if the user has chosen to keep private which creators they pledge to. Can be null. |
| image\_url | string | The user's profile picture URL, scaled to width 400px. |
| is\_email\_verified | boolean | `true` if the user has confirmed their email. |
| like\_count | integer | How many posts this user has liked. |
| social\_connections | object | Mapping from user's connected app names to external user id on the respective app. |
| thumb\_url | string | The user's profile picture URL, scaled to a square of size 100x100px. |
| url | string | URL of this user's creator or patron profile. |
| vanity | string | \[DEPRECATED!\] Use campaign.vanity. The public "username" of the user. patreon.com/ goes to this user's creator page. Non-creator users might not have a vanity. |
| is\_creator | boolean | `true` if this user has an active campaign. |
### User v2 Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| campaign | [Campaign](#campaign-v2) | |
| memberships | array\[[Member](#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. |
Webhook
-------
Webhooks are fired based on events happening on a particular campaign.
### Webhook Attributes
| Attribute | Type | Description |
| --- | --- | --- |
| 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. |
| 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. |
| secret | string | Secret used to sign your webhook message body, so you can validate authenticity upon receipt. |
| 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). |
### Webhook Relationships
| Relationship | Type | Description |
| --- | --- | --- |
| campaign | [Campaign](#campaign-v2) | The campaign whose events trigger the webhook. |
| client | [OAuth Client](#oauthclient) | The client which created the webhook |
Resources
=========
Our JSON responses follow the [JSON:API standard](http://jsonapi.org)
, with the following structure for our three main resources (users, campaigns, and pledges):
User
----
{
"type": "user"
"id":
"attributes": {
"first_name":
"last_name":
"full_name":
"vanity":
"email":
"about":
"facebook_id":
"image_url":
"thumb_url":
"youtube":
"twitter":
"facebook":
"created":
"url":
// optional properties
"like_count":
"comment_count":
}
"relationships": {
"campaign": ......
}
}
Campaign
--------
{
"type": "campaign"
"id":
"attributes": {
"summary":
"creation_name":
"pay_per_name":
"one_liner":
"main_video_embed":
"main_video_url":
"image_small_url":
"image_url":
"thanks_video_url":
"thanks_embed":
"thanks_msg":
"is_monthly":
"is_nsfw":
"created_at":
"published_at":
"pledge_url":
"pledge_sum":
"patron_count":
"creation_count":
"outstanding_payment_amount_cents":
}
"relationships": {
"creator": ......
"rewards": [ ..., , ... ]
"goals": [ ..., , ... ]
"pledges": [ ..., , ... ]
}
}
Pledge
------
{
"type": "pledge"
"id":
"attributes": {
"amount_cents": // Amount cents in the currency used by the patron
"created_at":
"currency": // Currency code of the pledge event (USD, GBP, EUR etc.)
"declined_since":
"patron_pays_fees":
"pledge_cap_cents":
// optional properties
"total_historical_amount_cents":
"is_paused":
"status": // The status of this pledge (valid, declined, pending, disabled)
"has_shipping_address":
}
"relationships": {
"patron": ......
"reward": ...... // Tier associated with this pledge
"creator": ......
"address": ......
}
}
API Endpoints
=============
> To use a given `access_token`, send it in the Authorization HTTPS Header as follows:
Authorization: Bearer
The three endpoints below are accessed using an OAuth client `access_token` obtained from the [OAuth](#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](#using-apiv2-with-apiv1)
. 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 '
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](#user)
who granted your OAuth client an `access_token`. It is most typically used in the [OAuth "Log in with Patreon flow"](https://www.patreon.com/platform/documentation/oauth)
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
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 '
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](#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//pledges?include=patron.null \
--header 'Authorization: Bearer
// TODO: get pagination example
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](#pledge)
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//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 in [the developers forum](https://www.patreondevelopers.com/)
.
More Data, Paging, and Sorting
==============================
Requesting specific data
------------------------
https://www.patreon.com/api/oauth2/api/campaigns//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](#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//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.
* To fetch a resource without any relationships, set `include=null`.
* To include a resource `foo` but not its relationships, set `include=foo.null`.
* You can also extend this to multiple includes, e.g. `include=foo.null,bar.baz.null`.
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//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](https://www.patreon.com/portal/registration/register-webhooks)
, 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](https://www.patreon.com/platform/documentation/webhooks)
. You can use this to verify us as the sender of the message.
### Triggers
A `trigger` is an event type. You can manage webhooks and triggers in [Patreon Platform Portal](https://www.patreon.com/portal/registration/register-webhooks)
.
| Trigger | Description |
| --- | --- |
| pledge:create **(deprecated)** | 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 **(deprecated)** | 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 **(deprecated)** | 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:
* 1 hour after first failure
* 3 hours later
* 1 day later
* 3 days later
* 1 week later
* 1 week later
* 1 week later
* Requires manual retry via our website
You can also use our [webhooks page](https://www.patreon.com/portal/registration/register-webhooks)
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. If you would like to know more please contact us in [the developers forum](https://www.patreondevelopers.com/)
.
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/](https://zapier.com/zapbook/patreon/)
### Use cases
* Track new patrons in Sales Force
* Get notified on slack when a new patron joins or leaves
* Add new patron's contact info to a google sheet
* Sync new patrons with a Mailchimp, Hubspot, ConvertKit, Drip, InfusionSoft, etc.
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, please contact us in [the developers forum](https://www.patreondevelopers.com/)
.
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](https://www.patreon.com/apps/wordpress)
.
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.
Accessibility
-------------
Patreon is committed to providing accessible websites to all of our users, and to becoming WCAG 2.1 AA-compliant. See our [accessibility page](https://www.patreon.com/policy/accessibility)
for more information.
Patreon encourages developers to follow best practices in designing and building apps that are accessible, and which adhere to the Guidelines established by the [Web Accessibility Initiative of the World Wide Web Consortium](https://www.w3.org/wai)
.
We sometimes link to other sites and provide features built by our users or by third party developers. These parties are not vendors to Patreon, and are not paid by us for their content. We have no control over the accessibility of the content, features, or apps third parties may build using our API, and we are not responsible for their providing inaccessible tools.
---
# Email Protection | Cloudflare
Please enable cookies.
Email Protection
================
You are unable to access this email address patreon.com
-------------------------------------------------------
The website from which you got to this page is protected by Cloudflare. Email addresses on that page have been hidden in order to keep them from being accessed by malicious bots. **You must enable Javascript in your browser in order to decode the e-mail address**.
If you have a website and are interested in protecting it in a similar way, you can [sign up for Cloudflare](https://www.cloudflare.com/sign-up?utm_source=email_protection)
.
* [How does Cloudflare protect email addresses on website from spammers?](https://support.cloudflare.com/hc/en-us/articles/200170016-What-is-Email-Address-Obfuscation-)
* [Can I sign up for Cloudflare?](https://support.cloudflare.com/hc/en-us/categories/200275218-Getting-Started)
Cloudflare Ray ID: **9314a8d17c781725** • Your IP: Click to reveal 54.237.218.47 • Performance & security by [Cloudflare](https://www.cloudflare.com/5xx-error-landing)
---