Adapty Developer Hub

Welcome to the AdaptyTeam developer hub. You'll find comprehensive guides and documentation to help you start working with Adapty as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    Discussions

API Specs

Learn how to get and manipulate with user's data, including subscription status, from your server

Base URL: https://api.adapty.io/api/v1/sdk

Authorization

Each API request must be signed with the secret token.

When calling API:

  • You must set Authorization header with value "Api-Key {secret_token}" (without quotes) to each request, for example Api-Key secret_live_BEHrYLTr.ce5zuDEWz06lFRNiaJC8mrLtL8fUwswD
  • Use JSON payload in request body for POST and PATCH requests
  • All request must set header Content-Type: application/json

Requests

Prolong/grant a subscription for a user

POST: /profiles/{profile_id}/paid-access-levels/{access_level}/grant/

Path params

ParamTypeRequiredNullableDescription
profile_idstrAdapty profile ID or developer's internal ID
access_levelstrID (slug) of a paid access level. Find it in Adapty Dashboard

Request params

ParamTypeRequiredNullableDescription
expires_atISO 8601 date❌* see belowSubscription deadline
duration_daysint❌* see belowAdditional days to a current subscription**
is_lifetimebool❌* see belowIf set true, then a user will forever have a paid access level forever
starts_atISO 8601 dateIf the start time of the action is in the future, then you can transfer it. If the start time and the period are indicated, the period will be counted from the indicated time
vendor_product_idstrVendor product ID which initiates subscription prolongation. The default value is adapty_promotion
vendor_transaction_idstrTransaction ID in a vendor environment
storestrA store where users purchased a product, such as app_store and play_store, can be custom. Default is adapty
introductory_offer_typestrA type of introduction offer. Available values are free_trial, pay_as_you_go, and pay_up_front. Default is null and the offer is not applied
pricefloatPrice of the subscription/purchase to save in transaction
proceedsfloatProceeds (price that is reduced due to stores' fee) of the subscription/purchase to save in transaction
price_localestrThe currency of the price and proceeds. Default is USD

There are three ways to grant users a subscription. So, at least one of is_lifetime, expires_at, duration_days, ** must be set. If more than one param is sent, then is_lifetime=true has a maximum priority, then expires_at, and lastly duration_days**.

As all payment processing is done by Apple/Google, Adapty can not control or affect it. So, when using duration_days to a current subscription, remember that a user still will be charged on a needed day. For example, the user has a monthly subscription and the next charge date will be 5th or April. You grant a user additional 7 days, but the user still is charged on the 5th of April!. It's best using duration_days with never subscribed users or churned. In that case reference day is a day of granting.

Transaction

If all vendor_product_id, vendor_transaction_id, and store are specified, Adapty creates and saves transaction entry so this grant is accounted in Charts (Revenue, MRR, Subscriptions) unless the transaction with these parameters already exists (e.g. it was generated by iOS purchase). If price is specified, it is associated with this transaction.

Currently, this type of transaction does not generate any profile events and does not affect users' subscription status.

Also, be aware that these transactions affect billing since they are counted towards MTR.

Sample request:

{
    "starts_at": "2020-01-15T15:10:36.517975+0000",
    "expires_at": "2020-02-15T15:10:36.517975+0000",
    "vendor_product_id": "basic_subscription_1_month",
    "vendor_transaction_id": "123456789",
    "store": "app_store",
    "introductory_offer_type": null
}

Sample response:

{
  "data": {
    "app_id": "ff90dd2e-e7f2-454b-9d86-071036a284fe",
    "profile_id": "77112400-89f1-4465-b9c9-5437e58c6688",
    "customer_user_id": "[email protected]",
    "paid_access_levels": {
      "premium": {
        "id": "premium",
        "is_active": true,
        "is_lifetime": false,
        "expires_at": "2023-03-29T15:30:34.000000+0000",
        "starts_at": null,
        "will_renew": false,
        "vendor_product_id": "adapty_promotion",
        "store": "adapty",
        "activated_at": "2020-03-26T16:24:19.497674+0000",
        "renewed_at": "2020-03-26T16:24:19.497674+0000",
        "unsubscribed_at": null,
        "billing_issue_detected_at": null,
        "is_in_grace_period": false,
        "active_introductory_offer_type": "free_trial",
        "active_promotional_offer_type": null,
        "active_promotional_offer_id": null,
        "cancellation_reason": null
      }
    },
    "subscriptions": {
      "com.adapty.premium.monthly": {
        "is_active": false,
        "is_lifetime": false,
        "expires_at": "2020-02-21T16:30:34.000000+0000",
        "starts_at": null,
        "will_renew": false,
        "vendor_product_id": "com.adapty.premium.monthly",
        "vendor_transaction_id": "1000000630116569",
        "vendor_original_transaction_id": "1000000625263604",
        "store": "app_store",
        "activated_at": "2020-02-10T19:14:02.000000+0000",
        "renewed_at": "2020-02-21T16:25:34.000000+0000",
        "unsubscribed_at": "2020-02-21T16:30:34.000000+0000",
        "billing_issue_detected_at": "2020-02-21T16:30:34.000000+0000",
        "is_in_grace_period": false,
        "active_introductory_offer_type": null,
        "active_promotional_offer_type": null,
        "active_promotional_offer_id": null,
        "cancellation_reason": "voluntarily_cancelled",
        "is_sandbox": true
      },
      "com.adapty.premium.weekly": {
        "is_active": false,
        "is_lifetime": false,
        "expires_at": "2020-02-10T19:32:00.000000+0000",
        "starts_at": null,
        "will_renew": true,
        "vendor_product_id": "com.adapty.premium.weekly",
        "vendor_transaction_id": "1000000625265713",
        "vendor_original_transaction_id": "1000000625263604",
        "store": "app_store",
        "activated_at": "2020-02-10T19:14:02.000000+0000",
        "renewed_at": "2020-02-10T19:29:00.000000+0000",
        "unsubscribed_at": null,
        "billing_issue_detected_at": null,
        "is_in_grace_period": false,
        "active_introductory_offer_type": null,
        "active_promotional_offer_type": null,
        "active_promotional_offer_id": null,
        "cancellation_reason": null,
        "is_sandbox": true
      },
      "basic_subscription_unlimited": {
        "is_active": true,
        "is_lifetime": false,
        "expires_at": "2021-02-27T11:00:30.000000+0000",
        "starts_at": null,
        "will_renew": false,
        "vendor_product_id": "basic_subscription_unlimited",
        "vendor_transaction_id": "1000000632277988",
        "vendor_original_transaction_id": "1000000632277988",
        "store": "app_store",
        "activated_at": "2020-02-27T11:00:30.000000+0000",
        "renewed_at": null,
        "unsubscribed_at": null,
        "billing_issue_detected_at": null,
        "is_in_grace_period": false,
        "active_introductory_offer_type": null,
        "active_promotional_offer_type": null,
        "active_promotional_offer_id": null,
        "cancellation_reason": null,
        "is_sandbox": true
      }
    },
    "non_subscriptions": null
  }
}

Learn more about responses in the API Objects section.

Revoke subscription from a user

POST: /profiles/{profile_id}/paid-access-levels/{access_level}/revoke/

Path parameters

ParamTypeRequiredNullableDescription
profile_idstrAdapty profile ID or developer's internal ID
access_levelstrID (slug) of a paid access level. Find it in Adapty Dashboard

Request parameters

ParamTypeRequiredNullableDescription
is_refundboolWhether this subscription is revoked due to a refund

Revokes user's subscription by setting unsubscribed_at to current datetime, and expires_at to a maximum of current starts_at and current datetime (to avoid expires_at being less than starts_at). If there is a transaction associated with this paid access level, this transaction expiration is also set to the new expires_at value. If is_refund is true, the transaction is marked as a refund, and revenue is set to zero.

Get info about a user

GET: /profiles/{profile_id}/

Path params

ParamTypeRequiredNullableDescription
profile_idstrAdapty profile ID or developer's internal ID

Response example is the same as for Prolong/grant a subscription for a user.

Create a user

POST: /profiles/

Request params

ParamTypeRequiredNullableDescription
customer_user_idstr

Sample request

{
    "customer_user_id": "123456"
}

You can also set user's attributes the same way as in the PATCH method.

Set the user's attribute

PATCH: /profiles/{profile_id}/

Path params

ParamTypeRequiredNullableDescription
profile_idstrAdapty profile ID or developer's internal ID

Request params

Param Type Required Nullable Description
email str
phone_number str
first_name str
last_name str
gender str

f|m|o

f - female

m - male

o - other

birthday date 1990-10-31

If you'd like to set custom attributes, you can pass them in custom_attributes dictionary. Maximum of 10 custom attributes for the profile allowed to be set. Only strings and floats allowed as values, booleans will be converted to floats.

ParamTypeRequiredNullableDescription
attribute_keystrOnly letters, numbers, dashes, points, and underscores allowed. The attribute key must be no more than 30 characters.
attribute_valuestr|floatThe attribute value must be no more than 30 characters. Send empty value or null to delete the attribute.

Sample request

{
    "phone_number": "+18003330000",
    "custom_attributes": {
        "grade": 10,
        "favorite_topic": "sports"
    }
}

Updated 9 days ago


API Specs


Learn how to get and manipulate with user's data, including subscription status, from your server

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.