import {z} from 'zod' export type GetApiAdsConnectionIdCampaignArgs = {limit?: number | undefined, offset?: number | undefined, updated_gte?: string | undefined, sort?: string | undefined, order?: string | undefined, query?: string | undefined, org_id?: string | undefined, start_gte?: string | undefined, end_lt?: string | undefined, status?: string | undefined, goal?: string | undefined, effective_status?: string | undefined, fields?: (Array<'id' | 'created_at' | 'updated_at' | 'name' | 'organization_id' | 'status' | 'effective_status' | 'start_at' | 'end_at' | 'budget_amount' | 'budget_period' | 'budget_unit' | 'total_spend_amount' | 'targeting' | 'goal' | 'planned_spend_amount' | 'frequency_cap' | 'advertising_channel_type' | 'campaign_budget_identifier' | 'currency' | 'category' | 'has_eu_political_ads' | 'labels' | 'kpi' | 'metadata' | 'raw'>) | undefined, raw?: string | undefined, connection_id: string}; export type GetApiAdsConnectionIdCampaignOptions = {baseUrl?: string | undefined, jwt?: string | undefined, fetch?: typeof fetch | undefined}; export const targetRef = z.object({id: z.string().optional(), name: z.string().optional()}); export const propertyAdsCampaignTargetingGeographicCountries = z.array(targetRef); export const propertyAdsCampaignTargetingGeographicRegions = z.array(targetRef); export const cityTarget = z.object({id: z.string(), name: z.string().optional(), radius: z.number().optional(), radius_unit: z.enum(["MILES", "KILOMETERS"]).optional()}); export const propertyAdsCampaignTargetingGeographicCities = z.array(cityTarget); export const propertyAdsCampaignTargetingGeographicPostalCodes = z.array(targetRef); export const propertyAdsCampaignTargetingGeographicUsDmas = z.array(targetRef); export const propertyAdsCampaignTargetingGeographicExcludedCountries = z.array(targetRef); export const propertyAdsCampaignTargetingGeographicExcludedRegions = z.array(targetRef); export const propertyAdsCampaignTargetingGeographicExcludedCities = z.array(cityTarget); export const propertyAdsCampaignTargetingGeographicExcludedPostalCodes = z.array(targetRef); export const propertyAdsCampaignTargetingGeographicExcludedUsDmas = z.array(targetRef); export const propertyAdsCampaignTargetingGeographicLocationTypes = z.array(z.enum(["HOME", "RECENT", "TRAVEL"])); export const propertyAdsCampaignTargetingGeographic = z.object({countries: propertyAdsCampaignTargetingGeographicCountries.optional(), regions: propertyAdsCampaignTargetingGeographicRegions.optional(), cities: propertyAdsCampaignTargetingGeographicCities.optional(), postal_codes: propertyAdsCampaignTargetingGeographicPostalCodes.optional(), us_dmas: propertyAdsCampaignTargetingGeographicUsDmas.optional(), excluded_countries: propertyAdsCampaignTargetingGeographicExcludedCountries.optional(), excluded_regions: propertyAdsCampaignTargetingGeographicExcludedRegions.optional(), excluded_cities: propertyAdsCampaignTargetingGeographicExcludedCities.optional(), excluded_postal_codes: propertyAdsCampaignTargetingGeographicExcludedPostalCodes.optional(), excluded_us_dmas: propertyAdsCampaignTargetingGeographicExcludedUsDmas.optional(), location_types: propertyAdsCampaignTargetingGeographicLocationTypes.optional(), presence_type: z.enum(["PRESENCE", "PRESENCE_OR_INTEREST"]).optional()}); export const propertyAdsCampaignTargetingDemographic = z.object({age_min: z.number().optional(), age_max: z.number().optional(), male: z.boolean().optional(), female: z.boolean().optional()}); export const propertyAdsCampaignTargetingAudienceCustomAudiences = z.array(targetRef); export const propertyAdsCampaignTargetingAudienceExcludedCustomAudiences = z.array(targetRef); export const lookalikeAudience = z.object({id: z.string(), name: z.string().optional(), similarity: z.number().optional(), source_audience_id: z.string().optional()}); export const propertyAdsCampaignTargetingAudienceLookalikeAudiences = z.array(lookalikeAudience); export const propertyAdsCampaignTargetingAudienceInterests = z.array(targetRef); export const propertyAdsCampaignTargetingAudienceExcludedInterests = z.array(targetRef); export const propertyAdsCampaignTargetingAudienceBehaviors = z.array(targetRef); export const propertyAdsCampaignTargetingAudienceExcludedBehaviors = z.array(targetRef); export const propertyAudienceCombinationInterests = z.array(targetRef); export const propertyAudienceCombinationBehaviors = z.array(targetRef); export const propertyAudienceCombinationReferences = z.array(targetRef); export const propertyAudienceCombinationLifeEvents = z.array(targetRef); export const audienceCombination = z.object({interests: propertyAudienceCombinationInterests.optional(), behaviors: propertyAudienceCombinationBehaviors.optional(), references: propertyAudienceCombinationReferences.optional(), life_events: propertyAudienceCombinationLifeEvents.optional()}); export const propertyAdsCampaignTargetingAudienceCombinationSpec = z.array(audienceCombination); export const propertyAdsCampaignTargetingAudience = z.object({custom_audiences: propertyAdsCampaignTargetingAudienceCustomAudiences.optional(), excluded_custom_audiences: propertyAdsCampaignTargetingAudienceExcludedCustomAudiences.optional(), lookalike_audiences: propertyAdsCampaignTargetingAudienceLookalikeAudiences.optional(), interests: propertyAdsCampaignTargetingAudienceInterests.optional(), excluded_interests: propertyAdsCampaignTargetingAudienceExcludedInterests.optional(), behaviors: propertyAdsCampaignTargetingAudienceBehaviors.optional(), excluded_behaviors: propertyAdsCampaignTargetingAudienceExcludedBehaviors.optional(), combination_spec: propertyAdsCampaignTargetingAudienceCombinationSpec.optional()}); export const propertyAdsCampaignTargetingPlacementPlatforms = z.array(z.string()); export const propertyAdsCampaignTargetingPlacementFacebookPositions = z.array(z.string()); export const propertyAdsCampaignTargetingPlacementInstagramPositions = z.array(z.string()); export const propertyAdsCampaignTargetingPlacementMessengerPositions = z.array(z.string()); export const propertyAdsCampaignTargetingPlacementAudienceNetworkPositions = z.array(z.string()); export const propertyAdsCampaignTargetingPlacement = z.object({platforms: propertyAdsCampaignTargetingPlacementPlatforms.optional(), facebook_positions: propertyAdsCampaignTargetingPlacementFacebookPositions.optional(), instagram_positions: propertyAdsCampaignTargetingPlacementInstagramPositions.optional(), messenger_positions: propertyAdsCampaignTargetingPlacementMessengerPositions.optional(), audience_network_positions: propertyAdsCampaignTargetingPlacementAudienceNetworkPositions.optional()}); export const propertyAdsCampaignTargetingDeviceTypes = z.array(targetRef); export const propertyAdsCampaignTargetingDeviceUserDevice = z.array(targetRef); export const propertyAdsCampaignTargetingDeviceUserOs = z.array(targetRef); export const propertyAdsCampaignTargetingDeviceCarriers = z.array(targetRef); export const propertyAdsCampaignTargetingDevice = z.object({types: propertyAdsCampaignTargetingDeviceTypes.optional(), user_device: propertyAdsCampaignTargetingDeviceUserDevice.optional(), user_os: propertyAdsCampaignTargetingDeviceUserOs.optional(), carriers: propertyAdsCampaignTargetingDeviceCarriers.optional()}); export const propertyAdsCampaignTargetingLanguage = z.array(targetRef); export const adsKeyword = z.object({text: z.string(), match_type: z.enum(["BROAD", "PHRASE", "EXACT"]).optional()}); export const propertyAdsCampaignTargetingContentKeywords = z.array(adsKeyword); export const propertyAdsCampaignTargetingContentExcludedKeywords = z.array(adsKeyword); export const propertyAdsCampaignTargetingContentTopics = z.array(targetRef); export const propertyAdsCampaignTargetingContentExcludedTopics = z.array(targetRef); export const propertyAdsCampaignTargetingContentUrls = z.array(z.string()); export const propertyAdsCampaignTargetingContentExcludedUrls = z.array(z.string()); export const propertyAdsCampaignTargetingContentVideoYoutubeVideos = z.array(z.string()); export const propertyAdsCampaignTargetingContentVideoExcludedYoutubeVideos = z.array(z.string()); export const propertyAdsCampaignTargetingContentVideoYoutubeChannels = z.array(z.string()); export const propertyAdsCampaignTargetingContentVideoExcludedYoutubeChannels = z.array(z.string()); export const propertyAdsCampaignTargetingContentVideoPositions = z.array(z.enum(["PREROLL", "MIDROLL", "POSTROLL", "INSTREAM", "OUTSTREAM"])); export const propertyAdsCampaignTargetingContentVideoPlayerSizes = z.array(z.enum(["SMALL", "LARGE", "HD"])); export const propertyAdsCampaignTargetingContentVideoDurations = z.array(z.enum(["SHORT", "MEDIUM", "LONG"])); export const propertyAdsCampaignTargetingContentVideo = z.object({youtube_videos: propertyAdsCampaignTargetingContentVideoYoutubeVideos.optional(), excluded_youtube_videos: propertyAdsCampaignTargetingContentVideoExcludedYoutubeVideos.optional(), youtube_channels: propertyAdsCampaignTargetingContentVideoYoutubeChannels.optional(), excluded_youtube_channels: propertyAdsCampaignTargetingContentVideoExcludedYoutubeChannels.optional(), positions: propertyAdsCampaignTargetingContentVideoPositions.optional(), player_sizes: propertyAdsCampaignTargetingContentVideoPlayerSizes.optional(), durations: propertyAdsCampaignTargetingContentVideoDurations.optional()}); export const propertyAdsCampaignTargetingContent = z.object({keywords: propertyAdsCampaignTargetingContentKeywords.optional(), excluded_keywords: propertyAdsCampaignTargetingContentExcludedKeywords.optional(), topics: propertyAdsCampaignTargetingContentTopics.optional(), excluded_topics: propertyAdsCampaignTargetingContentExcludedTopics.optional(), urls: propertyAdsCampaignTargetingContentUrls.optional(), excluded_urls: propertyAdsCampaignTargetingContentExcludedUrls.optional(), video: propertyAdsCampaignTargetingContentVideo.optional()}); export const propertyAdsCampaignTargetingBrandSafetyExcludedPublisherCategories = z.array(z.string()); export const propertyAdsCampaignTargetingBrandSafetyExcludedContentLabels = z.array(z.string()); export const propertyAdsCampaignTargetingBrandSafetyBrandSafetyContentFilterLevels = z.array(z.string()); export const propertyAdsCampaignTargetingBrandSafetyPublisherVisibilityCategories = z.array(z.enum(["limited", "standard", "expanded"])); export const propertyAdsCampaignTargetingBrandSafetyBlockListIds = z.array(z.string()); export const propertyAdsCampaignTargetingBrandSafety = z.object({excluded_publisher_categories: propertyAdsCampaignTargetingBrandSafetyExcludedPublisherCategories.optional(), excluded_content_labels: propertyAdsCampaignTargetingBrandSafetyExcludedContentLabels.optional(), brand_safety_content_filter_levels: propertyAdsCampaignTargetingBrandSafetyBrandSafetyContentFilterLevels.optional(), publisher_visibility_categories: propertyAdsCampaignTargetingBrandSafetyPublisherVisibilityCategories.optional(), block_list_ids: propertyAdsCampaignTargetingBrandSafetyBlockListIds.optional()}); export const adSchedule = z.object({day_of_week: z.enum(["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"]), start_hour: z.number(), start_minute: z.number().optional(), end_hour: z.number(), end_minute: z.number().optional(), bid_modifier: z.number().optional()}); export const propertyAdsCampaignTargetingSchedule = z.array(adSchedule); export const propertyAdsCampaignTargetingOptimization = z.object({mode: z.enum(["TARGETING", "OBSERVATION"]).optional(), advantage_audience: z.boolean().optional(), advantage_placements: z.boolean().optional(), targeting_optimization_expansion_all: z.boolean().optional()}); export const propertyAdsCampaignTargeting = z.object({geographic: propertyAdsCampaignTargetingGeographic.optional(), demographic: propertyAdsCampaignTargetingDemographic.optional(), audience: propertyAdsCampaignTargetingAudience.optional(), placement: propertyAdsCampaignTargetingPlacement.optional(), device: propertyAdsCampaignTargetingDevice.optional(), language: propertyAdsCampaignTargetingLanguage.optional(), content: propertyAdsCampaignTargetingContent.optional(), brand_safety: propertyAdsCampaignTargetingBrandSafety.optional(), schedule: propertyAdsCampaignTargetingSchedule.optional(), optimization: propertyAdsCampaignTargetingOptimization.optional()}); export const propertyAdsCampaignFrequencyCap = z.object({is_unlimited: z.boolean().optional(), time_unit: z.enum(["UNSPECIFIED", "LIFETIME", "MONTHS", "WEEKS", "DAYS", "HOURS", "MINUTES"]).optional(), time_unit_count: z.number().optional(), max_impressions: z.number().optional(), max_views: z.number().optional()}); export const propertyAdsCampaignLabels = z.array(z.string()); export const propertyAdsCampaignKpi = z.object({type: z.enum(["UNSPECIFIED", "CPM", "CPC", "CPA", "CTR", "VIEWABILITY", "CPIAVC", "CPE", "CPV", "CLICK_CVR", "IMPRESSION_CVR", "VCPM", "VTR", "AUDIO_COMPLETION_RATE", "VIDEO_COMPLETION_RATE", "CPCL", "CPCV", "TOS10", "MAXIMIZE_PACING", "CUSTOM_IMPRESSION_VALUE_OVER_COST", "OTHER"]).optional(), amount: z.number().optional(), percentage: z.number().optional(), string_value: z.string().optional(), algorithm_id: z.string().optional()}); export const adsMetadata = z.object({id: z.string().optional(), slug: z.string().optional(), value: z.union([z.record(z.string(), z.unknown()), z.string(), z.number(), z.boolean(), z.array(z.union([z.object({}), z.string(), z.number(), z.boolean()]))]).optional(), namespace: z.string().optional(), format: z.enum(["TEXT", "NUMBER", "DATE", "BOOLEAN", "FILE", "TEXTAREA", "SINGLE_SELECT", "MULTIPLE_SELECT", "MEASUREMENT", "PRICE", "YES_NO", "CURRENCY", "URL"]).optional(), extra_data: z.union([z.record(z.string(), z.unknown()), z.string(), z.number(), z.boolean(), z.array(z.union([z.object({}), z.string(), z.number(), z.boolean()]))]).optional()}); export const propertyAdsCampaignMetadata = z.array(adsMetadata); export const adsCampaign = z.object({id: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), name: z.string().optional(), organization_id: z.string().optional(), status: z.enum(["UNSPECIFIED", "ACTIVE", "PAUSED", "ARCHIVED", "DRAFT", "SCHEDULED_FOR_DELETION", "PROCESSING", "PROCESSING_FAILED"]).optional(), effective_status: z.enum(["UNSPECIFIED", "SERVING", "LIMITED", "LEARNING", "PAUSED", "PENDING", "ENDED", "MISCONFIGURED", "NOT_ELIGIBLE", "ARCHIVED", "REMOVED"]).optional(), start_at: z.string().optional(), end_at: z.string().optional(), budget_amount: z.number().optional(), budget_period: z.enum(["DAILY", "MONTHLY", "TOTAL", "LIFETIME"]).optional(), budget_unit: z.enum(["UNSPECIFIED", "CURRENCY", "IMPRESSIONS"]).optional(), total_spend_amount: z.number().optional(), targeting: propertyAdsCampaignTargeting.optional(), goal: z.enum(["UNSPECIFIED", "BRAND_AWARENESS", "ENGAGEMENT", "REACH", "WEBSITE_TRAFFIC", "LEADS", "SALES", "APP_PROMOTION"]).optional(), planned_spend_amount: z.number().optional(), frequency_cap: propertyAdsCampaignFrequencyCap.optional(), advertising_channel_type: z.enum(["TEXT", "IMAGE", "VIDEO", "RESPONSIVE", "SHOPPING", "APP", "CALL", "CAROUSEL", "SOCIAL", "DISPLAY", "SEARCH", "AUDIO", "YOUTUBE", "NATIVE", "CTV", "DOOH", "PERFORMANCE_MAX"]).optional(), campaign_budget_identifier: z.string().optional(), currency: z.string().optional(), category: z.string().optional(), has_eu_political_ads: z.boolean().optional(), labels: propertyAdsCampaignLabels.optional(), kpi: propertyAdsCampaignKpi.optional(), metadata: propertyAdsCampaignMetadata.optional(), raw: z.record(z.string(), z.unknown()).optional()}); export const adsCampaigns = z.array(adsCampaign); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * List all campaigns * * GET /ads/{connection_id}/campaign */ export const getApiAdsConnectionIdCampaign = async (args: GetApiAdsConnectionIdCampaignArgs, options?: GetApiAdsConnectionIdCampaignOptions) => { const {baseUrl = "https://api.unified.to", fetch: fetchFn = fetch, jwt} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.limit != null) query.append("limit", String(args.limit)) if (args.offset != null) query.append("offset", String(args.offset)) if (args.updated_gte != null) query.append("updated_gte", String(args.updated_gte)) if (args.sort != null) query.append("sort", String(args.sort)) if (args.order != null) query.append("order", String(args.order)) if (args.query != null) query.append("query", String(args.query)) if (args.org_id != null) query.append("org_id", String(args.org_id)) if (args.start_gte != null) query.append("start_gte", String(args.start_gte)) if (args.end_lt != null) query.append("end_lt", String(args.end_lt)) if (args.status != null) query.append("status", String(args.status)) if (args.goal != null) query.append("goal", String(args.goal)) if (args.effective_status != null) query.append("effective_status", String(args.effective_status)) for (const item of args.fields ?? []) query.append("fields", String(item)) if (args.raw != null) query.append("raw", String(args.raw)) if (jwt !== undefined) headers.set("authorization", jwt) const url = `${baseUrl.replace(/\/+$/, '')}/ads/${encodeURIComponent(String(args.connection_id))}/campaign${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(adsCampaigns, await res.json()) };