API Integration (Advanced)
Get Personalized API - Migrate from User-Level Offer API
This guide covers moving from /hotoffers_api.php versions 1 and 2 to the Get Personalized v3 response. No API key is required. Identify the request with the wall ID and the same user ID used for clicks and progress.
Endpoint and request
Use GET over HTTPS and URL-encode the actual user ID in the path. The REST path parameter is named user_id. The legacy Get Personalized URL /hotoffers_v3_api.php also remains available and accepts uid as a query parameter.
Legacy parameter | Get Personalized | Migration action |
|---|---|---|
|
| Keep the numeric wall ID. |
|
| Move the ASCII user ID into the REST path; use |
|
| Request 1 through 500 offers. Required unless |
|
| Use |
|
| Use |
|
| Pass the user’s IP when calling from your server. |
Calling from a browser supplies the caller’s IP by default, but does not automatically select the device. Pass ios or android for mobile users on either integration path.
Other supported options include sid3, os_version, bid_floor and experiment_id. A positive bid_floor excludes lower-reward offers. Use offer_id on either route for one eligible offer; without numoffers, its effective maximum is 500. include_sortmetric is accepted but ignored, and does not add sort metrics to the response. See the technical guide for the full request contract.
Response shape and ranking
Read offers from response.offers instead of treating the entire response as an array. The v3 envelope contains status, publisher_id, wall_id, support_id, total, offset, limit and offers, with ranking and policy metadata.
total is the matching offer count before the requested maximum. offset is currently 0; this endpoint returns the top N rather than accepting an offset. limit is the effective requested maximum, not the returned count. A single-offer lookup can therefore return one offer and limit: 500.
support_id identifies the user’s support record. It can be an integer for a newly created record or a digit string for an existing one; it is not a per-request ID. Preserve it for troubleshooting.
Use returned array order for ranking. hot_offers_order is retained for compatibility and currently always 0. Echo the response’s identifier when recording wall impressions, including 0; do not independently choose a split-test bucket.
Field mapping
Legacy field | Get Personalized v3 | Migration action |
|---|---|---|
|
| Campaign ID. |
|
| Campaign name. |
|
| Continue displaying the description. |
|
| Requirements belong to each event. |
|
| Continue displaying the additional terms. |
|
| Allow the full configured delay-label set, including Daily, Weekly and empty values. |
|
| Use the total for the offer and event rewards for individual steps. Allow fractions. |
|
| Sum of listed event rewards; use this standard total. |
|
| User-specific URL; serve as returned. |
|
| Iterate creatives with width and height. |
| Get Progress API | Retrieve event progress separately. |
Current response fields
The current schema includes headline, offer_type, offer_category, offer_flow, payment_model, tag, tags, text-or-null multiple_leads, events, capping, total_user_reward, epc, wall_hidden, attributed_click_time, mobile_package_id, estimated_completion_time and active_date. Consult the Swagger reference for their types and conditional presence.
Before a click, offer-level and event-level reward_expiration_date and offer-level support_expiration_date are null. Use nullable reward_window_days and integer support_window_days as durations. A null event duration uses the offer duration. Do not construct deadlines from response-generation time.
After a click, the expiration dates use the stored reward-window start, falling back to the click timestamp. Campaign and base-event durations use the stored click-time settings. Tier overrides use a stored snapshot when available; a tier added after the click can use its current override configuration. A null event deadline inherits the offer deadline. A click with no snapshotted campaign reward window keeps a null campaign reward duration and date. A support duration still exists without a reward window. See the technical guide for examples.
There are no offer_conversion_window, event_conversion_window, non_linear, payout or total_payout fields in Personalized v3. The response also omits user_eligible, in_progress, user_completed and recommended_score. Get Progress provides progress; Get Offers provides publisher payout fields.
Modern-response migration history
Earlier v3 responses returned a separate frequency_limit field and numeric multiple_leads. The current v3 response removes that separate field and returns the named policy in multiple_leads. Update parsers and cached records for the text-or-null type. The existing api_version=3 option still selects the modern envelope; api_version=1 or 2 selects legacy flat arrays. This contract update does not introduce another response version.
Events, identifiers and progress
Always iterate events[] for single-event and tiered offers. Each event includes event_description, fractional-capable user_reward, conversion_type, nullable reward_expiration_date and reward_window_days, is_sequential, event_order, is_non_crediting, event_id and sid4.
event_order is a one-based integer for an ordered step or false for an independent step. Tracking-only events have is_non_crediting: true and no user reward. Legacy tiers and currency_award_with_tiers fields still appear for tiered offers, but are not substitutes for the event list and standard total.
Keep sid4 as the raw offer/tier identifier used for conversion matching and the $sid4$ postback value. event_id is independently configured and maps to $event_id$, with $eventid$ as its valid alias. Either identifier may be empty. No synthetic base_<offer_id> value or fallback from one identifier to the other is generated.
Replace tiers_url progress handling with Get Progress. Its events contain completion timestamps, points awarded and reward status. Do not expect progress booleans in Personalized.
Bans, hidden offers and errors
Hard user or IP restrictions return HTTP 403 with status: error and an error object whose code is USER_BANNED or IP_BANNED. A successful response with banned: true instead indicates a soft missing-credit-report restriction; offers can still be returned. Reflect the support restriction without treating it as a hard offer-access ban.
An offer with wall_hidden: true stays in the response. Exclude it from browse sections while retaining it where needed for progress views.
Handle both error shapes: status: failure with message, and status: error with error.code/error.message. Validation errors return 400; inactive walls or publishers can return structured 403; wall-not-found and no-offer cases return 404. A failed offer_id lookup returns structured 404 OFFER_NOT_FOUND.
Tracking and migration checklist
sid3 is included in standard generated tracking URLs and can return through the $sid3$ postback variable. Keep its ASCII value within 200 characters before URL encoding. Preview destinations can bypass tracking. Keep the entire encoded callback URL within delivery and receiver limits.
Use HTTPS and the
user_idREST path, withapi_version=3or its default.Supply the actual device and, for server requests, the user’s IP.
Read the response envelope, preserve array order and handle mixed-type
support_id.Display event requirements and additional terms, fractional rewards and nullable fields.
Preserve
sid4andevent_idindependently, and use Get Progress for event state.Handle hard bans, soft support restrictions, hidden offers and both error formats.
For migration help, contact your account manager with the relevant support_id.
Share feedback on this documentation
