late 0.0.1122

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.212.1
 * Contact: support@zernio.com
 * Generated by: https://openapi-generator.tech
 */

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

/// UploadedOrDerivedAudience : customer_list, website, lookalike or engagement audience (uploaded or derived from a source).
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct UploadedOrDerivedAudience {
    #[serde(rename = "accountId")]
    pub account_id: String,
    /// Platform ad account ID. Must start with act_ for Meta; bare platform id for others (Google customer id, X/TikTok/LinkedIn/Pinterest account id).
    #[serde(rename = "adAccountId")]
    pub ad_account_id: String,
    #[serde(rename = "name")]
    pub name: String,
    #[serde(rename = "description", skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(rename = "type")]
    pub r#type: Type,
    /// Required for website_retargeting audiences (LinkedIn only). Each rule is a URL pattern; a member who visits any matching page enters the segment. Needs the LinkedIn Insight Tag installed on the customer's site; the segment only starts filling once the tag reports visits.  The response's `platformAudienceId` is the LinkedIn adSegment id, valid for downstream use. These segments appear in GET /v1/ads/audiences with  `type: website_retargeting` once LinkedIn has finished building them.
    #[serde(rename = "matchRules", skip_serializing_if = "Option::is_none")]
    pub match_rules: Option<Vec<models::UploadedOrDerivedAudienceMatchRulesInner>>,
    /// Required for engagement audiences (LinkedIn only): what members engaged with: a video/leadgen/single-image ad campaign, a Company Page or an Event page.
    #[serde(rename = "sourceType", skip_serializing_if = "Option::is_none")]
    pub source_type: Option<SourceType>,
    /// Required for engagement audiences. The action, validated by LinkedIn against `sourceType`. Common values: VIDEO_ADS FIRST_QUARTILE / MIDPOINT / THIRD_QUARTILE / FULL_COMPLETE; LEAD_GEN_FORMS VIEW_FORM / LEAD_FORM_SUBMIT; ORGANIZATION_PAGES VIEW / CTA_CLICK; EVENT_PAGES RSVPED / VIDEO_VIEWED / ENGAGEMENT / CLICK.
    #[serde(rename = "trigger", skip_serializing_if = "Option::is_none")]
    pub trigger: Option<String>,
    /// Required for engagement audiences. Rolling window.
    #[serde(rename = "lookbackDays", skip_serializing_if = "Option::is_none")]
    pub lookback_days: Option<LookbackDays>,
    /// Required for engagement audiences. Campaign URNs for the ad source types, organization URNs for pages and events. LinkedIn creates one rule per source, all sharing the same trigger and lookbackDays.
    #[serde(rename = "engagementSources", skip_serializing_if = "Option::is_none")]
    pub engagement_sources: Option<Vec<String>>,
    /// Required for company_list audiences (LinkedIn only): plain-text company rows for account targeting. Each row needs at least one identifier. Not hashed, LinkedIn matches these against its own company graph. LinkedIn recommends 1,000+ companies for a usable match rate and takes up to 48h to process the list. Replace the list later with POST /v1/ads/audiences/{audienceId}/companies.
    #[serde(rename = "companies", skip_serializing_if = "Option::is_none")]
    pub companies: Option<Vec<models::UploadedOrDerivedAudienceCompaniesInner>>,
    /// website: the Meta pixel, TikTok pixel or Pinterest tag id. Required on those three, rejected on Google.
    #[serde(rename = "pixelId", skip_serializing_if = "Option::is_none")]
    pub pixel_id: Option<String>,
    /// Required for website (Meta max 180, TikTok 7/14/30/60/90/180, Pinterest and Google max 540), meta_engagement (max 365) and tiktok_engagement (7/14/30/60/90/180; organic and live video and most business-account events only 7/14/30).
    #[serde(rename = "retentionDays", skip_serializing_if = "Option::is_none")]
    pub retention_days: Option<i32>,
    /// Required for meta_engagement audiences (Meta only): what people engaged with. `page` = a Facebook Page, `instagram` = an IG professional account, `video` = a video.
    #[serde(rename = "engagementSource", skip_serializing_if = "Option::is_none")]
    pub engagement_source: Option<EngagementSource>,
    /// Required for meta_engagement: the Page / IG account / video id.
    #[serde(rename = "sourceId", skip_serializing_if = "Option::is_none")]
    pub source_id: Option<String>,
    /// meta_engagement: the engagement event; defaults per source (page → page_engaged, instagram → ig_business_profile_all, video → video_watched). Ignored when `rule` is provided.  website on TikTok: the pixel event (default `PAGE BROWSE`). website on Pinterest: the tag event (`pagevisit`, `signup`, `checkout`, `viewcategory`, `search`, `addtocart`, `watchvideo`, `lead`, `custom` or a partner-defined event).  tiktok_engagement (required): the TikTok engagement event, validated per `source` (TikTok's filter values, spaces included): - ads: `CLICK`, `IMPRESSION`, `PLAY 2S`, `PLAY 6S`, `PLAY 25`, `PLAY 50`, `PLAY 75`,   `PLAY OVER`, and the `ENGAGEMENT APP PROFILE` / `ENGAGEMENT TIKTOK INSTANT` /   `ENGAGEMENT COLLECTION ADS` `CLICK` and `IMPRESSION` events. - organic_video: `ORGANIC VIDEO PLAY 2S`, `ORGANIC VIDEO PLAY 6S`,   `ORGANIC VIDEO PLAY OVER`, `ORGANIC VIDEO ENGAGEMENT`. - live_video: `LIVE VIDEO VIEW`, `LIVE VIDEO ENGAGEMENT`. - business_account: `BUSINESS ACCOUNT PROFILE FOLLOW`, `BUSINESS ACCOUNT PROFILE VISIT`,   `BUSINESS ACCOUNT ENGAGEMENT`, `BUSINESS ACCOUNT PLAY 2S`, `BUSINESS ACCOUNT PLAY 6S`,   `BUSINESS ACCOUNT PLAY OVER` and the rest of TikTok's business-account events. An unknown value is a 400 that lists the valid ones.
    #[serde(rename = "event", skip_serializing_if = "Option::is_none")]
    pub event: Option<String>,
    /// Required for lookalike audiences
    #[serde(rename = "sourceAudienceId", skip_serializing_if = "Option::is_none")]
    pub source_audience_id: Option<String>,
    /// 2-letter code, required for lookalike audiences
    #[serde(rename = "country", skip_serializing_if = "Option::is_none")]
    pub country: Option<String>,
    /// lookalike on Meta (0.01-0.20) and Pinterest (0.01-0.10, whole percents). Rejected on TikTok and Google.
    #[serde(rename = "ratio", skip_serializing_if = "Option::is_none")]
    pub ratio: Option<f64>,
    /// lookalike on TikTok and Google: audience breadth. Rejected on Meta and Pinterest.
    #[serde(rename = "size", skip_serializing_if = "Option::is_none")]
    pub size: Option<Size>,
    /// Required for tiktok_engagement: what people engaged with.
    #[serde(rename = "source", skip_serializing_if = "Option::is_none")]
    pub source: Option<Source>,
    /// tiktok_engagement: ad group / campaign ids for `ads`, video ids for `organic_video` and `live_video` (max 10). Required except for `business_account`.
    #[serde(rename = "sourceIds", skip_serializing_if = "Option::is_none")]
    pub source_ids: Option<Vec<String>>,
    /// tiktok_engagement: the TikTok identity that owns the videos or business account. Required for organic_video, live_video and business_account.
    #[serde(rename = "identityId", skip_serializing_if = "Option::is_none")]
    pub identity_id: Option<String>,
    /// tiktok_engagement: type of `identityId`.
    #[serde(rename = "identityType", skip_serializing_if = "Option::is_none")]
    pub identity_type: Option<IdentityType>,
    /// tiktok_engagement: required when identityType is BC_AUTH_TT.
    #[serde(
        rename = "identityAuthorizedBcId",
        skip_serializing_if = "Option::is_none"
    )]
    pub identity_authorized_bc_id: Option<String>,
    /// pinterest_engagement: Pinterest's `engager_type`, passed through when set.
    #[serde(rename = "engagerType", skip_serializing_if = "Option::is_none")]
    pub engager_type: Option<EngagerType>,
    /// pinterest_engagement: limit to one engagement action.
    #[serde(rename = "engagementType", skip_serializing_if = "Option::is_none")]
    pub engagement_type: Option<EngagementType>,
    /// pinterest_engagement: people who engaged with Pins from these domains. The domain must be claimed on the Pinterest account or Pinterest rejects it.
    #[serde(rename = "engagementDomains", skip_serializing_if = "Option::is_none")]
    pub engagement_domains: Option<Vec<String>>,
    /// pinterest_engagement: people who engaged with these campaigns' ads.
    #[serde(rename = "campaignIds", skip_serializing_if = "Option::is_none")]
    pub campaign_ids: Option<Vec<String>>,
    /// pinterest_engagement: people who engaged with these ads.
    #[serde(rename = "adIds", skip_serializing_if = "Option::is_none")]
    pub ad_ids: Option<Vec<String>>,
    /// pinterest_engagement: people who engaged with these Pins. At least one of engagementDomains, campaignIds, adIds or pinIds is required.
    #[serde(rename = "pinIds", skip_serializing_if = "Option::is_none")]
    pub pin_ids: Option<Vec<String>>,
    /// website on Meta, TikTok and Google. Narrows the audience from all visitors to visitors of URLs containing this substring. Ignored when `rule` is supplied. A 400 on Pinterest, which only matches exact URLs.
    #[serde(rename = "urlContains", skip_serializing_if = "Option::is_none")]
    pub url_contains: Option<String>,
    /// Meta only (a 400 elsewhere). Optional raw Meta rule, replacing the one we build. Omit it for all visitors of `pixelId`, or use `urlContains` for the common page-match case.  For `website` this is Meta's Flexible Audience Rule and is VALIDATED before we call Meta: every entry in `inclusions.rules` (and `exclusions.rules`) must carry `event_sources`, `retention_seconds` AND `filter`. Meta rejects a rule missing any of the three with code 100 / subcode 1713098 (\"Invalid rule JSON format\"), so a bad shape is a 400 here instead. The pre-2018 flat shapes (`{url: ...}`, `{event: ...}`) are not accepted by Meta at all (subcode 1870029).  Example, visitors of /checkout in the last 30 days: `{\"inclusions\":{\"operator\":\"or\",\"rules\":[{\"event_sources\":[{\"id\":\"<pixelId>\",\"type\":\"pixel\"}],\"retention_seconds\":2592000,\"filter\":{\"operator\":\"and\",\"filters\":[{\"field\":\"url\",\"operator\":\"i_contains\",\"value\":\"/checkout\"}]}}]}}`  Note Meta DERIVES `retention_days` from `retention_seconds` and stores `event_sources[].id` as a number, so a rule read back will not be byte-identical to the one you sent.  For `meta_engagement` the rule is forwarded verbatim and NOT validated: that type has two dialects (the `video` source uses a legacy flat array), so no single schema covers both.
    #[serde(rename = "rule", skip_serializing_if = "Option::is_none")]
    pub rule: Option<serde_json::Value>,
    /// Data source declaration for GDPR compliance (customer_list only)
    #[serde(rename = "customerFileSource", skip_serializing_if = "Option::is_none")]
    pub customer_file_source: Option<String>,
}

impl UploadedOrDerivedAudience {
    /// customer_list, website, lookalike or engagement audience (uploaded or derived from a source).
    pub fn new(
        account_id: String,
        ad_account_id: String,
        name: String,
        r#type: Type,
    ) -> UploadedOrDerivedAudience {
        UploadedOrDerivedAudience {
            account_id,
            ad_account_id,
            name,
            description: None,
            r#type,
            match_rules: None,
            source_type: None,
            trigger: None,
            lookback_days: None,
            engagement_sources: None,
            companies: None,
            pixel_id: None,
            retention_days: None,
            engagement_source: None,
            source_id: None,
            event: None,
            source_audience_id: None,
            country: None,
            ratio: None,
            size: None,
            source: None,
            source_ids: None,
            identity_id: None,
            identity_type: None,
            identity_authorized_bc_id: None,
            engager_type: None,
            engagement_type: None,
            engagement_domains: None,
            campaign_ids: None,
            ad_ids: None,
            pin_ids: None,
            url_contains: None,
            rule: None,
            customer_file_source: None,
        }
    }
}
///
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Type {
    #[serde(rename = "customer_list")]
    CustomerList,
    #[serde(rename = "company_list")]
    CompanyList,
    #[serde(rename = "engagement")]
    Engagement,
    #[serde(rename = "meta_engagement")]
    MetaEngagement,
    #[serde(rename = "tiktok_engagement")]
    TiktokEngagement,
    #[serde(rename = "pinterest_engagement")]
    PinterestEngagement,
    #[serde(rename = "website")]
    Website,
    #[serde(rename = "website_retargeting")]
    WebsiteRetargeting,
    #[serde(rename = "lookalike")]
    Lookalike,
}

impl Default for Type {
    fn default() -> Type {
        Self::CustomerList
    }
}
/// Required for engagement audiences (LinkedIn only): what members engaged with: a video/leadgen/single-image ad campaign, a Company Page or an Event page.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum SourceType {
    #[serde(rename = "VIDEO_ADS")]
    VideoAds,
    #[serde(rename = "LEAD_GEN_FORMS")]
    LeadGenForms,
    #[serde(rename = "ORGANIZATION_PAGES")]
    OrganizationPages,
    #[serde(rename = "EVENT_PAGES")]
    EventPages,
    #[serde(rename = "SINGLE_IMAGE_ADS")]
    SingleImageAds,
}

impl Default for SourceType {
    fn default() -> SourceType {
        Self::VideoAds
    }
}
/// Required for engagement audiences. Rolling window.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum LookbackDays {
    #[serde(rename = "30")]
    Variant30,
    #[serde(rename = "60")]
    Variant60,
    #[serde(rename = "90")]
    Variant90,
    #[serde(rename = "180")]
    Variant180,
    #[serde(rename = "365")]
    Variant365,
}

impl Default for LookbackDays {
    fn default() -> LookbackDays {
        Self::Variant30
    }
}
/// Required for meta_engagement audiences (Meta only): what people engaged with. `page` = a Facebook Page, `instagram` = an IG professional account, `video` = a video.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum EngagementSource {
    #[serde(rename = "page")]
    Page,
    #[serde(rename = "instagram")]
    Instagram,
    #[serde(rename = "video")]
    Video,
}

impl Default for EngagementSource {
    fn default() -> EngagementSource {
        Self::Page
    }
}
/// lookalike on TikTok and Google: audience breadth. Rejected on Meta and Pinterest.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Size {
    #[serde(rename = "narrow")]
    Narrow,
    #[serde(rename = "balanced")]
    Balanced,
    #[serde(rename = "broad")]
    Broad,
}

impl Default for Size {
    fn default() -> Size {
        Self::Narrow
    }
}
/// Required for tiktok_engagement: what people engaged with.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Source {
    #[serde(rename = "ads")]
    Ads,
    #[serde(rename = "organic_video")]
    OrganicVideo,
    #[serde(rename = "live_video")]
    LiveVideo,
    #[serde(rename = "business_account")]
    BusinessAccount,
}

impl Default for Source {
    fn default() -> Source {
        Self::Ads
    }
}
/// tiktok_engagement: type of `identityId`.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum IdentityType {
    #[serde(rename = "TT_USER")]
    TtUser,
    #[serde(rename = "BC_AUTH_TT")]
    BcAuthTt,
}

impl Default for IdentityType {
    fn default() -> IdentityType {
        Self::TtUser
    }
}
/// pinterest_engagement: Pinterest's `engager_type`, passed through when set.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum EngagerType {
    #[serde(rename = "1")]
    Variant1,
    #[serde(rename = "2")]
    Variant2,
}

impl Default for EngagerType {
    fn default() -> EngagerType {
        Self::Variant1
    }
}
/// pinterest_engagement: limit to one engagement action.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum EngagementType {
    #[serde(rename = "click")]
    Click,
    #[serde(rename = "save")]
    Save,
    #[serde(rename = "closeup")]
    Closeup,
    #[serde(rename = "comment")]
    Comment,
    #[serde(rename = "like")]
    Like,
}

impl Default for EngagementType {
    fn default() -> EngagementType {
        Self::Click
    }
}