Grant Premium Access via API
Promotional access API
Grant and revoke promotional (free) access to a permission group for a single customer. Use it for support compensations, giveaways, partner campaigns and similar cases.
Authentication
Send an API key in the Authorization header:
Authorization: Bearer <API_KEY>
For server-to-server calls, use the app's secret S2S key (sk_...) or SDK API key. The public SDK API key is also accepted, but it ships inside your app binary, so don't rely on it for backend integrations.
Base URL: https://api.apphud.com
Grant promotional access
POST /v1/promotions
Gives the customer a promotional subscription in a permission group. A customer has at most one promotion per permission group: a new grant replaces the current one, so the same call also extends or shortens a promotion.
Body parameters (JSON)
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | one of user_id / device_id | Customer's user ID. |
device_id | string | one of user_id / device_id | Customer's device ID. |
product_id | string | optional | Product ID; access is granted to that product's permission group. |
duration | integer | one of duration / expires_at | Length of the premium in days, counted from the moment of the request. |
expires_at | string | one of duration / expires_at | Exact expiration time, ISO 8601 (e.g. 2030-04-26T12:34:00+03:00 or 2030-04-26T09:34:00Z). A value without an offset is treated as UTC. Must be in the future. |
Pass exactly one of duration and expires_at. Pass product_id whenever the app has more than one permission group.
Example: grant for 30 days
curl -X POST https://api.apphud.com/v1/promotions \
-H "Authorization: Bearer $APPHUD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_123",
"duration": 30
}'Example: grant until an exact date
curl -X POST https://api.apphud.com/v1/promotions \
-H "Authorization: Bearer $APPHUD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_123",
"product_id": "com.example.premium.monthly",
"expires_at": "2030-04-26T12:34:00+03:00"
}'Response: 201 Created
201 CreatedReturns the customer, including the promotional subscription (status: "promo"). Trimmed example:
{
"data": {
"results": {
"id": "…",
"user_id": "user_123",
"subscriptions": [
{
"status": "promo",
"kind": "autorenewable",
"product_id": "com.example.premium.monthly",
"group_id": "a1b2c3d4-0000-0000-0000-000000000000",
"started_at": "2030-01-10T08:00:00.000Z",
"expires_at": "2030-04-26T09:34:00.000Z",
"autorenew_enabled": false
}
]
},
"meta": {}
},
"errors": null
}Revoke premium access
DELETE /v1/promotions
Removes the customer's promotion in a permission group. Revoking when there is no promotion succeeds and changes nothing.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | one of user_id / device_id | Customer's user ID. |
device_id | string | one of user_id / device_id | Customer's device ID. |
product_id | string | one of product_group_id / product_id | Product ID |
Example
curl -X DELETE "https://api.apphud.com/v1/promotions?user_id=user_123&product_id=com.product.id" \
-H "Authorization: Bearer $APPHUD_API_KEY"Response: 200 OK
200 OKReturns the customer in the same format as the grant response, without the revoked subscription.
Errors
Errors use the standard envelope:
{
"data": { "results": null, "meta": null },
"errors": [{ "id": "error", "title": "Pass either duration or expires_at, not both" }]
}| Status | id | title | When |
|---|---|---|---|
| 401 | Missing or invalid API key. | ||
| 404 | resource | Not found | Customer not found, or neither user_id nor device_id was passed. |
| 422 | error | Pass either duration or expires_at, not both | Both fields were passed. |
| 422 | error | Either duration or expires_at is required | Neither field was passed. |
| 422 | expires_at | must be an ISO 8601 date-time | expires_at is not ISO 8601. |
| 422 | expires_at | must be in the future | expires_at is now or in the past. |
| 422 | duration | must be greater than or equal to 0 | Negative duration. |
| 422 | error | Unable to find product group | Unknown product_id. |
| 422 | error | Pass product_id | Revoke without a product. |
List user's promotional subscriptions
Use Customers API to retrieve the user's subscriptions. Iterate through the subscription objects, find a subscription with the promotional status, and verify its expiration date.
Updated 1 day ago
