{
  "endpoint": "NotificationHandler",
  "preferredHttpPath": "n",
  "alternateHttpPaths": [
    "HttpNotification"
  ],
  "summary": "Notification-related APIs.",
  "description": "Users can subscribe to notifications of various types using this endpoint.\n            Email notifications can happen immediately, in a daily digest, or in a weekly digest.\n            Links in emails contain URLS that can be used to modify email subscriptions without logging in.\n            In-app notifications are also supported and the information needed to hook those up is also configured and provided by this endpoint.",
  "apis": [
    {
      "name": "Unsubscribe",
      "httpMethod": "GET",
      "httpPathRegex": "^/unsubscribe/(?<signature>[^?/&]+)",
      "subPathPattern": "/unsubscribe/{signature}",
      "summary": "Unsubscribes the specified user from email notifications.",
      "parameters": [
        {
          "name": "signature",
          "required": true,
          "type": "SignedSecurityToken",
          "description": "The <see cref=\"T:AmbientServices.SignedSecurityToken\" /> to be sure the link used by caller was generated by PicMe."
        }
      ],
      "return": {
        "type": "UnsubscribeResponse",
        "description": "A <see cref=\"T:PicMeApi.UnsubscribeResponse\" /> containing the response."
      }
    },
    {
      "name": "TrackOpen",
      "httpMethod": "GET",
      "httpPathRegex": "^/ni/(?<signature>[^?/&]+)",
      "subPathPattern": "/ni/{signature}",
      "summary": "Tracks a user opening an email notification.",
      "parameters": [
        {
          "name": "signature",
          "required": true,
          "type": "SignedSecurityToken",
          "description": "The <see cref=\"T:AmbientServices.SignedSecurityToken\" /> to be sure the link used by caller was generated by PicMe."
        }
      ],
      "return": {
        "type": "BufferedRawLambdaResponse",
        "description": "A <see cref=\"T:AmbientServices.BufferedRawLambdaResponse\" /> containing the response."
      }
    },
    {
      "name": "UpdateFirebaseCloudMessagingProjectConfig",
      "httpMethod": "PUT",
      "httpPathRegex": "^/config/firebase-project",
      "subPathPattern": "/config/firebase-project",
      "summary": "Updates the Firebase Cloud Messaging project configuration.",
      "parameters": [
        {
          "name": "config",
          "required": true,
          "type": "FirebaseCloudMessagingProjectConfig",
          "description": "The <see cref=\"T:AmbientServices.FirebaseCloudMessagingProjectConfig\" /> to store."
        }
      ],
      "return": {
        "type": "UpdateFirebaseCloudMessagingProjectConfigResponse",
        "description": "A <see cref=\"T:PicMeApi.UpdateFirebaseCloudMessagingProjectConfigResponse\" /> containing the response"
      }
    },
    {
      "name": "GetFirebaseCloudMessagingProjectConfig",
      "httpMethod": "GET",
      "httpPathRegex": "^/config/firebase-project",
      "subPathPattern": "/config/firebase-project",
      "summary": "Gets the Firebase Cloud Messaging projecct configuration needed by the client.",
      "parameters": [],
      "return": {
        "type": "GetFirebaseCloudMessagingProjectConfigResponse",
        "description": "A <see cref=\"T:PicMeApi.GetFirebaseCloudMessagingProjectConfigResponse\" /> containing the response"
      }
    },
    {
      "name": "SendTestPushNotification",
      "httpMethod": "POST",
      "httpPathRegex": "^/test-push-notification",
      "subPathPattern": "/test-push-notification",
      "summary": "Sends a test push notification to all the authenticated user's registered devices.",
      "parameters": [
        {
          "name": "collectionId",
          "required": true,
          "type": "CollectionId",
          "description": "The <see cref=\"T:PicMeModel.CollectionId\" /> to use for the notification message."
        },
        {
          "name": "collectionCommentCount",
          "required": false,
          "type": "Int32",
          "description": "The number of comments on the collection."
        },
        {
          "name": "uploadId",
          "required": false,
          "type": "UploadId?",
          "description": "The <see cref=\"T:PicMeModel.UploadId\" /> for the upload (if an upload notification is desired)."
        },
        {
          "name": "uploadCommentCount",
          "required": false,
          "type": "Int32",
          "description": "The number of comments on the specified upload."
        },
        {
          "name": "uploadReactionCount",
          "required": false,
          "type": "Int32",
          "description": "The number of reactions on the specified upload."
        }
      ],
      "return": {
        "type": "SendTestNotificationResponse",
        "description": "A <see cref=\"T:PicMeApi.SendTestNotificationResponse\" /> containing the response"
      }
    },
    {
      "name": "PutPushNotificationSubscriptionConfigurations",
      "httpMethod": "PUT",
      "httpPathRegex": "^/push-notification",
      "subPathPattern": "/push-notification",
      "summary": "Sets one or more push notification subscription configurations.",
      "parameters": [
        {
          "name": "subscriptions",
          "required": true,
          "type": "PushNotificationSubscription[]",
          "description": "An array of <see cref=\"T:PicMeModel.PushNotificationSubscription\" /> to set."
        }
      ],
      "return": {
        "type": "PutPushNotificationSubscriptionConfigurationsResponse",
        "description": "A <see cref=\"T:PicMeApi.PutPushNotificationSubscriptionConfigurationsResponse\" /> containing the response."
      }
    },
    {
      "name": "ListPushNotificationSubscriptionConfigurations",
      "httpMethod": "GET",
      "httpPathRegex": "^/push-notification",
      "subPathPattern": "/push-notification",
      "summary": "Lists the user's push notification subscription configurations.",
      "parameters": [],
      "return": {
        "type": "ListPushNotificationSubscriptionConfigurationsResponse",
        "description": "A <see cref=\"T:PicMeApi.ListPushNotificationSubscriptionConfigurationsResponse\" /> containing the response."
      }
    },
    {
      "name": "GetUserNotificationSummaryByRange",
      "httpMethod": "GET",
      "httpPathRegex": "^/summary-range",
      "subPathPattern": "/summary-range",
      "summary": "Gets a summary of the ambient user's notification events for the specified time range.",
      "parameters": [
        {
          "name": "startTime",
          "required": true,
          "type": "DateTime",
          "description": "The minimum <see cref=\"T:System.DateTime\" /> whose notification events are to be retrieved."
        },
        {
          "name": "endTime",
          "required": true,
          "type": "DateTime",
          "description": "The maximum <see cref=\"T:System.DateTime\" /> whose notification events are to be retrieved."
        },
        {
          "name": "collectionId",
          "required": false,
          "type": "CollectionId?",
          "description": "An optional <see cref=\"T:PicMeModel.CollectionId\" /> to restrict the listed notifications to the specified collection."
        }
      ],
      "return": {
        "type": "GetUserNotificationSummaryResponse",
        "description": "A <see cref=\"T:PicMeApi.GetUserNotificationSummaryResponse\" /> containing the response"
      }
    },
    {
      "name": "MarkNotificationSummaryRead",
      "httpMethod": "PUT",
      "httpPathRegex": "^/summary/read",
      "subPathPattern": "/summary/read",
      "summary": "Marks the specified notification event as read.",
      "parameters": [
        {
          "name": "date",
          "required": true,
          "type": "DateOnly",
          "description": "The <see cref=\"T:System.DateOnly\" /> whose notification events are to be retrieved."
        },
        {
          "name": "scope",
          "required": true,
          "type": "DataScope",
          "description": "The <see cref=\"T:AmbientServices.DataScope\" /> for the event, often a collecction scope."
        },
        {
          "name": "targetEntityTypeId",
          "required": true,
          "type": "RecordTypeId",
          "description": "The <see cref=\"T:AmbientServices.RecordTypeId\" /> for the target entity."
        },
        {
          "name": "targetEntityId",
          "required": true,
          "type": "String",
          "description": "The ID of the event entity."
        },
        {
          "name": "eventType",
          "required": true,
          "type": "NotificationDigestEventType",
          "description": "The <see cref=\"T:PicMeModel.NotificationDigestEventType\" /> indication what type of event happened."
        }
      ],
      "return": {
        "type": "MarkNotificationSummaryReadResponse",
        "description": "A <see cref=\"T:PicMeApi.MarkNotificationSummaryReadResponse\" /> containing the response"
      }
    },
    {
      "name": "RegisterFirebaseDevice",
      "httpMethod": "PUT",
      "httpPathRegex": "^/fbd/register",
      "subPathPattern": "/fbd/register",
      "summary": "Registers a firebase device for the currently-authenticated user.\n            See <see cref=\"M:PicMeApi.NotificationApis.DeregisterFirebaseDevice(AmbientServices.Auth,PicMeApi.AuthData,System.String)\" /> for deregistration.",
      "parameters": [
        {
          "name": "firebaseDeviceId",
          "required": true,
          "type": "String",
          "description": "A string containing the firebase device ID to be attached to the authenticated user's account."
        }
      ],
      "return": {
        "type": "RegisterFirebaseDeviceResponse",
        "description": "A <see cref=\"T:PicMeApi.RegisterFirebaseDeviceResponse\" /> containing the response."
      }
    },
    {
      "name": "DeregisterFirebaseDevice",
      "httpMethod": "DELETE",
      "httpPathRegex": "^/fbd/register",
      "subPathPattern": "/fbd/register",
      "summary": "Deregisters a firebase device for the currently-authenticated user.\n            The device should have been previously registered using <see cref=\"M:PicMeApi.NotificationApis.RegisterFirebaseDevice(AmbientServices.Auth,PicMeApi.AuthData,System.String)\" />, but if it hasn't no error is returned, as this function is idempotent.",
      "parameters": [
        {
          "name": "firebaseDeviceId",
          "required": true,
          "type": "String",
          "description": "A string containing the firebase device ID to be attached to the authenticated user's account."
        }
      ],
      "return": {
        "type": "DeregisterFirebaseDeviceResponse",
        "description": "A <see cref=\"T:PicMeApi.DeregisterFirebaseDeviceResponse\" /> containing the response."
      }
    },
    {
      "name": "ListRegisteredFirebaseDevices",
      "httpMethod": "GET",
      "httpPathRegex": "^/fbd/register",
      "subPathPattern": "/fbd/register",
      "summary": "Lists the users registered firebase devices.\n            The devices have been previously registered using <see cref=\"M:PicMeApi.NotificationApis.RegisterFirebaseDevice(AmbientServices.Auth,PicMeApi.AuthData,System.String)\" />, but haven't been\n            deregistered using <see cref=\"M:PicMeApi.NotificationApis.DeregisterFirebaseDevice(AmbientServices.Auth,PicMeApi.AuthData,System.String)\" />.",
      "parameters": [],
      "return": {
        "type": "ListRegisteredFirebaseDevicesResponse",
        "description": "A <see cref=\"T:PicMeApi.ListRegisteredFirebaseDevicesResponse\" /> containing the response."
      }
    },
    {
      "name": "PutNotificationSubscriptionConfigurations",
      "httpMethod": "PUT",
      "httpPathRegex": "^/notification",
      "subPathPattern": "/notification",
      "summary": "Sets one or more notification subscription configurations.",
      "parameters": [
        {
          "name": "subscriptions",
          "required": true,
          "type": "NotificationSubscription[]",
          "description": "An array of <see cref=\"T:PicMeModel.NotificationSubscription\" /> to set."
        }
      ],
      "return": {
        "type": "PutNotificationSubscriptionConfigurationsResponse",
        "description": "A <see cref=\"T:PicMeApi.PutNotificationSubscriptionConfigurationsResponse\" /> containing the response."
      }
    },
    {
      "name": "ListNotificationSubscriptionConfigurations",
      "httpMethod": "GET",
      "httpPathRegex": "^/notification",
      "subPathPattern": "/notification",
      "summary": "Lists the user's notification subscription configurations.",
      "parameters": [],
      "return": {
        "type": "ListNotificationSubscriptionConfigurationsResponse",
        "description": "A <see cref=\"T:PicMeApi.ListNotificationSubscriptionConfigurationsResponse\" /> containing the response."
      }
    },
    {
      "name": "GetUserNotificationEventsByRange",
      "httpMethod": "GET",
      "httpPathRegex": "^/event-range",
      "subPathPattern": "/event-range",
      "summary": "Gets the ambient user's notification events for the specified time range.",
      "parameters": [
        {
          "name": "startTime",
          "required": true,
          "type": "DateTime",
          "description": "The minimum <see cref=\"T:System.DateTime\" /> whose notification events are to be retrieved."
        },
        {
          "name": "endTime",
          "required": true,
          "type": "DateTime",
          "description": "The maximum <see cref=\"T:System.DateTime\" /> whose notification events are to be retrieved."
        },
        {
          "name": "collectionId",
          "required": false,
          "type": "CollectionId?",
          "description": "An optional <see cref=\"T:PicMeModel.CollectionId\" /> to restrict the listed notifications to the specified collection."
        }
      ],
      "return": {
        "type": "GetUserNotificationEventsResponse",
        "description": "A <see cref=\"T:PicMeApi.GetUserNotificationEventsResponse\" /> containing the response"
      }
    },
    {
      "name": "MarkNotificationEventRead",
      "httpMethod": "PUT",
      "httpPathRegex": "^/event/read",
      "subPathPattern": "/event/read",
      "summary": "Marks the specified notification event as read.",
      "parameters": [
        {
          "name": "scope",
          "required": true,
          "type": "DataScope",
          "description": "The <see cref=\"T:AmbientServices.DataScope\" /> for the event, often a collecction scope."
        },
        {
          "name": "targetEntityTypeId",
          "required": true,
          "type": "RecordTypeId",
          "description": "The <see cref=\"T:AmbientServices.RecordTypeId\" /> for the target entity."
        },
        {
          "name": "targetEntityId",
          "required": true,
          "type": "String",
          "description": "The ID of the event entity."
        },
        {
          "name": "eventType",
          "required": true,
          "type": "NotificationDigestEventType",
          "description": "The <see cref=\"T:PicMeModel.NotificationDigestEventType\" /> indication what type of event happened."
        },
        {
          "name": "eventTime",
          "required": true,
          "type": "DateTime",
          "description": "The <see cref=\"T:System.DateTime\" /> when the event happened."
        },
        {
          "name": "actorId",
          "required": true,
          "type": "String",
          "description": "The ID of the entity responsible for causing the event (usually the user that did something)."
        },
        {
          "name": "parameters",
          "required": true,
          "type": "String[]?",
          "description": "The array of parameters for the notification (may be null, but must be specified)."
        }
      ],
      "return": {
        "type": "MarkNotificationEventReadResponse",
        "description": "A <see cref=\"T:PicMeApi.MarkNotificationEventReadResponse\" /> containing the response"
      }
    },
    {
      "name": "GetUserNotificationSummary",
      "httpMethod": "GET",
      "httpPathRegex": "^/summary",
      "subPathPattern": "/summary",
      "summary": "Gets a summary of the ambient user's notification events for the specified date.",
      "parameters": [
        {
          "name": "date",
          "required": true,
          "type": "DateOnly",
          "description": "The <see cref=\"T:System.DateOnly\" /> whose notification events are to be retrieved."
        },
        {
          "name": "collectionId",
          "required": false,
          "type": "CollectionId?",
          "description": "An optional <see cref=\"T:PicMeModel.CollectionId\" /> to restrict the listed notifications to the specified collection."
        }
      ],
      "return": {
        "type": "GetUserNotificationSummaryResponse",
        "description": "A <see cref=\"T:PicMeApi.GetUserNotificationSummaryResponse\" /> containing the response"
      }
    },
    {
      "name": "GetUserNotificationEvents",
      "httpMethod": "GET",
      "httpPathRegex": "^/event",
      "subPathPattern": "/event",
      "summary": "Gets the ambient user's notification events for the specified date.",
      "parameters": [
        {
          "name": "date",
          "required": true,
          "type": "DateOnly",
          "description": "The <see cref=\"T:System.DateOnly\" /> whose notification events are to be retrieved."
        },
        {
          "name": "collectionId",
          "required": false,
          "type": "CollectionId?",
          "description": "An optional <see cref=\"T:PicMeModel.CollectionId\" /> to restrict the listed notifications to the specified collection."
        }
      ],
      "return": {
        "type": "GetUserNotificationEventsResponse",
        "description": "A <see cref=\"T:PicMeApi.GetUserNotificationEventsResponse\" /> containing the response"
      }
    }
  ],
  "types": [
    {
      "name": "SignedSecurityToken",
      "summary": "A struct that holds a PicMe collection sharing authorization code.",
      "description": "<pitch>Strongly-typed wrapper for a signed security token string, preventing accidental misuse of raw strings in authorization paths that expect a cryptographically signed value.</pitch>\n<pledge>Value type with transparent JSON serialization via <see cref=\"T:AmbientServices.SignedSecurityTokenJsonConverter\" />. Construct via <see cref=\"M:AmbientServices.SignedSecurityToken.FromRaw(System.String,System.Nullable{System.Int64})\" />; no validation is performed at construction—callers are responsible for verifying the token before trusting it.</pledge>\n<plan>Thin wrapper over a <c>string</c> with an optional runtime-only <see cref=\"P:AmbientServices.SignedSecurityToken.KeyHash\" /> for diagnosing key-mismatch issues without exposing key material. <see cref=\"T:AmbientServices.ProxyTypeAttribute\" /> marks it as a string proxy for parameter binding.</plan>",
      "type": "proxy",
      "representedBy": "String"
    },
    {
      "name": "UnsubscribeResponse",
      "summary": "A record containing the response of a request to unsubscribe.",
      "type": "composite",
      "members": [
        {
          "name": "collectionsUnsubscribed",
          "type": "Int32"
        }
      ]
    },
    {
      "name": "BufferedRawLambdaResponse",
      "summary": "A special API response type for returning raw data such as binary image data.",
      "description": "<pitch>Use as the return type for API functions that return binary data (e.g. images): causes <c>LambdaApiWrapper</c> to respond with a base64-encoded body and the specified Content-Type, bypassing JSON serialization.</pitch>",
      "type": "proxy",
      "representedBy": "Byte[]"
    },
    {
      "name": "FirebaseCloudMessagingProjectConfig",
      "summary": "The Firebase cloud messaging configuration.",
      "description": "<pitch>Deserialization target for the Firebase service-account JSON key file stored in the external secrets manager. Contains the project ID, private key, and OAuth endpoint URLs needed to authenticate with Firebase Admin SDK.</pitch>",
      "type": "composite",
      "members": [
        {
          "name": "type",
          "type": "String",
          "summary": "The type of credential."
        },
        {
          "name": "projectId",
          "type": "String",
          "summary": "The project ID allocated by Firebase."
        },
        {
          "name": "privateKeyId",
          "type": "String",
          "summary": "The ID of the private Key."
        },
        {
          "name": "privateKey",
          "type": "String",
          "summary": "The actual private key."
        },
        {
          "name": "clientEmail",
          "type": "String",
          "summary": "The client email."
        },
        {
          "name": "clientId",
          "type": "String",
          "summary": "The client ID."
        },
        {
          "name": "authUri",
          "type": "String",
          "summary": "The auth URI."
        },
        {
          "name": "tokenUri",
          "type": "String",
          "summary": "The token URI."
        },
        {
          "name": "authProviderX509CertUrl",
          "type": "String",
          "summary": "The provider's certificate URL."
        },
        {
          "name": "clientX509CertUrl",
          "type": "String",
          "summary": "The client's certificate URL."
        }
      ]
    },
    {
      "name": "UpdateFirebaseCloudMessagingProjectConfigResponse",
      "summary": "A record containing the response to a request to set the Firebase Cloud Messaging project configuration."
    },
    {
      "name": "GetFirebaseCloudMessagingProjectConfigResponse",
      "summary": "A record containing the response to a request to get the Firebase Cloud Messaging project configuration.",
      "type": "composite",
      "members": [
        {
          "name": "firebaseProjectId",
          "type": "String",
          "summary": "The Firebase Cloud Messaging project ID."
        }
      ]
    },
    {
      "name": "CollectionId",
      "summary": "A struct that holds a PicMe collection id.",
      "description": "<pitch>Typed wrapper around a PicMe collection identifier string, with factory methods, <see cref=\"T:AmbientServices.DataScope\" /> integration, and a stable ELF hash for sharding.</pitch>",
      "type": "proxy",
      "representedBy": "String"
    },
    {
      "name": "UploadId",
      "summary": "A struct that holds a PicMe upload id.  A collection id is required for this to uniquely identify a upload.",
      "description": "<pitch>Typed upload identifier that encodes the MIME type, timestamp, and optional uploader metadata into a sortable string, with factory methods and local-record-path conversion.</pitch>",
      "type": "proxy",
      "representedBy": "String"
    },
    {
      "name": "SendTestNotificationResponse",
      "summary": "A record containing the response to a request to send a test notification.",
      "type": "composite",
      "members": [
        {
          "name": "deviceNotificationsSent",
          "type": "Int32",
          "summary": "The number of device notifications sent."
        }
      ]
    },
    {
      "name": "PushNotificationSubscription",
      "summary": "A record that contains information about desired push notification types.\n            Multiple such records may exist, one as a default for each user, and others with overrides for each collection.\n            If such a record doesn't exist, the default will be <see cref=\"F:PicMeModel.NotificationType.Uploads\" />.",
      "description": "<pitch>Per-user push notification preference record: stores which event types the user wants pushed to their device, optionally scoped to a specific collection.</pitch>",
      "type": "composite",
      "members": [
        {
          "name": "collectionId",
          "type": "CollectionId?",
          "summary": "The <see cref=\"P:PicMeModel.PushNotificationSubscription.CollectionId\" /> of the collection the settings belong to, or null if they're the default selections."
        },
        {
          "name": "types",
          "type": "NotificationType?",
          "summary": "An optional set of <see cref=\"T:PicMeModel.NotificationType\" /> indicating which type(s) of notifications are desired."
        }
      ]
    },
    {
      "name": "NotificationType",
      "summary": "An enumeration of types of notifications.",
      "description": "<pitch>Flags enum controlling which event categories (uploads, comments, votes) a user wants to be notified about.</pitch>",
      "type": "enum",
      "flags": true,
      "enumValues": [
        {
          "name": "None",
          "summary": "The user does not want to receive notifications for any change types.",
          "value": 0
        },
        {
          "name": "Uploads",
          "summary": "Notifications that new items have been uploaded.",
          "value": 2
        },
        {
          "name": "Comments",
          "summary": "Notifications about new comments.",
          "value": 16
        },
        {
          "name": "Votes",
          "summary": "Notifications about new votes (poll activity/reactions/likes).",
          "value": 32
        }
      ]
    },
    {
      "name": "PutPushNotificationSubscriptionConfigurationsResponse",
      "summary": "A record containing the response of a request to put the push notification subscription configurations."
    },
    {
      "name": "ListPushNotificationSubscriptionConfigurationsResponse",
      "summary": "A record containing push notification subscription configurations.",
      "type": "composite",
      "members": [
        {
          "name": "subscriptions",
          "type": "PushNotificationSubscription[]",
          "summary": "The <see cref=\"T:PicMeModel.PushNotificationSubscription\" />s for the user."
        }
      ]
    },
    {
      "name": "GetUserNotificationSummaryResponse",
      "summary": "A record containing the response to a request to get the user's notification events.",
      "type": "composite",
      "members": [
        {
          "name": "events",
          "type": "UserNotificationSummary[]",
          "summary": "An array of <see cref=\"T:PicMeApi.UserNotificationSummary\" />s summarizing the user's notification events."
        },
        {
          "name": "actors",
          "type": "UserInfo[]",
          "summary": "An array of <see cref=\"T:AmbientServices.UserInfo\" />s for the actors that caused the events."
        }
      ]
    },
    {
      "name": "UserInfo",
      "summary": "A record containing basic information about a collaborating user, usually a co-participant in some activity.",
      "description": "<pitch>Slim display projection of a <see cref=\"T:AmbientServices.UserAccount\" /> for use in participant lists; includes signed profile-picture URL and an <see cref=\"P:AmbientServices.UserInfo.Unavailable\" /> flag for privacy-hidden users.</pitch>",
      "type": "composite",
      "members": [
        {
          "name": "userId",
          "type": "UserId",
          "summary": "The <see cref=\"P:AmbientServices.UserInfo.UserId\" /> of this user."
        },
        {
          "name": "unavailable",
          "type": "Boolean",
          "summary": "Whether the user's information is available or not.  If not available, an anonymous placeholder name will be used."
        },
        {
          "name": "name",
          "type": "String",
          "summary": "The user's name."
        },
        {
          "name": "getProfilePicture",
          "type": "Uri?",
          "summary": "A <see cref=\"T:System.Uri\" /> that can be used to retrieve the user's profile picture if one is available, or null if no profile photo is available for this user."
        },
        {
          "name": "externalIds",
          "type": "ExternalEntityIdentifier[]?",
          "summary": "An optional array of <see cref=\"T:AmbientServices.ExternalEntityIdentifier\" /> identifying this user account in external systems."
        }
      ]
    },
    {
      "name": "ExternalEntityIdentifier",
      "summary": "A record that contains an external system identifier and an identifier for a specific item in that system.",
      "description": "<pitch>Opaque cross-system reference pairing a system name (e.g. \"com.facebook\") with a system-specific item ID; used to link database records to their counterparts in external platforms.</pitch>",
      "type": "composite",
      "members": [
        {
          "name": "externalSystemId",
          "type": "String",
          "summary": "A string that uniquely identifies an external system, often a reverse domain name like 'com.facebook' or 'com.venmo'."
        },
        {
          "name": "externalItemId",
          "type": "String",
          "summary": "A string that uniquely identifies an item in that external system."
        }
      ]
    },
    {
      "name": "UserId",
      "summary": "A struct that holds a user identifier.",
      "description": "<pitch>Compact, URL-safe user identifier; use as the key for user-scoped database records and as a <see cref=\"T:AmbientServices.DataScope\" /> to partition records per-user.</pitch>\n<pledge>May not contain slashes or backslashes; <see cref=\"P:AmbientServices.UserId.Anonymous\" /> is the empty-string sentinel for unauthenticated users; <see cref=\"M:AmbientServices.UserId.New\" /> generates a globally unique ID from <see cref=\"T:AmbientServices.GenericIdentifier\" />.</pledge>",
      "type": "proxy",
      "representedBy": "String"
    },
    {
      "name": "UserNotificationSummary",
      "summary": "A record containing information about a notification event for a specific user.",
      "type": "composite",
      "members": [
        {
          "name": "recipientEntityId",
          "type": "String",
          "summary": "The ID of the recipient entity (usually a user)."
        },
        {
          "name": "targetEntity",
          "type": "EntityInfo",
          "summary": "A <see cref=\"T:PicMeApi.EntityInfo\" /> for the target entity."
        },
        {
          "name": "eventType",
          "type": "NotificationDigestEventType",
          "summary": "The <see cref=\"T:PicMeModel.NotificationDigestEventType\" /> indication what type of event happened."
        },
        {
          "name": "actors",
          "type": "UserId[]",
          "summary": "An array of <see cref=\"T:AmbientServices.UserId\" />s for the actors that caused the events."
        },
        {
          "name": "firstEventTime",
          "type": "DateTime",
          "summary": "The <see cref=\"T:System.DateTime\" /> when the first event happened."
        },
        {
          "name": "lastEventTime",
          "type": "DateTime",
          "summary": "The <see cref=\"T:System.DateTime\" /> when the last event happened (will be the same as <paramref name=\"FirstEventTime\" /> if there is only one event."
        },
        {
          "name": "read",
          "type": "Boolean",
          "summary": "Whether or not this notification has been read."
        }
      ]
    },
    {
      "name": "EntityInfo",
      "summary": "User-readble information about an entity.",
      "type": "composite",
      "members": [
        {
          "name": "scope",
          "type": "DataScope",
          "summary": "The <see cref=\"T:AmbientServices.DataScope\" /> for the event, often a collection scope."
        },
        {
          "name": "entityTypeId",
          "type": "RecordTypeId",
          "summary": "The <see cref=\"T:AmbientServices.RecordTypeId\" /> for the target entity."
        },
        {
          "name": "entityId",
          "type": "String",
          "summary": "The ID of the event entity."
        },
        {
          "name": "parentTitle",
          "type": "String?",
          "summary": "The parent title, if there is a parent."
        },
        {
          "name": "title",
          "type": "String",
          "summary": "The name assigned to the entity."
        }
      ]
    },
    {
      "name": "DataScope",
      "summary": "A string that contains a data scope which distinguishes one set of data (records or indexes) from another.\n            It can be part or all of one or more record identifiers or paths, or any other unique string, but must not contain embedded NUL characters.",
      "description": "<pitch>Namespace key that partitions records and indexes so child records of one entity are stored and queried independently from those of another; use <see cref=\"P:AmbientServices.DataScope.Global\" /> when no scoping is needed.</pitch>\n<pledge>Cannot contain embedded NUL characters; the empty scope equals <see cref=\"P:AmbientServices.DataScope.Global\" />; a <see cref=\"T:AmbientServices.RecordGlobalId\" /> can be converted to a scope via its <see cref=\"M:AmbientServices.RecordGlobalId.AsScope\" /> method to parent child records under it.</pledge>",
      "type": "proxy",
      "representedBy": "String"
    },
    {
      "name": "RecordTypeId",
      "summary": "A struct that holds a record type identifier.\n            Record type identifiers uniquely identify a specific type of record, but take care, as they can be environment-specific (ie. the same type can have different record type identifiers in different environments).",
      "description": "<pitch>Compact, path-safe token that names a record type in the database file system; survives .NET class renames without breaking stored S3 paths.</pitch>\n<pledge>Never empty and never contains a slash; the default zero-value is <see cref=\"P:AmbientServices.RecordTypeId.Unknown\" />; <see cref=\"P:AmbientServices.RecordTypeId.Raw\" /> returns the bare code, <see cref=\"P:AmbientServices.RecordTypeId.Encoded\" /> returns a percent-encoded form safe for embedding in S3 paths.</pledge>",
      "type": "proxy",
      "representedBy": "String"
    },
    {
      "name": "NotificationDigestEventType",
      "summary": "An enumeration of notification digest actions.",
      "description": "<pitch>Identifies the category of activity that triggered a notification digest entry: upload, message, or vote.</pitch>",
      "type": "enum",
      "flags": false,
      "enumValues": [
        {
          "name": "Upload",
          "summary": "An item was uploaded to a collection.  The target entity ID is an upload ID with a scope that is a collection.",
          "value": 0
        },
        {
          "name": "Message",
          "summary": "A discussion message was added.  The target entity ID is a discussion message id with a scope that is either a collection or an upload.",
          "value": 1
        },
        {
          "name": "Vote",
          "summary": "Someone voted in a poll.  The target entity ID is either an upload with a scope that is a collection, or a collection with global scope.",
          "value": 2
        }
      ]
    },
    {
      "name": "MarkNotificationSummaryReadResponse",
      "summary": "A record containing the response to a request to mark a notification summary as read."
    },
    {
      "name": "RegisterFirebaseDeviceResponse",
      "summary": "A record containing the response to a request to register a firebase device.",
      "type": "composite",
      "members": [
        {
          "name": "previouslyRegistered",
          "type": "Boolean",
          "summary": "Whether the device was previously registered."
        }
      ]
    },
    {
      "name": "DeregisterFirebaseDeviceResponse",
      "summary": "A record containing the response to a request to deregister a firebase device."
    },
    {
      "name": "ListRegisteredFirebaseDevicesResponse",
      "summary": "A record containing the response from a request to list the firebase devices.",
      "type": "composite",
      "members": [
        {
          "name": "firebaseDeviceIds",
          "type": "String[]",
          "summary": "An array containing the registered firebase device IDs."
        }
      ]
    },
    {
      "name": "NotificationSubscription",
      "summary": "A record that contains information about desired notification types, channels, and frequency.\n            Multiple such records may exist, one as a default for each user, and others with overrides for each collection.\n            If such a record doesn't exist, the default will be <see cref=\"F:PicMeModel.NotificationType.Uploads\" />, <see cref=\"F:PicMeModel.NotificationChannel.Email\" />, <see cref=\"F:PicMeModel.NotificationFrequency.Daily\" />.",
      "description": "<pitch>Per-user notification preference record: stores which event types, channels, and frequency the user wants, optionally scoped to a specific collection.</pitch>",
      "type": "composite",
      "members": [
        {
          "name": "collectionId",
          "type": "CollectionId?",
          "summary": "The <see cref=\"P:PicMeModel.NotificationSubscription.CollectionId\" /> of the collection the settings belong to, or null if they're the default selections."
        },
        {
          "name": "types",
          "type": "NotificationType?",
          "summary": "An optional set of <see cref=\"T:PicMeModel.NotificationType\" /> indicating which type(s) of notifications are desired."
        },
        {
          "name": "channels",
          "type": "NotificationChannel?",
          "summary": "An optional set of <see cref=\"T:PicMeModel.NotificationChannel\" /> indicating which channels the notifications should be sent through."
        },
        {
          "name": "frequency",
          "type": "NotificationFrequency?",
          "summary": "An optional set of <see cref=\"T:PicMeModel.NotificationFrequency\" /> indicating how frequencly notifications should be sent."
        }
      ]
    },
    {
      "name": "NotificationFrequency",
      "summary": "An enumeration of how often to notify someone of an event.",
      "description": "<pitch>Controls how urgently notifications are batched and sent: as soon as possible, once daily, or never.</pitch>",
      "type": "enum",
      "flags": false,
      "enumValues": [
        {
          "name": "Asap",
          "summary": "The user wants to be notified as soon as possible.",
          "value": 1
        },
        {
          "name": "Daily",
          "summary": "The user wants to be notified daily.",
          "value": 3
        },
        {
          "name": "Never",
          "summary": "The user does not want to be notified ever.",
          "value": 2147483647
        }
      ]
    },
    {
      "name": "NotificationChannel",
      "summary": "An enumeration of channels over which notifications may be sent.",
      "description": "<pitch>Flags enum specifying which delivery channels (currently only email) a user wants to receive notifications through.</pitch>",
      "type": "enum",
      "flags": true,
      "enumValues": [
        {
          "name": "None",
          "summary": "The user does not want to receive notifications through any channel.",
          "value": 0
        },
        {
          "name": "Email",
          "summary": "The wants to receive notifications by email.",
          "value": 1
        }
      ]
    },
    {
      "name": "PutNotificationSubscriptionConfigurationsResponse",
      "summary": "A record containing the response of a request to put the notification subscription configurations."
    },
    {
      "name": "ListNotificationSubscriptionConfigurationsResponse",
      "summary": "A record containing notification subscription configurations.",
      "type": "composite",
      "members": [
        {
          "name": "subscriptions",
          "type": "NotificationSubscription[]",
          "summary": "The <see cref=\"T:PicMeModel.NotificationSubscription\" />s for the user."
        }
      ]
    },
    {
      "name": "GetUserNotificationEventsResponse",
      "summary": "A record containing the response to a request to get the user's notification events.",
      "type": "composite",
      "members": [
        {
          "name": "events",
          "type": "UserNotificationEvent[]",
          "summary": "An array of <see cref=\"T:PicMeApi.UserNotificationEvent\" />s for the user's notification events."
        },
        {
          "name": "targetEntities",
          "type": "EntityInfo[]",
          "summary": "An array of <see cref=\"T:PicMeApi.EntityInfo\" />s for the target entities."
        },
        {
          "name": "actors",
          "type": "UserInfo[]",
          "summary": "An array of <see cref=\"T:AmbientServices.UserInfo\" />s for the actors that caused the events."
        }
      ]
    },
    {
      "name": "UserNotificationEvent",
      "summary": "A record containing information about a notification event for a specific user.",
      "type": "composite",
      "members": [
        {
          "name": "recipientEntityId",
          "type": "String",
          "summary": "The ID of the recipient entity (usually a user)."
        },
        {
          "name": "scope",
          "type": "DataScope",
          "summary": "The <see cref=\"T:AmbientServices.DataScope\" /> for the event, often a collecction scope."
        },
        {
          "name": "targetEntityTypeId",
          "type": "RecordTypeId",
          "summary": "The <see cref=\"T:AmbientServices.RecordTypeId\" /> for the target entity."
        },
        {
          "name": "targetEntityId",
          "type": "String",
          "summary": "The ID of the event entity."
        },
        {
          "name": "eventType",
          "type": "NotificationDigestEventType",
          "summary": "The <see cref=\"T:PicMeModel.NotificationDigestEventType\" /> indication what type of event happened."
        },
        {
          "name": "eventTime",
          "type": "DateTime",
          "summary": "The <see cref=\"T:System.DateTime\" /> when the event happened."
        },
        {
          "name": "actorId",
          "type": "UserId",
          "summary": "The ID of the entity responsible for causing the event (usually the user that did something)."
        },
        {
          "name": "parameters",
          "type": "String[]?",
          "summary": "Optional parameters specific to the event type."
        },
        {
          "name": "read",
          "type": "Boolean",
          "summary": "Whether or not this notification has been read."
        }
      ]
    },
    {
      "name": "MarkNotificationEventReadResponse",
      "summary": "A record containing the response to <see cref=\"M:PicMeApi.NotificationApis.MarkNotificationEventRead(AmbientServices.IFileSystem,AmbientServices.Database,PicMeApi.AuthData,AmbientServices.DataScope,AmbientServices.RecordTypeId,System.String,PicMeModel.NotificationDigestEventType,System.DateTime,System.String,System.String[])\" />.",
      "type": "composite",
      "members": [
        {
          "name": "updatedEvent",
          "type": "UserNotificationEvent",
          "summary": "The updated <see cref=\"T:PicMeApi.UserNotificationEvent\" />."
        }
      ]
    }
  ]
}