The Offers API returns the same offer inventory the Offer Wall renders — as JSON, so you can build your own earning experience: custom cards, your own sorting, native UI. One endpoint, personalized per user, paginated.
Authentication
HTTP Basic auth on every request: the username is your publisher ID, the password is your API key — both shown in the publisher portal (requires a publisher login). The publisher ID also appears in the endpoint path; access is decided by your credentials, not by the path segment.
GET https://edgecash.ai/api/v1/publishers/YOUR_PUBLISHER_ID/offers?subid1=user_123
Responses: 200 with the offers payload; 401 when credentials
are invalid; 422 when a parameter fails validation.
Query parameters
| Parameter | Type | Required | Example | Description |
|---|---|---|---|---|
subid1 |
string | Yes | subid1=user_123 |
Your unique identifier of the end-user this request is for. Max 60 characters. Used to score the user and personalize the response — never share the same value across different users. |
countries[] |
string[2] | No | countries[]=US&countries[]=CA |
ISO-2 country codes. Returns offers available in these countries, including offers open to all countries. |
platforms[] |
int | No | platforms[]=3 |
Platform IDs — see the Platform mapping below. Offers for Any (All) platforms are always included. |
categories[] |
int | No | categories[]=5 |
Category IDs. Matches any category the offer belongs to. |
payout_models[] |
int | No | payout_models[]=1 |
Payout model IDs — see the Payout model mapping below. |
multi_events |
bool | No | multi_events=1 |
1 = only multi-event offers (more than one entry in the events array); 0 or omitted = all offers. Accepts 1 or 0 only. |
per_page |
int | No | per_page=50 |
Results per page. Min 1, max 100. Default 25. |
Platform mapping
| ID | Platform |
|---|---|
| 1 | Any (All) |
| 2 | iOS / Apple |
| 3 | Android |
| 4 | Desktop |
Payout model mapping
| ID | Payout model |
|---|---|
| 1 | CPI |
| 2 | CPE |
| 3 | CPA |
| 4 | CPL |
| 5 | CPS |
| 6 | CPR |
| 7 | CPC |
| 8 | CPCV |
| 9 | Rev Share |
Request examples
curl --user 'YOUR_PUBLISHER_ID:YOUR_API_KEY' \
--header 'Accept: application/json' \
'https://edgecash.ai/api/v1/publishers/YOUR_PUBLISHER_ID/offers?subid1=user_123&countries[]=US&platforms[]=1&per_page=25'
$client = new \GuzzleHttp\Client();
$response = $client->get('https://edgecash.ai/api/v1/publishers/YOUR_PUBLISHER_ID/offers', [
'auth' => ['YOUR_PUBLISHER_ID', 'YOUR_API_KEY'],
'headers' => ['Accept' => 'application/json'],
'query' => [
'subid1' => 'user_123',
'countries' => ['US', 'CA'],
'platforms' => [1],
'per_page' => 25,
],
]);
$offers = json_decode($response->getBody()->getContents(), true);
import requests
response = requests.get(
'https://edgecash.ai/api/v1/publishers/YOUR_PUBLISHER_ID/offers',
auth=('YOUR_PUBLISHER_ID', 'YOUR_API_KEY'),
headers={'Accept': 'application/json'},
params={
'subid1': 'user_123',
'countries[]': ['US', 'CA'],
'platforms[]': [1],
'per_page': 25,
},
)
offers = response.json()
import axios from 'axios';
const response = await axios.get('https://edgecash.ai/api/v1/publishers/YOUR_PUBLISHER_ID/offers', {
auth: { username: 'YOUR_PUBLISHER_ID', password: 'YOUR_API_KEY' },
headers: { Accept: 'application/json' },
params: {
subid1: 'user_123',
'countries[]': ['US', 'CA'],
'platforms[]': [1],
per_page: 25,
},
});
const offers = response.data;
package main
import (
"encoding/json"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://edgecash.ai/api/v1/publishers/YOUR_PUBLISHER_ID/offers?subid1=user_123&countries[]=US&platforms[]=1&per_page=25", nil)
req.SetBasicAuth("YOUR_PUBLISHER_ID", "YOUR_API_KEY")
req.Header.Set("Accept", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
var offers map[string]interface{}
json.NewDecoder(res.Body).Decode(&offers)
}
Sample response
{
"data": [
{
"id": 1234,
"name": "Coin Master — Android CPI",
"display_name": "Coin Master",
"description": "Install Coin Master and open the app.",
"display_description": "Install & play Coin Master!",
"package_id": "com.moonactive.coinmaster",
"platform": "Android",
"payout_model": "CPI",
"difficulty": "Easy",
"preview_url": "https://play.google.com/store/apps/details?id=com.moonactive.coinmaster",
"categories": [
{ "id": 9, "name": "Casino", "is_primary": true },
{ "id": 2, "name": "Mobile Apps", "is_primary": false },
{ "id": 1, "name": "Free", "is_primary": false }
],
"countries": ["US", "CA", "GB"],
"tags": ["new", "high-payout"],
"currency": "USD",
"conversion_rate": null,
"epc": null,
"events": [
{
"id": 5678,
"name": "Install",
"display_order": 1,
"is_completed": false,
"is_pending_review": false,
"is_attempted": false,
"payout": 2.50,
"estimated_time_to_complete": 600,
"geo_payouts": []
}
],
"caps": [],
"pro_tips": [],
"target_systems": [],
"creatives": [],
"tracking_link": "https://edgecash.ai/click?t=k7Ax9dQp2eR8&subid1=user_123",
"start_date": "2026-03-01T00:00:00+00:00",
"end_date": null
}
],
"links": { "first": "...", "last": "...", "prev": null, "next": null },
"meta": { "current_page": 1, "last_page": 1, "per_page": 25, "total": 1 }
}
tracking_link already carries the subid1 you
sent — send the user straight to it. The t= token is opaque: don't modify
it. You may append subid2/subid3/subid4/device
(up to 60 characters each) — they come back in
postbacks.
Field reference
Offer data[]
One entry per visible offer. Pagination metadata lives in links and meta.
| Field | Type | Notes |
|---|---|---|
id |
int | Stable offer identifier. |
name |
string | Internal offer name — useful for logs and dashboards. |
display_name |
string|null | User-facing name. Falls back to name if not set. |
description |
string|null | Internal description. Plain text. |
display_description |
string|null | User-facing description. |
package_id |
string|null | Android package or iOS bundle ID where applicable. |
platform |
string | Human-readable label — see the Platform mapping above. |
payout_model |
string | Human-readable label — see the Payout model mapping above. |
difficulty |
string | One of: Easy, Medium, Hard, Very Hard. |
preview_url |
string|null | Store listing or landing page used for preview. |
categories |
object[] | Every category the offer belongs to; at most one entry carries is_primary = true. |
countries |
string[2][] | ISO-2 country codes the offer is targeted to. |
tags |
string[] | Editorial tags. May be empty. |
currency |
string | Currency for every payout value in the response. Always USD today. |
conversion_rate |
float|null | Reserved — currently always null. |
epc |
float|null | Reserved — currently always null. |
events |
object[] | See Events below. Non-hidden conversion events; may be empty. |
caps |
object[] | Active conversion caps. See Caps below. Empty when none are set. |
pro_tips |
object[] | See Pro Tips below. |
target_systems |
object[] | OS / version targeting. See Target Systems below. |
creatives |
object[] | Icons and banners attached to the offer. See Creatives below. |
tracking_link |
string|null | Ready-to-use tracking link — already contains the subid1 you sent. The token (?t=...) is opaque: do not modify it; changing subid1 on the URL invalidates the link. You may append subid2/subid3/subid4/device. null when this end user already holds this offer through another of their accounts (one person = one offer); the catalog also omits offers the user fully attempted or that belong to another account of theirs. |
start_date |
string(ISO-8601)|null | When the offer becomes active. null = always-on. |
end_date |
string(ISO-8601)|null | When the offer expires. null = no end date. |
Events data[].events[]
Conversion events (milestones) a user can complete for this offer.
| Field | Type | Notes |
|---|---|---|
id |
int | Event identifier — comes back in postbacks as [EID]. |
name |
string | Event label (Install, Tutorial, Level 5, Purchase…). |
display_order |
int | Sort order. Lower = shown first. |
is_completed |
bool | A Payable or Paid transaction of this end user exists for the event. |
is_pending_review |
bool | The only transactions are under internal review. |
is_attempted |
bool | A transaction of any status exists — the event cannot be repeated by this person. |
payout |
float | Amount in USD paid to you when the end-user completes this event. |
estimated_time_to_complete |
int|null | Estimated seconds for an average user to complete the event. null when not supplied. |
geo_payouts |
object[] | Per-country payout overrides. See Geo Payouts below. |
Geo Payouts data[].events[].geo_payouts[]
Overrides the base event payout for a specific country.
| Field | Type | Notes |
|---|---|---|
country |
string[2] | ISO-2 country code the override applies to. |
payout |
float | Amount in USD paid when the end-user is from this country. Overrides the event payout. |
Caps data[].caps[]
Active throttles on this offer. Conversions stop counting once a cap is hit.
| Field | Type | Notes |
|---|---|---|
type |
string | One of: Leads, Clicks, Revenue. |
value |
int | The cap ceiling (count for Leads/Clicks, USD for Revenue). |
frequency |
string | One of: Hourly, Daily, Weekly, Monthly, Custom, Lifetime. |
Pro Tips data[].pro_tips[]
Curated hints you can surface to the end user.
| Field | Type | Notes |
|---|---|---|
name |
string | Tip text. |
display_order |
int | Sort order. Lower = shown first. |
Target Systems data[].target_systems[]
Per-OS targeting. Empty array = no OS restrictions beyond the offer platform.
| Field | Type | Notes |
|---|---|---|
os |
string | One of: Android, iOS (iPhone), iPadOS (iPad), Windows, macOS, Linux, ChromeOS. |
version_min |
number|null | Lowest accepted OS version (major.minor). null = no lower bound. |
version_max |
number|null | Highest accepted OS version (major.minor). null = no upper bound. |
Creatives data[].creatives[]
Icons, banners and other promo art you can use to advertise the offer.
| Field | Type | Notes |
|---|---|---|
id |
int | Creative identifier. |
mime_type |
string | MIME type of the file. |
width |
int|null | Pixel width. null when not measured. |
height |
int|null | Pixel height. null when not measured. |
is_primary |
bool | Exactly one creative per offer is marked primary. |
file_url |
string|null | Public URL. null when the file is missing. |
Pagination Links links
Standard paginator links block.
| Field | Type | Notes |
|---|---|---|
first |
string | URL of the first page. |
last |
string | URL of the last page. |
prev |
string|null | URL of the previous page. null on the first page. |
next |
string|null | URL of the next page. null on the last page. |
Pagination Meta meta
Counts and current page for the paginator.
| Field | Type | Notes |
|---|---|---|
current_page |
int | 1-based page index. |
last_page |
int | Total number of pages. |
per_page |
int | Rows per page — controlled by the per_page query parameter. |
total |
int | Total offers visible to your account, across all pages. |
Support ticket form
If one of your users has a problem with an offer (a missing reward or anything else), send them to our support ticket form. Build the link from your
publisher ID, the offer id returned by this API and the same
subid1 you put on the user's click:
https://edgecash.ai/support-ticket/YOUR_PUBLISHER_ID/OFFER_ID?subid1=user_123
- The user must have clicked the offer through our tracking with that
subid1— without a click the form is not available. - One ticket per user per offer in 60 days; a user who already filed one sees an "already submitted" notice.
- Proof files are optional: up to 10 images (jpg, jpeg or png, 5 MB each) and one video (mp4, avi or mov, up to 150 MB).
- Our support team answers the user directly at the email they enter on the form.
Ready to start earning?
Tell us about your app, site or traffic — and start monetizing with EdgeCash.