# Their own photos and files (https://lazyfrog.dev/docs/guide/their-own-photos-and-files)

{/* Generated by scripts/generate-docs.ts from services/gateway/src/guide.md. Do not edit. */}

Photos pasted into the chat reach you as pictures, not files. Three ways to get them into the
project, on any plan:
- **In ChatGPT**, when the user attached the photos to their message: `fs_import` with `files`
  (ChatGPT fills each one in; you don't write the download address yourself) saves them into
  `/data/import`, up to 50 MB each and 20 a call, never over a file already there, recorded as
  the user's own (they attached them). Say what was saved, and anything refused with its reason.
- **An image your app made** (ChatGPT's image generation, anything you created rather than a file
  the user attached): `fs_import` it with `generated: true`, always. Without it the image is
  recorded as the user's own photo. Saved one without it? `fs_import` the same file again with
  `generated: true`: nothing is saved twice and its record becomes "made from a prompt".
- **On the LazyFrog card** in the chat (Claude on the web, desktop and phone, and ChatGPT show it
  under a `project` or `deploy` result): point the user to its **Add photos** button. They pick
  photos, PDFs or short videos on their computer or phone, or drop them on the card, up to 50 MB
  each; the card says in the chat when they're in (or your next LazyFrog result does), and they
  are recorded as the user's own. Where the app can't send from the card, its button opens the
  upload link instead.
- **Everywhere else**, or when `fs_import` says no files came with the call (the app didn't pass
  them): give the user the upload link, Project › Files, the Upload box, at
  `https://app.lazyfrog.dev/p/<slug>/files?path=data/import` (they drop the files or choose
  them, from a computer or a phone, up to 50 MB each). Never say photos can't reach the project.
  Claude Code and Codex on the user's machine can also commit a photo into a clone of the
  project and push it to git.lazyfrog.dev (it lands under `/workspace`, in the code, not
  `/data/import`); the link is still the simplest for the owner's own photos.

Every way they land in `/data/import`, which isn't served. Look at them with `images` `view`
(`paths: ["data/import"]`, free): a contact sheet with each one's real size and orientation, so
you know which photo is which; then
`images` `place` puts each into its slot on a page (`from`, `file`, `slot`, `alt`), at the right
widths and cropped to the slot's shape, also free. `images` `edit` `operation: "optimise"` is for
a photo with no slot (a gallery you build around them). iPhone HEIC photos: convert first in
`exec` (`magick in.heic -quality 90 out.jpg`). Links to Google Drive, Dropbox or WhatsApp work
with `exec curl` on paid plans only; a file fetched that way has no recorded source, so ask the
owner to confirm it on the Plan tab ("These photos are mine"), or to upload it instead. A file
saved with `fs_import` is recorded as theirs, as an upload is: they attached it. It is for their
attachments only, and for an image your app made in the chat that the user picked (with
`generated: true`, recorded as made from a prompt, not as theirs); never for a photo found on the
web.

**Handing the owner a file** (a print-ready PDF, a QR code for table cards, an export): save it
under `/data/out/`, which isn't served, and give them
`https://app.lazyfrog.dev/p/<slug>/files?path=data/out`: they open the file there and tap
**Download**. Don't put it in the site's folder to get a link: it would go live with the next
publish.
