Integrate with Revifly to discover offers and generate unique vouchers for your audience.
Every request requires your API credentials in headers. These are issued by Revifly when your account is approved.
X-API-Key: your_api_key
X-API-Secret: your_api_secret
Credentials are available in your Publisher Portal. Never expose the secret client-side.
https://revifly.com/api/v1/publisher/
Revifly identifies users via a SHA-256 hash of their mobile number in E.164 format. You compute this hash on your server and pass it as customer_identifier. Revifly stores it as-is — it is never hashed a second time and the raw mobile number never reaches our servers.
1. Take the user's mobile number
2. Strip all non-digit characters ( + spaces - parentheses )
3. Include the full country code → result is E.164 digits
India : "919876543210"
UK : "447911123456"
US : "15551234567"
4. hash = lowercase( SHA-256( e164_digit_string ) )
// JavaScript (Node.js / browser Web Crypto)
async function mobileHash(mobile) {
const digits = mobile.replace(/\D/g, '');
const buf = await crypto.subtle.digest(
'SHA-256',
new TextEncoder().encode(digits)
);
return Array.from(new Uint8Array(buf))
.map(b => b.toString(16).padStart(2, '0')).join('');
}
// Python
import hashlib
def mobile_hash(mobile: str) -> str:
digits = ''.join(c for c in mobile if c.isdigit())
return hashlib.sha256(digits.encode()).hexdigest()
// PHP
function mobileHash(string $mobile): string {
$digits = preg_replace('/\D/', '', $mobile);
return hash('sha256', $digits);
}
Input : "919876543210" (Indian number with country code, digits only)
SHA-256: 9b4fc4c2... (verify: echo -n "919876543210" | sha256sum)
Fetch the catalogue of active offers you can promote. Cache this response — it changes infrequently.
Endpoint: GET /api/v1/publisher/get_offers
| Param | Type | Default | Description |
|---|---|---|---|
brand_id | int | — | Filter to a single brand |
q | string | — | Search in title, description, brand name |
limit | int | 50 | Results per page (max 100) |
offset | int | 0 | Pagination offset |
{
"status": "success",
"data": {
"publisher": { "publisher_id": 1, "publisher_name": "Acme App" },
"pagination": { "limit": 50, "offset": 0, "count": 12 },
"offers": [
{
"offer_id": 42,
"brand_id": 7,
"brand_name": "FashionBrand",
"title": "20% off your first order",
"description": "Exclusive discount for new customers.",
"category": "Fashion",
"discount_type": "percentage",
"discount_value": 20.0,
"min_purchase_amount": 500.0,
"currency": "INR",
"start_date": "2026-01-01",
"end_date": "2026-12-31",
"status": "active",
"terms_and_conditions": "Valid on orders of ₹500 or more. Valid until 31 Dec 2026.",
"image_url": "https://...",
"brand_logo_url": "https://...",
"shop_url": "https://fashionbrand.myshopify.com"
}
]
}
}
Fetch a single offer and record an impression. Call this when you are about to show a specific offer to a specific user — it logs one impression event for brand reporting.
Endpoint: GET /api/v1/publisher/get_offer_detail?offer_id={id}
| Param | Type | Required | Description |
|---|---|---|---|
offer_id | int | Yes | Offer to fetch and log |
user_hash | string (64 hex) | No | Mobile hash of the user being shown the offer |
sub_source | string | No | Attribution tag, max 100 chars |
{
"status": "success",
"data": {
"offer": { /* same fields as get_offers */ }
}
}
Returns OFFER_NOT_FOUND (404) if the offer is inactive, expired, or not in your catalogue. Rate limit: 200 req/min per publisher.
Generate a unique voucher code for an offer. The voucher is created in Shopify and is ready to use at checkout immediately.
Endpoint: POST /api/v1/publisher/generate_voucher
Content-Type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
offer_id | int | Yes | Offer to generate a voucher for |
customer_identifier | string (64 hex) | Recommended | Mobile hash of the user (see Mobile hash above). Required for deduplication and active-cap enforcement. |
quantity | int | No | 1–50, default 1 |
sub_source | string | No | Attribution tag, max 100 chars (e.g. campaign name, placement) |
custom_code | string | No | Request a specific voucher code string |
POST https://revifly.com/api/v1/publisher/generate_voucher
Content-Type: application/json
X-API-Key: your_api_key
X-API-Secret: your_api_secret
{
"offer_id": 42,
"customer_identifier": "9b4fc4c2e7c5a2a3e1e9f98b05e3f5b1...",
"sub_source": "home_feed"
}
{
"status": "success",
"data": {
"voucher_code": "RV-ABC123XYZ",
"voucher_id": 456,
"offer_id": 42,
"offer_title": "20% off your first order",
"brand_name": "FashionBrand",
"expiry": "2026-12-31 23:59:59",
"image_url": "https://...",
"checkout_url": "https://fashionbrand.myshopify.com/discount/RV-ABC123XYZ"
}
}
checkout_url pre-applies the voucher at checkout — link users directly to it to reduce redemption friction.
Each publisher has a configurable cap on how many active (generated but not yet used, unexpired) vouchers a single user can hold simultaneously. The default is 10. If the user is at their cap you will receive:
HTTP 429
{
"status": "error",
"message": "User has reached the active voucher limit for this publisher",
"data": { "error_code": "USER_ACTIVE_VOUCHER_LIMIT" }
}
This is an anti-abuse guard. Contact Revifly support to adjust the cap for your account.
Fetch all vouchers belonging to a user (identified by their mobile hash) for your publisher account. Use this to build a "My Vouchers" view within your app.
Endpoint: GET /api/v1/publisher/user_vouchers
| Param | Type | Required | Description |
|---|---|---|---|
user_hash | string (64 hex) | Yes | Mobile hash of the user |
status | string | No | all (default), active, used, or expired |
limit | int | No | Max results (default 20, max 100) |
offset | int | No | Pagination offset |
{
"status": "success",
"data": {
"user_hash": "9b4fc4c2...",
"pagination": { "limit": 20, "offset": 0, "count": 3 },
"vouchers": [
{
"voucher_id": 456,
"voucher_code": "RV-ABC123XYZ",
"offer_id": 42,
"offer_title": "20% off your first order",
"brand_name": "FashionBrand",
"discount_type": "percentage",
"discount_value": 20.0,
"currency": "INR",
"status": "active",
"validity": "Valid until 31 Dec 2026",
"expiry_date": "2026-12-31",
"created_at": "2026-05-18 10:00:00"
}
]
}
}
Only returns vouchers generated by your publisher account. Rate limit: 100 req/min per publisher.
Instead of building a voucher wallet UI yourself, you can link users to Revifly's hosted wallet page. It shows their available and used vouchers with copy buttons and shop links, served from Revifly's domain.
https://revifly.com/wallet/?pub={your_publisher_code}&uhash={user_mobile_hash}
# Compute the user's hash and build the URL
user_hash = mobileHash("919876543210")
wallet_url = "https://revifly.com/wallet/?pub=mypublishercode&uhash=" + user_hash
noindex — not indexed by search engines| Code | HTTP | Meaning |
|---|---|---|
PUBLISHER_INVALID | 401 | API key or secret incorrect |
VALIDATION_ERROR | 400 | Missing or malformed required field |
INVALID_CUSTOMER_IDENTIFIER | 400 | customer_identifier is not a valid 64-char hex mobile hash |
INVALID_USER_HASH | 400 | user_hash is not a valid 64-char hex mobile hash |
OFFER_NOT_FOUND | 404 | Offer does not exist or is not in your catalogue |
OFFER_NOT_ACTIVE | 403 | Offer exists but is not currently active |
OFFER_DATE_INVALID | 403 | Offer is outside its valid date range |
BRAND_CAMPAIGN_PAUSED | 403 | Brand has paused the campaign |
QUANTITY_LIMIT_EXCEEDED | 400 | Requested quantity is above the max (50) |
PUBLISHER_DAILY_LIMIT_REACHED | 429 | Publisher daily voucher cap reached |
USER_ACTIVE_VOUCHER_LIMIT | 429 | User already holds the maximum active vouchers for this publisher |
USER_DAILY_LIMIT_REACHED | 429 | User has generated too many vouchers in the past 24 hours |
DUPLICATE_VOUCHER | 409 | User already has a voucher for this offer (one-per-customer offer) |
VOUCHER_CREATION_FAILED | 500 | Voucher creation failed on Revifly's side — retry |
RATE_LIMIT | 429 | API rate limit exceeded |
INTERNAL_ERROR | 500 | Unexpected server error — retry |
Four ways to distribute Revifly offers — choose based on your platform's capabilities.
| Model | How it works | Best for |
|---|---|---|
| 1 — Landing page | Link users to /v/?o={offer_id}&pub={code}. Revifly collects the mobile, generates and displays the voucher. |
Any publisher — zero integration effort |
| 2 — Direct API | Call get_offer_detail (impression), then generate_voucher with the user's mobile hash. Display the voucher code in your own UI. |
Apps with a known logged-in user |
| 3 — Campaign token | Generate a single-use token via the portal. Link user to /c/{token}. User picks an offer; Revifly generates the voucher. |
SMS, email, or push campaigns to a specific user |
| 4 — Feed sync | Pull the full offer catalogue via get_offers on a schedule. Render offers in your platform; link click-throughs to Model 1 or use Model 2 for generation. |
Aggregators, loyalty portals with their own UI |