-
-
Subscription created
-
Subscription updated
-
Subscription renewal
-
Subscription ended
-
Subscription upgrade
-
Access granted
-
Access modified
-
Access revoked
-
Shared access granted
-
Shared access modified
-
Shared access revoked
-
Vouchers
-
Site license
-
User data
-
User address update
-
User payment method
-
Payments
-
Auto-renew in My Account (deprecated)
-
Shared subscription (deprecated)
-
Unlock the full potential of our feature and take your skills to the next level! Dive into our Training Center and discover exclusive Best Practice resources that will elevate your implementation strategy. With expert tips and insider knowledge, you'll become a master in no time. Access the links below to learn more and gain a competitive edge.
Ready to get started? Our Training Center is just a click away: here.
*For more information about our Training center, please visit the article here.
Webhooks overview
If you may need access to the events later, we strongly recommend to use your own storage system (a database or Kafka) for more efficient processing and replay capabilities.
The search functionality of the publisher/webhook/list endpoint is designed only for ad-hoc investigations (not reporting or automated resend), especially when dealing with a large number of events, and may result in severe rate limiting (HTTP 429) or timeouts.
If the 'webhook.estimated_count.enabled' setting is enabled for apps with a high volume of events, we recommend scrolling without considering the actual "total" value to determine the call count. Continue scrolling while 'current_response.total > offset + count'.
Configuring your endpoint
Webhooks can be sent to any HTTP or HTTPS endpoint. To configure an endpoint login to your Piano dashboard and click Manage → Webhooks. Toggle the webhooks indicator to the “on” position, click on the blue URL to edit the endpoint, and enter your endpoint URL.
The data sent in our webhooks is available within a query string and is encrypted. The query string should be run through this SDK (PHP, Java, Python) in order to decrypt the data you'll need to query the Piano API for additional information.
Your endpoint must respond with a 200 OK HTTP status code for it to be configured successfully. We are sending the webhook message just once if the response is 200. You are able to request resending the webhook again manually.
When sending a response to the target URL/endpoint, our webhook service will wait 7 seconds for a response before a timeout occurs and it considers the sending as unsuccessful. There is no limitation on the retention period for undelivered webhooks.
Webhooks can be enabled or disabled by event. Using the webhooks manager, you can select which webhooks to send to your endpoint by event. All enabled webhooks will be sent to the selected endpoint.
Webhook events are never batched, you will always receive one webhook message per single event.
Selecting webhooks
Once webhooks are enabled, webhook events can be selectively turned on or off inside the webhooks manager modal. By default, all webhook events will be set to fire when webhooks are enabled. This setting can be reversed by checking the box that selects all webhooks.
Individual webhooks can be turned off or on from this modal using the checkbox beside the webhook name.
Selected webhooks are displayed at the top of the webhook list. This setting can be undone by clicking the filter icon and selecting NO GROUPING.
Queueing, blocking, and skipping
All webhooks are by default sent sequentially; this prevents problems that would occur if they were sent out of order. For example, if someone cancels their annual subscription and then re-subscribes at the monthly rate, Piano would need to process those events in order for the user to maintain their access. If the cancel event was sent after the resubscribe event, the user would incorrectly end up without any access.
So, whenever an access event occurs in Piano, we place the webhook event into a single queue for processing. Every successful response that we get back from your endpoint will tell us to proceed with the next webhook. If your endpoint responds with a non-200 HTTP status code, this informs Piano that the endpoint was down or unable to process the webhook. We don’t guarantee the sending order for webhooks that failed at least once, only for those successfully being sent.
Although we aim to ensure prompt data transmission through our Webhook service, it's crucial to acknowledge that real-time delivery cannot be guaranteed. While most webhook deliveries occur within seconds, it's imperative to recognize the inherent variability in delivery times. Delays can range from 30 seconds to approximately one hour, influenced by the responsiveness of publisher servers and retries following timeouts. The expected p95 delivery time is 1 minute. This metric signifies that 95% of requests are processed and transmitted within this specified timeframe, ensuring that the vast majority of data transmissions occur promptly and efficiently.
Because webhooks are sent sequentially and are inherently “blocking” each other, your server should only respond with a non-200 HTTP status code in the case of true, exceptional failure. Any failures of business logic should be properly caught and handled inside of your application.
The retry frequency for failed webhooks is as follows:
1. We try to send a webhook every 30 seconds for 3 minutes;
2. Then we try to send the webhook every 60 seconds for 7 minutes;
3. Then we try to send the webhook every 5 minutes for 50 minutes;
4. Then we try to send the webhook once every 1 hour.
Please note that the above times are only indicative, as failed webhooks are queued and this can affect the retry times. In terms of total retry counts, we try to send every failed webhook no more than 237 times.
If the last 237th attempt is still not successfully sent, webhooks will be deactivated on your Piano application altogether.
If a webhook can't be delivered, it first receives the status failed and then transitions to inactive once we have reached the maximum sending attempts.
Checkout integration
Webhooks are sent asynchronously. Because of this, webhooks should not be used to determine access after new purchases. If webhooks were used in this manner, after a purchase it's possible that the user would continue to see a “doesn't-have-access” state because of a lag in webhook communication between your local entitlements database and Piano. If there is a failed webhook blocking future processing, this situation would exacerbate itself.
Piano instead recommends using an approach similar to the below, where you register the complete callback to synchronously fetch new entitlements (more info on the complete callback here). In this case, you would implement a /verify-conversion page that would perform the action of fetching the new user entitlements from the Piano API and updating your local datastore.
tp.offer.show({
offerId: "O1234",
templateId: "OTABCDEF",
complete: function(conversion) {
$.ajax({
url: "/verify-conversion",
method: "POST",
data : {
conversion : conversion
},
success: function(data) {
// reload the page, update the user state, etc.
}
});
}
});
Viewing webhooks
There are two ways to view all previously-sent webhooks in your account. You can either call the/publisher/webhook/list API method directly or you can log into your Piano application and navigate to the webhooks screen by going to Manage→Webhooks.
The webhooks screen will provide you with a list of past webhook requests, the status of each request (success, pending, or failed), the date attempted, the associated user, and an option to resend the request. You can also view the webhook’s header, body, and response messages. Note, that we retain the response body only for unsuccessful requests. If your endpoint's response will contain additional data, this information will be logged in the body section of the webhook.
On the screen you'll also see an indicator that shows the current webhook status:
This indicates that webhooks are processing normally and no action is needed. If the webhooks indicator is red, this means that there is a webhook blocking future processing. In that case, you should filter the webhooks to find only the failing ones and either skip or resend them.
If you've determined that your system does not need to receive a webhook, you can skip it manually from the dashboard. From the webhooks page, click the down arrow next to the failing webhook and press the Skip button. After you do this, Piano will attempt to send the next webhook.
You can list all webhooks by calling the API endpoint /publisher/webhook/list but to get specific webhooks you would need to pass the parameter webhook_id. More information is available here.
The webhooks feature is designed primarily for delivering events to publisher endpoints and is not intended as a high-performance event storage or querying mechanism. As such, it is not recommended to rely on the /publisher/webhook/list API endpoint as an event storage system. If long-term access to events is necessary, you should implement a custom storage solution, such as a database or Kafka. These systems allow for efficient event processing and the ability to replay events as needed.
The search functionality available through this endpoint is intended solely for ad-hoc investigations. It is not designed for reporting or automated resending of events. Attempting to use this feature for complex queries, particularly those involving a large number of events, may result in significant performance issues, such as rate limiting (HTTP status code 429) or timeouts.
To improve performance and avoid these issues, we recommend narrowing your query filters. For example, reducing the timeframe to the last few days can help limit the scope of the search and improve response times.
The lifespan of webhooks is limited to 1 month. This means, that you will only be able to access webhooks (and the responses/data) sent in the past 30 days, either via the Piano dashboard directly or also the API.
We retain the response body only for unsuccessful requests, omitting successful (HTTP 200) responses.
Exponential backoff on failure
Piano will automatically attempt to resend a webhook event in case your server is unavailable at any given moment. After six consecutive failures, an email will be sent to you notifying you of the issue. A second email will be sent after 20 failures. From the 24th attempt onward, an email will be sent for each additional failure until the webhook is successfully delivered, skipped, or the webhook endpoint is disabled. This logic applies to every attempt made to deliver each individual webhook event.
The system will cease its attempt to send webhooks after seven days of failures, at which point the webhook endpoint will be deactivated in your Piano application. Additional emails will be sent 24 hours, 8 hours, and 1 hour before deactivation. In the case of deactivation, you will have to manually turn webhooks back on to continue processing and any access events that happened between the deactivation and re-enabling will be lost. You will have to manually query Piano's API to sync your local datastore again.
The email address receiving these emails can be configured under Edit Business → Notification email.
Types of webhooks
Piano webhooks are sent based on access and content locking events. Access event webhooks are sent based on certain events happening within Piano that affect a user's access to a resource. These access events are grouped into three categories: granting, modifying, and revoking. Content locking events, on the other hand, are separated into two categories: lock and unlock.
Below is a full list of all webhook events along with descriptions and information about whether these events are triggered by you, the user, or Piano's system. The format of webhooks is standardized across all Piano webhook events. There are two fields that you should key off of to determine what has happened: the type field, which indicates the high-level event that has occurred, and the event field, which provides more detail about the specific event. Formatting examples for each type of event are provided below each table of events.
Subscription created
This event indicates that a user's subscription has been created:
|
Type |
Event |
Triggered By |
Notes |
|
|
|
User |
Sent when end-user makes a purchase where a financial transaction took place. It will also fire when Print Subscription Confirmation (PSC) is redeemed. For free trials and free periods, the |
|
|
|
User |
Sent when a user signs up for a free trial or purchases a free dynamic term period. |
|
|
|
You |
Sent when the end-user is subscribed to a term by the client representative and a financial transaction takes place. |
|
|
|
You |
Sent when end-user is subscribed to a term with a free trial or a free period. |
|
|
|
You, or User, or Piano |
Sent when a subscription was successfully upgraded (specifically when a new subscription for this upgrade was created and payment was successful). Or when subscription entered the grace period upon upgrade had successfully exited the grace period. |
|
|
|
User or Piano |
Sent when an upgrade was executed, but the newly created subscription for the new term entered a grace period because of the payment failure. |
|
|
|
Piano |
Sent when a subscription was created by the import tool used by the Piano support team. |
Contents of the webhook
|
Field |
Type |
Value |
|---|---|---|
|
type |
string |
webhook type: |
|
version |
string |
|
|
typeTitle |
string |
webhook type title: |
|
event |
string |
event:
|
|
eventTitle |
string |
event title:
|
|
aid |
string |
application id |
|
uid |
string |
end-user id |
|
user_email |
string |
end-user’s email address |
|
term_id |
string |
term id |
|
term_type |
string |
term type:
|
|
rid |
string |
resource id |
|
access_id |
string |
main access id, associated with subscription (access of subscription owner):
|
|
subscription_id |
string |
subscription id |
|
status |
string |
subscription status:
|
|
create_date |
long |
subscription creation date |
|
start_date |
long |
subscription start date (differs from subscription crate date for subscriptions purchased with the future start date and imported subscriptions) |
|
next_bill_date |
long |
the value of the “next billing date” field of the subscription (not null): |
|
billing_plan |
string |
billing plan of the last purchased period:
|
|
access_period_id |
string |
id of the access the last purchased access period:
|
|
active_billing_plan |
string |
billing plan of the active period:
|
|
active_access_period_id |
string |
id of the access the active access period:
|
|
upi_id |
string |
id of the renewal payment method associated with the subscription |
|
auto_renew |
boolean |
the state of the auto-renew toggle associated with the subscription:
|
|
is_in_grace |
boolean |
shows if the subscription is currently in grace period |
|
grace_period_start_date |
long |
grace period start date |
|
grace_period_length |
int |
grace period length in days |
|
failure_counter |
int |
number of payment failures |
|
passive_churn_logic_id |
string |
id of the churn prevention logic |
|
decline_reason |
string |
decline reason for a payment attempt |
|
payment_id |
string |
id of a payment associated with subscription creation |
|
created_by |
string |
id of a user initiated the action that result in subscription creation |
Examples
Example 1. Response to a term_applied_by_publisher event on a payment term
{
"type": "subscription_created",
"version": 2,
"typeTitle": "Subscription created",
"event": "term_applied_by_publisher",
"eventTitle": "New purchase by publisher",
"aid": "ss1h4oKtfc",
"uid": "e34495b7-b4ab-442d-b86a-67e91bf228d1",
"user_email": "demo@user.io",
"term_id": "TMSJR8VIH86D",
"term_type": "PAYMENT",
"rid": "RAMON2M",
"access_id": "94pvQDQFpR3L",
"subscription_id": "RCA3J7CYFH28",
"status": "ACTIVE",
"create_date": 1731055696,
"start_date": 1731055694,
"next_bill_date": 1733647694,
"billing_plan": "$15.00 per month",
"access_period_id": null,
"active_billing_plan": "$15.00 per month",
"active_access_period_id": null,
"upi_id": "PMWIWEQT8JTD",
"auto_renew": true,
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"payment_id": "UPRWT1LNKFKW",
"created_by": "LlfvQvlIwk"
}
Example 2. Response to a term_applied_by_publisher event on a dynamic term
{
"type": "subscription_created",
"version": 2,
"typeTitle": "Subscription created",
"event": "term_applied_by_publisher",
"eventTitle": "New purchase by publisher",
"aid": "ss1h4oKtfc",
"uid": "e34495b7-b4ab-442d-b86a-67e91bf228d1",
"user_email": "demo@user.io",
"term_id": "TMC2P9M6J5YU",
"term_type": "DYNAMIC",
"rid": "RCO8VOC",
"access_id": "6K3QY4sDH5sx",
"subscription_id": "RCFJE8ZK209T",
"status": "ACTIVE",
"create_date": 1731055839,
"start_date": 1731055836,
"next_bill_date": 1733647822,
"billing_plan": "$10.00/every 1 month(s)",
"access_period_id": "APGPK0QRA1EH",
"active_billing_plan": "$10.00/every 1 month(s)",
"active_access_period_id": "APGPK0QRA1EH",
"upi_id": "PMWIWEQT8JTD",
"auto_renew": true,
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"payment_id": "UPRAXJ9T95OR",
"created_by": "LlfvQvlIwk"
}
Subscription updated
This event indicates that a user's subscription has been updated:
|
Type |
Event |
Triggered by |
Notes |
|
|
|
Piano |
Sent when a subscription with a future start date is activated |
|
|
|
Piano |
Sent when dynamic subscription entered manually purchased next access period (via manual renew functionality) |
|
|
|
You |
Sent when the subscription's next billing date is updated manually in UI or via API (not applicable for dynamic terms) |
|
|
|
You or User |
Sent when payment method associated with a subscription is updated (changed) |
|
|
|
You or User |
Sent when the payment address associated with a subscription is updated (changed). Not when the address is edited |
|
|
|
You or User |
Sent when the list of shared accounts of a subscription is updated: manually (via MA/PD/API) or automatically (when the shared subscription is purchased, imported, or upgraded). |
|
|
|
You or User |
Sent when subscription's auto-renew status had been changed to enabled (only applicable for payment subscriptions) |
|
|
|
You or User |
Sent when the subscription's auto-renew status had been changed to disabled (only applicable for payment subscriptions) |
|
|
|
Piano |
Sent when dynamic subscription unlimited period had been converted to a period of another type. Action initiated by You, but done asynchronously |
|
|
|
You or User |
Sent when dynamic subscription had been canceled |
|
|
|
You or User |
Sent when dynamic subscription had been resumed |
|
|
|
You or Piano |
Sent when a specific access period of dynamic subscription was selected for the next renewal |
|
|
|
You or Piano |
Sent when specific access period of dynamic subscription was unselected for next renewal (renewal will occur according to currently up-to-date billing configuration) |
|
|
|
Piano |
Sent when scheduled subscription is re-activated because there was a new period added to the schedule associated with the scheduled term |
|
|
|
Piano |
Sent when subscription entered grace period upon the automated renewal |
|
|
|
Piano |
Sent when the subscription successfully exited the grace period upon the automated/manual renewal |
|
|
|
You or User |
Sent when a deferred upgrade was scheduled for a subscription |
|
|
|
You |
Sent when a scheduled deferred upgrade was canceled by You |
|
|
|
User |
Sent when a scheduled deferred upgrade was canceled by the end-user (this action also triggers a deferred subscription cancellation) |
|
|
|
User |
Sent when subscription with the suspended deferred upgrade was resumed (this action also re-activates the subscription) |
|
|
|
Piano or User |
Sent when a subscription that was in a grace period started upon the upgrade had successfully exited the grace period |
Contents of the webhook
|
Field |
Type |
Value |
|---|---|---|
|
type |
|
webhook type: |
|
version |
|
|
|
typeTitle |
|
webhook type title: |
|
event |
|
event:
|
|
eventTitle |
|
event title:
|
|
aid |
|
application id |
|
uid |
|
end-user id |
|
user_email |
|
end-user’s email address |
|
term_id |
|
term id |
|
term_type |
|
term type:
|
|
rid |
|
resource id |
|
access_id |
|
main access id, associated with subscription (access of subscription owner):
|
|
subscription_id |
|
subscription id |
|
status |
|
subscription status:
|
|
create_date |
|
subscription create date |
|
start_date |
|
subscription start date (differs from subscription crate date for subscriptions purchased with deferred start and imported subscriptions) |
|
next_bill_date |
|
the value of the “next billing date” field of the subscription (not
|
|
billing_plan |
|
billing plan of the last purchased period:
|
|
access_period_id |
|
id of the access the last purchased access period:
|
|
active_billing_plan |
|
billing plan of the active period:
|
|
active_access_period_id |
|
id of the last access the active access period:
|
|
upi_id |
|
id of the renewal payment method associated with the subscription |
|
auto_renew |
|
the state of the auto-renew toggle associated with the subscription:
|
|
shared_accounts |
|
array of all shared accounts currently associated with the shared subscription (includes accounts with both redeemed and not redeemed accesses) - see the |
|
is_in_grace |
|
shows if the subscription is currently in grace period |
|
grace_period_start_date |
|
grace period start date |
|
grace_period_length |
|
grace period length in days |
|
failure_counter |
|
number of payment failures |
|
passive_churn_logic_id |
|
id of the churn prevention logic |
|
decline_reason |
|
decline reason for a payment attempt |
|
updated_by |
|
id of a user initiated the action that resulted in subscription updating |
UserSubscriptionAccount
The UserSubscriptionAccount object as part of the shared_account array in the subscripiton webhooks:
|
Field |
Type |
Value |
|
account_id |
|
id of shared account (any item added to the list as a potential CHILD end-user, no matter if the access was redeemed or not, no matter if this shared account has an associated CHILD end-user or not) |
|
user_id |
|
id of CHILD end-user associated with shared account:
|
|
|
|
email of shared account:
|
|
first_name |
|
first name of shared account:
|
|
last_name |
|
last name of shared account:
|
|
personal_name |
|
personal name of shared account:
|
|
redeemed |
|
CHILD access redemption date:
|
Examples
Example 1. Response to a subscription_payment_method_updated event on a payment term
{
"type": "subscription_updated",
"version": 2,
"typeTitle": "Subscription updated",
"event": "subscription_payment_method_updated",
"eventTitle": "Subscription payment method updated",
"aid": "hcxX89Lysu",
"uid": "a8db5940-e6b0-4f80-a1ca-ff2efeb46e72",
"user_email": "testUserParent@io.io",
"term_id": "TMZLF8VXAPHX",
"term_type": "PAYMENT",
"rid": "R2YEUGI",
"access_id": "OXaeX4AK6AfH",
"subscription_id": "RCYBDXV83B68",
"status": "ACTIVE",
"create_date": 1748266932,
"start_date": 1748266930,
"next_bill_date": 1753537330,
"billing_plan": "$22.00 per month",
"access_period_id": null,
"active_billing_plan": "$22.00 per month",
"active_access_period_id": null,
"upi_id": "PM24JSGH13M9",
"auto_renew": true,
"shared_accounts": [
{
"account_id": "SAV115Q6YHJR",
"user_id": "2f597da0-b188-48b8-87c5-cba46cfb2ba6",
"email": "testUserChild@io.io",
"first_name": "firstName",
"last_name": "lastName",
"personal_name": "firstName lastName",
"redeemed": 1748266945
},
{
"account_id": "SASU7Z7JZKTA",
"user_id": null,
"email": "testUserChild2@io.io",
"first_name": null,
"last_name": null,
"personal_name": null,
"redeemed": null
}
],
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"updated_by": "3QriFCs2yx"
}
Example 2. Response to a subscription_deferred_canceled event on a dynamic term
{
"type": "subscription_updated",
"version": 2,
"typeTitle": "Subscription updated",
"event": "subscription_deferred_canceled",
"eventTitle": "Subscription canceled (deferred cancel)",
"aid": "vb45MHjPsu",
"uid": "3dfc67fe-9099-4b1a-9500-fc88239e7ccc",
"user_email": "testUser@io.io",
"term_id": "TM0KCBAS5F1M",
"term_type": "DYNAMIC",
"rid": "RNQUDNX",
"access_id": "bb4Ne8g5Xswl",
"subscription_id": "RC53ANJSK7LS",
"status": "COMPLETED",
"create_date": 1748601911,
"start_date": 1748601908,
"next_bill_date": 1756550693,
"billing_plan": "$22.00/every 1 month(s)",
"access_period_id": "APLHUFACWIJZ",
"active_billing_plan": "$11.00/every 1 month(s)",
"active_access_period_id": "APTZW610TP94",
"upi_id": "PMV8USHYJO5W",
"auto_renew": true,
"shared_accounts": [
{
"account_id": "SAV115Q6YHJR",
"user_id": "2f597da0-b188-48b8-87c5-cba46cfb2ba6",
"email": "testUserChild@io.io",
"first_name": "firstName",
"last_name": "lastName",
"personal_name": "firstName lastName",
"redeemed": 1748266945
},
{
"account_id": "SASU7Z7JZKTA",
"user_id": null,
"email": "testUserChild2@io.io",
"first_name": null,
"last_name": null,
"personal_name": null,
"redeemed": null
}
],
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"updated_by": "2Wkp0eI7hL"
}
Subscription renewal
This event indicates that a user's subscription has been renewed:
|
Type |
Event |
Triggered by |
Notes |
|
|
|
Piano |
Sent when Piano's system successfully auto-renews a user's subscription, including the successful completion of the grace period. If an auto-renewal fails, the |
|
|
|
You or User |
Sent when a user manually renews a subscription, or when you manually renew a user's subscription on the user's behalf. |
|
|
|
Piano |
Sent when Piano's system is unable to auto-renew a user's subscription due to any reason, but mostly because of the payment failure. This includes all cases of payment failure: immediate subscription expiration if there is no grace period, grace period starting after the first payment failure, all unsuccessful payment attempts in the grace period, and subscription expiration after the last payment attempt in the grace period. If an auto-renewal fails due to a 3DS authentication failure, the |
|
|
|
Piano |
Sent instead of the |
Contents of the webhook
|
Field |
Type |
Value |
|---|---|---|
|
type |
|
webhook type: |
|
version |
|
|
|
typeTitle |
|
webhook type title: |
|
event |
|
event:
|
|
eventTitle |
|
event title:
|
|
aid |
|
application id |
|
uid |
|
end-user id |
|
user_email |
|
end-user’s email address |
|
term_id |
|
term id |
|
term_type |
|
term type:
|
|
rid |
|
resource id |
|
access_id |
|
main access id, associated with subscription (access of subscription owner):
|
|
subscription_id |
|
subscription id |
|
status |
|
subscription status:
|
|
create_date |
|
subscription create date |
|
start_date |
|
subscription start date (differs from subscription crate date for subscriptions purchased with deferred start and imported subscriptions) |
|
next_bill_date |
|
the value of the “next billing date” field of the subscription (not
|
|
billing_plan |
|
billing plan of the last purchased period:
|
|
access_period_id |
|
id of the access the last purchased access period:
|
|
active_billing_plan |
|
billing plan of the active period:
|
|
active_access_period_id |
|
id of the last access the active access period:
|
|
upi_id |
|
id of the renewal payment method associated with the subscription |
|
auto_renew |
|
the state of the auto-renew toggle associated with the subscription:
|
|
shared_accounts |
|
array of all shared accounts currently associated with the shared subscription (includes accounts with both redeemed and not redeemed accesses) - see the UserSubscriptionAccount model above |
|
is_in_grace |
|
shows if the subscription is currently in grace period |
|
grace_period_start_date |
|
grace period start date |
|
grace_period_length |
|
grace period length in days |
|
failure_counter |
|
number of payment failures |
|
passive_churn_logic_id |
|
id of the churn prevention logic |
|
decline_reason |
|
decline reason for a payment attempt |
|
payment_id |
|
id of a payment associated with subscription creation |
|
renewal_type |
|
renewal type:
|
|
renewed_by |
|
id of a user initiated the action that resulted in subscription updating |
Examples
Example 1. Response to a subscription_auto_renewed event on a payment term
{
"type": "subscription_renewal",
"version": 2,
"typeTitle": "Subscription renewal",
"event": "subscription_auto_renewed",
"eventTitle": "Subscription was automatically renewed",
"aid": "hcxX89Lysu",
"uid": "a8db5940-e6b0-4f80-a1ca-ff2efeb46e72",
"user_email": "testUserParent@io.io",
"term_id": "TMZLF8VXAPHX",
"term_type": "PAYMENT",
"rid": "R2YEUGI",
"access_id": "OXaeX4AK6AfH",
"subscription_id": "RCYBDXV83B68",
"status": "ACTIVE",
"create_date": 1748266932,
"start_date": 1748266930,
"next_bill_date": 1753537330,
"billing_plan": "$22.00 per month",
"access_period_id": null,
"active_billing_plan": "$22.00 per month",
"active_access_period_id": null,
"upi_id": "PM24JSGH13M9",
"auto_renew": true,
"shared_accounts": [
{
"account_id": "SAV115Q6YHJR",
"user_id": "2f597da0-b188-48b8-87c5-cba46cfb2ba6",
"email": "testUserChild@io.io",
"first_name": "firstName",
"last_name": "lastName",
"personal_name": "firstName lastName",
"redeemed": 1748266945
},
{
"account_id": "SASU7Z7JZKTA",
"user_id": null,
"email": "testUserChild2@io.io",
"first_name": null,
"last_name": null,
"personal_name": null,
"redeemed": null
}
],
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"payment_id": "UPTXUR9N7YM0",
"renewal_type": "RENEWAL",
"renewed_by": "3QriFCs2yx"
}
Example 2. Response to a subscription_manually_renewed event on a dynamic term
{
"type": "subscription_renewal",
"version": 2,
"typeTitle": "Subscription renewal",
"event": "subscription_manually_renewed",
"eventTitle": "Subscription was manually renewed by user",
"aid": "vb45MHjPsu",
"uid": "3dfc67fe-9099-4b1a-9500-fc88239e7ccc",
"user_email": "testUser@io.io",
"term_id": "TM0KCBAS5F1M",
"term_type": "DYNAMIC",
"rid": "RNQUDNX",
"access_id": "bb4Ne8g5Xswl",
"subscription_id": "RC53ANJSK7LS",
"status": "ACTIVE",
"create_date": 1748601911,
"start_date": 1748601908,
"next_bill_date": 1756550693,
"billing_plan": "$22.00/every 1 month(s)",
"access_period_id": "APLHUFACWIJZ",
"active_billing_plan": "$11.00/every 1 month(s)",
"active_access_period_id": "APTZW610TP94",
"upi_id": "PMV8USHYJO5W",
"auto_renew": true,
"shared_accounts": [
{
"account_id": "SAV115Q6YHJR",
"user_id": "2f597da0-b188-48b8-87c5-cba46cfb2ba6",
"email": "testUserChild@io.io",
"first_name": "firstName",
"last_name": "lastName",
"personal_name": "firstName lastName",
"redeemed": 1748266945
},
{
"account_id": "SASU7Z7JZKTA",
"user_id": null,
"email": "testUserChild2@io.io",
"first_name": null,
"last_name": null,
"personal_name": null,
"redeemed": null
}
],
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"payment_id": "UPN0R55BAXL5",
"renewal_type": "RENEWAL",
"renewed_by": "2Wkp0eI7hL"
}
Subscription ended
This event indicates that a user's subscription has ended:
|
Type |
Event |
Triggered by |
Notes |
|
|
|
You or User |
Sent when a subscription is canceled using the immediate cancellation button |
|
|
|
Piano |
Sent when subscription renewal had failed and there is no grace period configured OR when subscription was canceled and not going to renew OR when there's no next access period configured in the term for this subscription |
|
|
|
Piano |
Sent for subscription FROM when subscription with suspended upgrade reached renewal date and didn't upgrade |
|
|
|
You, or User, or Piano |
Sent for subscription FROM when subscription upgrade was successfully executed |
|
|
|
Piano |
Sent for the subscription FROM when a scheduled upgrade was not successful and there is no grace period configured in the term TO |
|
|
|
Piano |
Sent when an upgrade was executed, but the newly created subscription for the new term entered a grace period because of a payment failure. |
Contents of the webhook
|
Field |
Type |
Value |
|---|---|---|
|
type |
string |
webhook type: |
|
version |
string |
|
|
typeTitle |
string |
webhook type title: |
|
event |
string |
event:
|
|
eventTitle |
string |
event title:
|
|
aid |
string |
application id |
|
uid |
string |
end-user id |
|
user_email |
string |
end-user’s email address |
|
term_id |
string |
term id |
|
term_type |
string |
term type:
|
|
rid |
string |
resource id |
|
access_id |
string |
main access id, associated with subscription (access of subscription owner):
|
|
subscription_id |
string |
subscription id |
|
status |
string |
subscription status:
|
|
create_date |
long |
subscription create date |
|
start_date |
long |
subscription start date (differs from subscription crate date for subscriptions purchased with deferred start and imported subscriptions) |
|
next_bill_date |
long |
the value of the “next billing date” field of the subscription (not null):
|
|
billing_plan |
string |
billing plan of the last purchased period:
|
|
access_period_id |
string |
id of the access the last purchased access period:
|
|
active_billing_plan |
string |
billing plan of the last active period:
|
|
active_access_period_id |
string |
id of the last access the active access period:
|
|
upi_id |
string |
id of the renewal payment method associated with the subscription |
|
auto_renew |
boolean |
the state of the auto-renew toggle associated with the subscription:
|
|
shared_accounts |
|
array of all shared accounts currently associated with the shared subscription (includes accounts with both redeemed and not redeemed accesses) - see the |
|
is_in_grace |
boolean |
shows if the subscription is currently in a grace period:
|
|
grace_period_start_date |
long |
grace period start date:
|
|
grace_period_length |
int |
grace period length in days:
|
|
failure_counter |
int |
number of payment failures:
|
|
passive_churn_logic_id |
string |
id of the churn prevention logic:
|
|
decline_reason |
string |
decline reason for a payment attempt:
|
|
ended_by |
string |
id of a user initiated the action that resulted in the subscription ending:
|
Examples
Example 1. Response to a subscription_canceled event on a payment term
{
"type": "subscription_ended",
"version": 2,
"typeTitle": "Subscription ended",
"event": "subscription_canceled",
"eventTitle": "Subscription canceled (immediate cancel)",
"aid": "hcxX89Lysu",
"uid": "a8db5940-e6b0-4f80-a1ca-ff2efeb46e72",
"user_email": "testUserParent@io.io",
"term_id": "TMZLF8VXAPHX",
"term_type": "PAYMENT",
"rid": "R2YEUGI",
"access_id": "OXaeX4AK6AfH",
"subscription_id": "RCYBDXV83B68",
"status": "CANCELLED",
"create_date": 1748266932,
"start_date": 1748266930,
"next_bill_date": 1753537330,
"billing_plan": "$22.00 per month",
"access_period_id": null,
"active_billing_plan": "$22.00 per month",
"active_access_period_id": null,
"upi_id": "PM24JSGH13M9",
"auto_renew": true,
"shared_accounts": [
{
"account_id": "SAV115Q6YHJR",
"user_id": "2f597da0-b188-48b8-87c5-cba46cfb2ba6",
"email": "testUserChild@io.io",
"first_name": "firstName",
"last_name": "lastName",
"personal_name": "firstName lastName",
"redeemed": 1748266945
},
{
"account_id": "SASU7Z7JZKTA",
"user_id": null,
"email": "testUserChild2@io.io",
"first_name": null,
"last_name": null,
"personal_name": null,
"redeemed": null
}
],
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"ended_by": "3QriFCs2yx"
}
Example 2. Response to a subscription_expired event on a dynamic term
{
"type": "subscription_ended",
"version": 2,
"typeTitle": "Subscription ended",
"event": "subscription_expired",
"eventTitle": "Subscription expired",
"aid": "vb45MHjPsu",
"uid": "3dfc67fe-9099-4b1a-9500-fc88239e7ccc",
"user_email": "testUser@io.io",
"term_id": "TM0KCBAS5F1M",
"term_type": "DYNAMIC",
"rid": "RNQUDNX",
"access_id": "bb4Ne8g5Xswl",
"subscription_id": "RC53ANJSK7LS",
"status": "EXPIRED",
"create_date": 1748601911,
"start_date": 1748601908,
"next_bill_date": 1759229093,
"billing_plan": "$22.00/every 1 month(s)",
"access_period_id": "APLHUFACWIJZ",
"active_billing_plan": "$22.00/every 1 month(s)",
"active_access_period_id": "APLHUFACWIJZ",
"upi_id": "PMV8USHYJO5W",
"auto_renew": true,
"shared_accounts": [
{
"account_id": "SAV115Q6YHJR",
"user_id": "2f597da0-b188-48b8-87c5-cba46cfb2ba6",
"email": "testUserChild@io.io",
"first_name": "firstName",
"last_name": "lastName",
"personal_name": "firstName lastName",
"redeemed": 1748266945
},
{
"account_id": "SASU7Z7JZKTA",
"user_id": null,
"email": "testUserChild2@io.io",
"first_name": null,
"last_name": null,
"personal_name": null,
"redeemed": null
}
],
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"ended_by": "2Wkp0eI7hL"
}
Subscription upgrade
This event indicates that a user's subscription has been changed to a new term:
|
Type |
Event |
Triggered by |
Notes |
|
|
|
You or User |
Sent when a user initiates a pending upgrade of their subscription, or when you initiate a pending upgrade of a user's subscription (including bulk upgrades). |
|
|
|
You, or User, or Piano |
Sent when a user immediately upgrades their subscription, or when you immediately upgrade a user's subscription on the user's behalf. Also sent when Piano's system successfully completes a previously scheduled pending upgrade of a user's subscription, including the successful completion of the grace period. If an upgrade fails, the |
|
|
|
You |
Sent when you cancel a previously scheduled pending upgrade of a user's subscription on the user's behalf. |
|
|
|
User |
Sent when a user suspends a previously scheduled pending upgrade of their subscription. |
|
|
|
User |
Sent when a user resumed a previously suspended pending upgrade of their subscription. |
|
|
|
Piano |
Sent when subscription with suspended upgrade reached renewal date and didn't upgrade |
|
|
|
Piano |
Sent when Piano's system is unable to complete a previously scheduled pending upgrade of a user's subscription due to any reason, but mostly because of the payment failure. This includes all cases of payment failure: immediate old subscription expiration without creating a new one if there is no grace period, grace period start for a new subscription after first payment failure, all unsuccessful payment attempts in the grace period, new subscription expiration after last payment attempt in the grace period. |
|
|
|
Piano |
Sent when an upgrade was executed, but the newly created subscription for the new term entered a grace period because of a payment failure. |
|
|
|
Piano |
Sent when the subscription exits grace period on renewal/billing attempt, grace period expiration or subscription cancellation. |
|
|
|
You or User |
Deprecated. Please use |
|
|
|
Piano |
Deprecated. Please use |
Contents of the webhook
|
Field |
Type |
Value |
|---|---|---|
|
type |
string |
webhook type: |
|
version |
string |
|
|
typeTitle |
string |
webhook type title: |
|
event |
string |
event:
|
|
eventTitle |
string |
event title:
|
|
aid |
string |
application id |
|
uid |
string |
end-user id |
|
user_email |
string |
end-user’s email address |
|
previous_term_id |
string |
termFROM id |
|
previous_term_name |
string |
termFROM name |
|
previous_subscription_id |
string |
subscriptionFROM id |
|
previous_subscription_rid |
string |
resourceFROM id |
|
previous_subscription_access_id |
string |
accessFROM id |
|
previous_billing_plan |
string |
billing plan of the last period of subscriptionFROM:
|
|
previous_access_period_id |
string |
access period id of the last period of subscriptionFROM:
|
|
new_term_id |
string |
termTO id |
|
new_term_name |
string |
termTO name |
|
new_subscription_id |
string |
subscriptionTO id |
|
new_subscription_rid |
string |
resourceTO id |
|
new_subscription_access_id |
string |
accessTO id |
|
new_billing_plan |
string |
billing plan of the first period of subscriptionTO (period, purchased on upgrade):
|
|
new_access_period_id |
string |
access period id of the first period of subscriptionTO (period, purchased on upgrade):
|
|
new_subscription_next_bill_date |
long |
the value of the “next billing date” field of the subscriptionTO (not
|
|
date_of_access_change |
long |
date of actual access change:
|
|
date_of_billing_change |
long |
date of actual billing plan change:
|
|
upi_id |
string |
id of the renewal payment method associated with the subscriptionTO (same as for subscriptionFROM) |
|
is_in_grace |
boolean |
shows if the subscriptionTO is currently in grace period:
|
|
grace_period_start_date |
long |
grace period start date:
|
|
grace_period_length |
int |
grace period length in days:
|
|
failure_counter |
int |
number of payment failures for subscriptionTO:
|
|
passive_churn_logic_id |
string |
id of the churn prevention logic:
|
|
decline_reason |
string |
decline reason for a payment attempt:
|
|
payment_id |
string |
id of a payment associated with upgrade: <id>: for
|
|
changed_by |
string |
id of a user initiated the upgrade or upgrade related action:
|
Examples
Example 1. Response to a term_change_finished event upon a successful upgrade of a payment term
{
"type": "term_change",
"version": 2,
"typeTitle": "Upgrade",
"event": "term_change_finished",
"eventTitle": "Upgrade finished",
"aid": "O28Dlkumsu",
"uid": "915c1d38-de94-46b8-a53c-d61f5f9a33f3",
"user_email": "test1@piano.io",
"previous_term_id": "TMUVP8YL3VU1",
"previous_term_name": "Payment FROM",
"previous_subscription_id": "RC0QR1FFOAZH",
"previous_subscription_rid": "R7QL719",
"previous_subscription_access_id": "XiZ3apUFEInE",
"previous_billing_plan": "$5.00 per month",
"previous_access_period_id": null,
"new_term_id": "TM4M8XNBXDUK",
"new_term_name": "Payment TO",
"new_subscription_id": "RCL2OKUORZ5P",
"new_subscription_rid": "RYNS2PZ",
"new_subscription_access_id": "H9pzzXdR7iFh",
"new_billing_plan": "$10.00 per month",
"new_access_period_id": null,
"new_subscription_next_bill_date": 1736678844,
"date_of_access_change": 1734000444,
"date_of_billing_change": 1734001271,
"upi_id": "PMIAAO7HZ4XF",
"is_in_grace": false,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": 0,
"passive_churn_logic_id": null,
"decline_reason": null,
"payment_id": "UP54X6BTA44T",
"changed_by": "915c1d38-de94-46b8-a53c-d61f5f9a33f3"
}
Example 2. Response to term_change_failure event upon an unsuccessful upgrade of a payment term
{
"type": "term_change",
"version": 2,
"typeTitle": "Upgrade",
"event": "term_change_failure",
"eventTitle": "Upgrade failure",
"aid": "O28Dlkumsu",
"uid": "915c1d38-de94-46b8-a53c-d61f5f9a33f3",
"user_email": "test1@piano.io",
"previous_term_id": "TMUVP8YL3VU1",
"previous_term_name": "Payment FROM",
"previous_subscription_id": "RCURT95NV8FL",
"previous_subscription_rid": "R7QL719",
"previous_subscription_access_id": "EP9I7cmch94Y",
"previous_billing_plan": "$5.00 per month",
"previous_access_period_id": null,
"new_term_id": "TMIY12FRWXF7",
"new_term_name": "Payment TO without GRACE",
"new_subscription_id": null,
"new_subscription_rid": "R9O828L",
"new_subscription_access_id": null,
"new_billing_plan": "$10.00 per month",
"new_access_period_id": null,
"new_subscription_next_bill_date": null,
"date_of_access_change": 1734077643,
"date_of_billing_change": null,
"upi_id": "PMIAAO7HZ4XF",
"is_in_grace": null,
"grace_period_start_date": null,
"grace_period_length": null,
"failure_counter": null,
"passive_churn_logic_id": null,
"decline_reason": "CALL_ISSUER",
"payment_id": null,
"changed_by": null
}
Access granted
These are all of the events that result in new access:
|
Type |
Event |
Triggered by |
Notes |
|---|---|---|---|
|
|
|
User |
Sent when a user makes a purchase where a financial transaction that took place. It will also fire when Print Subscription Confirmation (PSC) is redeemed. For free trials, the |
|
|
|
User |
Sent when a user signs up for a free trial. This event is only sent for free trials where the user will eventually be charged. If the user has a promo code that gives them 100% off of a fixed-time purchase, the |
|
|
|
You |
Sent when you create a user's subscription via the dashboard on the user's behalf. |
|
|
|
You |
Sent when end-user is subscribed to a term with a free trial or a free period. |
|
|
|
You |
Sent when a subscription is created by the import tool used by the Piano support team. |
|
|
|
You |
Sent when you use the Piano Dashboard to grant a user access. |
|
|
|
User |
Sent when a user redeems a promo code for 100% off of a fixed-time purchase. If a user redeems a promo code where there is a transaction that takes place (or will take place in the case of a free trial), either the |
|
|
|
User |
Sent when a user is granted access after providing their address information on your website for the purpose of the PSC. |
|
|
|
Piano |
Sent when cross app access has been granted. |
|
|
|
User |
Sent when a user is granted access in return for registering on your website. |
|
|
|
You |
Sent when a user converts on a custom term. |
|
|
|
User |
Sent when a user redeems access under site license. |
|
|
|
You, or User, or Piano |
Sent upon a successful subscription upgrade.
|
|
|
|
Piano |
Sent when an upgrade was executed, but the newly created subscription for the new term entered a grace period because of a payment failure.
|
Contents of the webhook
|
Field |
Type |
Value |
|---|---|---|
|
type |
string |
webhook type: |
|
version |
string |
|
|
typeTitle |
string |
webhook type title: |
|
event |
string |
event:
|
|
eventTitle |
string |
event title:
|
|
aid |
string |
application id |
|
expires |
|
access expiration date:
|
|
term_id |
|
term id:
|
|
uid |
|
end-user id |
|
rid |
|
resource id |
|
access_id |
|
access id |
|
user_email |
|
end-user's email address |
|
contract_id |
|
contract id:
|
|
payment_id |
|
user payment id:
|
|
conversion_id |
|
conversion id:
|
Examples
Example 1. Response to a term_applied_by_publisher event on a payment term
{
"type": "access_granted",
"version": 2,
"typeTitle": "Access granted",
"event": "term_applied_by_publisher",
"eventTitle": "New purchase by publisher",
"aid": "hcxX89Lysu",
"expires": 1751313599,
"term_id": "TMZLF8VXAPHX",
"uid": "a8db5940-e6b0-4f80-a1ca-ff2efeb46e72",
"rid": "R2YEUGI",
"access_id": "OXaeX4AK6AfH",
"user_email": "testUserParent@io.io",
"contract_id": null,
"payment_id": "UPOI7Z4OISQ2",
"conversion_id": null
}
Example 2. Response to a new_purchase event on a dynamic term
{
"type": "access_granted",
"version": 2,
"typeTitle": "Access granted",
"event": "new_purchase",
"eventTitle": "New purchase",
"aid": "cNDPkdkYsu",
"expires": 1751313599,
"term_id": "TM1661TNEBIP",
"uid": "3dfc67fe-9099-4b1a-9500-fc88239e7ccc",
"rid": "RHVJYOV",
"access_id": "sAiSWHku14c2",
"user_email": "testUser@io.io",
"contract_id": null,
"payment_id": "UPFM5KXK6RDD",
"conversion_id": null
}
Note that the value for conversion_id is only being populated for external terms such as CDS, Apple iTunes, Google/SwG or Newscycle.
Access modified
These are all of the events that indicate that an access has been modified:
|
Type |
Event |
Triggered by |
Notes |
|---|---|---|---|
|
|
|
Piano |
Sent when an access is modified after a subscription with a future start date is activated. |
|
|
|
Piano |
Sent when an access is modified after Piano's system successfully auto-renews a user's subscription. In case of a payment failure upon the auto-renewal, the webhook |
|
|
|
User |
Sent when an access is modified after a user manually renews a subscription, or when you manually renew a user's subscription on the user's behalf. |
|
|
|
Piano |
Sent when an access is modified after the Piano system grants additional days of access to a user whose subscription Piano is unable to automatically renew. After the grace period is over, we send the |
|
|
|
You or User |
Sent when an access is modified after a dynamic subscription is canceled and it modifies a user's access. |
|
|
|
You or User |
Sent when an access is modified after a dynamic subscription is resumed and a user's access is extended. |
|
|
|
You or User |
Sent when an access is modified after you update the next bill date on a user's subscription or when a user's subscription is cancelled due to disabling their account. |
|
|
|
You |
Sent when an access is modified after a dynamic subscription's unlimited period is converted to a period of another type. The action is initiated by You, but done asynchronously. |
|
|
|
You or User |
Sent when an access is modified after you modify a user's non-subscription-based access. The access associated with the subscription is modified by updating the next bill date which triggers the This webhook is also sent when a user requests an upgrade and their new access takes effect. |
|
|
|
Piano |
Sent when a cross app access is modified. |
|
|
|
Piano |
Sent when an access is modified after a site license is renewed. |
Contents of the webhook
|
Field |
Type |
Value |
|---|---|---|
|
type |
string |
webhook type: |
|
version |
string |
|
|
typeTitle |
string |
webhook type title: |
|
event |
string |
event:
|
|
eventTitle |
string |
event title:
|
|
aid |
string |
application id |
|
expires |
long |
access expiration date:
|
|
term_id |
string |
term id:
|
|
uid |
string |
end-user id |
|
rid |
string |
resource id |
|
access_id |
string |
access id |
|
user_email |
string |
end-user's email address |
|
contract_id |
string |
contract id:
|
|
payment_id |
string |
user payment id:
|
|
conversion_id |
string |
conversion id:
|
*When a subscription is manually renewed while in the grace period, the system records the notification in the user’s history, but intentionally skips sending the access_modified webhook. This is because entering the grace period already grants access through the end of the current access period. The manual renewal resolves the overdue payment, and once the subscription exits the grace period, the user’s access remains unchanged and continues until the end of that period.
Examples
Example 1. Response to a subscription_auto_renewed event on a payment term
{
"type": "access_modified",
"version": 2,
"typeTitle": "Access modified",
"event": "subscription_auto_renewed",
"eventTitle": "Subscription was automatically renewed",
"aid": "hcxX89Lysu",
"expires": 1751313599,
"term_id": "TMZLF8VXAPHX",
"uid": "a8db5940-e6b0-4f80-a1ca-ff2efeb46e72",
"rid": "R2YEUGI",
"access_id": "OXaeX4AK6AfH",
"user_email": "testUserParent@io.io",
"contract_id": null,
"payment_id": "UPTXUR9N7YM0",
"conversion_id": null
}
Example 2. Response to a subscription_deferred_canceled event on a dynamic term
{
"type": "access_modified",
"version": 2,
"typeTitle": "Access modified",
"event": "subscription_manually_renewed",
"eventTitle": "Subscription was manually renewed by user",
"aid": "vb45MHjPsu",
"expires": 1759262399,
"term_id": "TM0KCBAS5F1M",
"uid": "3dfc67fe-9099-4b1a-9500-fc88239e7ccc",
"rid": "RNQUDNX",
"access_id": "bb4Ne8g5Xswl",
"user_email": "testUser@io.io",
"contract_id": null,
"payment_id": "UPN0R55BAXL5",
"conversion_id": null
}
Access revoked
These are all of the events that indicate revoked access:
|
Type |
Event |
Triggered by |
Notes |
|---|---|---|---|
|
|
|
You |
Sent when a user's access is revoked. |
|
|
|
Piano |
Sent when Piano is unable to charge a user's credit card to renew their subscription, and there is no grace period or the grace period has ended. |
|
|
|
Piano |
Sent when Piano determines that non-subscription-based access has ended. The |
|
|
|
User |
Sent when a user cancels their subscription or when you cancel a user's subscription on their behalf. |
|
|
|
Piano |
Sent when Piano attempts to renew a user's subscription and determines that auto-renew is turned off. |
|
|
|
Piano |
Sent when cross app access has been revoked. |
|
|
|
Piano |
Sent when the end user's site license expires. |
|
|
|
You |
Sent when the end user's site license was canceled. |
|
|
|
You, or User, or Piano |
Sent upon a successful upgrade execution.
|
|
|
|
Piano |
Sent when a pending upgrade is suspended.
|
|
|
|
Piano |
Sent in case of failure on a pending upgrade, with no grace in termTO/periodTO.
|
|
|
|
Piano |
Sent when an upgrade was executed, but the newly created subscription for the new term entered a grace period because of a payment failure.
|
Contents of the webhook
|
Field |
Type |
Value |
|
type |
|
webhook type: |
|
version |
|
|
|
typeTitle |
|
webhook type title: |
|
event |
|
event:
|
|
eventTitle |
|
event title:
|
|
aid |
|
application id |
|
expires |
|
access expiration date:
|
|
term_id |
|
term id:
|
|
uid |
|
end-user id |
|
rid |
|
resource id |
|
access_id |
|
access id |
|
user_email |
|
end-user’s email address |
|
contract_id |
|
contract id:
|
Examples
Example 1. Response to a subscription_canceled event on a payment term
{
"type": "access_revoked",
"version": 2,
"typeTitle": "Access revoked",
"event": "subscription_canceled",
"eventTitle": "Subscription canceled (immediate cancel)",
"aid": "hcxX89Lysu",
"expires": -1,
"term_id": "TMZLF8VXAPHX",
"uid": "a8db5940-e6b0-4f80-a1ca-ff2efeb46e72",
"rid": "R2YEUGI",
"access_id": "OXaeX4AK6AfH",
"user_email": "testUserParent@io.io",
"contract_id": null
}
Example 2. Response to a subscription_expired event on a dynamic term
{
"type": "access_revoked",
"version": 2,
"typeTitle": "Access revoked",
"event": "subscription_expired",
"eventTitle": "Subscription expired",
"aid": "vb45MHjPsu",
"expires": 1748603688,
"term_id": "TM0KCBAS5F1M",
"uid": "3dfc67fe-9099-4b1a-9500-fc88239e7ccc",
"rid": "RNQUDNX",
"access_id": "bb4Ne8g5Xswl",
"user_email": "testUser@io.io",
"contract_id": null
}
Shared access granted
These events indicate that a user has received access under a shared subscription.
|
Type |
Event |
Triggered by |
Notes |
|
|
|
Piano |
Sent when a child access is automatically redeemed due to the purchase, import, activation, update, upgrade, or grace period of the parent subscription. |
|
|
|
User |
Sent when a user manually redeems their child access via a invitation link from email or via MA. |
Contents of the webhook
|
Field |
Type |
Value |
|
type |
|
webhook type: |
|
version |
|
|
|
typeTitle |
|
webhook type title: |
|
event |
|
event:
|
|
eventTitle |
|
event title:
|
|
aid |
|
application id |
|
uid |
|
CHILD end-user's id |
|
user_email |
|
CHILD end-user’s email address |
|
access_id |
|
CHILD access id |
|
expires |
|
CHILD access expiration date:
|
|
term_id |
|
term id of PARENT subscription:
|
|
term_type |
|
term type of PARENT subscription:
|
|
rid |
|
resource id |
|
parent_uid |
|
PARENT end-user id |
|
parent_subscription_id |
|
PARENT subscription id |
Examples
Example 1. Response to a shared_subscription_child_access_auto_redeemed event on a payment term
{
"type": "shared_access_granted",
"version": 2,
"typeTitle": "Shared access granted",
"event": "shared_subscription_child_access_auto_redeemed",
"eventTitle": "Child access auto redeemed",
"aid": "PfBGJcdpsu",
"uid": "472aa39b-12e8-42af-b772-8c998bed77c6",
"user_email": "testUserChild@io.io",
"access_id": "PfP7PNuG8PD3",
"expires": 1753905599,
"term_id": "TMDW8TL68SRI",
"term_type": "PAYMENT",
"rid": "R7U33ER",
"parent_uid": "53ed042d-1e2c-4063-a2e3-8bec3c15d576",
"parent_subscription_id": "RC0TCFOY77BZ"
}
Example 2. Response to a shared_subscription_child_access_manually_redeemed event on a dynamic term
{
"type": "shared_access_granted",
"version": 2,
"typeTitle": "Shared access granted",
"event": "shared_subscription_child_access_manually_redeemed",
"eventTitle": "Child access manually redeemed",
"aid": "PfBGJcdpsu",
"uid": "e4b13fc0-c120-4968-9165-a3ae07592cc3",
"user_email": "testUserChild@io.io",
"access_id": "wk7hRfKfAKtr",
"expires": 1753905599,
"term_id": "TMUGCTMDIKGX",
"term_type": "DYNAMIC",
"rid": "RGCMKA2",
"parent_uid": "53ed042d-1e2c-4063-a2e3-8bec3c15d576",
"parent_subscription_id": "RCDAZL03AIST"
}
Shared access modified
These events indicate that a user's child access under a shared subscription has been modified.
|
Type |
Event |
Triggered by |
Notes |
|
|
|
Piano |
Sent for a CHILD access modified when the auto-renewal of its PARENT subscription succeeds on the initial attempt. |
|
|
|
You or User |
Sent for a CHILD access modified upon a successful manual renewal of the PARENT subscription. |
|
|
|
Piano |
Sent for a CHILD access modified when a grace period is started upon a failed auto-renewal of the PARENT subscription. |
|
|
|
You or User |
Sent for a CHILD access modified upon a deferred cancellation of the PARENT subscription (the subscription doesn't have a scheduled pending upgrade and is not on the last billing period of its access period). |
|
|
|
You or User |
Sent for a CHILD access modified upon a resumption of the PARENT subscription (the subscription doesn't have a scheduled pending upgrade and is not on the last billing period of its access period). |
|
|
|
You |
Sent for a CHILD access modified upon an update of the next billing period of the PARENT subscription via the Dashboard or API. |
|
|
|
You |
Sent for a CHILD access modified upon a conversion of an unlimited access period for a dynamic term when the PARENT subscription is active on this period. |
Contents of the webhook
|
Field |
Type |
Value |
|
type |
|
webhook type: |
|
version |
|
|
|
typeTitle |
|
webhook type title: |
|
event |
|
event:
|
|
eventTitle |
|
event title:
|
|
aid |
|
application id |
|
uid |
|
CHILD end-user id |
|
user_email |
|
CHILD end-user’s email address |
|
access_id |
|
CHILD access id |
|
expires |
|
CHILD access expiration date:
|
|
term_id |
|
term id of PARENT subscription:
|
|
term_type |
|
term type of PARENT subscription:
|
|
rid |
|
resource id |
|
parent_uid |
|
PARENT end-user id |
|
parent_subscription_id |
|
PARENT subscription id |
Examples
Example 1. Response to a subscription_deferred_canceled event on a payment term
{
"type": "shared_access_modified",
"version": 2,
"typeTitle": "Shared access modified",
"event": "subscription_deferred_canceled",
"eventTitle": "Subscription canceled (deferred cancel)",
"aid": "PfBGJcdpsu",
"uid": "472aa39b-12e8-42af-b772-8c998bed77c6",
"user_email": "testUserChild@io.io",
"access_id": "T0Q4I1gZBMHo",
"expires": 1759607999,
"term_id": "TMASFSUO3PWV",
"term_type": "PAYMENT",
"rid": "R7U33ER",
"parent_uid": "53ed042d-1e2c-4063-a2e3-8bec3c15d576",
"parent_subscription_id": "RC0TCFOY77BZ"
}
Example 2. Response to a subscription_resumed event on a dynamic term
{
"type": "shared_access_modified",
"version": 2,
"typeTitle": "Shared access modified",
"event": "subscription_resumed",
"eventTitle": "Subscription resumed",
"aid": "2rsQ4RqFsu",
"uid": "5ebac7ac-4adc-4d18-9b72-0e8df95bb154",
"user_email": "testUserChild@io.io",
"access_id": "T0Q4I1gZBMHo",
"expires": 1759607999,
"term_id": "TMPIESUO3PWV",
"term_type": "DYNAMIC",
"rid": "RDVZ3X5",
"parent_uid": "decbe198-27b5-469b-a2db-c62d78490950",
"parent_subscription_id": "RCFJVD89OVEZ"
}
Shared access revoked
These events indicate that a user's child access under a shared subscription has been revoked.
|
Type |
Event |
Triggered by |
Notes |
|
|
|
You,
|
Sent when a parent user removes a child user from the list of shared accounts or when you do it via API or the dashboard on the parent user's behalf. |
|
|
|
You or User |
Sent when a child user manually revokes their child access or when you do it via API on the child user's behalf. |
|
|
|
You or User |
Sent when a user cancels their subscription or when you cancel a user's subscription on their behalf. Triggered for CHILD accounts with redeemed access. |
|
|
|
Piano |
Sent when a subscription renewal has failed and there is no grace period configured, or when a subscription has been canceled and will not renew, or when there's no next access period configured in the term for this subscription. |
|
|
|
You,
|
Sent when a subscription is successfully upgraded. Triggered for a CHILD account with redeemed access to the termFROM, when such a CHILD is being removed from the list of shared accounts. |
|
|
|
Piano |
Sent when a pending upgrade is suspended. Triggered for a CHILD account with redeemed access to the termFROM, when such a CHILD is being removed from the list of shared accounts. |
|
|
|
Piano |
Sent in case of failure on a pending upgrade, with no grace in termTO/periodTO. Triggered for a CHILD account with redeemed access to the termFROM, when such a CHILD is being removed from the list of shared accounts. |
|
|
|
Piano |
Sent when an upgrade was executed, but the newly created subscription for the new term entered a grace period because of the payment failure. Triggered for a CHILD account with redeemed access to the termFROM, when such a CHILD is being removed from the list of shared accounts. |
Contents of the webhook
|
Field |
Type |
Value |
|
type |
|
webhook type: |
|
version |
|
|
|
typeTitle |
|
webhook type title: |
|
event |
|
event:
|
|
eventTitle |
|
event title:
|
|
aid |
|
application id |
|
uid |
|
CHILD end-user id |
|
user_email |
|
CHILD end-user’s email address |
|
access_id |
|
CHILD access id |
|
expires |
|
CHILD access expiration date:
|
|
term_id |
|
term id of PARENT subscription:
|
|
term_type |
|
term type of PARENT subscription:
|
|
rid |
|
resource id |
|
parent_uid |
|
PARENT end-user id |
|
parent_subscription_id |
|
PARENT subscription id |
Examples
Example 1. Response to a shared_subscription_child_left event on a payment term
{
"type": "shared_access_revoked",
"version": 2,
"typeTitle": "Shared access revoked",
"event": "shared_subscription_child_left",
"eventTitle": "Child left",
"aid": "nAmj7xEtsu",
"uid": "7a00fc40-4b9a-474f-80ef-3b2b5dbe7b98",
"user_email": "testUserChild@io.io",
"access_id": "dJIalfl3D5ke",
"expires": -1,
"term_id": "TM6K8R7QDP5J",
"term_type": "PAYMENT",
"rid": "RWMVGQN",
"parent_uid": "ec8ea432-64b5-44fe-8010-1895f8bc2917",
"parent_subscription_id": "RCTLDQ6MW4YM"
}
Example 2. Response to a shared_subscription_child_access_revoked event on a dynamic term
{
"type": "shared_access_revoked",
"version": 2,
"typeTitle": "Shared access revoked",
"event": "shared_subscription_child_access_revoked",
"eventTitle": "Child access revoked",
"aid": "nAmj7xEtsu",
"uid": "110d6f29-a91c-4869-a9a8-d0610ed7358a",
"user_email": "testUserChild@io.io",
"access_id": "Nemz4Vs3P2It",
"expires": -1,
"term_id": "TMIKFHI0MM3C",
"term_type": "DYNAMIC",
"rid": "RONJAEU",
"parent_uid": "387b2711-285d-4fd9-b101-b750115f4e6e",
"parent_subscription_id": "RCG3DJ2O6CHO"
}
Vouchers
These events indicate users have engaged with vouchers or gift offers.
|
Type |
Event |
Triggered by |
Notes |
|---|---|---|---|
|
|
User |
Sent when a user converts on a gift offer and purchases a voucher. |
|
|
|
Piano |
Sent when the gift is successfully delivered to the recipient after the voucher has been purchased. |
|
|
|
User |
Sent when gift recipient redeems their gift and begins their period of access. |
|
|
|
|
Piano |
Sent when access to the resource is triggered after the gift is redeemed. |
|
|
You |
Sent when a gift voucher's access has been revoked. |
Examples
Example 1. Response to a voucher_purchased event
{
"version": 2,
"type": "voucher_purchased",
"event": "voucher_purchase",
"aid": "eBGQWilSFK",
"voucher_id": "VPS4VGpzhavq",
"term_id": "TMDK47VMOY35",
"voucher_state": 5,
"voucher_send_date_timestamp": 1571248201,
"voucher_recipient_name": "Example Giftee",
"voucher_recipient_email": "<a class="c-link" href="mailto:giftee@gmail.com" target="_blank" rel="noopener noreferrer">giftee@gmail.com</a>",
"voucher_message": "here is your gift",
"voucher_code": "2O0KYE5",
"voucher_expires_timestamp": 1602870614,
"voucher_issue_term_conversion_id": "TCJJFBQO4L6D",
"voucher_redeem_term_conversion_id": "TCFV21GB7122",
"address_id": "UAV9XL30TSMY"
}
Example 2. Response to a voucher_delivered event
{
"version": 2,
"type": "voucher_delivered",
"event": "voucher_delivery",
"aid": "eBGQWilSFK",
"voucher_id": "VPS4VGpzhavq",
"term_id": "TMDK47VMOY35",
"voucher_state": 5,
"voucher_send_date_timestamp": 1571248201,
"voucher_recipient_name": "Example Giftee",
"voucher_recipient_email": "<a class="c-link" href="mailto:giftee@gmail.com" target="_blank" rel="noopener noreferrer">giftee@gmail.com</a>",
"voucher_message": "here is your gift",
"voucher_code": "2O0KYE5",
"voucher_expires_timestamp": 1602870614,
"voucher_issue_term_conversion_id": "TCJJFBQO4L6D",
"voucher_redeem_term_conversion_id": "TCFV21GB7122",
"address_id": "UAV9XL30TSMY"
}
Example 3. Response to a voucher_redeemed event
{
"version": 2,
"type": "voucher_redeemed",
"event": "to_giftee_voucher_redeemed",
"aid": "eBGQWilSFK",
"voucher_id": "VPS4VGpzhavq",
"term_id": "TMDK47VMOY35",
"voucher_state": 5,
"voucher_send_date_timestamp": 1571248201,
"voucher_recipient_name": "Example Giftee",
"voucher_recipient_email": "<a class="c-link" href="mailto:giftee@gmail.com" target="_blank" rel="noopener noreferrer">giftee@gmail.com</a>",
"voucher_message": "here is your gift",
"voucher_code": "2O0KYE5",
"voucher_expires_timestamp": 1602870614,
"voucher_issue_term_conversion_id": "TCJJFBQO4L6D",
"voucher_redeem_term_conversion_id": "TCFV21GB7122",
"address_id": "UAV9XL30TSMY"
}
Example 4. Response to a voucher_revoked event
{
"version": 2,
"type": "voucher_revoked",
"event": "voucher_revoked",
"aid": "eBGQWilSFK",
"voucher_id": "VPS4VGpzhavq",
"term_id": "TMDK47VMOY35",
"voucher_state": 5,
"voucher_send_date_timestamp": 1571248201,
"voucher_recipient_name": "Example Giftee",
"voucher_recipient_email": "<a class="c-link" href="mailto:giftee@gmail.com" target="_blank" rel="noopener noreferrer">giftee@gmail.com</a>",
"voucher_message": "here is your gift",
"voucher_code": "2O0KYE5",
"voucher_expires_timestamp": 1602870614,
"voucher_issue_term_conversion_id": "TCJJFBQO4L6D",
"voucher_redeem_term_conversion_id": "TCFV21GB7122",
"address_id": "UAV9XL30TSMY"
}
Site license
These are all events that fire in connection with site licenses.
All notifications include the parameters version (2), aid, type, typeTitle, event, and eventTitle.
|
Type |
Event |
Triggered by |
Notes |
|
|
|
You |
We send this webhook when a new Site license is created. |
|
|
|
You |
We send this webhook when an existing Site license is updated. |
|
|
|
You |
This webhook is sent when an email domain or specific email address contract is created. |
|
|
|
You |
This webhook is sent when an email domain or specific email address contract is updated. |
|
|
|
You |
This webhook is sent when an email domain or specific email address contract is deleted. |
|
|
|
You |
We send this webhook when a new user is added to a contract. |
|
|
|
User |
We send this webhook when the end-user redeems a site license contract. |
|
|
|
Piano |
We send this webhook when the end user's site license contract is renewed. |
|
|
|
You |
We send this webhook when the end user's site license contract access is revoked. |
|
|
|
Piano |
We send this webhook when the end user's site license contract access expires. |
|
|
|
You |
We send this webhook when the end-user is invited to a site license contract. |
Examples
Example 1. Response to a licensee_created event
{
"version": 2,
"type": "licensee_created",
"typeTitle": "Licensee created",
"event": "licensee_created",
"eventTitle": "Licensee created",
"aid": "XTSRGNiPaH",
"licensee_id": "LCS1FYAN2WT74"
}
Example 2. Response to a contract_created event
{
"version": 2,
"type": "contract_created",
"typeTitle": "Contract created",
"event": "contract_created",
"eventTitle": "Contract created",
"aid": "XTSRGNiPaH",
"contract_id": "TMYIODEP48W1"
}
Example 3. Response to a contract_user_created event
{
"version": 2,
"type": "contract_user_created",
"typeTitle": "Contract user created",
"event": "contract_user_created",
"eventTitle": "Contract user created",
"aid": "XTSRGNiPaH",
"contract_id": "TMPZR0WZV5BN",
"user_email": "test@example.com"
}
Example 4. Response to a contract_redeemed event
{
"Version": 2,
"type": "contract_redeemed",
"typeTitle": "Contract redeemed",
"event": "licensee_contract_redeemed",
"eventTitle": "Contract redeemed",
"aid": "XTSRGNiPaH",
"contract_id": "TMPZR0WZV5BN",
"conversion_id": "TC4IGE500S9T",
"uid": "PNIWrbGg3qui132",
"user_email": "test@example.com"
}
Example 5. Response to a contract_user_access_revoked event
{
"Version": 2,
"type": "contract_user_access_revoked",
"typeTitle": "Contract user access revoked",
"event": "licensee_contract_subscription_canceled",
"eventTitle": "Contract subscription canceled",
"aid": "XTSRGNiPaH",
"contract_id": "TMPZR0WZV5BN",
"uid": "PNIWrbGg3qui132",
"user_email": "test@example.com"
}
Example 6. Response to a licensee_invite_to_contract event
{
"Version": 2,
"type": "licensee_invite_to_contract",
"typeTitle": "User invited to contract",
"Event": "licensee_invite_to_contract",
"eventTitle": "Users invited to contract",
"aid": "XTSRGNiPaH",
"contract_id": "TMPZR0WZV5BN",
"user_email": "test@example.com"
}
User data
These events indicate user data has been added, updated, or deleted:
|
Type |
Event |
Triggered by |
Notes |
|---|---|---|---|
|
|
|
You or User |
Sent when a user is created through registration or by the publisher dashboard. User creation events include user registration, passwordless registration (single and non-single step), social registration. On your side, events include creating new users via the 'Add new user' button, and bulk creation of users through email or import. |
|
|
|
You or User |
Sent when an end user, you, or file import updates the first name, last name, or email fields in the My Account page. |
|
|
|
You or User |
Sent when you or the end user updates a custom field. Note that this does not include consent field updates. |
|
|
|
User |
Sent when the user updates their password through My Account or they reset their password through the email link. Note that a publisher user can trigger the reset password action, but only an end user can complete it. |
|
|
|
You or User |
Sent when you or the user disable their accounts or their account is disabled via the publisher dashboard. |
|
|
|
User |
Sent when the user confirms their email through double opt-in. |
Examples
Example 1. Response to a user_created event
When a user is created, the their identifier (UID) is sent in the webhook body.
{
"type": "user_created",
"event": "user_created",
"uid": "43097265",
"aid": "87jJKj3jf3",
"timestamp": "1575621625"
}
Example 2. Response to a user_updatedevent
For updated user information, the actual information input into the user profile is not displayed in the webhook body. For custom field updates, the name of the custom field updates is included in the webhook. The user profile update looks like this:
{
"type": "user_updated",
"event": "user_updated",
"uid": "43097265",
"aid": "87jJKj3jf3",
"timestamp": "1575543633"
}
The custom field update looks like this:
{
"type": "user_updated",
"event": "piano_id_user_custom_fields_updated",
"uid": "43097265",
"aid": "87jJKj3jf3",
"timestamp":"1575544166",
"Updated_custom_fields":"date_id,num_id,text_id"
}
User address update
These are all of the events that result in a user address update:
|
Type |
Event |
Triggered by |
Notes |
|
|
You or User |
We send this webhook when the end-user updates their delivery address associated with a subscription or a voucher in My Account, or when the delivery address associated with one or several subscriptions or vouchers is updated in publisher dashboard. |
|
|
|
User |
Deprecated. Please use |
Examples
Example 1. Response to an address_updated event
{
"type": "address_updated",
"event": "address_updated",
"aid": "jIwpUvdZM7",
"uid": "HCT7oB6uSi",
"address_id": "UAV9XL30TSMY",
"subscription_id": ["RCOWL8YOHU18","RCOWL8YOHU19","RCOWL8YOHU20"],
"voucher_id": ["VPS4VGpzhavq","VPS4VGpzhavr"]
}
Example 2. Response to a user_address_updated event. DEPRECATED.
{
"type": "user_address_updated",
"event": "user_address_updated",
"aid": "jIwpUvdZM7",
"uid": "HCT7oB6uSi",
"term_id": "TM0B60EUU3UR",
"subId": "RCOWL8YOHU18",
"access_id": "48c1ShRnfvb8",
"psc_subscriber_number": "1"
}
User payment method
The user_payment_method webhook type and events are disabled for all applications at the time of release, and may be enabled as needed by interested client users.
These are all events related to management of user payment methods.
|
Type |
Event |
Triggered by |
Notes |
|
|
|
User |
We send this webhook when a user creates a new payment method. |
|
|
|
User |
We send this webhook when a user updates the existing payment method or changes the payment method associated with a subscription. |
Example
{
"version": 2,
"type": "user_payment_method",
"event": "(user_payment_method_new|user_payment_method_update)",
"user_payment_info_id": "PME5WHTVT394",
"user_subscriptions": ["RC31FDSDA339","RC31FDSDA329"],
"uid": "43097265",
"aid": "87jJKj3jf3"
}
Payments
These are payment-related webhooks available in Piano:
|
Type |
Event |
Triggered by |
Notes |
|---|---|---|---|
|
|
|
Piano |
Sent when the user payment status has been changed to Completed. |
|
|
|
Piano |
Sent when the user payment fails, is canceled or aborted. |
|
|
|
Piano |
Sent when the user payment has been created in the Initiated status. |
|
|
|
Piano |
Sent when the user payment status has been changed to Pending. |
|
|
|
You or User |
Sent when a full or partial refund has been issued. |
Contents of the webhook
|
Field |
Required |
Type |
Value |
|---|---|---|---|
|
type |
Required |
|
webhook type:
|
|
typeTitle |
Required |
|
webhook type title:
|
|
event |
Required |
|
Webhook event:
|
|
eventTitle |
Required |
|
webhook event title:
|
|
triggeredBy |
Required |
|
The type of payment trigger. Possible values:
|
|
version |
Required |
|
2 |
|
userPaymentId |
Required |
|
The user-payment ID in Piano. |
|
status |
Required |
|
The user payment status. |
|
statusValue |
Required |
|
The user payment status value. |
|
amount |
Optional |
|
The amount from userPayment that has been actually charged. |
|
userPaymentInfoId |
Optional |
|
The UPI ID in Piano. |
|
externalPaymentId |
Optional |
|
The external UPI token. |
|
xternalCustomerId |
Optional |
|
The external customer Id = payment_method_token (for imports) |
|
aId |
Required |
|
The Piano application ID where the payment has been initiated. |
|
uId |
Required |
|
The internal user ID in Piano. |
|
termId |
Required |
|
The Piano term ID that has been purchased. |
|
resourseId |
Required |
|
The Piano resource ID that is represented with the purchased term. |
|
subscriptionId |
Optional |
|
The Piano subscription ID that has been created as a result of the purchase or the payment has been made. The parameter could be specified for MITs only. |
|
accessId |
Optional |
|
The Piano access ID that has been created. The parameter could be specified for MITs only. |
|
billingPeriodDateFrom |
Optional |
|
The start date of the subscription billing period that is paid with current user payment. The parameter could be specified for MITs only. |
|
billingPeriodDateTo |
Optional |
|
The end date of the subscription billing period that is paid with the current user payment. The parameter could be specified for MITs only. |
|
merchantID |
Optional |
|
Merchant ID from External provider configuration. |
|
paymentMethodKey |
Optional |
|
The value that represents the payment method that should be displayed in the External payment page after the end-user is redirected from Piano. Could be used in cases when there are multiple external payment method configurations for a single merchant. |
|
sourceInt |
Required |
|
Internal Piano identifier of the payment method. |
Examples
Example 1. Response to a payment_completed event
{
"type": "payment_completed",
"typeTitle": "Payment completed",
"event": "payment_completed",
"eventTitle": "Payment completed",
"triggeredBy": "new_purchase",
"version": 2,
"userPaymentId": "UP589XOSLJWKHT",
"status": 0,
"statusValue": "completed",
"amount": 10,
"userPaymentInfoId": "UPIUUI256887",
"extPaymentId": OOIUYTVJJG,
"extCustomerId": JGGFTYNJLO,
"termId": "TMOUVRK06GPG",
"aid": "AJJHYYFLPPUV",
"uid": "UFFTDH6507J",
"resourceId": "RJHHYYTTY",
"subscriptionId": SUUNNHTRWR66,
"accessId": "AKKI6F1PPMMJ",
"billingPeriodDateFrom": 08012024,
"billingPeriodDateTo": 08312024,
"subscriptionPeriodCounter": 3,
"merchantId": null,
"paymentMethodKey": null,
"sourceInt": 71
}
Example 2. Response to a payment_failed event
{
"type": "payment_failed",
"typeTitle": "Payment failed",
"event": "payment_failed",
"eventTitle": "Payment failed",
"triggeredBy": "new_purchase",
"version": 2,
"userPaymentId": "UP589XOSLJWKHT",
"status": 4,
"statusValue": "canceled",
"amount": 10,
"userPaymentInfoId": "UPIUUU251557866",
"extPaymentId": "UYTRGHJNK",
"extCustomerId": "IUYRGHJHJN",
"termId": "TMOUVRK06GPG",
"aid": "AJJHYYFLPPUV",
"uid": "UFFTDH6507J",
"resourseId": "RJHHYYTTY",
"subscriptionId": SUUNNHTRWR66,
"accessId": "AKKI6F1PPMMJ",
"billingPeriodDateFrom": 08012024,
"billingPeriodDateTo": 08312024,
"errorCode": "",
"errorMessage": "",
"merchantId": null,
"paymentMethodKey": null,
"sourceInt": 71
}
Example 3. Response to a payment_initiated event
{
"type": "payment_initiated",
"typeTitle": "Payment initiated",
"event": "payment_initiated",
"eventTitle": "Payment initiated",
"triggeredBy": "new_purchase",
"version": 2,
"userPaymentId": "UP589XOSLJWKHT",
"status": 7,
"statusValue": "initiated",
"amount": 10,
"userPaymentInfoId": null,
"extPaymentId": "HGGHUHLIJ",
"extCustomerId": "YREWBJKLL",
"termId": "TMOUVRK06GPG",
"aid": "AJJHYYFLPPUV",
"uid": "UFFTDH6507J",
"resourseId": "RJHHYYTTY",
"subscriptionId": null,
"accessId": null,
"billingPeriodDateFrom": null,
"billingPeriodDateTo": null,
"merchantID":"gjghhidl",
"paymentMethodKey": "card",
"sourceInt": 71
}
Example 4. Response to a payment_pending event
{
"type": "payment_pending",
"typeTitle": "Payment pending",
"event": "payment_pending",
"eventTitle": "Payment pending",
"triggeredBy": "new_purchase",
"version": 2,
"userPaymentId": "UP589XOSLJWKHT",
"status": 5,
"statusValue": "pending",
"amount": 10,
"userpaymentInfoID": "UPIIIII5135",
"extPaymentId": "UYTRTYYBBHY",
"extCustomerId": "OIUTRYYNJGF",
"termId": "TMOUVRK06GPG",
"aid": "AJJHYYFLPPUV",
"uid": "UFFTDH6507J",
"resourseId": "RJHHYYTTY",
"subscriptionId": SUUNNHTRWR66,
"accessId": "AKKI6F1PPMMJ",
"billingPeriodDateFrom": 08012024,
"billingPeriodDateTo": 08312024,
"subscriptionPeriodCounter": 3,
"merchantId": null,
"paymentMethodKey": null,
"sourceInt": 71
}
Example 5. Response to a payment_refund event
{
"type": "payment_refund",
"version": 2,
"typeTitle": "Payment refund",
"event": "purchase_refund",
"eventTitle": "Payment refunded",
"aid": "<AID>",
"uid": "PNIVOlt0Tqk1ujg",
"payment_id": "UPYKHS7YT66S",
"amount": 10,
"subscription_id": "RCJ6IIP4V658",
"access_id": "oN0vFhcAcdoG"
}
Auto-renew in My Account (deprecated)
This event type is completely deprecated. Please use subscription_updated instead.
|
Type |
Event |
Triggered by |
Notes |
|
|
|
User |
We send this webhook when the end-user interacts with the Auto-renew toggle in My Account. Deprecated. Instead, please use the |
Example
{
"version": 2,
"type": "subscription_auto_renew_changed",
"event": "subscription_auto_renew_changed_by_end_user",
"aid": "vd2rNmtWqy",
"uid": "mQrUXVrjyR",
"subscription_id": "RCA2VW9I8S9P",
"term_id": "TML7FFHCWB76",
"auto_renew": "enabled"
}
Shared subscription (deprecated)
This event type is completely deprecated. Please use the shared_access_granted, shared_access_revoked, or shared_access_modified webhook type instead. You can also obtain the child accesses of a shared subscription using the UserSubscriptionAccount object, which is available in the shared_accounts field of the subscription_updated, subscription_renewal and subscription_ended webhook types.
|
Type |
Event |
Triggered by |
Notes |
|
|
|
User |
Sent when a child user redeems their shared subscription access via My Account. Deprecated. Instead, please use the |
Example
{
"version": 2,
"type": "shared_subscription_child",
"typeTitle": "Shared subscription child access granted",
"event": "shared_subscription_child",
"eventTitle": "Shared subscription child",
"aid": "XTSRGNiPaH",
"expires": -1,
"email": "demo@piano.io",
"access_id": "aR3eXhufAeGN",
"term_id": "TMS6NTTUXICY",
"rid": "RD4NTHK",
"uid": "PNIDDCJAEquotvw",
"parent_uid": "PNIio9tntquots0",
"parent_subscription_id": "RCHUXPZQNZWK"
}