GET /offers
List offers
Every offer matching the filters, paged. A full sync pages in the default order (listed); a change sync sends updatedAtFrom with the time of your last sync. Costs one request of your quota. Needs a key with the offers scope.
page (query)- 1-based page number. Do not send with after.
limit (query)- Offers per page, at most 500.
after (query)- The nextCursor of the previous page. Stable when offers are added. Do not send with page.
kind (query)- Only game keys, or only eSIM plans.
platform (query)- A platform code from GET /meta (case-insensitive).
region (query)- A region code from GET /meta, or an eSIM destination or country code (case-insensitive).
currency (query)- The currency every price is stated in.
inStock (query)- Only offers that can be bought now (true) or that cannot (false).
updatedAtFrom (query)- Only offers changed at or after this time (ISO 8601). Use it to sync changes.
sort (query)- listed: first listed first, then sku (the stable order for full syncs). updatedAt_desc: most recently changed first.
profile (query)- Shape each offer for an importer you already run: allkeyshop, kinguin or g2a. Omit for the full v2 offer.
Answers: 200 A page of offers. With profile, each offer is in that profile's shape. 400 A query parameter is not valid. 401 No valid key. 403 The key is valid but may not do this. 429 Over a rate limit or the daily quota. Wait for Retry-After. 503 Briefly unavailable. Retry with backoff.
{
"data": [
{
"sku": "KSV-MWDDYETFMD",
"kind": "game",
"name": "Real Heroes: Firefighter HD (PC) Steam Key GLOBAL",
"productName": "Real Heroes: Firefighter HD",
"slug": "real-heroes-firefighter-hd-steam-global",
"platform": "STEAM",
"region": "GLOBAL",
"edition": "Standard",
"isAddOn": false,
"image": "https://andalu.com/img/cover/real-heroes-firefighter-hd.jpg",
"url": "https://andalu.com/go/MAYA10/KSV-MWDDYETFMD",
"currency": "EUR",
"price": 4.49,
"priceMinor": 449,
"priceStatus": "available",
"feesIncluded": true,
"prices": {
"card": {
"currency": "EUR",
"price": 4.49,
"priceMinor": 449
},
"ideal": {
"currency": "EUR",
"price": 4.12,
"priceMinor": 412
}
},
"rails": [
{
"id": "card",
"name": "Credit / Debit Card",
"currency": "EUR",
"price": 4.49,
"priceMinor": 449
},
{
"id": "ideal",
"name": "iDEAL",
"currency": "EUR",
"price": 4.12,
"priceMinor": 412
}
],
"voucher": null,
"stock": "in_stock",
"inStock": true,
"updatedAt": "2026-10-02T07:00:00.000Z",
"priceValidUntil": "2026-10-03",
"purchaseRules": {
"maxPerOrder": 10,
"minOrderEur": 2,
"activationRegions": null,
"platform": "STEAM",
"deviceRequirement": null,
"deliveryMethod": "email",
"returnable": false
}
},
{
"sku": "esim-JP_3_30",
"kind": "esim",
"name": "Japan eSIM 3 GB 30 Days - Prepaid Travel Data",
"productName": "Japan eSIM",
"slug": "japan",
"platform": "ESIM",
"region": "JP",
"edition": null,
"isAddOn": false,
"image": "https://andalu.com/esim/japan/opengraph-image",
"url": "https://andalu.com/go/MAYA10/esim-JP_3_30",
"currency": "EUR",
"price": 6.9,
"priceMinor": 690,
"priceStatus": "available",
"feesIncluded": true,
"prices": {
"card": {
"currency": "EUR",
"price": 6.9,
"priceMinor": 690
}
},
"rails": [
{
"id": "card",
"name": "Credit / Debit Card",
"currency": "EUR",
"price": 6.9,
"priceMinor": 690
}
],
"voucher": null,
"stock": "in_stock",
"inStock": true,
"updatedAt": "2026-10-02T07:00:00.000Z",
"priceValidUntil": "2026-10-03",
"purchaseRules": {
"maxPerOrder": 10,
"minOrderEur": null,
"activationRegions": null,
"platform": null,
"deviceRequirement": "esim_unlocked_phone",
"deliveryMethod": "email",
"returnable": false
},
"destination": "Japan",
"country": "JP",
"regionCodes": [
"JP"
],
"dataGb": 3,
"dataType": "total",
"days": 30
}
],
"meta": {
"totalResults": 2,
"page": 1,
"limit": 100,
"nextCursor": null,
"hasNextPage": false
},
"sandbox": true
}
GET /offers/{sku}
Get one offer
One offer by sku. Costs one request of your quota. Needs a key with the offers scope.
sku (path)- The offer sku.
currency (query)- The currency every price is stated in.
profile (query)- Shape each offer for an importer you already run: allkeyshop, kinguin or g2a. Omit for the full v2 offer.
Answers: 200 The offer. 400 A query parameter is not valid. 401 No valid key. 403 The key is valid but may not do this. 404 Not found. 429 Over a rate limit or the daily quota. Wait for Retry-After. 503 Briefly unavailable. Retry with backoff.
{
"data": {
"sku": "KSV-MWDDYETFMD",
"kind": "game",
"name": "Real Heroes: Firefighter HD (PC) Steam Key GLOBAL",
"productName": "Real Heroes: Firefighter HD",
"slug": "real-heroes-firefighter-hd-steam-global",
"platform": "STEAM",
"region": "GLOBAL",
"edition": "Standard",
"isAddOn": false,
"image": "https://andalu.com/img/cover/real-heroes-firefighter-hd.jpg",
"url": "https://andalu.com/go/MAYA10/KSV-MWDDYETFMD",
"currency": "EUR",
"price": 4.49,
"priceMinor": 449,
"priceStatus": "available",
"feesIncluded": true,
"prices": {
"card": {
"currency": "EUR",
"price": 4.49,
"priceMinor": 449
},
"ideal": {
"currency": "EUR",
"price": 4.12,
"priceMinor": 412
}
},
"rails": [
{
"id": "card",
"name": "Credit / Debit Card",
"currency": "EUR",
"price": 4.49,
"priceMinor": 449
},
{
"id": "ideal",
"name": "iDEAL",
"currency": "EUR",
"price": 4.12,
"priceMinor": 412
}
],
"voucher": null,
"stock": "in_stock",
"inStock": true,
"updatedAt": "2026-10-02T07:00:00.000Z",
"priceValidUntil": "2026-10-03",
"purchaseRules": {
"maxPerOrder": 10,
"minOrderEur": 2,
"activationRegions": null,
"platform": "STEAM",
"deviceRequirement": null,
"deliveryMethod": "email",
"returnable": false
}
},
"sandbox": true
}
GET /feed.json
The snapshot as JSON
Every offer in one JSON document, rebuilt hourly, EUR, with your tracked links. Needs the feed scope (approved comparison sites). Send If-None-Match with the last ETag: an unchanged snapshot answers 304 and costs nothing. A full download counts against your quota and the 12 an hour snapshot allowance. Served gzip when you send Accept-Encoding: gzip. Needs a key with the feed scope.
If-None-Match (header)- The ETag of the snapshot you hold. If it is still current the answer is 304 with no body, and costs no quota.
Answers: 200 The snapshot. 304 Your snapshot is current. No body, no quota. 401 No valid key. 403 The key is valid but may not do this. 429 Over a rate limit or the daily quota. Wait for Retry-After. 503 The snapshot is not built yet, or a dependency is briefly down.
{
"version": "2.0.0",
"currency": "EUR",
"data": [
{
"sku": "KSV-MWDDYETFMD",
"kind": "game",
"name": "Real Heroes: Firefighter HD (PC) Steam Key GLOBAL",
"productName": "Real Heroes: Firefighter HD",
"slug": "real-heroes-firefighter-hd-steam-global",
"platform": "STEAM",
"region": "GLOBAL",
"edition": "Standard",
"isAddOn": false,
"image": "https://andalu.com/img/cover/real-heroes-firefighter-hd.jpg",
"url": "https://andalu.com/go/MAYA10/KSV-MWDDYETFMD",
"currency": "EUR",
"price": 4.49,
"priceMinor": 449,
"priceStatus": "available",
"feesIncluded": true,
"prices": {
"card": {
"currency": "EUR",
"price": 4.49,
"priceMinor": 449
},
"ideal": {
"currency": "EUR",
"price": 4.12,
"priceMinor": 412
}
},
"rails": [
{
"id": "card",
"name": "Credit / Debit Card",
"currency": "EUR",
"price": 4.49,
"priceMinor": 449
},
{
"id": "ideal",
"name": "iDEAL",
"currency": "EUR",
"price": 4.12,
"priceMinor": 412
}
],
"voucher": null,
"stock": "in_stock",
"inStock": true,
"updatedAt": "2026-10-02T07:00:00.000Z",
"priceValidUntil": "2026-10-03",
"purchaseRules": {
"maxPerOrder": 10,
"minOrderEur": 2,
"activationRegions": null,
"platform": "STEAM",
"deviceRequirement": null,
"deliveryMethod": "email",
"returnable": false
}
}
],
"meta": {
"totalResults": 1,
"page": null,
"limit": 1,
"nextCursor": null,
"hasNextPage": false
},
"updatedAt": "2026-10-02T07:00:00.000Z"
}
GET /feed.xml
The snapshot as XML
Every offer in one XML document, rebuilt hourly, EUR, with your tracked links. Needs the feed scope (approved comparison sites). Send If-None-Match with the last ETag: an unchanged snapshot answers 304 and costs nothing. A full download counts against your quota and the 12 an hour snapshot allowance. Served gzip when you send Accept-Encoding: gzip. Needs a key with the feed scope.
If-None-Match (header)- The ETag of the snapshot you hold. If it is still current the answer is 304 with no body, and costs no quota.
Answers: 200 The snapshot. 304 Your snapshot is current. No body, no quota. 401 No valid key. 403 The key is valid but may not do this. 429 Over a rate limit or the daily quota. Wait for Retry-After. 503 The snapshot is not built yet, or a dependency is briefly down.
<?xml version="1.0" encoding="UTF-8"?>
<offers version="2.0.0" currency="EUR">
<offer><sku>KSV-MWDDYETFMD</sku><kind>game</kind><name>Real Heroes: Firefighter HD (PC) Steam Key GLOBAL</name><price>4.49</price><priceMinor>449</priceMinor><inStock>true</inStock><url>https://andalu.com/go/MAYA10/KSV-MWDDYETFMD</url></offer>
<meta><totalResults>1</totalResults><updatedAt>2026-10-02T07:00:00.000Z</updatedAt></meta>
</offers>
GET /meta
The vocabulary and your limits
Every code a filter takes (platforms, regions, eSIM destinations, currencies), the sorts and profiles, and your key's limits and scopes. Costs one request of your quota. Needs a key with the offers scope.
Answers: 200 The vocabulary. 401 No valid key. 403 The key is valid but may not do this. 429 Over a rate limit or the daily quota. Wait for Retry-After. 503 Briefly unavailable. Retry with backoff.
{
"data": {
"version": "2.0.0",
"kinds": [
"game",
"esim"
],
"platforms": [
{
"code": "STEAM",
"name": "Steam",
"kind": "game"
},
{
"code": "ESIM",
"name": "eSIM",
"kind": "esim"
}
],
"regions": [
{
"code": "GLOBAL",
"name": "Global"
}
],
"esimDestinations": [
{
"code": "JP",
"name": "Japan"
}
],
"currencies": [
{
"code": "EUR",
"minorUnit": 2
}
],
"stockStates": [
"in_stock",
"out_of_stock"
],
"sorts": [
"listed",
"updatedAt_desc"
],
"profiles": [
"allkeyshop",
"kinguin",
"g2a"
],
"pageLimitMax": 500,
"offerCount": 2,
"limits": {
"tier": "marketer",
"perMinute": 30,
"perDay": 5000,
"snapshotsPerHour": 0
},
"scopes": [
"offers"
]
},
"sandbox": true
}
GET /stats
Your clicks, earnings and API use
Your daily clicks (all, and valid ones), your earnings by state, and your API requests per day. Needs the stats scope. Costs one request of your quota. Needs a key with the stats scope.
from (query)- First UTC day, YYYY-MM-DD. Default: 29 days before to.
to (query)- Last UTC day, YYYY-MM-DD. Default: today. At most 400 days from from.
Answers: 200 Your numbers. 400 A query parameter is not valid. 401 No valid key. 403 The key is valid but may not do this. 429 Over a rate limit or the daily quota. Wait for Retry-After. 503 Briefly unavailable. Retry with backoff.
{
"data": {
"period": {
"from": "2026-09-03",
"to": "2026-10-02"
},
"clicks": [
{
"day": "2026-10-01",
"clicks": 120,
"validClicks": 97
}
],
"totals": {
"clicks": 120,
"validClicks": 97
},
"earnings": [
{
"state": "pending",
"count": 3,
"currency": "EUR",
"amount": 1.24,
"amountMinor": 124
}
],
"apiRequests": [
{
"day": "2026-10-01",
"requests": 412
}
]
},
"sandbox": false
}
GET /openapi.json
openapi.json
This document, as JSON. Public: no key needed.
Answers: 200 This document, as JSON.
{
"info": {
"title": "Andalu Partner Offer API"
}
}
GET /openapi.yaml
openapi.yaml
This document, as YAML. Public: no key needed.
Answers: 200 This document, as YAML.
openapi: 3.1.0
GET /postman.json
postman.json
A Postman collection generated from this document. Set the apiKey variable to your test key. Public: no key needed.
Answers: 200 A Postman collection generated from this document. Set the apiKey variable to your test key.
{
"info": {
"title": "Andalu Partner Offer API"
}
}