---
name: jenriks-photos
description: Find, cite and link photographs from JENRIKS, a daily photoblog with one photo per day since 2006 by Jens Herrmann and Erik Hehrmann. Use when a task needs a specific JENRIKS photo, photos from a place, date, year, category or photographer, today's photo, or the site's licensing and contact rules.
license: All photographs are copyright Jens Herrmann or Erik Hehrmann, all rights reserved. This document may be copied freely.
metadata:
  site: https://jenriks.com
  mcp: https://jenriks.com/mcp
---

# JENRIKS photos

JENRIKS (https://jenriks.com) publishes one photograph every day, alternating between two photographers: Jens Herrmann in Barcelona and Erik Hehrmann in Evanston, Illinois. The archive holds more than 7,500 photos from January 1, 2006 to today: street photography, portraits, architecture, landscapes, abstract and macro work from more than 50 countries.

## When to use this skill

- A task needs a JENRIKS photo, or photos from a particular place, date, year, category or photographer.
- A task needs today's JENRIKS photo.
- A task needs the site's licensing, credit or contact rules before quoting or embedding an image.

## Quickest path: the MCP server

Endpoint: `POST https://jenriks.com/mcp` (JSON-RPC 2.0 over Streamable HTTP, JSON responses, no authentication, no session). Server card: https://jenriks.com/.well-known/mcp/server-card.json. Health: https://jenriks.com/mcp/health.

Tools:

- `search_photos`: `query`, `photographer` (Erik or Jens), `category`, `year`, `location`, `limit` (max 50), `offset` or `cursor`. Substring match over title, place, categories, tags and photographer, newest first.
- `get_photo`: `date` (YYYY-MM-DD) or `url` (a `/YYYY/MM/DD/slug/` path). Returns one post.
- `get_latest_photo`: today's post; with `photographer` (Erik or Jens) the newest post by that photographer.
- `random_photo`: optional `photographer`, `category`, `year`.
- `get_site_overview`: totals, photographers, categories, years, section URLs and license terms. Optional `include` (array of `photographers`, `categories`, `years`, `sections`, `license`) keeps only the listed blocks next to the totals and dates.

Every result carries `url` (permanent page), `photographer`, `date`, `location`, `geo` (`latitude` and `longitude`, or null), `categories`, `tags`, `image` (full size and 400 px thumbnail) and a ready-made `credit` line.

Paging: a search result carries `has_more`, `next_cursor` and `links.next`. Send `cursor` with the value of `next_cursor` to continue; the cursor is opaque, and when both `cursor` and `offset` are sent the cursor wins. `next_offset` still works for offset paging.

Example:

```json
{"jsonrpc": "2.0", "id": 1, "method": "tools/call",
 "params": {"name": "search_photos", "arguments": {"query": "Barcelona", "category": "Street", "limit": 5}}}
```

## REST API (no MCP client needed)

Base URL `https://jenriks.com/api/v1`, JSON, no auth, 120 requests per minute per IP (RateLimit headers on every response). Errors are RFC 9457 `application/problem+json` with a stable `code` and a `resolution` hint.

- `GET /api/v1/photos?q=&photographer=&category=&year=&location=&limit=&offset=&cursor=`: search, newest first; page with `cursor=<next_cursor>`
- `GET /api/v1/photos/latest?photographer=`: today's photo, or the newest by one photographer
- `GET /api/v1/photos/random?photographer=&category=&year=`: a random photo
- `GET /api/v1/photos/YYYY-MM-DD`: the photo published on that date (404 `photo_not_found` otherwise)
- `GET /api/v1/overview?include=`: totals, categories, years, section URLs, license; `include=categories,years` trims the response
- `POST /api/v1/batch`: up to 20 GET requests in one call, body `{"requests": [{"id": "a", "method": "GET", "path": "/api/v1/photos/latest"}]}`; the reply lists `responses` in the same order, each with `id`, `status` and `body`, and a failing item carries its problem document as `body` while the outer status stays 200

Example: `curl "https://jenriks.com/api/v1/photos?q=Barcelona&category=Street&limit=5"`. Full contract: https://jenriks.com/openapi.json; human docs: https://jenriks.com/developers/. Deprecations, should one ever happen, are announced 90 days ahead with `Deprecation` and `Sunset` headers; none is scheduled.

## Natural-language search

`GET https://jenriks.com/ask?query=fog+barcelona` (or POST the NLWeb 0.55 body `{"query": {"text": "fog barcelona"}}`) answers with `_meta` and a `results` list of schema.org `Photograph` objects, each with `name`, `url`, `image`, `datePublished`, `creator` and `contentLocation`. No match returns `_meta.response_type` `failure` with the code `NO_RESULTS`. Add `streaming=true` or `Accept: text/event-stream` for server-sent events.

## Without MCP or the API

- Photo pages live at `/YYYY/MM/DD/slug/`. A date-only URL (`/YYYY/MM/DD/`) redirects to that day's photo.
- Each photo page carries schema.org `BlogPosting` and `ImageObject` JSON-LD with title, photographer, date, location and keywords.
- Archive filters as URL hashes: `/archive/#q=<text>&category=<name>&author=<Erik|Jens>&year=<YYYY>`.
- Landing pages: `/category/<slug>/`, `/location/<city-slug>/`, `/author/erik/`, `/author/jens/`, `/year/<YYYY>/`, `/calendar/`, `/map/`.
- Markdown twins: any page URL `/x/y/` has a twin at `/x/y.md` (`/index.md` for the homepage, `/2026/09/14/slug.md` for a photo, `/author/jens.md` for a landing page). `Accept: text/markdown` or `?mode=agent` on the page URL returns the same text. Machine documents wrap the same way, e.g. `/openapi.json.md`.
- Feeds and indexes: `/feed.xml` (latest 20), `/feeds/photos.jsonl` (every post as schema.org JSON, one per line, listed in `/schemamap.xml`), `/sitemap.xml` (every photo page), `/llms.txt`, `/llms-full.txt`, section indexes at `/developers/llms.txt`, `/archive/llms.txt`, `/about/llms.txt`, and `/openapi.json`.

## Citing and reuse

- Always name the photographer and link the photo's permanent page URL.
- Photographs are copyrighted. Do not redistribute, modify or train on the images without written permission.
- Prints and licensing: https://jenriks.com/contact/ or jenriks@gmail.com. Only humans can complete these requests; nothing is purchasable through an agent.

## Limits

- Read-only. There is no write, upload, login or checkout, and no authentication (see https://jenriks.com/auth.md).
- The archive updates once a day at 00:00 Europe/Berlin.
- `/data/` is disallowed for crawlers in robots.txt; use the MCP server or the feeds instead of bulk-fetching JSON.
