About Field Notes
An open journal of the natural world
Field Notes is a digital collection of observations from the natural world — field records, surveys, sketches, and quiet discoveries, shared openly with anyone who cares to read them.
Every note here began outdoors. A hawk crossing a river valley. The careful architecture of a dune grass community. The sound of insects on a June night. These are the small, specific moments that a naturalist carries home in a field bag, transcribed to paper while the details are still fresh.
What you'll find here
- Field observations — detailed records of species, behavior, and encounters in the wild.
- Surveys & records — systematic notes on the plants and animals of a particular place.
- Seasonal records — phenology, movement patterns, and the slow changes of the landscape.
Notes are written in the tradition of the field journal: dated, located, and recorded with enough detail that another person could return to the same place and find the same things.
Why public?
Observation is a shared practice. The notes of earlier naturalists — often collected over decades — remain a gift to those who follow. This journal is offered in the same spirit: a working record that anyone may read, use, and build upon. Whether you are a seasoned field observer or someone simply curious about the world outdoors, there is a place for you here.
How this journal sketches itself
Most entries here describe something seen outdoors. The sketches that go with them describe something that happens right after: the moment a submission from a Bloom device becomes a page on this site.
That handoff is a single Netlify function, netlify/functions/sync-entry.js, and it does three things — upload whatever media came in to Cloudinary, ask Cloudinary to generate a sketch to match, and open a pull request so nothing publishes without a human looking at it first.
From device to pull request
A submission arrives as JSON: a catalog number, a timestamp, a note, and optionally a photo and a hand-drawn sketch, both already base64-encoded on the device. The function:
- Branches off
main—entry/<slug>-<timestamp>— so every submission is isolated. - Uploads the photo and sketch, if present, to Cloudinary (
field-notes/<slug>andfield-notes/<slug>-sketch) so the site can deliver them through Cloudinary's CDN with automatic format and quality optimization. - Asks Cloudinary to generate an AI field sketch (below).
- Writes the markdown file into
src/content/notes/, referencing all three images as Cloudinary delivery URLs. Only the markdown is committed to the repo — image binaries live in Cloudinary. - Opens a PR against
main, labeleddevice-submission.
That last step is the actual safety mechanism. The endpoint itself checks nothing beyond size and required fields — no auth, because a field device shouldn't need to manage credentials. Review happens on GitHub, not at submission time.
Generating a sketch with a reference image
Every entry gets an AI-generated sketch, whether or not the observer submitted a photo or drew one by hand. The prompt is built from the note text:
"Create a field sketch illustration in the style of the reference image [1]. The sketch should depict: (the note). Use a vintage field journal aesthetic with earthy tones, hand-drawn quality, and scientific illustration style."

The [1] isn't decorative — it points at a reference_imagesarray passed to Cloudinary's image_to_image generation endpoint, pinned to one fixed image (above) that acts as a style guide. Every generated sketch is steered toward that same look, so the AI sketches across dozens of entries — different handwriting, different species, different observers — still read as one consistent visual voice rather than a new style each time.
The request that goes to Cloudinary:
fetch(`https://api.cloudinary.com/v2/generate/${cloudName}/image_to_image`, {
method: "POST",
headers: { Authorization: `Basic ${credentials}` },
body: JSON.stringify({
prompt,
reference_images: [{ source_type: "url", url: REFERENCE_IMAGE_URL }],
model: { family: "nano-banana", tier: "premium" },
target: { target_type: "managed_asset", public_id: `field-notes/${slug}-ai` },
}),
});The response points at the generated asset, which Cloudinary already stores as a managed asset — the function's markdown references its delivery URL (withf_auto,q_auto) rather than downloading a copy into the repo. If generation fails — missing credentials, a bad response, a network hiccup — the function doesn't fail the whole submission. It logs the reason, skips the AI sketch, and lets the PR go through with whatever media did arrive.
Why bother
A device in the field can capture a photo or a rough sketch, but not always both, and not always well. The AI sketch is a third, more consistent artifact — something that gives every entry, however partial, the same hand-drawn field-journal feel this site is trying to have throughout.
Read the journal
The most recent observations live on the journal page, newest first. Each entry records where it was made, when it was made, and what was seen.