API Reference
POST /surveys
Request survey offers for a panelist — list mode or single-offer mode.
Request
POST https://publishers.mypinio.com/api/v1/publishers/surveys| Authentication | Bearer or X-API-Key |
| Content-Type | application/json |
| Methods | POST only |
Local docs: use Download collection and import the file in Postman (File → Import). Run in Postman needs the public URL at publishers.mypinio.com — Postman cannot fetch collections from localhost.
Request body
Required
| Field | Type | Description |
|---|---|---|
appId | string | App ID from the Publisher Portal (Apps) |
panelistId | string | Your stable identifier for this panelist |
country | string | ISO 3166-1 alpha-2, uppercase (e.g. DE, US) |
locale | string | BCP 47 tag (e.g. de-DE, en-US) |
Optional
| Field | Type | Description |
|---|---|---|
maxSurveys | number | Optional. Max offers to return; capped at your account limit. If omitted, up to your account limit is returned |
subId1 | string | Optional tracking ID, passed through the session |
subId2 | string | Optional tracking ID |
subId3 | string | Optional tracking ID |
profileDetails | object | Profiling attributes (see below) |
smartdefender | object | Optional fraud-verification payload if your stack provides one |
surveyId | string | Request a single offer by ID instead of a list |
sid | string | Alias for surveyId |
profileDetails
Send one object (not an array). age and gender are required from 2026-10-06 (see the changelog); until then, responses to requests without them include a warnings entry.
| Key | Type | Notes |
|---|---|---|
age | integer | Required from 2026-10-06. JSON number (not a string), 0–130 |
gender | string | Required from 2026-10-06. male or female (not case-sensitive; m, f, 1 = male, 2 = female also accepted). Must be a string. Other values count as present but are not used for matching |
postalCode | string | Also accepts postal_code, zip, zipcode (one value only) |
city | string | |
maid | string | Mobile advertising ID |
email | string | When used for matching |
Other keys are ignored.
Examples
List offers:
{
"appId": "YOUR_APP_ID",
"panelistId": "user_abc123",
"country": "DE",
"locale": "de-DE",
"maxSurveys": 10,
"profileDetails": {
"age": 34,
"postalCode": "10115",
"gender": "female"
}
}Single offer:
{
"appId": "YOUR_APP_ID",
"panelistId": "user_abc123",
"country": "DE",
"locale": "de-DE",
"surveyId": "987654"
}Response — HTTP 200 success
Rely only on the fields below. Other fields may appear in responses during development accounts but are not part of the stable contract.
Top-level fields
| Field | Type | Description |
|---|---|---|
requestStatus | string | "true" on success |
hasSurveys | boolean | Whether any offers are returned |
hasPartlyQuestions | boolean | Profiling partially complete |
message | string | Optional status text (truncated) |
reason | string | Optional reason text (truncated) |
appId | string | Echo of your request |
panelistId | string | Echo of your request |
country | string | Echo of your request |
locale | string | Echo of your request |
rewardUnitName | string | Label for end-user rewards (e.g. PINTOS) |
surveyCount | number | Number of items in surveys |
surveys | array | Offers, highest reward first |
profilingUrl | string | Deprecated (legacy). Optional link for base profile questions. Still returned for backward compatibility; will be removed later. Prefer showing surveys / partlySurveys and opening entryLink — profiling runs inline on click. |
partlySurveys | array | Same shape as surveys. Offers that need a few client-specific questions before redirect. |
warnings | array | Optional. Non-fatal notices, each with a code and a message — see Warnings. |
Warnings
code | Meaning |
|---|---|
matching_timeout | Survey matching did not answer within 5 seconds. The response is a normal 200 with hasSurveys: false and empty lists. Show your empty state and call again on the panelist's next page view. |
profile_fields_required_soon | profileDetails.age / profileDetails.gender missing; required from 2026-10-06 (fields lists the missing keys). |
Survey object
| Field | Type | Description |
|---|---|---|
surveyId | string | Offer identifier |
id | string | Same as surveyId when present |
entryLink | string | HTTPS URL — open to start the survey |
cpi | number | Your CPI for this offer (USD). |
loi | number | Length of interview (minutes) |
ir | number | Incidence rate (percent) |
category | string | Category label |
userRewardAmount | number | Suggested panelist reward in rewardUnitName units |
Example
{
"appId": "YOUR_APP_ID",
"panelistId": "user_abc123",
"country": "DE",
"locale": "de-DE",
"requestStatus": "true",
"hasSurveys": true,
"hasPartlyQuestions": false,
"rewardUnitName": "PINTOS",
"surveyCount": 1,
"surveys": [
{
"surveyId": "123456",
"entryLink": "https://…",
"cpi": 1.5,
"loi": 10,
"ir": 40,
"category": "Shopping",
"userRewardAmount": 150
}
]
}Prerequisites and errors
| Condition | HTTP | message (typical) |
|---|---|---|
| Redirect URLs not configured | 400 | Redirect URLs / signing secret required |
Unknown or wrong-org appId | 404 | Unknown appId… |
| Invalid JSON or validation | 400 | Missing required field… |
See Errors and Redirect URLs.