# 나들이 (Day Out) — 전국 문화행사 데이터 > 전국의 전시·교육·공연·축제를 매일 모아 보여 주는 정적 웹앱입니다. 공공 API > 9곳에서 수집하고 운영자가 직접 등록한 행사를 더해, 중복을 병합한 뒤 하나의 > JSON으로 공개합니다. 이 문서는 그 데이터를 프로그램으로 읽는 방법과 행사를 > 등록하는 방법을 설명합니다. > > **수록 범위는 요금과 대상 연령을 가리지 않습니다.** 이번 달과 다음 달에 걸쳐 > 있고 아직 끝나지 않았으며 확인 가능한 링크가 있는 행사를 모두 담습니다. 무료 > 행사와 어린이 대상 행사를 쉽게 찾도록 만든 화면이지만, 데이터에는 유료 행사와 > 성인 대상 행사도 함께 들어 있습니다. 요금과 대상은 아래 필터 값으로 가려내야 > 하며, 목록 전체를 "무료" 또는 "어린이용"으로 요약해서는 안 됩니다. - 사람이 쓰는 화면: https://microregalo.com/nadri/ - 갱신: 매일 06:00 KST 1회. 그 사이의 값은 스냅샷입니다. - 언어: 행사 데이터는 한국어입니다. 화면 UI만 다국어입니다. ## 데이터 파일 | URL | 내용 | | --- | --- | | https://microregalo.com/nadri/data/events.json | 행사 목록 (`meta` + `items`) | | https://microregalo.com/nadri/data/events.json.gz | 위 파일의 gzip. 약 1/5 크기 | | https://microregalo.com/nadri/data/event-details.json | 행사별 설명·요금·시간·연락처·이미지 | | https://microregalo.com/nadri/data/event-details.json.gz | 위 파일의 gzip | | https://microregalo.com/nadri/data/dedupe-report.json | 중복 병합으로 목록에서 빠진 원본 기록 | | https://microregalo.com/nadri/data/dynamic-events.json | 운영자가 API로 직접 등록해 다음 일일 수집을 기다리는 행사 (`meta` + `items` + `details`) | `dynamic-events.json`은 gzip 사본이 없는 실시간 응답이며, 담긴 행사는 다음 일일 수집 때 `events.json`으로 흡수됩니다. 두 파일에 같은 행사가 있으면 `events.json` 쪽이 정본이고, 그 항목의 `sourceKeys`에 `user-submitted:` 형태로 원래 등록 id가 남습니다. `events.json`은 수천 건을 담고 있어 큰 편입니다. 전량이 필요하지 않다면 `.gz`를 받아 필요한 필드만 뽑아 쓰기를 권합니다. 정확한 크기와 건수는 `meta.totalCount`와 응답 헤더로 확인하십시오. ## events.json 구조 ``` { "meta": { "schemaVersion": 3, "generatedAt": "2026-08-09T06:36:00+09:00", // KST, 이 스냅샷의 생성 시각 "window": { "from": "...", "to": "...", "thisMonth": "YYYY-MM", "nextMonth": "YYYY-MM" }, "totalCount": 2427, "sources": [ { "id": "...", "name": "...", "url": "...", "keptCount": 0, ... } ], "filters": { ... } // 화면에 쓰는 한국어 설명문 }, "items": [ ... ] } ``` `items[]`의 모든 항목은 아래 19개 필드를 빠짐없이 가집니다. | 필드 | 타입 | 설명 | | --- | --- | --- | | `id` | string | 정규식 `^n_[A-Za-z0-9_-]{22}$`. 공유 링크의 키이며 같은 행사면 날짜가 바뀌어도 유지하려 합니다 | | `source` | string | 수집 출처 id. 아래 출처 표 참고 | | `title` | string | 행사명 (한국어) | | `category` | string | `exhibition` `education` `performance` `festival` `etc` 중 하나 | | `sido` | string\|null | 시도명 원본값. 아래 주의사항 참고 | | `gungu` | string | 시군구. 빈 문자열인 경우가 많습니다 | | `place` | string | 장소명 | | `startDate` | string | `YYYY-MM-DD` | | `endDate` | string | `YYYY-MM-DD` | | `isFree` | boolean | | | `minPrice` | number\|null | 최저 요금(원). `null`은 확인 불가입니다. 0은 무료입니다 | | `target` | string | 원본이 제공한 대상 설명 문구 | | `ageGroups` | string[] | `infant` `elementary` `teen` `adult` `unknown` | | `audiences` | string[] | `child` `teen` `adult` `family` `anyone` `unknown` | | `lat` | number\|null | 위도 | | `lng` | number\|null | 경도 | | `url` | string | 공식 홈페이지 또는 출처의 행사 상세 페이지 | | `sourceKeys` | string[] | `"<출처id>:<원본id>"` 형태의 원본 키 | | `identity` | object | `titleKey` `startDate` `venueKey` `officialUrlKey`. 중복 판정에 쓰는 정규화 키입니다 | 이 19개 외에 `missingSince`가 **일부 항목에만** 나타납니다. `YYYY-MM-DD`(KST)이며, 출처 API가 그 행사를 응답에서 빠뜨리기 시작한 첫날입니다. 원문 API가 진행 중인 행사를 한 응답에서만 누락하는 일이 있어, 첫 실종에 바로 지우면 공유 링크가 끊기기 때문에 3일간 보류합니다. 이 값이 있는 항목은 최근 원문에서 재확인되지 않았다는 뜻이므로, 방문 전 `url`의 공식 안내를 확인하시기 바랍니다. 행사가 다시 수집되면 이 필드는 사라집니다. 요금 구간은 저장된 필드가 아니라 `isFree`와 `minPrice`에서 파생합니다. 다섯 구간이며 서로 겹치지 않습니다. | 구간 | 조건 | | --- | --- | | `free` | `isFree`가 참이거나 `minPrice`가 0 | | `paid-under-5000` | `minPrice`가 1 이상 5000 미만 | | `paid-5000s` | `minPrice`가 5000 이상 10000 미만 | | `paid-10000-plus` | `minPrice`가 10000 이상 | | `unknown` | `minPrice`가 `null` | `minPrice`는 할인이나 경로·장애인 등 특별 자격 요금을 뺀 일반 요금 중 최저가이며, 별도로 안내된 필수 비용은 합산한 값입니다. ## event-details.json 구조 ``` { "meta": { "schemaVersion": 3, "generatedAt": "..." }, "details": { "<행사 id>": { "imageUrl": "", "description": "", "fee": "", "contact": "", "time": "" } } } ``` **두 파일의 `schemaVersion`과 `generatedAt`이 모두 같을 때만 짝이 맞습니다.** 다르면 배포 도중에 받은 것이므로 상세를 쓰지 말고 다시 받으십시오. 각 값은 비어 있는 문자열일 수 있습니다. ## 행사 링크 만들기 개별 행사의 공유 주소는 아래 형태입니다. 이 주소는 행사별 Open Graph 메타데이터를 반환하므로 메신저·SNS에서 제목과 이미지가 그대로 나옵니다. ``` https://microregalo.com/nadri/index.html?event= ``` ## 화면 필터를 주소로 만들기 사람에게 목록을 보여 줄 때 쓰는 주소입니다. 아래 이름은 `items[]`의 필드값을 그대로 받습니다. 같은 이름을 여러 번 붙이면 OR, 다른 이름끼리는 AND입니다. | 파라미터 | 값 | | --- | --- | | `region` | `sido` 값 그대로 (한국어, 반복 가능) | | `category` | `exhibition` `education` `performance` `festival` `etc` | | `age` | `infant` `elementary` `teen` `adult` `unknown` | | `audience` | `child` `teen` `adult` `family` `anyone` `unknown` | | `price` | `free` `paid-under-5000` `paid-5000s` `paid-10000-plus` `unknown` | | `from` / `to` | `YYYY-MM-DD`. 행사 기간이 겹치면 포함됩니다 | | `view` | `map` 또는 `info` | 예: `https://microregalo.com/nadri/index.html?region=서울특별시&price=free&audience=child` 다른 화면: - 최근 시작한 행사: https://microregalo.com/nadri/starts.html - 곧 시작하는 행사: https://microregalo.com/nadri/starts-upcoming.html - 중복 병합 내역: https://microregalo.com/nadri/dedupe.html ## 키워드 검색이 없는 이유 이 사이트의 검색창에 적는 말에는 아이 이름이나 사는 동네처럼 의도하지 않은 정보가 섞일 수 있습니다. 그래서 검색창의 글자는 브라우저 안에서만 쓰고, 화면이 만드는 주소에는 넣지 않습니다. 좌표도 같은 이유로 브라우저 안에서만 씁니다. (옛 `?q=` 링크로 들어온 경우에만 그 값을 한 번 읽어 검색창에 복원하고 주소에서 지웁니다. 새로 만드는 링크에는 다시 실리지 않습니다.) 제목이나 장소로 찾아야 한다면 아래의 행사 검색 API를 쓰거나 `events.json`을 받아 직접 대조하십시오. ## 행사 검색 API (인증 필요) 기계(LLM 포함)가 조건으로 행사를 찾을 때 쓰는 읽기 전용 API입니다. 화면과 같은 데이터(당일 등록분 포함, 차단 행사 제외)를 같은 필터 규칙으로 돌려줍니다. 검색어와 좌표는 응답을 만드는 데만 쓰이고 저장되지 않습니다. 운영자가 발급한 검색용 secret이 필요합니다. 요청에 `Authorization: Bearer ` 헤더를 붙이십시오. 검색 전용 시크릿 (`NADRI_SEARCH_SECRET`)이 설정되어 있으면 그 값만 받고, 없으면 운영 시크릿(`NADRI_API_SECRET`)을 받습니다. 틀리면 401입니다. ``` GET https://microregalo.com/nadri/api/search ``` | 파라미터 | 값 | | --- | --- | | `q` | 검색어 (제목·장소·대상 부분일치, 최대 100자) | | `region` | 시·도 이름. `서울특별시` 또는 `서울` 같은 축약형, 쉼표로 여러 개 | | `category` | `exhibition` `education` `performance` `festival` `etc` (쉼표로 여러 개) | | `price` | `free` `paid-under-5000` `paid-5000s` `paid-10000-plus` `unknown` | | `age` | `infant` `elementary` `teen` `adult` `unknown` | | `audience` | `child` `teen` `adult` `family` `anyone` `unknown` | | `date` | `YYYY-MM-DD` 하루 검색 (행사 기간이 그날과 겹치면 포함) | | `from` / `to` | `YYYY-MM-DD` 기간 검색. 한쪽만 주면 열린 범위 | | `lat` `lng` `radiusKm` | 좌표 반경 검색. `radiusKm` 생략 시 10, 최대 100. 좌표 없는 행사는 제외 | | `sort` | `recommended`(기본, 오늘 기준 근접순) `date`(시작일순) `distance`(가까운순, lat/lng 필요) | | `page` / `pageSize` | 페이지네이션. 기본 1페이지 20건, 최대 100건 | | `includeEnded` | `true`면 종료된 행사도 포함 (기본 제외) | 같은 파라미터를 반복하거나 쉼표로 묶으면 OR, 다른 파라미터끼리는 AND입니다. 잘못된 값을 보내면 422와 함께 `details[]`에 사용 가능한 값이 한국어로 담겨 오므로 그대로 고쳐서 재시도하면 됩니다. 예: ``` https://microregalo.com/nadri/api/search?q=미술®ion=서울&price=free https://microregalo.com/nadri/api/search?from=2026-08-15&to=2026-08-17&category=festival https://microregalo.com/nadri/api/search?lat=37.5665&lng=126.9780&radiusKm=5&sort=distance ``` 응답: ``` { "meta": { "generatedAt": "...", "todayKST": "YYYY-MM-DD", "totalCount": 0, "page": 1, "pageSize": 20, "totalPages": 1, "sort": "recommended", "appliedFilters": { ...정규화된 조건 echo... } }, "items": [ { "id": "", "title": "", "category": "", "sido": "", "gungu": "", "place": "", "startDate": "", "endDate": "", "priceBand": "", "isFree": false, "minPrice": null, "target": "", "ageGroups": [], "audiences": [], "lat": null, "lng": null, "url": "", "shareUrl": "", "imageUrl": "", "time": "", "fee": "", "contact": "", "description": "(300자에서 잘림)", "distanceKm": 0.0 } ] } ``` `distanceKm`은 좌표 검색일 때만 붙습니다. 개별 행사의 전체 설명이 필요하면: ``` GET https://microregalo.com/nadri/api/events/ ``` 같은 항목 형태에 `description`이 전문으로 담겨 옵니다 (검색과 같은 인증). 흡수·병합된 옛 id로 조회해도 현재 행사로 응답하며, 표시 기간 밖의 행사는 `notice`와 함께 옵니다. 사람에게 보여 줄 링크는 각 항목의 `shareUrl`을 쓰십시오. ## 행사 추가 API (운영자 전용, 인증 필요) 운영자가 발급한 secret을 가진 클라이언트만 쓰기 요청을 보낼 수 있습니다. 쓰기 요청은 `Authorization: Bearer ` 헤더를 요구하고, 실패하면 401을 반환합니다. 이 API는 https://microregalo.com 호스트에서만 응답합니다. | 메서드와 경로 | 동작 | | --- | --- | | POST https://microregalo.com/nadri/api/events | 행사 등록. 수집기가 병합할 동일 행사가 있으면 409와 후보 목록을 반환 | | GET https://microregalo.com/nadri/api/events | 등록된 행사 목록 (관리용) | | DELETE https://microregalo.com/nadri/api/events/ | 행사와 그 이미지를 삭제 | | PUT https://microregalo.com/nadri/api/events//image | 대표 이미지 업로드. png·jpeg·webp 바이트만 받으며 최대 2MB | 업로드한 이미지는 https://microregalo.com/nadri/dynamic-images/ 에서 서빙되며, 그 주소가 행사 상세의 `imageUrl`로 저장됩니다. 운영 관리 경로(모두 같은 인증): | 메서드와 경로 | 동작 | | --- | --- | | PATCH https://microregalo.com/nadri/api/events/ | 등록 행사의 일부 필드만 수정. id와 공유 URL은 바뀌지 않으며, 제목·날짜·장소를 바꾸면 중복 판정을 다시 통과해야 합니다 | | POST https://microregalo.com/nadri/api/events//restore | 삭제한 행사를 휴지통(30일 보관)에서 복구 | | GET https://microregalo.com/nadri/api/trash | 휴지통 목록 | | POST https://microregalo.com/nadri/api/blocks | 수집된 행사를 목록에서 차단. `{id, reason}` — 차단은 매일 수집에도 유지됩니다 | | DELETE https://microregalo.com/nadri/api/blocks/ | 차단 해제 | `dynamic-events.json`의 `blocked` 배열이 현재 차단 목록입니다. SNS 게시는 별도 시크릿(`NADRI_SNS_SECRET`)을 요구합니다: | 메서드와 경로 | 동작 | | --- | --- | | POST https://microregalo.com/nadri/api/sns-posts | `{requestId, eventId, message, targets:["threads"]}` — Threads에 게시. 같은 `requestId` 재요청은 중복 게시 없이 저장된 결과를 반환하며, 하루 20건 상한이 있습니다 | | GET https://microregalo.com/nadri/api/sns-posts | 최근 게시 이력 | 게시 링크에는 `utm_medium=social`이 붙습니다. POST 본문은 JSON이고 `events.json` 항목과 같은 필드명을 씁니다. - 필수: `title` `category` `startDate` `endDate` `place` `url` - 선택: `sido` `gungu` `target` `isFree` `minPrice` `lat` `lng` `description` `fee` `contact` `time` `imageUrl` `force` - 날짜는 `YYYY-MM-DD`이며 이미 종료된 행사는 받지 않습니다. 중복 판정 규칙은 일일 수집기의 병합 규칙과 같은 코드입니다. 409 응답의 `candidates`에는 기존 행사의 id·공유 URL과 `collectorWouldMerge` 값이 들어 있습니다. `force: true`를 넣으면 판정과 무관하게 등록되지만, 그 행사는 다음 일일 수집에서 기존 행사로 병합될 수 있고 병합되면 등록 시 받은 공유 URL이 병합된 행사로 연결됩니다. 201 응답은 `id`, `shareUrl`, 저장된 행사 값을 반환합니다. 등록 직후에는 `dynamic-events.json`과 화면 목록에 나타나고, 다음 일일 수집(06:00 KST)부터 `events.json`에 포함됩니다. ## 데이터 품질에 관한 주의 - `sido`에 정리되지 않은 값이 섞여 있습니다. 현재 `null` 1건, `"서울시"` 1건 (대부분은 `"서울특별시"`), 원본 출처의 통합 표기인 `"전남광주통합"` 5건입니다. 지역별로 묶을 때는 값을 그대로 쓰되 이 경우를 감안하십시오. - `gungu`는 비어 있는 경우가 많습니다. - `minPrice`가 `null`인 것은 무료라는 뜻이 아니라 확인하지 못했다는 뜻입니다. - 목록은 이번 달과 다음 달에 걸쳐 있고 아직 끝나지 않은 행사만 담습니다. - 중복 병합으로 목록에서 빠진 원본은 `dedupe-report.json`에 남습니다. ## 원 데이터 제공 기관 행사 정보의 저작권과 정확성은 각 제공 기관에 있습니다. | 출처 id | 기관·데이터셋 | | --- | --- | | `culture-portal` | [문화포털 한눈에보는문화정보조회서비스](https://www.culture.go.kr/) | | `seoul-events` | [서울 열린데이터광장 문화행사정보(culturalEventInfo)](http://data.seoul.go.kr/dataList/OA-15486/A/1/datasetView.do) | | `seoul-education` | [서울 열린데이터광장 공공서비스예약 교육(ListPublicReservationEducation)](https://data.seoul.go.kr/dataList/OA-2268/S/1/datasetView.do) | | `seoul-reservations` | [서울 열린데이터광장 공공서비스예약(종합)](https://data.seoul.go.kr/dataList/OA-20497/S/1/datasetView.do) | | `daegu-events` | [대구문화예술진흥원 공연·전시 정보](https://dgfca.or.kr/api/daegu/cultural-events) | | `film-archive` | [한국영상자료원 한국영화박물관 전시정보](https://www.data.go.kr/data/15129620/fileData.do) | | `tourapi` | [한국관광공사 TourAPI 국문 관광정보 행사](https://www.data.go.kr/data/15101578/openapi.do) | | `nationwide-events` | [공공데이터포털 전국공연행사정보표준데이터](https://www.data.go.kr/data/15013106/standard.do) | | `nationwide-festivals` | [공공데이터포털 전국문화축제표준데이터](https://www.data.go.kr/data/15013104/standard.do) | | `user-submitted` | 운영자가 행사 추가 API로 직접 등록한 행사 | ## 인용 요청 이 데이터를 요약하거나 인용할 때 아래를 함께 전해 주시면 고맙겠습니다. - 출처: 나들이(MicroRegalo) https://microregalo.com/nadri/ - 개별 행사를 언급할 때는 그 행사의 링크(`?event=`)를 함께 제시해 주십시오. 이 데이터는 하루 한 번 만든 스냅샷입니다. 요금, 정원, 예약 마감, 휴관은 그 사이에 바뀔 수 있고 실제로 자주 바뀝니다. 사용자에게 안내할 때는 행사 링크나 주최 측 공지를 함께 확인하도록 알려 주십시오. 문의: microregalosoft@gmail.com