RevenueCat

Build With RevenueCat

Build a customized mobile subscription business with RevenueCat. We do the heavy lifting of normalizing subscribers from any source and maintain a single source of truth for subscription status, so you can get back to building your app.

RevenueCat is a powerful, secure, reliable, and free to use in-app purchase server with global support. All you need to get started is an API key.

Suggest Edits

RevenueCat REST API

 

Authentication

Authentication for the RevenueCat REST API is achieved by setting the Authorization header with a valid API key. You'll find two types of API keys in your RevenueCat dashboard: public and secret.

Certain endpoints require secret keys, which should be kept out of any publicly accessible areas such as GitHub, client-side code, and so forth. See our Authentication guide for more information.

Authorization: Bearer YOUR_REVENUECAT_API_KEY

Payload

The body of the POST requests should be encoded in JSON and have the 'Content-Type' header set to 'application/json'.

Content-Type: application/json
{
  "app_user_id": "user-1456",
  "fetch_token": "MQABC...EFH1234="
}
Suggest Edits

Get or Create Subscriber

Gets the latest subscriber info or creates one if it doesn't exist.

 

Header Auth

 Authentication is required for this endpoint.
gethttps://api.revenuecat.com/v1/subscribers/app_user_id
curl --request GET \
  --url https://api.revenuecat.com/v1/subscribers/app_user_id \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'GET',
  url:
   'https://api.revenuecat.com/v1/subscribers/app_user_id',
  headers:
   { 'content-type': 'application/json' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.revenuecat.com/v1/subscribers/app_user_id")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://api.revenuecat.com/v1/subscribers/app_user_id");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.revenuecat.com/v1/subscribers/app_user_id"

headers = {'content-type': 'application/json'}

response = requests.request("GET", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

{
    "request_date": "2019-07-26T17:40:10Z",
    "request_date_ms": 1564162810884,
    "subscriber": {
        "entitlements": {
            "pro_cat": {
                "expires_date": null,
                "product_identifier": "onetime",
                "purchase_date": "2019-04-05T21:52:45Z"
            }
        },
        "first_seen": "2019-02-21T00:08:41Z",
        "non_subscriptions": {
            "onetime": [
                {
                    "id": "cadba0c81b",
                    "is_sandbox": true,
                    "purchase_date": "2019-04-05T21:52:45Z",
                    "store": "app_store"
                }
            ]
        },
        "original_app_user_id": "XXX-XXXXX-XXXXX-XX",
        "original_application_version": "1.0",
        "other_purchases": {
            "onetime": {
                "purchase_date": "2019-04-05T21:52:45Z"
            }
        },
        "subscriptions": {
            "annual": {
                "billing_issues_detected_at": null,
                "expires_date": "2019-06-14T21:07:40Z",
                "is_sandbox": true,
                "original_purchase_date": "2019-02-21T00:42:05Z",
                "period_type": "normal",
                "purchase_date": "2019-06-14T20:07:40Z",
                "store": "app_store",
                "unsubscribe_detected_at": "2019-06-17T22:48:38Z"
            },
            "onemonth": {
                "billing_issues_detected_at": null,
                "expires_date": "2019-06-17T22:47:55Z",
                "is_sandbox": true,
                "original_purchase_date": "2019-02-21T00:42:05Z",
                "period_type": "normal",
                "purchase_date": "2019-06-17T22:42:55Z",
                "store": "app_store",
                "unsubscribe_detected_at": "2019-06-17T22:48:38Z"
            },
            "rc_promo_pro_cat_monthly": {
                "billing_issues_detected_at": null,
                "expires_date": "2019-08-26T01:02:16Z",
                "is_sandbox": false,
                "original_purchase_date": "2019-07-26T01:02:16Z",
                "period_type": "normal",
                "purchase_date": "2019-07-26T01:02:16Z",
                "store": "promotional",
                "unsubscribe_detected_at": null
            }
        }
    }
}
{'message': "Bad parameters"}
{'message': "Invalid API key"}

Path Params

app_user_id
string
required

The app user id used with the mobile SDK.

Headers

Content-Type
string
required

Required

X-Platform
string

Optionally set the X-Platform header to update the subscriber record's last_seen field. Set to either ios, android, macos or uikitformac. Don't set this if you are calling the getter for informational purposes.

 

Get OR create a subscriber

If the provided app_user_id doesn't exists, a new subscriber will be created with the App User Id.

Response

If the provided app_user_id exists, the response will contain the latest purchase information for that user.

Attribute
Description

request_date

The ISO 8601 datetime of the request.

request_date_ms

The Unix timestamp of the request.

subscriber

The Subscriber object:

Attribute
Description

original_app_user_id

The first App User Id that was registered for this user.

original_application_version

Only available on iOS. This will be null until an iOS receipt is sent for the user. After a receipt has been sent, it will indicate the first App Store version of your app that user installed.

first_seen

The ISO 8601 datetime that this user was first seen in RevenueCat .

entitlements

A mapping of Entitlement objects keyed by entitlement ID.

subscriptions

A mapping of Subscription objects keyed by product ID.

non_subscriptions

A mapping of Non-Subscription object arrays keyed by product ID.

other_purchases

Deprecated. See non_subscriptions

The Entitlement object:

Attribute
Description

expires_date

The ISO 8601 datetime this entitlement is set to expire (may be in the past).

purchase_date

The ISO 8601 datetime of the latest purchase or renewal.

product_identifier

The product identifier that unlocked this entitlement.

The Subscription object:

Attribute
Description

expires_date

The ISO 8601 datetime of the latest known expiration date.

purchase_date

The ISO 8601 datetime of the latest purchase or renewal.

original_purchase_date

The ISO 8601 datetime of the first recorded purchase of this product.

period_type

Possible values for period_type:

  • normal: The product is in it's normal period (default)
  • trial: The product is in a free trial period
  • intro: The product is in an introductory pricing period

store

Possible values for store:

  • app_store: The product was purchased through Apple App Store.
  • mac_app_store: The product was purchased through the Mac App Store.
  • play_store: The product was purchased through the Google Play Store.
  • stripe: The product was purchased through Stripe.
  • promotional: The product was granted via RevenueCat.

is_sandbox

Boolean indicating whether the subscription was purchased in sandbox or production environment.

unsubscribe_detected_at

The ISO 8601 datetime that an unsubscribe was detected. Will be null if previously unsubscribed user has resubscribed. Note the subscription may still be active, check the expires_date attribute.

billing_issues_detected_at

The ISO 8601 datetime that billing issues were detected. Will be null if previous billing issues were resolved. Note the subscription may still be active, check the expires_date attribute.

The Non-Subscription object:

Attribute
Description

id

A unique identifier for the transaction. You can use this to ensure you track consumption of all consumable products.

purchase_date

The ISO 8601 datetime that the purchase happened.

store

Possible values for store:

  • app_store: The product was purchased through Apple App Store.
  • mac_app_store: The product was purchased through the Mac App Store.
  • play_store: The product was purchased through the Google Play Store.
  • stripe: The product was purchased through Stripe.

is_sandbox

Boolean indicating whether the subscription was purchased in sandbox or production environment.

Suggest Edits

Delete Subscriber

Permanently deletes a subscriber.

 

Header Auth

 Authentication is required for this endpoint.
deletehttps://api.revenuecat.com/v1/subscribers/app_user_id
curl --request DELETE \
  --url https://api.revenuecat.com/v1/subscribers/app_user_id
var request = require("request");

var options = { method: 'DELETE',
  url:
   'https://api.revenuecat.com/v1/subscribers/app_user_id' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.revenuecat.com/v1/subscribers/app_user_id")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Delete.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://api.revenuecat.com/v1/subscribers/app_user_id");

xhr.send(data);
import requests

url = "https://api.revenuecat.com/v1/subscribers/app_user_id"

response = requests.request("DELETE", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

{"app_user_id": "XXX-XXXXX-XXXXX-XX", deleted: True}

Path Params

app_user_id
string
required

The app user id, or alias, of the subscriber.

 

Secret API Key Required

This endpoint requires a secret API key to be used.

Deleted Subscribers Cannot Be Recovered

Be careful when using this endpoint, when a subscriber is deleted, it cannot be brought back.

Response

If successful, the response will contain the deleted app_user_id.

Attribute
Description

app_user_id

The app user ID, or alias of the deleted subscriber.

Suggest Edits

Create a Purchase

Records a purchase for a user from iOS, Android, or Stripe.

 

Header Auth

 Authentication is required for this endpoint.
posthttps://api.revenuecat.com/v1/receipts
curl --request POST \
  --url https://api.revenuecat.com/v1/receipts \
  --header 'content-type: application/json' \
  --header 'x-platform: ios'
var request = require("request");

var options = { method: 'POST',
  url: 'https://api.revenuecat.com/v1/receipts',
  headers:
   { 'x-platform': 'ios',
     'content-type': 'application/json' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.revenuecat.com/v1/receipts")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request["x-platform"] = 'ios'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.revenuecat.com/v1/receipts");
xhr.setRequestHeader("content-type", "application/json");
xhr.setRequestHeader("x-platform", "ios");

xhr.send(data);
import requests

url = "https://api.revenuecat.com/v1/receipts"

headers = {
    'content-type': "application/json",
    'x-platform': "ios"
    }

response = requests.request("POST", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

// See the Subscriber object for response fields

Body Params

app_user_id
string
required

User id of the user the receipt is associated with.

fetch_token
string
required

For iOS, the base64 encoded receipt file, for Android the receipt token.

price
float

Price paid, only if associated with a purchase. Not required for Android.

currency
string

Currency code paid

payment_mode
string

Optionally used by the iOS SDK to communicate intro pricing periods. Either pay_as_you_go = 0, pay_up_front = 1, or free_trial = 2.

introductory_price
float

Introductory price paid

product_id
string

The Apple product identifier or SKU

is_restore
string

If true, the purchase will create an alias between any other users sharing the same fetch_token

Headers

Content-Type
string
required

Required content-type field

X-Platform
string
required

The platform this purchase is for. Either ios, android, macos or uikitformac

 

Response

If the response is successful, it will contain the updated Subscriber object.

Suggest Edits

Grant a Promotional Entitlement

Grants a user a promotional entitlement.

 

Header Auth

 Authentication is required for this endpoint.
posthttps://api.revenuecat.com/v1/subscribers/app_user_id/entitlements/entitlement_identifier/promotional
curl --request POST \
  --url https://api.revenuecat.com/v1/subscribers/app_user_id/entitlements/entitlement_identifier/promotional
var request = require("request");

var options = { method: 'POST',
  url:
   'https://api.revenuecat.com/v1/subscribers/app_user_id/entitlements/entitlement_identifier/promotional' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.revenuecat.com/v1/subscribers/app_user_id/entitlements/entitlement_identifier/promotional")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.revenuecat.com/v1/subscribers/app_user_id/entitlements/entitlement_identifier/promotional");

xhr.send(data);
import requests

url = "https://api.revenuecat.com/v1/subscribers/app_user_id/entitlements/entitlement_identifier/promotional"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

// See the Subscriber object for response fields

Path Params

app_user_id
string
required

The app user id, or alias, of the subscriber.

entitlement_identifier
string
required

The identifier for the entitlement you want to grant to the user.

Body Params

duration
string
required

How long of a duration to grant the promotional entitlement for. See below for possible values.

start_time_ms
date-time

A Unix epoch in milliseconds for when the promotional entitlement should start - can be in the past. If not provided, the entitlement will be granted immediately.

 

Secret API Key Required

This endpoint requires a secret API key to be used.

Duration Values

The duration parameter must be one of the following supported durations:

Value
Description

daily

24 hour access

weekly

7 day access

monthly

1 month access

two_month

2 month access

six_month

6 month access

yearly

1 year access

lifetime

200 year access

Response

If the response is successful, it will contain the updated Subscriber object.

Suggest Edits

Revoke Promotional Entitlements

Revokes all promotional entitlements for a given entitlement identifier and app user ID.

 

Header Auth

 Authentication is required for this endpoint.
posthttps://api.revenuecat.com/v1/subscribers/app_user_id/entitlement_identifier/revoke_promotionals
curl --request POST \
  --url https://api.revenuecat.com/v1/subscribers/app_user_id/entitlement_identifier/revoke_promotionals
var request = require("request");

var options = { method: 'POST',
  url:
   'https://api.revenuecat.com/v1/subscribers/app_user_id/entitlement_identifier/revoke_promotionals' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.revenuecat.com/v1/subscribers/app_user_id/entitlement_identifier/revoke_promotionals")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.revenuecat.com/v1/subscribers/app_user_id/entitlement_identifier/revoke_promotionals");

xhr.send(data);
import requests

url = "https://api.revenuecat.com/v1/subscribers/app_user_id/entitlement_identifier/revoke_promotionals"

response = requests.request("POST", url)

print(response.text)
A binary file was returned

You couldn't be authenticated

// See the Subscriber object for response fields

Path Params

app_user_id
string
required

The app user id, or alias, of the subscriber.

entitlement_identifier
string
required

The identifier for the entitlement you want to grant to the user.

 

Secret API Key Required

This endpoint requires a secret API key to be used.

Response

If the response is successful, it will contain the updated Subscriber object.

Suggest Edits

Add User Attribution

Attaches attribution data to a subscriber from specific supported networks.

 

Header Auth

 Authentication is required for this endpoint.
posthttps://api.revenuecat.com/v1/subscribers/app_user_id/attribution
curl --request POST \
  --url https://api.revenuecat.com/v1/subscribers/your%20user%20id/attribution \
  --header 'content-type: application/json'
var request = require("request");

var options = { method: 'POST',
  url:
   'https://api.revenuecat.com/v1/subscribers/your%20user%20id/attribution',
  headers:
   { 'content-type': 'application/json' } };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});
require 'uri'
require 'net/http'

url = URI("https://api.revenuecat.com/v1/subscribers/your%20user%20id/attribution")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'

response = http.request(request)
puts response.read_body
var data = JSON.stringify(false);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://api.revenuecat.com/v1/subscribers/your%20user%20id/attribution");
xhr.setRequestHeader("content-type", "application/json");

xhr.send(data);
import requests

url = "https://api.revenuecat.com/v1/subscribers/your%20user%20id/attribution"

headers = {'content-type': 'application/json'}

response = requests.request("POST", url, headers=headers)

print(response.text)
A binary file was returned

You couldn't be authenticated

Try the API to see results

Path Params

app_user_id
string
required

The app user id, or alias, of the subscriber.

Body Params

data
object
required

The data returned by the attribution network callbacks.

 
data.rc_idfa
string

The idfa from AdSupport on iOS. (iOS Only)

data.rc_gps_adid
string

The Google Play Services Advertising identifier. (Android Only)

network
int32
required

The attribution network the data is coming from. See below for possible values.

Headers

Content-Type
string
required
 

Attribution Source Network Codes

Attribution Source
Code

Apple Search Ads

0

Adjust

1

AppsFlyer

2

Branch

3

Tenjin

4

Facebook

5

Response

If the response is successful, it will contain an empty object { }.