Gifting articles
Table of Contents
Our gifting feature integrates with your system to enable subscribers to share specific pieces of otherwise-protected content to non-subscribers. This is a feature where we provide most of the infrastructure (and all of the UI) for this on our side, however we will need an API from you, details of which are below.
Auth provider support
Given the information required to be passed back and forth with regards to gifting articles, your authentication provider will need to support gift capabilities and be able to provide us the information specified in the API calls below. This should be checked prior to starting any work on gifting.
Redemption
Note that currently redemption of gifted articles happens on your website, we don't support redeeming in the app yet.
The flow
Users of your app will see a CTA to gift the article inline within the page.

When users tap on this they will see a modal allowing them to access the special GiftLink:

The fonts and colours on the article CTA & modal are themeable.
Only signed-in subscribers see the CTA. The app must report an active authorisation state with a user token, and the article must carry a canonical URL, otherwise nothing is rendered.
How it works
We provide the out-of-the-box interface above that allows users to gift articles to other users. You can control how many gifts a user is allowed to use during a given period.
For API-driven gifting, you can offer readers one of two delivery approaches:
- Link sharing: the reader copies a GiftLink or shares it with the device share sheet.
- Email delivery: the reader enters a recipient email address in the gifting modal, and your service creates the gift and sends the email. Pugpig does not send the email or store the recipient's address.
We will need an API provided to us to implement this feature. This gives you full control of gifting logic and limits. The GiftLink endpoint is part of the entitlement implementation. We call it twice, using two different HTTP methods, at two different points in the reader's journey:
| Method | When | What we expect back |
| GET | The reader taps Gift this article and the modal opens. | The reader's remaining allowance. No gift is spent. |
| POST |
Link sharing: the reader taps Copy gift link or Share gift link. Email delivery: the reader enters a recipient email address and taps Send gift email. |
Link sharing: a created gift link. Email delivery: confirmation that your service sent the email. This is the call that spends one of the reader's gifts. |
This split means that opening the modal, or opening it and changing their mind, never costs a reader a gift. A gift is spent only when they complete the delivery action. Your endpoint needs to distinguish the two: the GET reports how many gifts the reader has left and creates nothing; the POST creates the link or sends the email.
If your system cannot report an allowance without also creating a link, tell us during integration. We can then ignore the method and treat the GET as a create, so the reader spends a gift on opening the modal.
Inputs
Both calls take the same two query parameters:
-
token: the user token (or PKCE access token) we receive when the user logs in. -
url: the canonical URL of the article to be shared.
For email delivery, the POST also includes the recipient email address entered in the modal. Your endpoint must validate it, generate the gift, and send the email. Contact Support during integration for the request-field details.
Response
| Field | Type | Notes |
message |
string | Messaging on the number of gift links remaining, or messaging if they have run out. Used as the modal title when present. |
gift_code |
string | The gift code. Present on a created link. |
gift_url |
string | The gift URL. Its presence is what tells us a link exists (link sharing). |
gift_sent |
boolean | Email delivery only. Return true only after your service has successfully sent the email. Do not return the recipient's email address. |
gift_shares |
int | Number of gifts the reader has left. |
gift_limit |
string | Total gift allowance. |
Omit any field you have no value for rather than sending it as null.
A call with either required parameter missing returns a message-only JSON response (Invalid or missing token parameter given or Invalid or missing url parameter given). For email delivery, a missing or invalid recipient email must also return a clear message, and must not send an email or spend a gift.
Example responses
Allowance, answering the GET when the modal opens:
{
"message": "You have 3 gift articles left to share this month.",
"gift_shares": 3,
"gift_limit": "4"
}
The message can carry the remaining count. It is re-rendered after the POST response, so a message like "You have 3 gift articles left to share this month." counts down in place as the reader shares.
Created link, answering the POST when the reader copies or shares:
{
"message": "Thanks for sharing!",
"gift_code": "x1x2x3x4x5x6x7x8x9x0x",
"gift_url": "https://pugpig.com/news/launches/?gift=x1x2x3x4x5x6x7x8x9x0x",
"gift_shares": 2,
"gift_limit": "10"
}
Email sent, answering the POST after the email has been sent:
{
"message": "Your gift email has been sent.",
"gift_sent": true,
"gift_shares": 2,
"gift_limit": "10"
}
Return gift_sent: true only when the email was successfully sent. If validation or sending fails, return an explanatory message and either omit gift_sent or return false.
Out of gifts. Either method can return this:
{
"message": "You've run out of shares, come back next month!",
"gift_shares": 10,
"gift_limit": "10"
}
We also treat an allowance response as out-of-gifts when gift_limit is above zero and gift_shares is not.
Not charging twice for the same article
We hold the response for an article for as long as the reader stays on the page, so reopening the modal, or copying and then sharing, does not send a second POST.
That is not persisted. If the reader reloads the article and completes the action again, you will get a fresh POST for an article they have already gifted. Your endpoint needs to recognise that and not spend a second gift.
Analytics
Email delivery adds one event, GiftLinkEmailSent. It fires only after your endpoint confirms gift_sent: true, uses the existing /GiftLink category, and includes the standard gifting data (giftShares, giftLimit, articleUrl, and an empty giftCode) plus method: "server-email". The recipient's email address is never included, and failed validation or sending does not fire the event.
Redemption
Most users that redeem the gift will end up on your website. We assume your website will implement the gift token checking.
We recommend using the App Association File/Google file patterns to prevent Gift URLs opening in the app (for example, prevent all URLs with www.yoursite.com?gifttoken=123456).
Articles in multiple collections
Note that if an article is in more than one collection and those collections have different gifting settings, the article will follow the settings of the first collection in the feed.
Piano
Piano does not provide an API for gifting articles, which means we cannot implement the flow as described above in your app. However, as part of Composer Piano does have a ‘Share with a Friend' feature which serves essentially the same purpose. This is a web experience but if you have it set up for your website, the same experience can be embedded inline within your app articles. As with API-driven gifting the redemption of gifted articles happens on your website, not in the app.
Get in touch with support if you'd like to set this up. Please ensure you've first read the ‘Considerations’ section in the Piano doc linked above if you aren't already familiar with the feature from using it on your site (you'll see it does work slightly differently from the API method explained above). You will need to already have the Composer experience set up in order for our support team to implement it in your app.
Example of the out-of-the-box Piano-provided UI:
.png)


