// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.ads.datamanager.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/duration.proto";

option csharp_namespace = "Google.Ads.DataManager.V1";
option go_package = "cloud.google.com/go/datamanager/apiv1/datamanagerpb;datamanagerpb";
option java_multiple_files = true;
option java_outer_classname = "UserListProto";
option java_package = "com.google.ads.datamanager.v1";
option php_namespace = "Google\\Ads\\DataManager\\V1";
option ruby_package = "Google::Ads::DataManager::V1";

// A user list resource.
message UserList {
  option (google.api.resource) = {
    type: "datamanager.googleapis.com/UserList"
    pattern: "accountTypes/{account_type}/accounts/{account}/userLists/{user_list}"
    plural: "userLists"
    singular: "userList"
  };

  // Status of the user list.
  enum MembershipStatus {
    // Not specified.
    MEMBERSHIP_STATUS_UNSPECIFIED = 0;

    // Open status - User list is accruing members and can be targeted to.
    OPEN = 1;

    // Closed status - No new members being added.
    CLOSED = 2;
  }

  // Indicates the reason why the user list was closed.
  // This enum is only used when a list is auto-closed by the system.
  enum ClosingReason {
    // Not specified.
    CLOSING_REASON_UNSPECIFIED = 0;

    // The user list was closed because it has not been used in targeting
    // recently. See https://support.google.com/google-ads/answer/2472738
    // for details.
    UNUSED = 1;
  }

  // Enum describing possible access reasons.
  enum AccessReason {
    // Not specified.
    ACCESS_REASON_UNSPECIFIED = 0;

    // The resource is owned by the user.
    OWNED = 1;

    // The resource is shared to the user.
    SHARED = 2;

    // The resource is licensed to the user.
    LICENSED = 3;

    // The user subscribed to the resource.
    SUBSCRIBED = 4;

    // The resource is accessible to the user.
    AFFILIATED = 5;
  }

  // Indicates if this client still has access to the list.
  enum AccessStatus {
    // Not specified.
    ACCESS_STATUS_UNSPECIFIED = 0;

    // The access is enabled.
    ENABLED = 1;

    // The access is disabled.
    DISABLED = 2;
  }

  // Identifier. The resource name of the user list.
  // Format:
  // accountTypes/{account_type}/accounts/{account}/userLists/{user_list}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. The unique ID of the user list.
  int64 id = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. An option that indicates if a user may edit a list.
  bool read_only = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The display name of the user list.
  optional string display_name = 4 [(google.api.field_behavior) = REQUIRED];

  // Optional. A description of the user list.
  optional string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Membership status of this user list.
  optional MembershipStatus membership_status = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. An ID from external system. It is used by user list sellers to
  // correlate IDs on their systems.
  optional string integration_code = 7 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The duration a user remains in the user list.
  // Valid durations are exact multiples of 24 hours (86400 seconds).
  // Providing a value that is not an exact multiple of 24 hours will result in
  // an INVALID_ARGUMENT error.
  google.protobuf.Duration membership_duration = 8
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. The reason why this user list membership status is closed.
  optional ClosingReason closing_reason = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The reason this account has been granted access to the list.
  AccessReason access_reason = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Indicates if this share is still enabled. When a user list is
  // shared with the account this field is set to `ENABLED`. Later the user list
  // owner can decide to revoke the share and make it `DISABLED`.
  optional AccessStatus account_access_status = 11
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. Estimated number of members in this user list in different
  // target networks.
  SizeInfo size_info = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Eligibility information for different target networks.
  TargetNetworkInfo target_network_info = 13
      [(google.api.field_behavior) = OPTIONAL];

  // Additional information about the user list.
  oneof user_list_info {
    // Optional. Represents a user list that is populated by user ingested data.
    IngestedUserListInfo ingested_user_list_info = 14
        [(google.api.field_behavior) = OPTIONAL];
  }
}

// Estimated number of members in this user list in different target networks.
message SizeInfo {
  // Output only. Estimated number of members in this user list, on the Google
  // Display Network.
  int64 display_network_members_count = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Estimated number of members in this user list in the
  // google.com domain. These are the members available for targeting in Search
  // campaigns.
  int64 search_network_members_count = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Estimated number of members in this user list on YouTube.
  int64 youtube_members_count = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Estimated number of members in this user list on Gmail.
  int64 gmail_members_count = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Eligibility information for different target networks.
message TargetNetworkInfo {
  // Output only. Indicates this user list is eligible for Google Display
  // Network.
  bool eligible_for_display = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Indicates if this user list is eligible for Google Search
  // Network.
  optional bool eligible_for_search = 2
      [(google.api.field_behavior) = OPTIONAL];
}

// Represents a user list that is populated by user provided data.
message IngestedUserListInfo {
  // Enum containing the possible upload key types of a user list.
  enum UploadKeyType {
    // Not specified.
    UPLOAD_KEY_TYPE_UNSPECIFIED = 0;

    // Customer info such as email address, phone number or physical address.
    CONTACT_ID = 1;

    // Mobile advertising ids.
    MOBILE_ID = 2;

    // Third party provided user ids.
    USER_ID = 3;

    // Publisher advertiser identity reconciliation ids.
    PAIR_ID = 4;

    // Data Management Platform IDs:
    // - Google User ID
    // - Partner Provided ID
    // - Publisher Provided ID
    // - iOS IDFA
    // - Android advertising ID
    // - Roku ID
    // - Amazon Fire TV ID
    // - Xbox or Microsoft ID
    PSEUDONYMOUS_ID = 5;
  }

  // Required. Immutable. Upload key types of this user list.
  repeated UploadKeyType upload_key_types = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Optional. Additional information when `CONTACT_ID` is one of the
  // `upload_key_types`.
  ContactIdInfo contact_id_info = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Additional information when `MOBILE_ID` is one of the
  // `upload_key_types`.
  MobileIdInfo mobile_id_info = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Additional information when `USER_ID` is one of the
  // `upload_key_types`.
  UserIdInfo user_id_info = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Additional information when `PAIR_ID` is one of the
  // `upload_key_types`.
  //
  // This feature is only available to data partners.
  PairIdInfo pair_id_info = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Additional information for `PSEUDONYMOUS_ID` is one of the
  // `upload_key_types`.
  PseudonymousIdInfo pseudonymous_id_info = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Additional information for partner audiences.
  //
  // This feature is only available to data partners.
  PartnerAudienceInfo partner_audience_info = 7
      [(google.api.field_behavior) = OPTIONAL];
}

// Additional information when `CONTACT_ID` is one of the `upload_key_types`.
message ContactIdInfo {
  // Optional. Immutable. Source of the upload data
  optional DataSourceType data_source_type = 1 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Output only. Match rate for customer match user lists.
  int32 match_rate_percentage = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Additional information when `MOBILE_ID` is one of the `upload_key_types`.
message MobileIdInfo {
  // Key space for mobile ID.
  enum KeySpace {
    // Not specified.
    KEY_SPACE_UNSPECIFIED = 0;

    // The iOS keyspace.
    IOS = 1;

    // The Android keyspace.
    ANDROID = 2;
  }

  // Optional. Immutable. Source of the upload data.
  optional DataSourceType data_source_type = 1 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Required. Immutable. The key space of mobile IDs.
  optional KeySpace key_space = 2 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Required. Immutable. A string that uniquely identifies a mobile application
  // from which the data was collected.
  optional string app_id = 3 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];
}

// Additional information when `USER_ID` is one of the `upload_key_types`.
message UserIdInfo {
  // Optional. Immutable. Source of the upload data.
  optional DataSourceType data_source_type = 1 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.field_behavior) = IMMUTABLE
  ];
}

// Additional information when `PAIR_ID` is one of the `upload_key_types`.
//
// This feature is only available to data partners.
message PairIdInfo {
  // Required. Immutable. Identifies the publisher that the Publisher Advertiser
  // Identity Reconciliation user list is reconciled with. This field is
  // provided by the cleanroom provider and is only unique in the scope of that
  // cleanroom. This cannot be used as a global identifier across multiple
  // cleanrooms.
  optional int64 publisher_id = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Required. Descriptive name of the publisher to be displayed in the UI for a
  // better targeting experience.
  optional string publisher_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. This field denotes the percentage of membership match of this
  // user list with the corresponding publisher's first party data. Must be
  // between 0 and 100 inclusive.
  optional int32 match_rate_percentage = 3
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The count of the advertiser's first party data records that have
  // been uploaded to a clean room provider. This does not signify the size of a
  // PAIR user list.
  optional int64 advertiser_identifier_count = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Required. Immutable. Identifies a unique advertiser to publisher
  // relationship with one clean room provider or across multiple clean room
  // providers.
  optional string clean_room_identifier = 5 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];
}

// Additional information for partner audiences.
//
// This feature is only available to data partners.
message PartnerAudienceInfo {
  // Partner audience source.
  enum PartnerAudienceSource {
    // Not specified.
    PARTNER_AUDIENCE_SOURCE_UNSPECIFIED = 0;

    // Partner Audience source is commerce audience.
    COMMERCE_AUDIENCE = 1;

    // Partner Audience source is linear TV audience.
    LINEAR_TV_AUDIENCE = 2;

    // Partner Audience source is agency/provider audience.
    AGENCY_PROVIDER_AUDIENCE = 3;
  }

  // Required. Immutable. The source of the partner audience.
  optional PartnerAudienceSource partner_audience_source = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Optional. The commerce partner name.
  // Only allowed if `partner_audience_source` is `COMMERCE_AUDIENCE`.
  optional string commerce_partner = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Additional information when `PSEUDONYMOUS_ID` is one of the
// `upload_key_types`.
message PseudonymousIdInfo {
  // Sync status of the user list.
  enum SyncStatus {
    // Not specified.
    SYNC_STATUS_UNSPECIFIED = 0;

    // The user list has been created as a placeholder. List contents and/or
    // metadata are still being synced. The user list is not ready for use.
    CREATED = 1;

    // The user list is ready for use. Contents and cookies have been synced
    // correctly.
    READY_FOR_USE = 2;

    // An error has occurred syncing user list contents and/or metadata. The
    // user list cannot be used.
    FAILED = 3;
  }

  // Output only. Sync status of the user list.
  optional SyncStatus sync_status = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Immutable. The number of billable records (e.g. uploaded or
  // matched).
  optional int64 billable_record_count = 2 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.field_behavior) = IMMUTABLE
  ];
}

// Indicates source of upload data.
enum DataSourceType {
  // Not specified.
  DATA_SOURCE_TYPE_UNSPECIFIED = 0;

  // The uploaded data is first-party data.
  DATA_SOURCE_TYPE_FIRST_PARTY = 1;

  // The uploaded data is from a third-party credit bureau.
  DATA_SOURCE_TYPE_THIRD_PARTY_CREDIT_BUREAU = 2;

  // The uploaded data is from a third-party voter file.
  DATA_SOURCE_TYPE_THIRD_PARTY_VOTER_FILE = 3;

  // The uploaded data is third party partner data.
  DATA_SOURCE_TYPE_THIRD_PARTY_PARTNER_DATA = 4;
}
