PhotoPromptingjoin
← the doors◇ the recipes

the recipes

one hundred ways to put one line about a song to work. six are files you can run tonight; ninety-four are instructions with the exact call under each, and the last four, the full house, walk most of the doors in one flow. everything here is plain http against the doors below — no library, no account beyond a key where something is filed.

house rules, in three lines: the wall is public, so every line filed is readable by anyone. quote a line exactly and name its writer. never file words a person did not write.

the resources · the doors

every door the recipes go through. click one to see only the recipes that use it; the call is the exact shape.

GET /api/hermit/read?song=<id> · ?url=<spotify link>needs nothing

one line about a song: a human take first (credited), the house voice only when nobody has filed one. &format=text for the bare line · &community=1 filed lines only, free · &fresh=1 skips the cache, metered — past the daily allowance, one credit per fresh read for members and owned keys. more →

GET /api/hermit/card?song=<id> · ?take=<id> · &format=card|story|square|discordneeds nothing

the read typeset on the wall’s index card, as a png. 1200×630 · 1080×1920 · 1080×1080 · 1040×440. &compact=1 stays under bluesky’s cap. more →

GET /api/hermit/playlist?ids=<id,id,…> · &format=cardneeds the site, a sign-in or a key (the card: nothing)

one line per track for up to 30 tracks, human lines first, the house voice on misses (at most 6 fresh per call). &format=card is a 1080×1350 grid. off the site the records come as spotify links, without names; ten calls per network per ten minutes. more →

GET /api/v1/takes?song=<id or link>needs nothing

every human line filed on a record, newest first, up to 50, each with its writer, votes, element and permanent /t/ address. free, always. more →

GET /api/record/<spotify id>needs nothing

what the song page itself loads: the song, its lines with votes and elements, the house’s line, and sibling records. free. more →

POST /api/v1/takes { spotifyId|url, text, element?, author? } · x-api-keyneeds a key

file one line, 1–280 characters, no links, about one part of the song (sound · lyrics · title · canvas · art). the same gate the site uses: 60 a day per key, 10 a day per writer. more →

POST /api/explore { query }needs nothing

a feeling in words in; the moods it maps to and the human lines that match out, each with its song, artist and spotify link. more →

https://open.spotify.com/embed/track/<spotify id> (the read’s doors.embed)needs a browser

spotify’s own player, for a record’s thirty seconds. the sound plays there and only there: never another service’s clip beside spotify’s cover or song details, which spotify’s rules forbid. more →

GET /api/daily-songneeds nothing

today’s song, its top line, how many have been filed, and when it rolls over (midnight utc). more →

GET /api/battles/todayneeds nothing (voting is on the site)

two lines on one record, today. read it anywhere; the votes are cast on the wall, signed in. more →

GET /api/qr?text=<a photoprompting.org address>needs nothing

an svg qr code for any on-site address — a song page, a take, a diary. it refuses anything off-site. more →

GET /api/oembed?url=<take url>&format=jsonneeds nothing

oembed 1.0: paste a /t/ link into anything that speaks it (wordpress, ghost, notion) and the card renders. the framable card is /embed/take/<id>. more →

<script src="https://photoprompting.org/embed.js" data-pp-embed="<track>" data-theme="dark" async></script>needs nothing

the take on a track inside an iframe on any page. a track id, a spotify link, or a song uuid. more →

POST /api/hermit/prose { form, topic, length? } · x-user-token or x-api-keyneeds sign-in or a key

longer writing in the voice, one draft. forms: about · vignette · review · riff · launch-post · micro-essay · story. answers as { prose }. 8 per 10 minutes, and a day’s ceiling for the whole house. since 21 october a signed-in member or a key: an open door here was a free model for anyone. more →

POST /api/hermit/audition { text, songTitle?, songArtist? }needs nothing

one line written as the voice; the distilled profile answers { score 0–100, verdict, tell }. 6 per 10 minutes. more →

GET /api/hermit/voice-profileneeds nothing

the distilled personality — summary, moves, vocabulary, avoids — with the corpus size and the week it was distilled. it changes on mondays. more →

POST /api/hermit/interpret { spotifyId }needs nothing

the read with its paperwork: source (community or model), provenance (the take and writer, or the model and exemplar count), quality, cached or not. more →

POST /api/v1/voice { prompt, form?, length?, best?, voice_version? } · x-api-keyneeds a key

the commercial door. metered by the key’s daily quota, then by credits; every answer stamped with voice.version and corpus_takes; best:true is three drafts and a judge for 3 units. more →

https://photoprompting.org/api/mcp (streamable http, one sign-in screen)needs an assistant that speaks mcp

the hermit as a tool in claude, chatgpt, cursor or claude code: find_song · read_song · speak_take · song_card · read_playlist · takes_on_song · file_take. a key works as a bearer header too. more →

/botneeds a discord server

drop a spotify link in a channel, get the line and the 30 seconds. /take files one; /desk is for artists. more →

/s/<spotify id> · /t/<take id>needs nothing

one page per record and one per line — the art, the 30 seconds, every take, the door to write yours. link them, print them, put them in a qr. more →

GET /api/till · /api/till/go?sku=<id>needs a card

keys, credits, desk reads and tips, by card. the catalog is live at /api/till; a plain link starts a purchase from anywhere. more →

GET /api/credits/balanceneeds sign-in

your credits, as a number, plus how many keys are tied to your account. one credit covers one fresh read past the daily allowance on any metered door. the same figure sits on /credits and your profile row. more →

the resources · the reference

where the doors are documented, tried, and paid for.

  • the docsthe reference: every endpoint, every parameter, error shapes./docs
  • the doorsevery door tried live on one page — paste a link and watch them all answer./doors
  • openapi.jsonthe machine-readable contract; import it into anything that speaks openapi./openapi.json
  • llms.txtthe guide written for agents — when to reach for the wall and when not to./llms.txt
  • llms-full.txtthe long form of the same guide./llms-full.txt
  • mcp.jsonthe mcp discovery manifest./.well-known/mcp.json
  • connectthree steps to put the hermit inside claude, chatgpt, cursor or claude code./connect
  • the botthe discord bot: drop a link, get the line./bot
  • the auditionthe voice scores a line before it goes up, on the doors page./doors#audition
  • public/examplesthe six runnable files: journal.mjs · game.mjs · passphrase.mjs · nowplaying.sh · footer.html · photos.mjs./examples/journal.mjs
  • embed.jsthe drop-in widget./embed.js
  • the pressthe wall typeset for paper — index cards, a manuscript, broadsides./print
  • the diaryevery line filed on an artist’s songs, per artist./diary
  • todaythe day’s crown, what the wire posts./today
  • pricingguest → member → key; what a key’s quota is./pricing
  • creditsearn them with signal or buy them; your balance./credits
  • api accessask for a key./api-access
  • the voice licensewhat outputs you own and what the corpus and voice are not./voice-license

the resources · the walls

what each door allows before it asks you to slow down. cached and filed reads are free everywhere.

the read20 fresh reads a day per reader, from a public allowance of 150; members 12; keys their tier; then 1 credit per fresh read for members and owned keys. cached and filed reads are free and unlimited
the playlistup to 30 tracks a call; at most 6 fresh reads per call
the filing60 a day per key · 10 a day per writer · 30 a day per address · 300 a day overall
the prose8 per address per 10 minutes
the audition6 per address per 10 minutes
the licensed voicea key’s daily quota (25 · 100 · 350 · 1200 by tier), then 1 credit per read; best-of-three is 3
the mcp serveranonymous passes share a small daily allowance of fresh reads; file_take is ten a day per handle

six you can run · 01–06

each a single file in /examples, retried on hiccups, nothing but fetch. the same six sit on the doors.

01

the journal that asks first

journal.mjs ↗

give it a song; the house reads it first; you answer with one line; it is filed under your name. once a day and a diary accumulates.

run it

curl -sO https://photoprompting.org/examples/journal.mjs && PP_KEY=pp_… PP_NAME="you" node journal.mjs https://open.spotify.com/track/75IQVo8hqI1iwVZyvkN2VT
02

the private game

game.mjs ↗

five rounds from your own group’s records — a line, four songs, which one is it. --print makes rounds you can paste into a chat.

run it

curl -sO https://photoprompting.org/examples/game.mjs && node game.mjs 75IQVo8hqI1iwVZyvkN2VT 0bu0to8kgrXDzWklgZ3BuQ 5vkkhwtKWnGkFu3tagE71D 1byxxkw33SsLEYNRKdmaOQ
03

passphrases you remember

passphrase.mjs ↗

reads the lines on songs you name and mints long passphrases from their strangest words. it only reads public lines; nothing you type goes anywhere.

run it

curl -sO https://photoprompting.org/examples/passphrase.mjs && node passphrase.mjs 75IQVo8hqI1iwVZyvkN2VT 0bu0to8kgrXDzWklgZ3BuQ 1byxxkw33SsLEYNRKdmaOQ
04

the office speaker

nowplaying.sh ↗

one deadpan line in slack for whatever is playing. eight lines of shell around the read call in text format.

run it

curl -sO https://photoprompting.org/examples/nowplaying.sh && SLACK_WEBHOOK=https://hooks.slack.com/services/… bash nowplaying.sh 75IQVo8hqI1iwVZyvkN2VT
05

the record beside the photograph

photos.mjs ↗

photography: a folder of pictures becomes print-ready wall labels — each photo paired with the record people wrote about that mood, one line, and a qr that plays the 30 seconds at the frame. the photographs never leave your machine.

run it

curl -sO https://photoprompting.org/examples/photos.mjs && node photos.mjs ./shots # → shots/wall.html, open it, press print
06

the footer

footer.html ↗

end a newsletter or a page with one take as a card. swap the eight characters for any take on the wall.

run it

curl -s https://photoprompting.org/examples/footer.html

ninety-four more · 07–100

by the hour of the day they belong to, then by the room. narrow by category, by door, or by a word.

by door

showing 94 of 94

mornings & rituals

the same line at the same hour, until it is part of the day.8
07

the alarm that reads

mornings & rituals

your alarm song, read to you before you are upright. an automation runs at the alarm, fetches the line as plain text, and speaks it.

how

ios shortcuts · automation "when alarm goes off": Get Contents of URL → https://photoprompting.org/api/hermit/read?song=75IQVo8hqI1iwVZyvkN2VT&format=text Speak Text
doorsneeds · a phone
08

the coffee card

mornings & rituals

the day’s record on the counter. a cron pulls today’s song, fetches its square card, and sends it to the receipt printer or the e-ink frame.

how

ID=$(curl -s https://photoprompting.org/api/daily-song | jq -r .song.spotifyId) curl -s "https://photoprompting.org/api/hermit/card?song=$ID&format=square&community=1" -o today.png && lp today.png
doorsneeds · a printer or a frame
09

the commute, annotated

mornings & rituals

the tracks you will hear on the drive, one line each, sent to yourself before you leave the house.

how

curl -s "https://photoprompting.org/api/hermit/playlist?ids=75IQVo8hqI1iwVZyvkN2VT,0bu0to8kgrXDzWklgZ3BuQ,5vkkhwtKWnGkFu3tagE71D" \ | jq -r '.tracks[] | "\(.title) — \(.line)"'
doorsneeds · nothing
10

the shower line

mornings & rituals

you say one sentence about the song while the water runs; your assistant files it under your handle once you are dry. your words, not its.

how

by voice, to an assistant connected at https://photoprompting.org/api/mcp: "file this on show me how: the bass line walks home the long way — about the sound" → file_take(song, line, part: "sound") → it reads the line back, you say yes, it answers with the /t/ address
doorsneeds · an assistant with the mcp server
11

the lunch audition

mornings & rituals

one line a day, judged. keep the scores in a spreadsheet and watch the tell change over a month.

how

curl -s -X POST https://photoprompting.org/api/hermit/audition -H 'content-type: application/json' \ -d '{"text":"this chorus files its taxes early","songTitle":"Show Me How","songArtist":"Men I Trust"}' # → { "score": 0-100, "verdict": "…", "tell": "…" }
doorsneeds · nothing
12

the last song of the day

mornings & rituals

the final record you played, one line about it, appended to tonight’s note. a month of nights reads like a calendar.

how

ios shortcuts · "when sleep focus turns on": Get Current Song → Get Contents of URL → https://photoprompting.org/api/hermit/read?url=<the share link>&format=text Append to Note "nights"
doorsneeds · a phone
13

the saturday battle

mornings & rituals

today’s battle over breakfast. the household reads both lines and votes by show of hands; whoever picked the loser does the dishes.

how

curl -s https://photoprompting.org/api/battles/today | jq '{song: .battle.song.title, a: .battle.take_a.text, b: .battle.take_b.text}'
doorsneeds · nothing
14

the sunday letter

mornings & rituals

one record for the year. every sunday you file one line on it. in december the song’s page is the letter, in order, dated.

how

curl -s -X POST https://photoprompting.org/api/v1/takes -H "x-api-key: $PP_KEY" -H 'content-type: application/json' \ -d '{"spotifyId":"1byxxkw33SsLEYNRKdmaOQ","text":"week nine: the kettle again","element":"sound","author":"you"}' # the letter: https://photoprompting.org/s/1byxxkw33SsLEYNRKdmaOQ
doorsneeds · a key

writing & journals

the line is the entry; the song is where it is kept.9
15

the one-line memoir

writing & journals

forty songs in the order you met them, one line each. file them over a season, then pull your own lines back out into a manuscript.

how

for id in $IDS; do curl -s "https://photoprompting.org/api/v1/takes?song=$id" | jq -r '.takes[] | select(.author=="you") | .text' done > memoir.txt
doorsneeds · a key
16

the prompt jar

writing & journals

the voice’s signature moves, one drawn at random each morning as the day’s writing prompt. the jar refills on mondays when the voice re-distills.

how

curl -s https://photoprompting.org/api/hermit/voice-profile | jq -r '.profile.moves[]' | shuf -n 1
doorsneeds · nothing
17

the deadpan review column

writing & journals

a weekly sidebar written in the voice about whatever your newsletter covered. free tier, one draft, you edit.

how

curl -s -X POST https://photoprompting.org/api/hermit/prose -H 'content-type: application/json' \ -d '{"form":"review","topic":"a folding chair","length":"short"}' | jq -r .prose
doorsneeds · sign-in or a key
18

the rewrite drill

writing & journals

write a line, audition it, rewrite until the tell stops naming the same flaw. three tries, then file the survivor.

how

audition → read the "tell" → rewrite → audition again (6 per 10 minutes) then: POST https://photoprompting.org/api/v1/takes with the line that stopped getting the same note
doorsneeds · a key
19

the two-hand notebook

writing & journals

two people, one record, both file. the list shows who wrote what, and when, without either of you saying so.

how

curl -s "https://photoprompting.org/api/v1/takes?song=75IQVo8hqI1iwVZyvkN2VT" \ | jq -r '.takes[] | "\(.created_at[:10]) \(.author): \(.text)"'
doorsneeds · a key each
20

the opener

writing & journals

the week’s record as the topic; the voice writes two hundred words; you write the rest of the essay against it.

how

curl -s -X POST https://photoprompting.org/api/hermit/prose -H 'content-type: application/json' \ -d '{"form":"micro-essay","topic":"Show Me How by Men I Trust, on a tuesday"}' | jq -r .prose
doorsneeds · sign-in or a key
21

the warm-up

writing & journals

before you read anyone else, write your own line on today’s song. then look at what the wall said, and notice the difference.

how

curl -s https://photoprompting.org/api/daily-song | jq -r '.song | "\(.title) — \(.artist)"' # write yours first. then: curl -s "https://photoprompting.org/api/hermit/read?song=$(curl -s https://photoprompting.org/api/daily-song | jq -r .song.spotifyId)&community=1&format=text"
doorsneeds · nothing
22

the epigraph finder

writing & journals

a chapter has a mood. ask for it in words; take the most-voted line as the epigraph, with the writer’s name under it.

how

curl -s -X POST https://photoprompting.org/api/explore -H 'content-type: application/json' -d '{"query":"leaving a party early"}' \ | jq -r '.takes | sort_by(-.votes)[0] | "\(.text)\n — \(.display_name), on \(.songs.title)"'
doorsneeds · nothing
23

the sentence test

writing & journals

audition your best sentence from any draft. it scores how much the sentence reads like a thing a person would say once. low scores usually mean you were explaining.

how

curl -s -X POST https://photoprompting.org/api/hermit/audition -H 'content-type: application/json' \ -d '{"text":"<one sentence from your draft>"}' | jq '{score, tell}'
doorsneeds · nothing

home, hardware & displays

frames, printers, speakers, a pi in the kitchen.6
24

the frame that matches the room

home, hardware & displays

each room has a word — kitchen: sunday, office: focus, hall: leaving. the frame asks for the word, takes the first record that matches, and shows its card.

how

ID=$(curl -s -X POST https://photoprompting.org/api/explore -H 'content-type: application/json' -d '{"query":"sunday"}' \ | jq -r '.takes[0].songs.spotify_url' | grep -oE '[A-Za-z0-9]{22}') curl -s "https://photoprompting.org/api/hermit/card?song=$ID&format=square" -o frame.png
doorsneeds · a frame
25

the kitchen caption

home, hardware & displays

when the kitchen speaker changes track, the little display shows the line in text form. nobody asked; it is just there.

how

configuration.yaml: rest_command: hermit_line: url: "https://photoprompting.org/api/hermit/read?url={{ track_url }}&format=text" automation: on media_player track change → hermit_line → show on the display
doorsneeds · home assistant
26

the doorbell

home, hardware & displays

the doorbell rings and the hallway speaker says one line about the house’s record. guests stop asking what it means by the third visit.

how

automation: doorbell pressed → rest: https://photoprompting.org/api/hermit/read?song=0bu0to8kgrXDzWklgZ3BuQ&format=text tts.speak: the response body
doorsneeds · home assistant
27

the record shelf

home, hardware & displays

a label per vinyl: the line, the credit, and a qr to the song’s page, where the 30 seconds play. the shelf becomes its own liner notes.

how

curl -s "https://photoprompting.org/api/hermit/read?song=75IQVo8hqI1iwVZyvkN2VT&format=text" curl -s "https://photoprompting.org/api/qr?text=https://photoprompting.org/s/75IQVo8hqI1iwVZyvkN2VT" -o shelf-01.svg
doorsneeds · a label printer
28

the pi radio

home, hardware & displays

type a mood on the keypad. the pi opens each matching record in spotify’s own player, in order, and scrolls its line while the thirty seconds play.

how

curl -s -X POST https://photoprompting.org/api/explore -H 'content-type: application/json' -d '{"query":"rain on a bus"}' \ | jq -r '.takes[] | "\(.songs.spotify_url)\t\(.text)"' | while IFS=$'\t' read u line; do echo "$line"; timeout 35 chromium --kiosk "${u/\/track\//\/embed\/track\/}" # spotify’s player, thirty seconds a record done
doorsneeds · a raspberry pi
29

the car

home, hardware & displays

a song starts; you ask the assistant what the wall thinks; it says one sentence and stops. it never reads a link aloud.

how

by voice: "what does the hermit think of this song?" → find_song → speak_take → one plain sentence: the record, the credit, the line
doorsneeds · an assistant with the mcp server

work, slack & tooling

crons, hooks, actions, the channel that needs one human sentence.8
30

the standup opener

work, slack & tooling

nine o’clock, the channel gets one line on the day’s record. the standup starts with something nobody has to defend.

how

ID=$(curl -s https://photoprompting.org/api/daily-song | jq -r .song.spotifyId) LINE=$(curl -s "https://photoprompting.org/api/hermit/read?song=$ID&format=text") curl -s -X POST "$SLACK_WEBHOOK" -H 'content-type: application/json' -d "$(jq -cn --arg t "$LINE" '{text:$t}')"
doorsneeds · a slack webhook
31

the merge line

work, slack & tooling

a merged pull request gets one line from the author’s record. a json file in the repo maps handles to track ids; the action does the rest.

how

- run: | ID=$(jq -r ".\"$GITHUB_ACTOR\"" .records.json) curl -s "https://photoprompting.org/api/hermit/read?song=$ID&format=text" | gh pr comment "$PR" --body-file -
doorsneeds · github actions
32

the release card

work, slack & tooling

ci ships; the ops channel gets the release song’s card in the dark discord format instead of a green checkmark.

how

curl -s "https://photoprompting.org/api/hermit/card?song=$RELEASE_SONG&format=discord" -o release.png curl -s -F "[email protected]" "$DISCORD_WEBHOOK"
doorsneeds · a discord or slack webhook
33

the on-call list

work, slack & tooling

the pager fires and the incident channel gets the team’s six comfort records, one line each. the incident is still the incident; the channel is calmer.

how

curl -s "https://photoprompting.org/api/hermit/playlist?ids=$TEAM_SIX" | jq -r '.tracks[] | "▶ \(.title) — \(.line)"'
doorsneeds · a pager integration
34

the pre-commit motto

work, slack & tooling

a git hook prints one filed line before each commit. community only, so it costs nothing and never waits on a model.

how

.git/hooks/pre-commit: #!/bin/sh curl -s -m 2 "https://photoprompting.org/api/hermit/read?song=0bu0to8kgrXDzWklgZ3BuQ&community=1&format=text" || true
doorsneeds · git
35

the shell greeting

work, slack & tooling

a new line each time a terminal opens. two-second timeout, so a slow network never slows you down.

how

# .zshrc curl -s -m 2 "https://photoprompting.org/api/hermit/read?song=5vkkhwtKWnGkFu3tagE71D&format=text" 2>/dev/null; echo
doorsneeds · a terminal
36

the retro

work, slack & tooling

the sprint has a record. each teammate files one line on it under their own handle; the retro doc embeds the song’s page. nobody writes a paragraph.

how

POST https://photoprompting.org/api/v1/takes {"spotifyId":"<the sprint record>","text":"<one line>","author":"<their handle>"} <script src="https://photoprompting.org/embed.js" data-pp-embed="<the sprint record>" data-theme="dark" async></script>
doorsneeds · a key
37

the status page footer

work, slack & tooling

your status page ends with today’s crown as a card. green or red above, one human sentence below.

how

curl -s "https://photoprompting.org/api/oembed?url=https://photoprompting.org/t/f9fdc3d9&format=json" | jq -r .html
doorsneeds · nothing

photography, art & print

the record beside the picture; the line on paper.8
38

the zine

photography, art & print

a photograph on the left page, the card of the record that matches its mood on the right. sixteen spreads, stapled.

how

node photos.mjs ./shots # the built recipe makes shots/wall.html # or per spread: curl -s "https://photoprompting.org/api/hermit/card?song=<id>&format=square" -o spread-01-right.png
doorsneeds · a printer
39

the album insert

photography, art & print

a musician prints the lines listeners filed on the release as the insert of the physical edition. credited, dated, in the order they arrived.

how

curl -s "https://photoprompting.org/api/record/75IQVo8hqI1iwVZyvkN2VT" \ | jq -r '.takes | sort_by(.created_at)[] | "\(.text)\n — \(.display_name), \(.created_at[:10])\n"' > insert.txt
doorsneeds · nothing
40

the postcard series

photography, art & print

the 1200×630 card printed as a 4×6. on the back, a qr to the song’s page so the person you mail it to hears the 30 seconds.

how

curl -s "https://photoprompting.org/api/hermit/card?take=f9fdc3d9&format=card" -o front.png curl -s "https://photoprompting.org/api/qr?text=https://photoprompting.org/s/75IQVo8hqI1iwVZyvkN2VT" -o back.svg
doorsneeds · a printer
41

the test strip

photography, art & print

pick a mood; spotify’s player plays the record for about thirty seconds; that is your test-strip timer, with a line to read while the paper sits in the tray.

how

open "https://open.spotify.com/embed/track/75IQVo8hqI1iwVZyvkN2VT" # spotify’s player: when the thirty seconds end → pull the strip
doorsneeds · a darkroom
42

the caption

photography, art & print

the shoot had a mood. say it in words; the most-voted line on a matching record is the caption, with the writer’s name. nobody has to think of something to say under a photograph again.

how

curl -s -X POST https://photoprompting.org/api/explore -H 'content-type: application/json' -d '{"query":"golden hour, nobody talking"}' \ | jq -r '.takes | sort_by(-.votes)[0] | "\(.text) — \(.display_name)"'
doorsneeds · nothing
43

the manuscript

photography, art & print

your own lines, typeset as a book. the press at /print sets a manuscript from the wall; a year of lines is a volume.

how

https://photoprompting.org/print → manuscript # or gather them yourself, one record at a time: curl -s "https://photoprompting.org/api/v1/takes?song=<id>" | jq -r '.takes[] | select(.author=="you") | .text'
doorsneeds · a year of lines
44

the light and the grid

photography, art & print

eight long exposures from one night, each paired with the grid card of the eight records that played while the shutter was open.

how

curl -s "https://photoprompting.org/api/hermit/playlist?ids=<eight ids>&format=card" -o night-grid.png # 1080×1350
doorsneeds · nothing
45

the wall text

photography, art & print

gallery wall text in the voice: the form is "about", the topic is the show. your name under it; the voice’s version stamped in the corner if you like footnotes.

how

curl -s -X POST https://photoprompting.org/api/hermit/prose -H 'content-type: application/json' \ -d '{"form":"about","topic":"twelve photographs of the same bus stop","length":"short"}' | jq -r .prose
doorsneeds · sign-in or a key

games & parties

the wall as a deck of cards.8
46

the quiz round

games & parties

ten records in, ten lines out, titles stripped. teams name the record from the line alone. the house voice lines are the hard ones.

how

curl -s "https://photoprompting.org/api/hermit/playlist?ids=<ten ids>" | jq -r '.tracks[] | .line' | nl
doorsneeds · nothing
47

the birthday roast

games & parties

guests file one line each on the birthday person’s most-played record, under their own names. ten a day per writer, so nobody can dominate.

how

POST https://photoprompting.org/api/v1/takes {"spotifyId":"<their record>","text":"<the roast, one line>","author":"<guest>"} # the wall for the toast: https://photoprompting.org/s/<their record>
doorsneeds · a key
48

the table battle

games & parties

today’s battle on the television; the table argues; someone signs in and casts the table’s vote.

how

curl -s https://photoprompting.org/api/battles/today | jq '.battle | {song: .song.title, a: .take_a.text, b: .take_b.text}'
doorsneeds · a tv
49

the audition tournament

games & parties

one song, everyone writes a line, the audition scores them, the tells are read aloud in ascending order. the winner is not who you expect.

how

for line in "$@"; do curl -s -X POST https://photoprompting.org/api/hermit/audition -H 'content-type: application/json' \ -d "$(jq -cn --arg t "$line" '{text:$t, songTitle:"Show Me How", songArtist:"Men I Trust"}')" | jq -c '{score, tell}' done
doorsneeds · nothing
50

the invitation

games & parties

the night’s set as a grid card. that image is the invitation; the tracks are the promise.

how

curl -s "https://photoprompting.org/api/hermit/playlist?ids=<the set>&format=card" -o invite.png
doorsneeds · nothing
51

the karaoke intro

games & parties

before each song, the line on the screen for eight seconds. the singer walks up to a sentence instead of a countdown.

how

curl -s "https://photoprompting.org/api/hermit/read?url=<next song’s link>&format=text" # show it, wait 8s, start
doorsneeds · a screen
52

the road trip

games & parties

every new state line, the driver names a song and each passenger files one line about it by voice. the trip is on the wall by the time you are home.

how

by voice: "file this on <song>: <one line> — about the sound" → file_take under each passenger’s handle, ten a day each
doorsneeds · an assistant with the mcp server
53

the blind date with a record

games & parties

ask for a mood, hide the titles, play each record in spotify’s player. guess the artist from thirty seconds and one line.

how

curl -s -X POST https://photoprompting.org/api/explore -H 'content-type: application/json' -d '{"query":"driving home after a win"}' \ | jq -r '.takes[] | "\(.text)\t\(.songs.title)\t\(.songs.artist)"' # read column 1 aloud, keep 2 and 3
doorsneeds · nothing

classrooms & language

real sentences by real people, short enough to study.7
54

the esl warm-up

classrooms & language

students paraphrase three real lines on one record. the teacher files the best paraphrase under the student’s handle with the class key.

how

curl -s "https://photoprompting.org/api/v1/takes?song=75IQVo8hqI1iwVZyvkN2VT" | jq -r '.takes[:3][] | .text' # then the winner: POST https://photoprompting.org/api/v1/takes {"spotifyId":"…","text":"…","author":"<student handle>"}
doorsneeds · a class key
55

the figure hunt

classrooms & language

fifty lines across ten records. students tag each as metaphor, simile, understatement or plain statement, then argue about the ones that are two at once.

how

for id in $TEN; do curl -s "https://photoprompting.org/api/v1/takes?song=$id" | jq -r '.takes[:5][] | .text'; done > lines.txt
doorsneeds · nothing
56

the tone lesson

classrooms & language

the voice profile’s moves and avoids, read as a lesson on deadpan: what the voice does, what it refuses to do, and why the refusals are the style.

how

curl -s https://photoprompting.org/api/hermit/voice-profile | jq '.profile | {summary, moves, avoids}'
doorsneeds · nothing
57

the bell-ringer

classrooms & language

the day’s record and its top line open the period. five minutes: what part of the song is the line about, and how do you know.

how

curl -s https://photoprompting.org/api/daily-song | jq '{song: .song.title, artist: .song.artist, top: .topTake}'
doorsneeds · nothing
58

the translation drill

classrooms & language

translate a line into the target language and back again. compare with the original on the board; the words that did not survive are the lesson.

how

curl -s "https://photoprompting.org/api/v1/takes?song=0bu0to8kgrXDzWklgZ3BuQ" | jq -r '.takes[0] | "\(.text) — \(.author)"'
doorsneeds · nothing
59

the vocabulary wall

classrooms & language

the strangest words across the class’s records become the week’s list. the passphrase recipe already knows how to find them.

how

node passphrase.mjs <ids> # prints the word pool it drew from # or: curl -s "https://photoprompting.org/api/v1/takes?song=<id>" | jq -r '.takes[].text' | tr -cs '[:alpha:]' '\n' | awk 'length>7' | sort -u
doorsneeds · nothing
60

the decade

classrooms & language

a decade’s records, one line each on the board. then students file their own lines about the album art of the era, element "art".

how

curl -s "https://photoprompting.org/api/hermit/playlist?ids=<the decade>" | jq -r '.tracks[] | "\(.artist) — \(.title): \(.line)"' POST https://photoprompting.org/api/v1/takes {"spotifyId":"…","text":"…","element":"art","author":"<student>"}
doorsneeds · a class key

discovery & djs

the crate, the cue sheet, the second opinion.8
61

the crate

discovery & djs

a mood in; records you have not heard out, ranked by votes, each with its spotify link; the thirty seconds play in spotify’s player while you decide which to keep.

how

curl -s -X POST https://photoprompting.org/api/explore -H 'content-type: application/json' -d '{"query":"3am kitchen"}' \ | jq -r '.takes | sort_by(-.votes)[] | "\(.votes)\t\(.songs.artist) — \(.songs.title)\t\(.songs.spotify_url)"'
doorsneeds · nothing
62

the cue sheet

discovery & djs

the set’s track ids in, one line per track out, printed on the cue sheet. something to say into the mic that is not the title.

how

curl -s "https://photoprompting.org/api/hermit/playlist?ids=<the set>" | jq -r '.tracks[] | "\(.title)\t\(.line)\t\(.author // "the house")"' | column -ts $'\t'
doorsneeds · nothing
63

the radio hour

discovery & djs

top of the hour: the day’s record, the read, and the top human line credited on air. the credit is the whole point.

how

ID=$(curl -s https://photoprompting.org/api/daily-song | jq -r .song.spotifyId) curl -s "https://photoprompting.org/api/record/$ID" | jq -r '.takes | sort_by(-.votes)[0] | "\(.text) — \(.display_name), on the wall"'
doorsneeds · nothing
64

the second opinion

discovery & djs

the house line beside the human lines for the same record. where they disagree is the review; where they agree, the song won.

how

curl -s "https://photoprompting.org/api/hermit/read?song=75IQVo8hqI1iwVZyvkN2VT&fresh=1&format=text" curl -s "https://photoprompting.org/api/v1/takes?song=75IQVo8hqI1iwVZyvkN2VT" | jq -r '.takes[] | " \(.author): \(.text)"'
doorsneeds · nothing
65

the club

discovery & djs

one record a week. members file their lines by sunday; the song’s page is the agenda for the call. nobody prepares a speech.

how

POST https://photoprompting.org/api/v1/takes {"spotifyId":"<this week>","text":"<one line>","author":"<member>"} # the agenda: https://photoprompting.org/s/<this week>
doorsneeds · a key each
66

the band’s diary

discovery & djs

an artist’s page of lines, per song, lives at /diary/<artist>. pick the song with the fewest lines for next week; that is where the club is needed.

how

https://photoprompting.org/diary/men-i-trust # or count per record: curl -s "https://photoprompting.org/api/v1/takes?song=<id>" | jq .count
doorsneeds · nothing
67

the mood bridge

discovery & djs

the mood gives you spotify links; you build the playlist in your own account from them. the wall picks, spotify plays, as it should be.

how

curl -s -X POST https://photoprompting.org/api/explore -H 'content-type: application/json' -d '{"query":"first warm day"}' \ | jq -r '.takes[].songs.spotify_url' | sort -u
doorsneeds · your own spotify account
68

the label’s one-sheet

discovery & djs

the human lines on a release, credited, on the press one-sheet. the house line only where nobody has written yet, and marked as the house.

how

curl -s "https://photoprompting.org/api/v1/takes?song=<release>" | jq -r '.takes[] | "“\(.text)” — \(.author)"' curl -s "https://photoprompting.org/api/hermit/read?song=<release>" | jq -r '"\(.line) [\(.source)]"'
doorsneeds · nothing

assistants & agents

the hermit as a tool; the human as the only author.8
69

the assistant that credits

assistants & agents

connect once. ask what the wall says about a song; the line arrives with the writer’s handle and its permanent /t/ address, quoted exactly.

how

claude mcp add --transport http photoprompting https://photoprompting.org/api/mcp # then: "what does the wall say about show me how by men i trust?"
doorsneeds · claude, chatgpt, cursor or claude code
70

the voice-mode dj

assistants & agents

in a spoken conversation the assistant uses speak_take: one sentence, the record, the credit, the line. it never reads an address aloud; it offers to send it.

how

speak_take(song) → "on show me how by men i trust, <credit> wrote: <the line>."
doorsneeds · an assistant with voice mode
71

the playlist reader

assistants & agents

paste twelve links. read_playlist answers one line per track, human first, and a grid card url you can post as is.

how

read_playlist(tracks: [<up to 12 links or ids>], name: "friday") → { lines, quota, grid_card_url }
doorsneeds · an assistant with the mcp server
72

the dictation filer

assistants & agents

"file this on it: …" — the assistant files your words under your handle and never its own. an identical line already on the record comes back as already there.

how

file_take(song, "this bass line walks home the long way", part: "sound") → { filed, url, line, on, song, card_url } or { already_on_the_wall: true }
doorsneeds · an assistant with the mcp server
73

the cursor epigraph

assistants & agents

the coding agent can fetch the line for your readme’s epigraph when you ask, credited. it cannot write one, and it says so.

how

.cursor/mcp.json: { "mcpServers": { "photoprompting": { "url": "https://photoprompting.org/api/mcp" } } }
doorsneeds · cursor
74

the chatgpt app

assistants & agents

developer mode on, add the mcp url as an app, sign in once on the consent screen. from then on a pasted spotify link gets the wall’s line.

how

settings → apps → create → mcp server url: https://photoprompting.org/api/mcp → authentication: oauth
doorsneeds · chatgpt plus, pro or business
75

the morning agent

assistants & agents

a scheduled agent reads the day’s song and posts the credited line to your channel. it reads; it never files. the human is the only author on the wall.

how

daily 08:00 → GET https://photoprompting.org/api/daily-song → GET https://photoprompting.org/api/hermit/read?song=<spotifyId>&community=1 → post line + credit + /t/ address
doorsneeds · a scheduled agent
76

the bearer key

assistants & agents

an agent that already holds a key skips the sign-in screen: the key rides in the authorization header and reaches every door as x-api-key.

how

POST https://photoprompting.org/api/mcp Authorization: Bearer pp_… { "jsonrpc": "2.0", "method": "tools/list", "id": 1 }
doorsneeds · a key

web, embeds & publishing

the card where a stock photo used to go.8
77

the epigraph

web, embeds & publishing

every post opens with an embedded take instead of a hero image. one line, the record, the 30 seconds, in a frame the width of the column.

how

<script src="https://photoprompting.org/embed.js" data-pp-embed="0bu0to8kgrXDzWklgZ3BuQ" data-theme="dark" async></script>
doorsneeds · a page you can edit
78

the paste

web, embeds & publishing

paste a /t/ link on its own line. the cms asks the oembed door and the card renders. nothing to install.

how

https://photoprompting.org/t/f9fdc3d9 # what the cms asks: https://photoprompting.org/api/oembed?url=https://photoprompting.org/t/f9fdc3d9&format=json
doorsneeds · wordpress, ghost, notion, or anything with oembed
79

the link-in-bio

web, embeds & publishing

the card of your pinned take as the top block of your bio page. the image is the sentence you would say if someone asked.

how

<img src="https://photoprompting.org/api/hermit/card?take=<your take>&format=square" alt="my line on the wall" width="540">
doorsneeds · nothing
80

the last line

web, embeds & publishing

the issue has a record. the send script appends its line in text form under your sign-off, credited, every issue.

how

LINE=$(curl -s "https://photoprompting.org/api/hermit/read?song=$ISSUE_SONG&format=text") printf '\n\n—\n%s\n' "$LINE" >> issue.md
doorsneeds · a send script
81

the 404

web, embeds & publishing

"wrong record." your not-found page shows a random card from a short list of your records. people stay longer on the page that failed them.

how

const ids = ["75IQVo8hqI1iwVZyvkN2VT","0bu0to8kgrXDzWklgZ3BuQ","5vkkhwtKWnGkFu3tagE71D"] img.src = `https://photoprompting.org/api/hermit/card?song=${ids[Math.floor(Math.random()*ids.length)]}&format=card`
doorsneeds · a site
82

the og image

web, embeds & publishing

your review pages use the record’s card as the og:image. the link preview is a sentence, not a logo.

how

<meta property="og:image" content="https://photoprompting.org/api/hermit/card?song=75IQVo8hqI1iwVZyvkN2VT&format=card">
doorsneeds · a site
83

the show notes

web, embeds & publishing

each episode has a record. the notes carry the read and the human lines; the cover carries a qr to the song’s page.

how

curl -s "https://photoprompting.org/api/hermit/read?song=<id>&format=text" curl -s "https://photoprompting.org/api/v1/takes?song=<id>" | jq -r '.takes[] | "- \(.text) — \(.author)"' curl -s "https://photoprompting.org/api/qr?text=https://photoprompting.org/s/<id>" -o cover-qr.svg
doorsneeds · a podcast
84

the server

web, embeds & publishing

the bot in your server: drop a spotify link in any channel and the line comes back with the 30 seconds. /take files one; nobody leaves discord.

how

https://photoprompting.org/bot → add to server → paste a link in a channel
doorsneeds · a discord server

family & memory

one record, many hands, a year.6
85

the memorial record

family & memory

one song for someone gone. family files lines across a year, each under their own name; the song’s page is the memorial. the wall is public — write what you would say aloud.

how

POST https://photoprompting.org/api/v1/takes {"spotifyId":"<their song>","text":"<one line>","author":"<your name>"} # the page: https://photoprompting.org/s/<their song>
doorsneeds · a key
86

the milestone book

family & memory

the song that was playing at each first — first steps, first word, first day — and one line filed on it. at the end of the year, pull them all.

how

for id in $MILESTONE_SONGS; do curl -s "https://photoprompting.org/api/v1/takes?song=$id" | jq -r '.takes[] | select(.author=="us") | "\(.created_at[:10]) \(.text)"'; done
doorsneeds · a key
87

the long-distance line

family & memory

two cities, one record a week. both file one line; the difference between the two lines is the phone call.

how

curl -s "https://photoprompting.org/api/v1/takes?song=<this week>" | jq -r '.takes[] | "\(.author): \(.text)"'
doorsneeds · a key each
88

the mood mirror

family & memory

type how you feel in plain words; read what other people wrote when they felt it; play one record in spotify’s player. no advice, no account, no record kept of you.

how

curl -s -X POST https://photoprompting.org/api/explore -H 'content-type: application/json' -d '{"query":"tired but fine"}' \ | jq -r '.takes[:5][] | "\(.text) — \(.display_name)"'
doorsneeds · nothing
89

the anniversary card

family & memory

the take you filed on your song, printed as the card. the record, your line, your name, the address of the wall it hangs on.

how

curl -s "https://photoprompting.org/api/hermit/card?take=<your take id>&format=card" -o card.png && lp card.png
doorsneeds · a printer
90

the family key

family & memory

one key, everyone files by voice through the assistant under their own handle. sunday, the week’s records go through the playlist door and the grid card goes on the fridge.

how

file_take(…, author: "<each person>") all week curl -s "https://photoprompting.org/api/hermit/playlist?ids=<the week>&format=card" -o week.png
doorsneeds · a key

measure & meter

provenance, versions, quotas, the number on the balance.6
91

the element census

measure & meter

across a hundred records, which part of the song do people write about — the sound, the lyrics, the title, the art, the canvas. count the element field and find out.

how

for id in $HUNDRED; do curl -s "https://photoprompting.org/api/v1/takes?song=$id" | jq -r '.takes[].element // "unstamped"'; done | sort | uniq -c | sort -rn
doorsneeds · nothing
92

the drift log

measure & meter

the voice re-distills every monday. a weekly fetch of the profile, diffed against last week’s, is a log of how the wall’s voice moves.

how

curl -s https://photoprompting.org/api/hermit/voice-profile | jq '{week_epoch, corpus_size, moves: .profile.moves}' > "profile-$(date +%F).json" diff profile-<last>.json profile-<this>.json
doorsneeds · a cron
93

the crowd and the house

measure & meter

the most-voted human line against the interpret door’s answer and its paperwork: source, provenance, quality. a table of a hundred records is a study.

how

curl -s "https://photoprompting.org/api/v1/takes?song=<id>" | jq -r '.takes | sort_by(-.votes)[0].text' curl -s -X POST https://photoprompting.org/api/hermit/interpret -H 'content-type: application/json' -d '{"spotifyId":"<id>"}' | jq '{source, quality, provenance}'
doorsneeds · nothing
94

the version pin

measure & meter

a pipeline that pins voice_version. when the voice re-distills, the door answers 409 with the current version before anything is charged. nothing drifts in silence.

how

curl -s -X POST https://photoprompting.org/api/v1/voice -H "x-api-key: $PP_KEY" -H 'content-type: application/json' \ -d '{"prompt":"a folding chair","form":"review","voice_version":"hermit-<pinned>"}' # 409 → { current_version } ; every 200 carries voice.version and corpus_takes
doorsneeds · a key
95

the provenance ledger

measure & meter

every licensed answer carries voice.version, corpus_takes and the license summary. write them beside the output you publish, and an audit a year from now knows exactly which voice wrote what.

how

curl -s -X POST https://photoprompting.org/api/v1/voice -H "x-api-key: $PP_KEY" -H 'content-type: application/json' \ -d '{"prompt":"a folding chair","form":"review"}' \ | jq '{at: now|todate, version: .voice.version, corpus: .voice.corpus_takes, license: .license, text}' >> provenance.jsonl
doorsneeds · a key
96

the office key

measure & meter

a starter key from the till, bought signed in so the key is tied to your account. credits carry past the daily quota, and the balance page shows the number that is left.

how

https://photoprompting.org/api/till/go?sku=key-starter # signed in → the key is yours https://photoprompting.org/api/till/go?sku=credits-100 curl -s https://photoprompting.org/api/credits/balance --cookie "<your session>" # or just open https://photoprompting.org/credits
doorsneeds · a card

the full house

four that walk most of the doors in one flow. their free parts were run against production, as written, before they were filed.4
97

the quarter-past canary

the full house

a quarter past midnight utc, when the record and the battle roll, a cron walks nine doors and asserts each against its documented shape: the date moved, both battle lines are present and end tomorrow, the profile is distilled and no older than eight days, a filed read answers 200 inside two seconds, three community records come back all human with zero fresh reads, the card header says 200, the oembed is rich, the qr is an svg, spotify’s player answers for the record. one line per door; a fail pages the channel with the door names in the message. every check is free by construction, so it can run every night for years.

how

# cron: 15 0 * * * (a quarter past midnight utc: did the house turn over?) X=75IQVo8hqI1iwVZyvkN2VT; T=f9fdc3d9; D=$(date -u +%F); F= ok(){ printf 'ok %s\n' "$1"; }; no(){ printf 'fail %s\n' "$1"; F="$F $1"; } curl -s https://photoprompting.org/api/daily-song | jq -e --arg d "$D" '.date==$d and (.song.spotifyId|length)==22' >/dev/null && ok daily || no daily curl -s https://photoprompting.org/api/battles/today | jq -e --arg d "$D" '.battle | (.take_a.text|length)>0 and (.take_b.text|length)>0 and .ends_at[:10] > $d' >/dev/null && ok battle || no battle # eight days, not seven: on mondays this call is what triggers the re-distill, and it is served last week's profile with refreshing:true while that runs. by tuesday a stale one is a real fail curl -s https://photoprompting.org/api/hermit/voice-profile | jq -e '.source=="distilled" and ((.week_epoch[:19]+"Z"|fromdate) > (now-8*86400))' >/dev/null && ok profile || no profile [ -n "$(curl -sf -m 2 "https://photoprompting.org/api/hermit/read?song=$X&community=1&format=text")" ] && ok read || no read # -f, because the text format carries error messages as text: a 4xx or 5xx must print nothing curl -s "https://photoprompting.org/api/hermit/playlist?ids=$X,0bu0to8kgrXDzWklgZ3BuQ,5vkkhwtKWnGkFu3tagE71D&community=1" | jq -e '.shown==3 and all(.tracks[]; .source=="community") and .quota.fresh_used==0' >/dev/null && ok playlist || no playlist curl -sI "https://photoprompting.org/api/hermit/card?take=$T&format=card" | grep -qi '^x-card-status: 200' && ok card || no card curl -s "https://photoprompting.org/api/oembed?url=https://photoprompting.org/t/$T&format=json" | jq -e '.type=="rich" and (.author_name|length)>0' >/dev/null && ok oembed || no oembed curl -sI "https://photoprompting.org/api/qr?text=https://photoprompting.org/s/$X" | grep -qi 'content-type: image/svg' && ok qr || no qr [ "$(curl -s -o /dev/null -w '%{http_code}' "https://open.spotify.com/embed/track/$X")" = 200 ] && ok player || no player [ -z "$F" ] || curl -s -X POST "$SLACK_WEBHOOK" -H 'content-type: application/json' -d "$(jq -cn --arg t "the house did not turn over cleanly at midnight. failed:$F" '{text:$t}')"
doorsneeds · nothing; a cron and a webhook. every check is free
98

the night ledger

the full house

ten minutes before the day rolls at midnight utc, a cron writes the day down: the record, every line on it with votes and elements, the house line, the battle as it stood, the paperwork on the read (source, provenance, quality, cached or not), the story card and a qr to the page. one folder per date, named by the wall's own date so folder and record never disagree, and on sundays the week's seven records as a grid from filed lines only. a year of nights is an archive with every line still credited; it is not a corpus, and training on takes needs a license.

how

# crontab (must run in utc): CRON_TZ=UTC # 50 23 * * * bash ~/ledger/night.sh (ten minutes before the record rolls) cd ~/ledger; S=$(curl -s https://photoprompting.org/api/daily-song); D=$(jq -r .date <<<"$S"); ID=$(jq -r .song.spotifyId <<<"$S") # the folder takes the wall's date, not the host's mkdir -p "$D"; cd "$D"; printf '%s\n' "$S" > song.json # the interpret first, so the house line it leaves is the one the record carries. without ?fresh=1 nothing is metered: on a cache miss the house generates once and caches it for a day curl -s -X POST https://photoprompting.org/api/hermit/interpret -H 'content-type: application/json' -d "{\"spotifyId\":\"$ID\"}" | jq '{source, quality, cached: (.cached // false), provenance, model}' > paperwork.json curl -s "https://photoprompting.org/api/record/$ID" > record.json # every line with votes and elements; the house line under .house.line curl -s https://photoprompting.org/api/battles/today | jq '.battle | {id, song: .song.title, a: {id: .take_a.id, text: .take_a.text, by: (.take_a.display_name // "anonymous"), votes: .votes_a}, b: {id: .take_b.id, text: .take_b.text, by: (.take_b.display_name // "anonymous"), votes: .votes_b}, leader: (if .votes_a == .votes_b then "tied" elif .votes_a > .votes_b then .take_a.id else .take_b.id end)}' > battle.json TOP=$(jq -r '.topTake.id // empty' song.json); Q="song=$ID&community=1"; [ -n "$TOP" ] && Q="take=$TOP" curl -s -D - "https://photoprompting.org/api/hermit/card?$Q&format=story" -o card.png | grep -i x-card-status # anything but 200 flags the folder curl -s "https://photoprompting.org/api/qr?text=https://photoprompting.org/s/$ID" -o qr.svg grep -qx "$ID" ../week.txt 2>/dev/null || echo "$ID" >> ../week.txt # sundays: the week's records as the grid, filed lines only. &community=1 never generates; a record with nothing filed draws with no line [ "$(date -u +%u)" = 7 ] && curl -s "https://photoprompting.org/api/hermit/playlist?ids=$(tail -7 ../week.txt | paste -sd, -)&community=1&name=week+of+$D&format=card" -o "../week-$D.png"
doorsneeds · a cron and a disk. nothing is metered
99

the audit of one record

the full house

one record, fully accounted for. the list gives every line with its writer, votes and element; the record gives the house line, its date and the sibling count; the interpret door says which line it serves and shows the paperwork; the profile says which week's judge is sitting, and every score below carries it; the audition scores the six most-voted lines, which is exactly one ten-minute window; the licensed voice writes the abstract for one unit of the key's daily quota, version stamped in the footnote. it ends as a printed card, and every number on the page came out of a door.

how

ID=75IQVo8hqI1iwVZyvkN2VT; curl -s "https://photoprompting.org/api/v1/takes?song=$ID" > list.json # the list: every line, credited, with votes and element jq '{count, votes: ([.takes[].votes]|add), elements: ([.takes[] | (.element // "unstamped")]|group_by(.)|map({(.[0]): length})|add)}' list.json curl -s "https://photoprompting.org/api/record/$ID" | jq '{title: .song.title, artist: .song.artist, house: .house.line, house_at: .house.updated_at, siblings: (.siblings|length)}' curl -s -X POST https://photoprompting.org/api/hermit/interpret -H 'content-type: application/json' -d "{\"spotifyId\":\"$ID\"}" | jq '{line: .interpretation, source, quality, cached: (.cached // false), provenance}' # which line the door serves, and its paperwork; unmetered without ?fresh=1 WEEK=$(curl -s https://photoprompting.org/api/hermit/voice-profile | jq -r .week_epoch); T=$(jq -r .song.title list.json); A=$(jq -r .song.artist list.json) # which week's judge is sitting # the audition: the six most-voted lines (six per address per ten minutes is the wall, so the loop stops there), each score stamped with the judge's week jq -r '.takes | sort_by(-.votes)[:6][] | "\(.short)\t\(.text)"' list.json | while IFS=$'\t' read -r s text; do curl -s -X POST https://photoprompting.org/api/hermit/audition -H 'content-type: application/json' -d "$(jq -cn --arg t "$text" --arg st "$T" --arg sa "$A" '{text:$t, songTitle:$st, songArtist:$sa}')" | jq -c --arg s "$s" --arg w "$WEEK" '{short:$s, score, tell, judge:$w}' done > scores.jsonl jq -s '[.[].score | numbers] | {scored: length, mean: (if length>0 then add/length else null end), min: min, max: max}' scores.jsonl # a 429 row has no score and is left out # the abstract: licensed and stamped; one unit from the key's daily quota, then a credit. the prompt is a title, a name and two counts, nothing from the song N=$(jq .count list.json); MEAN=$(jq -s -r '[.[].score | numbers] | if length>0 then add/length|round else "none" end' scores.jsonl) curl -s -X POST https://photoprompting.org/api/v1/voice -H "x-api-key: $PP_KEY" -H 'content-type: application/json' -d "$(jq -cn --arg p "an audit of the wall on $T by $A: $N lines, mean audition $MEAN" '{prompt:$p, form:"micro-essay", length:"short"}')" | jq '{abstract: .text, version: .voice.version, corpus: .voice.corpus_takes, remaining: .usage.remaining}' TOP=$(jq -r '.takes | sort_by(-.votes)[0].short' list.json); curl -s "https://photoprompting.org/api/hermit/card?take=$TOP&format=card" -o audit-front.png && lp audit-front.png # the print: the most-voted line, credited by the card itself
doorsneeds · a key and jq; one unit of the key's quota for the abstract
100

the artist issue

the full house

a zine about one artist, assembled from the wall. the record door names the seed and its six most-written sibling records with how many lines each carries (the rest live in the diary, where the back cover points); the list pulls every line on those seven, credited or anonymous, and tallies which part of the song this artist's listeners write about; the playlist door makes the cover from filed lines only, and its quota field is the proof that nothing on the cover was generated. the editorial is the one generated page, from the licensed voice for one unit of the key's daily quota, its version in the colophon; the embeds are the web edition, one per record.

how

# as one file: curl -sO https://photoprompting.org/examples/artist-issue.sh && bash artist-issue.sh "<spotify track link>" (PP_KEY=pp_… for the editorial) # or by hand, door by door: SEED=75IQVo8hqI1iwVZyvkN2VT; curl -s "https://photoprompting.org/api/record/$SEED" > seed.json; ARTIST=$(jq -r .song.artist seed.json) jq -r '.siblings[] | "\(.count)\t\(.title)"' seed.json # the six most-written sibling records, with how many lines each; the rest are in the diary jq -r '[.song.spotify_id] + [.siblings[].spotify_id] | .[]' seed.json > ids.txt for id in $(cat ids.txt); do curl -s "https://photoprompting.org/api/v1/takes?song=$id" | jq -c '.song.title as $t | .takes[] | {title:$t, short, text, author: (.author // "anonymous"), element, votes}'; done > issue.jsonl # the list: every line on the seven, credited jq -s 'group_by(.element // "unstamped") | map({(.[0].element // "unstamped"): length}) | add' issue.jsonl # which part of the song this artist's listeners write about # the cover: one filed line per record as the grid. &community=1 never generates, so fresh_used reads 0 and every line on the cover is human curl -s "https://photoprompting.org/api/hermit/playlist?ids=$(paste -sd, ids.txt)&community=1&name=the+artist+issue&format=card" -o cover.png curl -s "https://photoprompting.org/api/hermit/playlist?ids=$(paste -sd, ids.txt)&community=1" | jq '{total, shown, fresh: .quota.fresh_used}' jq -s -r 'group_by(.title)[] | sort_by(-.votes)[0].short' issue.jsonl | while read -r s; do curl -s "https://photoprompting.org/api/hermit/card?take=$s&format=square" -o "spread-$s.png"; done # the spreads: each record's most-voted line, credited by the card # the editorial: the one generated page, licensed, one unit from the key's daily quota (then a credit), its version in the colophon. the prompt is a name and two counts, nothing from the songs N=$(jq -s length issue.jsonl); R=$(wc -l < ids.txt | tr -d ' ') curl -s -X POST https://photoprompting.org/api/v1/voice -H "x-api-key: $PP_KEY" -H 'content-type: application/json' -d "$(jq -cn --arg p "an issue about the wall on $ARTIST: $N lines across $R records" '{prompt:$p, form:"launch-post", length:"short"}')" | jq '{editorial: .text, version: .voice.version, corpus: .voice.corpus_takes}' SLUG=$(printf '%s' "$ARTIST" | tr '[:upper:]' '[:lower:]' | sed "s/['\"]//g; s/[^a-z0-9]\{1,\}/-/g; s/^-//; s/-\$//"); curl -s "https://photoprompting.org/api/qr?text=https://photoprompting.org/diary/$SLUG" -o back.svg # the back cover: the diary, slugged the diary's way for plain names for id in $(cat ids.txt); do echo "<script src=\"https://photoprompting.org/embed.js\" data-pp-embed=\"$id\" data-theme=\"dark\" async></script>"; done > web.html # the web edition: one embed per record
doorsneeds · a key and a printer; one unit of the key's quota for the editorial

the pattern under all one hundred: read (the line, with the 30 seconds), list (every line on a record), file (your line, with a key). anything that can hold those three is the hundred and first. the terms for what you may do with the output are on the voice license; the doors themselves are on the docs.

← the doorsthe docsconnect an assistantevery room