late 0.0.1291

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

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

/// ErrorResponseDetails : Additional structured context for the error (for example field-level validation errors). What it carries depends on the endpoint and platform.  **Meta ads refusals.** The ones customers hit most come back with their own `code` instead of `platform_api_error`, the field to fix in `param`, and `details.fix` ({ label, url }) pointing at the Meta page that resolves it:  - `ad_account_payment_required` - `ad_account_policy_not_accepted` - `meta_security_check_required` - `meta_action_blocked` - `whatsapp_number_not_linked` - `invalid_targeting`  Meta's own error stays in the message and in `platformError`.  **Private replies.** `privateReplyConsumed` appears on the private-reply endpoint's 400 when the comment's single reply is already spent. `privateReplyOutcome: \"unknown\"` appears on its 502 when Meta answered a server error and the reply may have been delivered.  **Google quota 429.** On a Google Ads or YouTube Analytics 429, `quotaExhausted: true` marks the failure as Google's own quota, not a Zernio rate limit, so you can keep calling other platforms instead of backing off everywhere. When Google names the scope, `quotaScope` is also set:  - `DEVELOPER`: the shared budget (the developer token for Google Ads, the Google Cloud project for YouTube Analytics). Every account on Zernio is affected and there is nothing to change on your side. - `ACCOUNT`: your own ad account (Google Ads only).  A Meta 429 carries neither field.  **Zernio Google Ads burst-limit 429.** Carries `budgetScope` instead, never `quotaExhausted`. These are Zernio's own limits, applied before the call reaches Google, and both clear within a minute. They are separate axes from `quotaScope`, not the same pool named twice.  - `account`: the limit of 15 requests per minute per connected Google Ads account. - `user`: the ceiling of 120 requests per minute per Zernio user across all their Google Ads accounts.  **Failed Meta ad create** (`POST /v1/ads/create`, `POST /v1/ads/boost`, `POST /v1/ads/ctwa`). Carries `stage` (where it failed), `adAccountId` (on which ad account) and `createdObjects` (every object this request had already created, with what cleanup did to it).  - `left_behind` objects still exist on the ad account (Meta refused the delete, typically on a held account, or the delete hit a network error). Delete them yourself or reuse them. - `unconfirmedWrite` is set when Meta answered a create with a 5xx or dropped the connection and Zernio could not confirm whether the object exists. Check that parent before creating it again.  **Ineligible ad account: 422 `ad_account_unusable`.** When Meta refuses a write because the ad account's status is ineligible to manage ads (Meta subcode 2490592 or 4841021, on the write itself or on a cleanup delete), any Meta ads write answers it.  That covers create, boost, CTWA, campaign / ad set / ad updates and status changes.  The message names the ad account when known, links Meta's fix (https://www.facebook.com/business/help/422289316306981), lists the objects left behind and ends with Meta's original error, which also stays verbatim in `platformError`.  Meta often reports the first failure under an unrelated code (e.g. 1487194 on the creative), so branch on `code`, not on `platformError`.  **Missing Advertise permission: 403 `insufficient_permissions`.** When the Facebook user behind the connection's token lacks the Advertise permission on the ad account, any Meta ads write answers it.  Triggers: Meta subcode 2490585, 2490591 or 4841020 on the write, or a code 200 refusal such as 1487194 whose cleanup deletes Meta refused with 2490591 or 4841020.  Meta may still accept the campaign and ad set and refuse only the ad. The message names the ad account, asks for the Advertise or Manage permission on it (or a token granted `ads_management`, by reconnecting) and lists the objects left behind.  It ends with Meta's `error_user_title`, `error_user_msg` and subcode; the raw error stays in `platformError`.
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct ErrorResponseDetails {
    /// Meta ad create failures only. The step that failed:  - `media`: image/video download or upload. - `campaign` - `adset` - `creative` - `ad`: the ad POST itself, where Meta's code 31 / 3858385 hold and 100 / 1359188 payment rejections land. - `activation`: switching the created objects on. No longer returned: a refused switch to ACTIVE now answers 201 with an `activation_failed:` warning and the objects kept PAUSED. - `other`: a read or check before any write.
    #[serde(rename = "stage", skip_serializing_if = "Option::is_none")]
    pub stage: Option<Stage>,
    /// Meta ad create failures only. The ad account the request wrote to (`act_...`).
    #[serde(rename = "adAccountId", skip_serializing_if = "Option::is_none")]
    pub ad_account_id: Option<String>,
    /// Meta ad create failures only. Every object this request created before failing, in creation order. Objects you referenced (an existing campaign, ad set, creative or video) are never listed and never deleted.
    #[serde(rename = "createdObjects", skip_serializing_if = "Option::is_none")]
    pub created_objects: Option<Vec<models::ErrorResponseDetailsCreatedObjectsInner>>,
    #[serde(rename = "unconfirmedWrite", skip_serializing_if = "Option::is_none")]
    pub unconfirmed_write: Option<Box<models::ErrorResponseDetailsUnconfirmedWrite>>,
    /// Google Ads and YouTube Analytics 429 only. True when the upstream Google quota is spent rather than a Zernio limit.
    #[serde(rename = "quotaExhausted", skip_serializing_if = "Option::is_none")]
    pub quota_exhausted: Option<bool>,
    /// Google Ads and YouTube Analytics 429 only, when the scope is known. DEVELOPER is the shared budget (the developer token for Google Ads, the Google Cloud project for YouTube Analytics); ACCOUNT is your ad account (Google Ads only).
    #[serde(rename = "quotaScope", skip_serializing_if = "Option::is_none")]
    pub quota_scope: Option<QuotaScope>,
    /// Zernio Google Ads burst-limit 429 only (never set alongside `quotaExhausted`). `account` is the limit of 15 requests per minute per connected Google Ads account; `user` is the ceiling of 120 requests per minute per Zernio user across all their Google Ads accounts. Both clear within a minute.
    #[serde(rename = "budgetScope", skip_serializing_if = "Option::is_none")]
    pub budget_scope: Option<BudgetScope>,
}

impl ErrorResponseDetails {
    /// Additional structured context for the error (for example field-level validation errors). What it carries depends on the endpoint and platform.  **Meta ads refusals.** The ones customers hit most come back with their own `code` instead of `platform_api_error`, the field to fix in `param`, and `details.fix` ({ label, url }) pointing at the Meta page that resolves it:  - `ad_account_payment_required` - `ad_account_policy_not_accepted` - `meta_security_check_required` - `meta_action_blocked` - `whatsapp_number_not_linked` - `invalid_targeting`  Meta's own error stays in the message and in `platformError`.  **Private replies.** `privateReplyConsumed` appears on the private-reply endpoint's 400 when the comment's single reply is already spent. `privateReplyOutcome: \"unknown\"` appears on its 502 when Meta answered a server error and the reply may have been delivered.  **Google quota 429.** On a Google Ads or YouTube Analytics 429, `quotaExhausted: true` marks the failure as Google's own quota, not a Zernio rate limit, so you can keep calling other platforms instead of backing off everywhere. When Google names the scope, `quotaScope` is also set:  - `DEVELOPER`: the shared budget (the developer token for Google Ads, the Google Cloud project for YouTube Analytics). Every account on Zernio is affected and there is nothing to change on your side. - `ACCOUNT`: your own ad account (Google Ads only).  A Meta 429 carries neither field.  **Zernio Google Ads burst-limit 429.** Carries `budgetScope` instead, never `quotaExhausted`. These are Zernio's own limits, applied before the call reaches Google, and both clear within a minute. They are separate axes from `quotaScope`, not the same pool named twice.  - `account`: the limit of 15 requests per minute per connected Google Ads account. - `user`: the ceiling of 120 requests per minute per Zernio user across all their Google Ads accounts.  **Failed Meta ad create** (`POST /v1/ads/create`, `POST /v1/ads/boost`, `POST /v1/ads/ctwa`). Carries `stage` (where it failed), `adAccountId` (on which ad account) and `createdObjects` (every object this request had already created, with what cleanup did to it).  - `left_behind` objects still exist on the ad account (Meta refused the delete, typically on a held account, or the delete hit a network error). Delete them yourself or reuse them. - `unconfirmedWrite` is set when Meta answered a create with a 5xx or dropped the connection and Zernio could not confirm whether the object exists. Check that parent before creating it again.  **Ineligible ad account: 422 `ad_account_unusable`.** When Meta refuses a write because the ad account's status is ineligible to manage ads (Meta subcode 2490592 or 4841021, on the write itself or on a cleanup delete), any Meta ads write answers it.  That covers create, boost, CTWA, campaign / ad set / ad updates and status changes.  The message names the ad account when known, links Meta's fix (https://www.facebook.com/business/help/422289316306981), lists the objects left behind and ends with Meta's original error, which also stays verbatim in `platformError`.  Meta often reports the first failure under an unrelated code (e.g. 1487194 on the creative), so branch on `code`, not on `platformError`.  **Missing Advertise permission: 403 `insufficient_permissions`.** When the Facebook user behind the connection's token lacks the Advertise permission on the ad account, any Meta ads write answers it.  Triggers: Meta subcode 2490585, 2490591 or 4841020 on the write, or a code 200 refusal such as 1487194 whose cleanup deletes Meta refused with 2490591 or 4841020.  Meta may still accept the campaign and ad set and refuse only the ad. The message names the ad account, asks for the Advertise or Manage permission on it (or a token granted `ads_management`, by reconnecting) and lists the objects left behind.  It ends with Meta's `error_user_title`, `error_user_msg` and subcode; the raw error stays in `platformError`.
    pub fn new() -> ErrorResponseDetails {
        ErrorResponseDetails {
            stage: None,
            ad_account_id: None,
            created_objects: None,
            unconfirmed_write: None,
            quota_exhausted: None,
            quota_scope: None,
            budget_scope: None,
        }
    }
}
/// Meta ad create failures only. The step that failed:  - `media`: image/video download or upload. - `campaign` - `adset` - `creative` - `ad`: the ad POST itself, where Meta's code 31 / 3858385 hold and 100 / 1359188 payment rejections land. - `activation`: switching the created objects on. No longer returned: a refused switch to ACTIVE now answers 201 with an `activation_failed:` warning and the objects kept PAUSED. - `other`: a read or check before any write.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Stage {
    #[serde(rename = "media")]
    Media,
    #[serde(rename = "campaign")]
    Campaign,
    #[serde(rename = "adset")]
    Adset,
    #[serde(rename = "creative")]
    Creative,
    #[serde(rename = "ad")]
    Ad,
    #[serde(rename = "activation")]
    Activation,
    #[serde(rename = "other")]
    Other,
}

impl Default for Stage {
    fn default() -> Stage {
        Self::Media
    }
}
/// Google Ads and YouTube Analytics 429 only, when the scope is known. DEVELOPER is the shared budget (the developer token for Google Ads, the Google Cloud project for YouTube Analytics); ACCOUNT is your ad account (Google Ads only).
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum QuotaScope {
    #[serde(rename = "DEVELOPER")]
    Developer,
    #[serde(rename = "ACCOUNT")]
    Account,
}

impl Default for QuotaScope {
    fn default() -> QuotaScope {
        Self::Developer
    }
}
/// Zernio Google Ads burst-limit 429 only (never set alongside `quotaExhausted`). `account` is the limit of 15 requests per minute per connected Google Ads account; `user` is the ceiling of 120 requests per minute per Zernio user across all their Google Ads accounts. Both clear within a minute.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum BudgetScope {
    #[serde(rename = "account")]
    Account,
    #[serde(rename = "user")]
    User,
}

impl Default for BudgetScope {
    fn default() -> BudgetScope {
        Self::Account
    }
}