UpWolf Developers

Fields and what breaks without them

There is no field here that is merely nice to have. Required fields mean nothing works; recommended fields mean something specific gets worse, and the last column says exactly what.

required Without it the endpoint is unusable and we reject the response.
recommended Everything keeps running, and something measurable gets worse. This is the silent kind of damage.
optional Send it if you have it. Nothing depends on it today.

Active offers snapshot OffersSnapshot

JSON Schema · endpoint reference

Field Type Level What it does When missing
items[].external_id string required Stable id of the offer. Never reused for a different offer. Response is rejected.
items[].name string recommended Offer title, so the listing renders without a detail call. One extra detail request per offer just to show a name.
items[].company.name string recommended Company name for the same reason. Same as above.

Offer detail Offer

JSON Schema · endpoint reference

Field Type Level What it does When missing
external_id string required Same id as in the snapshot. Response is rejected.
version string required Opaque content fingerprint. Changes whenever the offer content changes. Response is rejected.
name string required Offer title. Becomes the headline of the creative. Response is rejected.
description string required Plain text or HTML. Everything the ad copy is written from — the richer, the better the ad. Response is rejected.
status string
published · pending · closed
required Only `published` offers get a running campaign; `closed` pauses it within minutes. Response is rejected.
updated_at string (ISO 8601) required When the offer last changed. Response is rejected.
company.name string required Advertiser name. Appears in the creative and prefixes the ad copy. Response is rejected.
company.logo_url string (URL) recommended Publicly reachable HTTPS image. Square or wide, at least 200 px. Creative is rendered without a logo — it works, it just looks generic.
company.introduction string optional Short company blurb; gives the ad copy something to work with beyond the offer itself. —
company.logo_approved boolean optional Set false if the logo is unverified; we then keep it out of rendered creative. —
area_id string recommended Your category id for the offer. Any stable identifier from your own taxonomy. Every campaign starts immediately instead of giving the offer a few days to fill organically, and the audience has no interest targeting — so it is wider and more expensive.
area_root_id string recommended Root of your category tree for the same offer. Ads run from the default page instead of the one matching the field.
locations[].city string recommended City as you write it in the listing. We map it to ad platform ids ourselves. Send the array even when empty — that tells us "remote", not "not implemented". Targeting falls back to the whole country instead of an 80 km radius around the cities — impressions paid for people who could never commute there.
language_code string (ISO 639-1) optional Language of the content. Without it we detect the language from the text. —
salaries[].minimum integer recommended Lower bound of the offered amount, in whole units of the currency. The creative cannot show an amount. Ads that name a number perform measurably better.
salaries[].maximum integer optional Upper bound, when you publish a range. —
salaries[].currency string (ISO 4217) recommended Currency of the amount, e.g. `CZK`. The amount is dropped from the creative rather than shown without a currency.
salaries[].measure string
hour · day · month · year · once
recommended Period the amount applies to. We assume a monthly amount, which reads as nonsense on hourly pay.

Change list OfferChanges

JSON Schema · endpoint reference

Field Type Level What it does When missing
items[].external_id string required Which offer changed. Response is rejected.
items[].version string required Its current content fingerprint. Response is rejected.
items[].status string
published · pending · closed
recommended Saves a detail call when all we need is the status. One detail request per changed offer just to learn whether it is still open.
items[].updated_at string (ISO 8601) recommended When it changed. The watermark can only move to the moment of the walk, so a slow walk re-reads offers it already saw.
next_page scalar | null required Handed back verbatim as `page`. `null` ends the walk. Response is rejected.

Campaign candidates CampaignCandidates

JSON Schema · endpoint reference

Field Type Level What it does When missing
items[].source_type string
visibility · ppc
required Which kind of product produced the candidate. Response is rejected.
items[].external_key string required Id of that product purchase on your side. Opaque to us; a number is fine. Response is rejected.
items[].offer_external_id string required The offer this campaign is for. Response is rejected.
items[].product string required Product key agreed with us — it selects budget, objective and ad account. Response is rejected.
items[].window.since string (ISO 8601) required Campaign may not run before this. Response is rejected.
items[].window.until string (ISO 8601) | null recommended End of the window. May be null for `ppc`, where we derive it from the product configuration. The campaign runs for the product default length instead of the window you sold.
items[].status string
active · cancelled
required `cancelled` on the same pair stops the campaign. Never express cancellation by omission. Response is rejected.
items[].updated_at string (ISO 8601) required Drives `updated_since` paging. Response is rejected.
items[].budget_override integer | null optional Budget in minor units (hundredths). Overrides the product default. —
items[].delay_override_days integer | null optional Overrides how long we wait before starting. —
items[].first_campaign_boost boolean optional New client — start immediately, skip the waiting period. Default false. —
next_page scalar | null required Handed back verbatim as `page`. `null` ends the walk. Response is rejected.

Response counts ApplicationsStats

JSON Schema · endpoint reference

Field Type Level What it does When missing
external_id string required Echo of the offer id. Response is rejected.
from string (ISO 8601) optional Echo of the requested lower bound. Handy when debugging, nothing depends on it. —
count integer required Quality responses since `from`. Must be an integer — a numeric string is ignored. Response is rejected.
total_count integer recommended All applications since `from`. Must be greater than or equal to `count`, otherwise we treat it as unknown. Charts show the quality count alone, with no idea how many applications it came out of.

Error Error

JSON Schema · endpoint reference

Field Type Level What it does When missing
error.code string required Short machine-readable code. Response is rejected.
error.message string required Human explanation. Ends up in our operator UI, so write it for a person. Response is rejected.
Unknown fields are ignored. Send whatever else your system has — extra keys never break the parser. That also means we can add fields to this contract without breaking your implementation.