late 0.0.1383

API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema). Request ids: responses carry an X-Request-Id header with the id we log the request under. Quote it when reporting a problem. A valid x-request-id you send is reused as that id.
Documentation
/*
 * Zernio API
 *
 * API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api  Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal.  Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).  Request ids: responses carry an X-Request-Id header with the id we log the request under. Quote it when reporting a problem. A valid x-request-id you send is reused as that id.
 *
 * The version of the OpenAPI document: 1.603.1
 * Contact: support@zernio.com
 * Generated by: https://openapi-generator.tech
 */

use crate::models;
use serde::{Deserialize, Serialize};

#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct UpdateAdSetRequest {
    #[serde(rename = "platform")]
    pub platform: Platform,
    #[serde(rename = "budget", skip_serializing_if = "Option::is_none")]
    pub budget: Option<Box<models::UpdateAdSetRequestBudget>>,
    /// Writes the ad set's own on/off switch (Meta: `configured_status`; X: the line item's `entity_status` ACTIVE / PAUSED), whatever delivery status its ads report. Omit if not toggling delivery state.
    #[serde(rename = "status", skip_serializing_if = "Option::is_none")]
    pub status: Option<Status>,
    /// Rename the ad set. At least one of budget/status/bidStrategy/name is required.  Supported on Meta, Google (the ad group), TikTok, LinkedIn (the campaign), Pinterest, X (the line item `name`), OpenAI and Reddit. Platforms without a rename return 501.  The new name is stored right away, so GET /v1/ads/ad-sets and GET /v1/ads/tree return it without a sync.
    #[serde(rename = "name", skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    /// Ad-set-level bid strategy. Overrides the campaign-level default.  - **Meta** (facebook, instagram): supported. - **TikTok:** the Meta-style enum is mapped to bid_type / bid_price / deep_bid_type automatically. - **OpenAI:** LOWEST_COST_WITH_BID_CAP and COST_CAP both map to the ad group's `bidding_config.max_bid_micros` (one knob covers both). LOWEST_COST_WITH_MIN_ROAS is rejected with 422 (no ROAS-based bidding). - **X:** writes the line item's `bid_strategy`: LOWEST_COST_WITHOUT_CAP = AUTO, LOWEST_COST_WITH_BID_CAP = MAX, COST_CAP = TARGET, with `bidAmount` as `bid_amount_local_micro`. LOWEST_COST_WITH_MIN_ROAS is rejected with 422. - **X objectives:** X decides which strategy the objective allows (TARGET only on REACH, FOLLOWERS and WEBSITE_CLICKS; MAX not on REACH or FOLLOWERS). - **Reddit:** see the mapping in the description above (LOWEST_COST_WITH_MIN_ROAS returns 422). - **Others** (linkedin, pinterest, google): 501 Not Implemented when bidStrategy is set.
    #[serde(rename = "bidStrategy", skip_serializing_if = "Option::is_none")]
    pub bid_strategy: Option<models::BidStrategy>,
    /// Meta only (400 elsewhere, before anything in the request is written). Writes the ad set's `dsa_beneficiary`, the legal entity that benefits from its ads. Same field and limits as `dsaBeneficiary` on POST /v1/ads/create. Only the fields you send are written.  This is the EU DSA field. For regional regimes (Brazil, Malaysia, Thailand, Australia, Singapore, Taiwan, India) use `regionalRegulatedCategories` and `regionalRegulationIdentities` instead.  Read it back with GET /v1/ads/ad-sets/{adSetId}?accountId={accountId}&fields=dsa_beneficiary,dsa_payor.
    #[serde(rename = "dsaBeneficiary", skip_serializing_if = "Option::is_none")]
    pub dsa_beneficiary: Option<String>,
    /// Meta only (400 elsewhere, before anything in the request is written). Writes the ad set's `dsa_payor`, the legal entity that pays for its ads, same field and limits as `dsaPayor` on POST /v1/ads/create. Can differ from `dsaBeneficiary`.
    #[serde(rename = "dsaPayor", skip_serializing_if = "Option::is_none")]
    pub dsa_payor: Option<String>,
    /// Meta only (400 elsewhere, before anything in the request is written). Writes the ad set's `regional_regulated_categories`, same values as on POST /v1/ads/create (AUSTRALIA_FINSERV, AUSTRALIA_UNIVERSAL, BRAZIL_REGULATION, INDIA_FINSERV, MALAYSIA_UNIVERSAL, SINGAPORE_UNIVERSAL, TAIWAN_FINSERV, TAIWAN_UNIVERSAL, THAILAND_UNIVERSAL, US_SECURITIES_LICENSING). Send it with `regionalRegulationIdentities`. An empty array is a 400.
    #[serde(
        rename = "regionalRegulatedCategories",
        skip_serializing_if = "Option::is_none"
    )]
    pub regional_regulated_categories: Option<Vec<String>>,
    /// Meta only (400 elsewhere, before anything in the request is written). Writes the ad set's `regional_regulation_identities`: the Verified identity IDs of the beneficiary and payer for each declared category.  - Same keys and validation as on POST /v1/ads/create (for example `universal_beneficiary` / `universal_payer` for BRAZIL_REGULATION, MALAYSIA_UNIVERSAL, THAILAND_UNIVERSAL and US_SECURITIES_LICENSING). - Send each ID as a string of digits; an empty object is a 400. - When Meta refuses the ad set for a missing verified advertiser, the 400 `platform_api_error` names the expected keys in `details.expectedIdentityKeys`, as on create.  Read both back with GET /v1/ads/ad-sets/{adSetId}?accountId={accountId}&fields=regional_regulated_categories,regional_regulation_identities.
    #[serde(
        rename = "regionalRegulationIdentities",
        skip_serializing_if = "Option::is_none"
    )]
    pub regional_regulation_identities: Option<
        std::collections::HashMap<
            String,
            models::UpdateAdSetRequestRegionalRegulationIdentitiesValue,
        >,
    >,
    #[serde(rename = "smartTargeting", skip_serializing_if = "Option::is_none")]
    pub smart_targeting: Option<Box<models::UpdateAdSetRequestSmartTargeting>>,
    #[serde(rename = "placements", skip_serializing_if = "Option::is_none")]
    pub placements: Option<Box<models::UpdateAdSetRequestPlacements>>,
    /// Reddit only: the ad group's new start_time, ISO 8601. A value without an offset (`YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS`) is read in the ad account timezone.  It cannot be earlier than the start of a campaign that starts in the future, nor at or after the ad group's end (400, `param: startDate`).  Every other platform ignores it (nothing is written and no error is returned, so a body that also sends `status` still applies it). Meta takes it in `platformSpecificData.startDate`.
    #[serde(rename = "startDate", skip_serializing_if = "Option::is_none")]
    pub start_date: Option<String>,
    /// Reddit only. The ad group's new end_time, ISO 8601, read in the ad account timezone when it has no offset; a date alone means the end of that day. `null` removes the end date so the ad group runs continuously.  Every other platform ignores it: nothing is written and no error is returned, so a body that also sends `status` still applies it. Meta takes it in `platformSpecificData.endDate`.  Returns 400 with `param: endDate` when:  - it is not after the start - it falls after the campaign's end - the campaign uses campaign budget optimization with no end date (Reddit then takes no end date on its ad groups) - `null` would outlive a campaign budget campaign that ends - `null` is sent for an ad group with a lifetime budget
    #[serde(
        rename = "endDate",
        default,
        with = "::serde_with::rust::double_option",
        skip_serializing_if = "Option::is_none"
    )]
    pub end_date: Option<Option<String>>,
    /// Targeting fields to change. Meta and Reddit (400 elsewhere).  **Reddit** (see the description above):  - `languages` must be among Reddit's ISO 639-1 codes (AR, CS, DA, DE, EL, EN, ES, FI, FR, HU, IT, JA, KO, NL, NO, PL, PT, RO, SV, VI, ZH, any case). - Emptying every included location is a 400 with `param: targeting.countries`. - Fields Reddit ad groups cannot take (age, income, devices, behaviors, B2B, `places`) return 400 with `param: targeting.<field>`.  **Meta**: same shape as the `targeting` object on POST /v1/ads/create.  - Only the keys you send change. Zernio reads the ad set's live targeting, merges your keys over it and writes the full spec back, so everything else (custom audiences, geo, age, interest groups, `targeting_automation`) is kept. - Setting any location replaces every location list. An empty list or `gender: all` clears that key. - `incomeTier` is resolved to Meta's income segment first (422 when Meta has none). - Fields Meta cannot target (LinkedIn B2B, Google `devices`, Reddit communities and keywords) return 400 with `param: targeting.<field>`. - An empty object is a 400, as is a `targeting.placements` object with no non-empty list (`param: targeting.placements`). - When the live targeting cannot be read, the request returns 502 and nothing is written.
    #[serde(
        rename = "targeting",
        default,
        with = "::serde_with::rust::double_option",
        skip_serializing_if = "Option::is_none"
    )]
    pub targeting: Option<Option<Box<models::TargetingSpec>>>,
    /// Bid cap in WHOLE currency units (USD: 5 = $5.00; JPY: 100 = ¥100). Required when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.  Internally converted to Meta's smallest-denomination integer, or (on OpenAI and X) to micros (× 1,000,000).  Meta only: may be sent alone, WITHOUT bidStrategy, to update the cap amount on an ad set whose parent campaign is COST_CAP or LOWEST_COST_WITH_BID_CAP. The strategy is inherited from the campaign and left untouched.
    #[serde(rename = "bidAmount", skip_serializing_if = "Option::is_none")]
    pub bid_amount: Option<f64>,
    /// Minimum ROAS as a decimal multiplier (2.0 = 2.0x). Required when bidStrategy is LOWEST_COST_WITH_MIN_ROAS. Sent to Meta as `bid_constraints.roas_average_floor` × 10000. Not supported on OpenAI (422).  Meta only: may be sent alone, WITHOUT bidStrategy, to update the floor on an ad set whose strategy (its own, or the campaign's under CBO) is LOWEST_COST_WITH_MIN_ROAS.
    #[serde(rename = "roasAverageFloor", skip_serializing_if = "Option::is_none")]
    pub roas_average_floor: Option<f64>,
    /// Meta only (other platforms return 501). Value rule set to attach to this ad set, from `/v1/ads/value-rule-sets`. Sending a different id replaces the current association. To DETACH, send `valueRulesApplied: false` and omit this field.
    #[serde(rename = "valueRuleSetId", skip_serializing_if = "Option::is_none")]
    pub value_rule_set_id: Option<String>,
    /// Meta only (other platforms return 501). `false` DETACHES the ad set's value rule set and must be sent WITHOUT `valueRuleSetId`; the combination returns 400. `true` is optional when attaching, since attachment is driven by `valueRuleSetId`, and requires it to be present.
    #[serde(rename = "valueRulesApplied", skip_serializing_if = "Option::is_none")]
    pub value_rules_applied: Option<bool>,
    #[serde(
        rename = "platformSpecificData",
        skip_serializing_if = "Option::is_none"
    )]
    pub platform_specific_data: Option<Box<models::UpdateAdSetRequestPlatformSpecificData>>,
}

impl UpdateAdSetRequest {
    pub fn new(platform: Platform) -> UpdateAdSetRequest {
        UpdateAdSetRequest {
            platform,
            budget: None,
            status: None,
            name: None,
            bid_strategy: None,
            dsa_beneficiary: None,
            dsa_payor: None,
            regional_regulated_categories: None,
            regional_regulation_identities: None,
            smart_targeting: None,
            placements: None,
            start_date: None,
            end_date: None,
            targeting: None,
            bid_amount: None,
            roas_average_floor: None,
            value_rule_set_id: None,
            value_rules_applied: None,
            platform_specific_data: None,
        }
    }
}
///
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Platform {
    #[serde(rename = "facebook")]
    Facebook,
    #[serde(rename = "instagram")]
    Instagram,
    #[serde(rename = "tiktok")]
    Tiktok,
    #[serde(rename = "linkedin")]
    Linkedin,
    #[serde(rename = "pinterest")]
    Pinterest,
    #[serde(rename = "google")]
    Google,
    #[serde(rename = "twitter")]
    Twitter,
    #[serde(rename = "openai")]
    Openai,
    #[serde(rename = "reddit")]
    Reddit,
}

impl Default for Platform {
    fn default() -> Platform {
        Self::Facebook
    }
}
/// Writes the ad set's own on/off switch (Meta: `configured_status`; X: the line item's `entity_status` ACTIVE / PAUSED), whatever delivery status its ads report. Omit if not toggling delivery state.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Status {
    #[serde(rename = "active")]
    Active,
    #[serde(rename = "paused")]
    Paused,
}

impl Default for Status {
    fn default() -> Status {
        Self::Active
    }
}