Validate Coupon API
Verify a referral or coupon code at checkout and read its authoritative discount before applying it
Validate Coupon API
Verify a referral / coupon code at checkout and read its authoritative discount before you apply any price reduction.
This is a read-only lookup. It lets your backend confirm a code is real and
eligible, and tells you exactly how much to discount — so the discount is
decided by RefVenue, never trusted from the client. It records nothing: no
conversion, no usage increment, no fraud side effects. After the sale completes,
record it with the Track Conversion API using the
same coupon_code.
Endpoint
GET https://tracking.refvenue.com/v1/validate-coupon
Authentication
Authenticate with your publishable key as a query parameter:
?publishable_key=refv_live_...
Get your publishable key from: Settings → API Keys/Secrets
If your key is scoped to a single program, the program_id you pass must match
that program.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
publishable_key | string | Required. Your API publishable key |
program_id | string | Required. Your program ID |
code | string | Required. The referral or coupon code entered at checkout |
Examples
Validate a code
curl "https://tracking.refvenue.com/v1/validate-coupon?publishable_key=refv_live_...&program_id=prog_abc123&code=SAVE20"Node.js / Express
app.post('/checkout/apply-code', async (req, res) => {
const { code } = req.body;
const params = new URLSearchParams({
publishable_key: process.env.REFVENUE_KEY,
program_id: process.env.REFVENUE_PROGRAM_ID,
code,
});
const response = await fetch(
`https://tracking.refvenue.com/v1/validate-coupon?${params}`
);
const result = await response.json();
if (!result.valid) {
return res.status(400).json({ error: 'Invalid code', reason: result.reason });
}
// Compute the discount RefVenue authorised — never trust a client value.
const discount =
result.discountType === 'percentage'
? subtotal * (result.discountValue / 100)
: result.discountValue;
res.json({ discount, finalTotal: subtotal - discount });
});Responses
Valid Code (200 OK)
{
"valid": true,
"code": "SAVE20",
"programId": "prog_abc123",
"affiliateId": "aff_xyz789",
"discountType": "percentage",
"discountValue": 20
}| Field | Type | Description |
|---|---|---|
valid | boolean | true when the code is usable |
code | string | The matched code |
programId | string | The program the code belongs to |
affiliateId | string | The affiliate that owns the code (who earns the commission) |
discountType | string | "percentage" (value is percent off) or "fixed" (value is amount off) |
discountValue | number | Discount amount in major currency units (e.g. 20 = 20% or $20) |
Not a Usable Code (200 OK)
An unknown, inactive, or ineligible code is a normal "no discount" outcome — it
returns 200 with valid: false, not an error, so you can handle it inline.
{
"valid": false,
"reason": "Coupon not found or inactive"
}reason | Meaning |
|---|---|
Coupon not found or inactive | No active code matches for this program |
Affiliate is not eligible | The owning affiliate is unapproved or blocked |
Error Responses
Missing Parameters (400)
{
"error": "publishable_key, program_id and code are required"
}Invalid Publishable Key (401)
{
"error": "Invalid publishable_key"
}Key Not Authorized for Program (403)
{
"error": "Publishable key does not authorize this program"
}How to Apply the Discount
discountValue is always in major currency units. Read discountType to decide
how to apply it:
const discount =
result.discountType === 'percentage'
? subtotal * (result.discountValue / 100) // e.g. 20 → 20% off
: result.discountValue; // e.g. 20 → $20 off
const finalTotal = subtotal - discount;Then, after payment succeeds, call the
Track Conversion API with the same coupon_code
and the post-discount revenue_amount so the affiliate is credited.
Best Practices
Validate server-side
Always validate from your backend, not the browser. The whole point is that the discount is decided by RefVenue and can't be tampered with by the client.
Treat valid: false as "no discount"
A valid: false response is expected for typos and expired codes. Show a "code
not valid" message and let checkout continue at full price — don't surface it as
a server error.
Cache lightly
Responses are cacheable for a short window (Cache-Control: private, max-age=30).
Discounts change rarely, but a deactivated code should stop discounting promptly,
so keep any caching brief on this money-path lookup.
Validate, then track
Validation never records anything. The sale is only attributed when you call Track Conversion after checkout — validate first to price the order, then track once payment clears.
Alternative Methods
- Track Conversion API - Record the sale after checkout
- Server-Side Guide - Implementation patterns
- JavaScript Tracking - Client-side tracking