{
  "slug": "private-online-photo-gallery",
  "question": "How do I create a private online photo gallery?",
  "method": "primary-docs",
  "checkedAt": "2026-10-26",
  "what": "Five properties of a shared photo album, for Viallo, Google Photos, SmugMug and iCloud: whether a viewer needs an account, whether the link takes a password, whether the owner can cut the link without deleting the album, whether downloads can be switched off for a link, and how much storage is free. Every vendor value was read from that vendor's own help page on the date above; every Viallo value from its code at origin/main.",
  "tools": [
    {
      "name": "python3",
      "version": "3.9.6",
      "use": "urllib fetch, stdlib only"
    },
    {
      "name": "curl",
      "version": "8.7.1 (SecureTransport, LibreSSL/3.3.6)"
    },
    {
      "name": "git",
      "version": "2.54.0 (Apple Git-157)",
      "use": "read only, via git show origin/main:<path>"
    }
  ],
  "inputs": [
    {
      "id": "google_share",
      "kind": "url",
      "url": "https://support.google.com/photos/answer/6131416?hl=en",
      "note": "Google Photos Help, Share photos & videos"
    },
    {
      "id": "google_controls",
      "kind": "url",
      "url": "https://support.google.com/photos/answer/9789702?hl=en",
      "note": "Google Photos Help, How shared album controls give your photos more privacy"
    },
    {
      "id": "google_privacy",
      "kind": "url",
      "url": "https://support.google.com/photos/answer/12840331?hl=en",
      "note": "Google Photos Help, How Google Photos protects your privacy & keeps you in control"
    },
    {
      "id": "google_one",
      "kind": "url",
      "url": "https://one.google.com/about/plans",
      "note": "Google One plans page; the free-storage sentence only. The page prices in EUR from this network, so no price is taken from it."
    },
    {
      "id": "apple_shared",
      "kind": "url",
      "url": "https://support.apple.com/en-us/108314",
      "note": "Apple Support, How to use Shared Albums in Photos on your iPhone, iPad, or Apple Vision Pro"
    },
    {
      "id": "apple_storage",
      "kind": "url",
      "url": "https://support.apple.com/en-us/108047",
      "note": "Apple Support, iCloud+ plans and pricing; the free-storage sentence only. Prices shown in EUR from this network and not used."
    },
    {
      "id": "smug_privacy",
      "kind": "zendesk",
      "url": "https://www.smugmughelp.com/api/v2/help_center/en-us/articles/18212691894420.json",
      "page": "https://www.smugmughelp.com/hc/en-us/articles/18212691894420-Gallery-Page-and-Folder-privacy-settings",
      "note": "SmugMug Help, Gallery, Page, and Folder privacy settings. The rendered page answers 403 Cloudflare to a script; the article body is read from the same help centre's public JSON API for the same article id."
    },
    {
      "id": "smug_settings",
      "kind": "zendesk",
      "url": "https://www.smugmughelp.com/api/v2/help_center/en-us/articles/18212440954772.json",
      "page": "https://www.smugmughelp.com/hc/en-us/articles/18212440954772-Change-settings-for-a-gallery-folder-or-page",
      "note": "SmugMug Help, Change settings for a gallery, folder, or page. Used only to establish that its gallery settings list no download switch."
    },
    {
      "id": "smug_downloads",
      "kind": "zendesk",
      "url": "https://www.smugmughelp.com/api/v2/help_center/en-us/articles/18212419649428.json",
      "page": "https://www.smugmughelp.com/hc/en-us/articles/18212419649428-Allow-limited-client-downloads-from-my-site",
      "note": "SmugMug Help, Allow limited client downloads from my site"
    },
    {
      "id": "gdrive",
      "kind": "url",
      "url": "https://support.google.com/drive/answer/2494822?hl=en",
      "note": "Google Drive Help, Share files from Google Drive. Used for the sentence about Anyone with the link in What to avoid."
    },
    {
      "id": "viallo_sharing_controller",
      "kind": "repo",
      "path": "apps/api/src/sharing/sharing.controller.ts",
      "note": "Viallo product claims are checked against its code, not its marketing pages"
    },
    {
      "id": "viallo_sharing_service",
      "kind": "repo",
      "path": "apps/api/src/sharing/sharing.service.ts"
    },
    {
      "id": "viallo_tiers",
      "kind": "repo",
      "path": "packages/shared/src/subscription/tiers.ts"
    },
    {
      "id": "viallo_currency",
      "kind": "repo",
      "path": "packages/shared/src/subscription/currency.ts"
    },
    {
      "id": "viallo_share_panel",
      "kind": "repo",
      "path": "apps/web/src/app/(public)/albums/[albumId]/_components/share-modal/UnifiedSharePanel.tsx"
    },
    {
      "id": "viallo_upload_queue",
      "kind": "repo",
      "path": "apps/web/src/lib/upload-queue.ts"
    },
    {
      "id": "viallo_heic_worker",
      "kind": "repo",
      "path": "apps/api/src/photos/heic-convert.worker.ts"
    },
    {
      "id": "smug_plans",
      "kind": "url",
      "url": "https://www.smugmug.com/plans",
      "note": "SmugMug plans page, read on 26 October 2026. It answers 200 from this network and prices in US dollars. Used for the 14-day free trial sentence only; no price is published."
    }
  ],
  "results": [
    {
      "id": "v-viewer",
      "option": "Viallo",
      "property": "viewer_account",
      "value": "No",
      "quote": "@ApiOperation({ summary: 'Access shared album by link (public)' })",
      "input": "viallo_sharing_controller"
    },
    {
      "id": "v-password",
      "option": "Viallo",
      "property": "password",
      "value": "No option; the address is the access",
      "quote": "options: { label?: string; downloadAllowed: boolean },",
      "input": "viallo_sharing_service",
      "note": "The call that mints a link takes a label and a download flag, and no password field exists on the path."
    },
    {
      "id": "v-cut",
      "option": "Viallo",
      "property": "cut_link",
      "value": "Yes, Revoke on any link",
      "quote": "$set: { isActive: false, revokedAt: new Date() }",
      "input": "viallo_sharing_service"
    },
    {
      "id": "v-downloads",
      "option": "Viallo",
      "property": "downloads_off",
      "value": "Yes, clear Allow download",
      "quote": "downloadAllowed: options.downloadAllowed,",
      "input": "viallo_sharing_service",
      "note": "The flag is per link and defaults to true, so a new link allows downloads until the owner clears it."
    },
    {
      "id": "v-free",
      "option": "Viallo",
      "property": "free_tier",
      "value": "2 albums, 200 photos, 10 GB",
      "quote": "maxAlbums: 2, maxPhotos: 200, maxStorageGB: 10,",
      "input": "viallo_tiers"
    },
    {
      "id": "g-viewer",
      "option": "Google Photos",
      "property": "viewer_account",
      "value": "No, with a shared link",
      "quote": "When you share a link to your photos, anyone with the link can view them.",
      "input": "google_share"
    },
    {
      "id": "g-password",
      "option": "Google Photos",
      "property": "password",
      "value": "Not documented",
      "quote": "Turn Link sharing on & off",
      "input": "google_controls",
      "notOn": [
        {
          "input": "google_controls",
          "word": "password"
        }
      ],
      "note": "The sharing-controls page documents link sharing on and off and contains no occurrence of the word password."
    },
    {
      "id": "g-cut",
      "option": "Google Photos",
      "property": "cut_link",
      "value": "Yes; link sharing off issues a new link",
      "quote": "To reset the link, turn link sharing off and then back on. The old link will no longer work and you can share the new link with people you trust.",
      "input": "google_controls"
    },
    {
      "id": "g-downloads",
      "option": "Google Photos",
      "property": "downloads_off",
      "value": "Not documented",
      "quote": "Turn Link sharing on & off",
      "input": "google_controls",
      "notOn": [
        {
          "input": "google_controls",
          "word": "download"
        }
      ],
      "note": "The sharing-controls page contains no occurrence of the word download."
    },
    {
      "id": "g-free",
      "option": "Google Photos",
      "property": "free_tier",
      "value": "15 GB, shared",
      "quote": "All Google accounts come with up to 15 GB of storage",
      "input": "google_one"
    },
    {
      "id": "s-viewer",
      "option": "SmugMug",
      "property": "viewer_account",
      "value": "No, with the gallery link",
      "quote": "To share them with a guest, provide a direct link to the gallery.",
      "input": "smug_privacy"
    },
    {
      "id": "s-password",
      "option": "SmugMug",
      "property": "password",
      "value": "Yes, People with Password",
      "quote": "You can lock down access to pages, folders, and galleries by choosing People with Password",
      "input": "smug_privacy"
    },
    {
      "id": "s-cut",
      "option": "SmugMug",
      "property": "cut_link",
      "value": "Yes, set visibility to Only Me",
      "quote": "Galleries, pages, and folders visible to Only Me are completely private and invisible to the rest of the world.",
      "input": "smug_privacy"
    },
    {
      "id": "s-downloads",
      "option": "SmugMug",
      "property": "downloads_off",
      "value": "No; Pro plans cap a client's downloads",
      "quote": "you can choose how many images you'd like to allow your client to download",
      "input": "smug_downloads",
      "notOn": [
        {
          "input": "smug_settings",
          "word": "download"
        }
      ],
      "note": "The documented control is a cap on how many images a Pro-level client may download. The gallery settings tour lists no download switch and contains no occurrence of the word download."
    },
    {
      "id": "s-free",
      "option": "SmugMug",
      "property": "free_tier",
      "value": "None; 14-day free trial",
      "quote": "you'll get the chance to explore every feature we've got with your 14-day free trial.",
      "input": "smug_plans",
      "note": "SmugMug's plans page states a 14-day free trial for every plan and lists no free tier."
    },
    {
      "id": "i-viewer",
      "option": "iCloud",
      "property": "viewer_account",
      "value": "No; Public Website before iOS 27",
      "quote": "Friends and family will be able to join and contribute their own photos on the web, even without an Apple Account or Apple device.",
      "input": "apple_shared"
    },
    {
      "id": "i-password",
      "option": "iCloud",
      "property": "password",
      "value": "Not documented; the owner can approve each person",
      "quote": "Tap Sharing Options to choose whether to invite and approve participants, or share the album with a link.",
      "input": "apple_shared",
      "notOn": [
        {
          "input": "apple_shared",
          "word": "password"
        }
      ],
      "note": "The Shared Albums page documents invite-and-approve or share-by-link and contains no occurrence of the word password."
    },
    {
      "id": "i-cut",
      "option": "iCloud",
      "property": "cut_link",
      "value": "Not documented; remove the subscriber",
      "quote": "You can remove subscribers at any time.",
      "input": "apple_shared",
      "note": "The page documents removing a subscriber. It documents turning Public Website on for albums made in iOS 26 and earlier, and no step that turns the link off."
    },
    {
      "id": "i-downloads",
      "option": "iCloud",
      "property": "downloads_off",
      "value": "Not documented",
      "quote": "Tap Save Image or Save Video.",
      "input": "apple_shared",
      "note": "The page documents that a participant saves a photo to their own library and no owner-side switch that turns saving off."
    },
    {
      "id": "i-free",
      "option": "iCloud",
      "property": "free_tier",
      "value": "5 GB",
      "quote": "with 5 GB of storage for free",
      "input": "apple_storage"
    },
    {
      "id": "i-saved",
      "option": "iCloud",
      "property": "saved_copy_survives",
      "value": "Yes, and it survives the album",
      "quote": "Any photos that you saved or downloaded from a shared album to your Photos library stay in your library even if the shared album is deleted or the person who created it stops sharing it.",
      "input": "apple_shared",
      "note": "Carries the revocation paragraph: cutting a link cannot withdraw a copy a viewer already saved."
    },
    {
      "id": "g-saved",
      "option": "Google Photos",
      "property": "saved_copy_survives",
      "value": "Yes, saving makes a copy in the recipient's library",
      "quote": "When you save a photo or video that has been shared with you, you receive a copy of it in your library.",
      "input": "google_share"
    }
  ],
  "notes": [
    {
      "what": "Competitor prices",
      "why": "This Mac's network exits in Germany, so Google One, iCloud+ and SmugMug price in euros with VAT, and smugmug.com answers 403 to a script. No competitor price is published in the post. Viallo's $6.99 Plus price comes from its code (packages/shared/src/subscription/currency.ts), not from a page."
    },
    {
      "what": "SmugMug's rendered help pages",
      "why": "They answer 403 behind Cloudflare, so every SmugMug quote comes from the same article through the help centre's public JSON API, named in inputs."
    },
    {
      "what": "Google Photos and iCloud download controls",
      "why": "No page read documents a switch that turns downloads off for a shared link. The cells say not documented rather than guessing."
    },
    {
      "what": "iCloud cutting a link",
      "why": "The page documents removing a subscriber and turning Public Website on, not turning the link off."
    },
    {
      "what": "SmugMug free tier",
      "why": "The plans page read today lists a 14-day free trial for every plan and no free tier. It prices in US dollars from this network; the price is not published in the post."
    },
    {
      "what": "Map view",
      "why": "Dropped from the comparison: the Google Photos pages read do not mention a map, and no iCloud page read today answered it. The post keeps map view only as a Viallo product fact."
    },
    {
      "what": "Absence cells",
      "why": "Where a cell says not documented, the script checks both the quoted sentence and that the word the option would use (password, download) does not occur on the page read."
    },
    {
      "what": "No account, album or share link of anyone else",
      "why": "No account was created, no album or share link belonging to anyone was opened, and no photo was downloaded or measured."
    }
  ]
}
