REST API 참조

이 페이지

EmDash는 지원되는 애플리케이션 프로그래밍 인터페이스(API)를 /_emdash/api/ 아래에 노출합니다. 요청 매개변수, 본문, 응답 스키마, 상태 코드, 클라이언트 생성에는 생성된 OpenAPI 3.1 문서를 사용하세요.

GET /_emdash/api/openapi.json

이 문서는 API가 사용하는 Zod 스키마와 동일한 것에서 생성됩니다. 구성된 미디어 업로드 최대 크기도 반영됩니다.

공개 계약 경계

OpenAPI 문서가 지원되는 REST API의 경계입니다. EmDash에는 관리자 패널 및 프로토콜 워크플로용 경로도 있습니다. 소스 트리에 있지만 OpenAPI에 없는 경로는 외부 클라이언트용 지원 REST 작업이 아닙니다.

이 구분은 백업, 바이라인 관리, 관계 순회, 플러그인 관리, 설정, 가져오기, 인증 경로에 적용됩니다. 백업은 백업 가이드를, 지원되는 바이라인 관리는 MCP 바이라인 도구를 사용하세요. OAuth 엔드포인트는 프로토콜 엔드포인트입니다. MCP OAuth 섹션에 설명된 메타데이터에서 발견하고 애플리케이션 REST 엔드포인트로 취급하지 마세요.

인증 및 권한 부여

대부분의 작업은 EmDash 세션 쿠키 또는 Bearer 토큰을 받습니다. 개인 액세스 토큰 또는 OAuth 액세스 토큰을 Authorization 헤더로 보내세요.

Authorization: Bearer $EMDASH_TOKEN

Bearer 토큰은 스코프와 연결된 사용자 역할로 제한됩니다. 세션 요청은 사용자 역할을 사용합니다. 권한 부여 모델은 사용자 역할 및 토큰 스코프를 참조하세요.

GET 및 POST /_emdash/api/comments/{collection}/{contentId}는 공개입니다. GET은 승인된 댓글을 반환하고 POST는 검토를 위해 댓글을 제출합니다. 나머지 댓글 검토 작업에는 인증이 필요합니다.

교차 사이트 요청 위조(CSRF) 방지

세션 쿠키로 인증하는 상태 변경 요청에는 다음 헤더를 포함하세요.

X-EmDash-Request: 1

Bearer 토큰 요청은 브라우저의 암시적 자격 증명을 사용하지 않으므로 헤더가 필요하지 않습니다. 공개 쓰기 작업에 대한 브라우저 요청은 헤더를 보내거나 EmDash 사이트의 공개 또는 요청 origin과 일치하는 Origin을 가져야 합니다.

응답 래퍼

성공한 JSON 응답은 success를 true로 설정하고 작업별 결과를 data에 둡니다.

{
	"success": true,
	"data": {
		"items": []
	}
}

오류는 success를 false로 설정하고 안정적인 기계 판독 가능 코드와 메시지를 포함합니다. 일부 오류에는 구조화된 details도 있습니다.

{
	"success": false,
	"error": {
		"code": "NOT_FOUND",
		"message": "Content item not found"
	}
}

각 OpenAPI 작업의 상태 코드와 오류 스키마를 사용하세요. 일반적인 상태는 잘못된 입력의 400, 자격 증명 누락 또는 무효의 401, 스코프 또는 권한 부족의 403, 리소스 없음의 404, 상태 충돌의 409, 크기 초과 업로드의 413, 플러그인에 의한 저장 거부의 422, 내부 실패의 500입니다.

엔드포인트 목록

작업 ID는 생성된 계약 내에서 안정적이며 OpenAPI 클라이언트 생성기에서 메서드 이름으로 자주 사용됩니다. 다음 목록은 생성된 OpenAPI 문서와 대조됩니다.

콘텐츠

메서드경로작업요약
GET/_emdash/api/content/{collection}listContent콘텐츠 항목 목록
POST/_emdash/api/content/{collection}createContent콘텐츠 항목 생성
GET/_emdash/api/content/{collection}/{id}getContent콘텐츠 항목 가져오기
PUT/_emdash/api/content/{collection}/{id}updateContent콘텐츠 항목 업데이트
DELETE/_emdash/api/content/{collection}/{id}deleteContent콘텐츠 항목 삭제(소프트 삭제)
POST/_emdash/api/content/{collection}/{id}/publishpublishContent콘텐츠 항목 게시
POST/_emdash/api/content/{collection}/{id}/unpublishunpublishContent콘텐츠 항목 게시 취소
POST/_emdash/api/content/{collection}/{id}/schedulescheduleContent향후 게시를 위해 콘텐츠 예약
DELETE/_emdash/api/content/{collection}/{id}/scheduleunscheduleContent예약된 게시 취소
POST/_emdash/api/content/{collection}/{id}/duplicateduplicateContent콘텐츠 항목 복제
POST/_emdash/api/content/{collection}/{id}/restorerestoreContent휴지통에서 콘텐츠 항목 복원
DELETE/_emdash/api/content/{collection}/{id}/permanentpermanentDeleteContent콘텐츠 항목 영구 삭제
GET/_emdash/api/content/{collection}/{id}/comparecompareContent라이브 및 초안 리비전 비교
POST/_emdash/api/content/{collection}/{id}/discard-draftdiscardDraft초안 변경 버리기
GET/_emdash/api/content/{collection}/{id}/lockgetEntryLock항목 편집 잠금 읽기
POST/_emdash/api/content/{collection}/{id}/lockacquireEntryLock항목 편집 잠금 획득 또는 갱신
DELETE/_emdash/api/content/{collection}/{id}/lockreleaseEntryLock호출자의 편집 잠금 해제
GET/_emdash/api/content/{collection}/{id}/translationsgetContentTranslations콘텐츠 항목의 번역 가져오기
GET/_emdash/api/content/{collection}/{id}/terms/{taxonomy}getContentTerms콘텐츠 항목에 할당된 분류체계 용어 가져오기
POST/_emdash/api/content/{collection}/{id}/terms/{taxonomy}setContentTerms콘텐츠 항목에 분류체계 용어 설정
GET/_emdash/api/content/{collection}/authorslistContentAuthors컬렉션 콘텐츠의 서로 다른 작성자 목록
GET/_emdash/api/content/{collection}/trashlistTrashedContent휴지통 콘텐츠 항목 목록

미디어

메서드경로작업요약
GET/_emdash/api/medialistMedia미디어 항목 목록
POST/_emdash/api/mediauploadMedia미디어 항목 업로드
GET/_emdash/api/media/folderslistMediaFolders미디어 폴더 목록
POST/_emdash/api/media/folderscreateMediaFolder미디어 폴더 생성
GET/_emdash/api/media/folders/{id}getMediaFolder미디어 폴더 가져오기
PUT/_emdash/api/media/folders/{id}updateMediaFolder미디어 폴더 업데이트
DELETE/_emdash/api/media/folders/{id}deleteMediaFolder미디어 폴더 삭제
GET/_emdash/api/media/{id}getMedia미디어 항목 가져오기
PUT/_emdash/api/media/{id}updateMedia미디어 메타데이터 업데이트
DELETE/_emdash/api/media/{id}deleteMedia미디어 항목 삭제
GET/_emdash/api/media/{id}/usagegetMediaUsage미디어 사용 세부 정보 가져오기
PUT/_emdash/api/media/{id}/replacereplaceMediaImage미디어 이미지 교체
POST/_emdash/api/admin/media-usage/repairrepairMediaUsage미디어 사용 인덱스 복구
GET/_emdash/api/admin/media-usage/progressgetMediaUsageProgress미디어 사용 인덱싱 진행률 가져오기
POST/_emdash/api/admin/media-usage/progressadvanceMediaUsageProgress미디어 사용 인덱싱 진행
GET/_emdash/api/admin/media-usage/worklistMediaUsageWork영구 미디어 사용 작업 목록
GET/_emdash/api/admin/media-usage/activationgetMediaUsageActivation미디어 사용 활성화 상태 가져오기
POST/_emdash/api/admin/media-usage/activationadvanceMediaUsageActivation미디어 사용 활성화 진행
POST/_emdash/api/admin/media-usage/work/retryretryMediaUsageWork영구 미디어 사용 작업 1건 재시도
GET/_emdash/api/admin/media-usage/collection-deletionslistMediaUsageCollectionDeletions영구 컬렉션 삭제 목록
POST/_emdash/api/admin/media-usage/collection-deletions/retryretryMediaUsageCollectionDeletion컬렉션 삭제 1건 재시도
POST/_emdash/api/media/upload-urlgetMediaUploadUrl미디어 업로드 대상 가져오기
POST/_emdash/api/media/{id}/confirmconfirmMediaUpload미디어 업로드 확인
PUT/_emdash/api/media/{id}/uploaduploadPendingMediaEmDash를 통해 보류 중인 미디어 파일 업로드

스키마

메서드경로작업요약
GET/_emdash/api/schema/block-typeslistBlockTypes블록 유형 목록
POST/_emdash/api/schema/block-typescreateBlockType블록 유형 생성
GET/_emdash/api/schema/block-types/{slug}getBlockType블록 유형 가져오기
PUT/_emdash/api/schema/block-types/{slug}updateBlockType블록 유형 업데이트
POST/_emdash/api/schema/block-types/{slug}/versions/{version}/activateactivateBlockTypeVersion블록 유형 버전 활성화
GET/_emdash/api/schema/collectionslistCollections모든 컬렉션 목록
POST/_emdash/api/schema/collectionscreateCollection컬렉션 생성
GET/_emdash/api/schema/collections/{slug}getCollection컬렉션 가져오기
PUT/_emdash/api/schema/collections/{slug}updateCollection컬렉션 업데이트
DELETE/_emdash/api/schema/collections/{slug}deleteCollection컬렉션 삭제
GET/_emdash/api/schema/collections/{slug}/fieldslistFields컬렉션 필드 목록
POST/_emdash/api/schema/collections/{slug}/fieldscreateField필드 생성
GET/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}getField필드 가져오기
PUT/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}updateField필드 업데이트
DELETE/_emdash/api/schema/collections/{slug}/fields/{fieldSlug}deleteField필드 삭제
POST/_emdash/api/schema/collections/reorderreorderCollections관리자 사이드바에서 컬렉션 순서 변경
POST/_emdash/api/schema/collections/{slug}/fields/reorderreorderFields컬렉션 내 필드 순서 변경
GET/_emdash/api/schema/orphanslistOrphanedTables고아 콘텐츠 테이블 목록
POST/_emdash/api/schema/orphans/{slug}registerOrphanedTable고아 테이블을 컬렉션으로 등록

댓글

메서드경로작업요약
GET/_emdash/api/comments/{collection}/{contentId}listPublicComments콘텐츠의 승인된 댓글 목록
POST/_emdash/api/comments/{collection}/{contentId}createComment새 댓글 제출
GET/_emdash/api/admin/commentslistAdminComments검토용 댓글 목록
GET/_emdash/api/admin/comments/countsgetCommentCounts댓글 상태 개수 가져오기
POST/_emdash/api/admin/comments/bulkbulkCommentAction댓글 일괄 승인, 스팸, 휴지통, 삭제
GET/_emdash/api/admin/comments/{id}getComment단일 댓글 가져오기
DELETE/_emdash/api/admin/comments/{id}deleteComment댓글 영구 삭제
PUT/_emdash/api/admin/comments/{id}/statusupdateCommentStatus댓글 상태 변경

분류체계

메서드경로작업요약
GET/_emdash/api/taxonomieslistTaxonomies모든 분류체계 정의 목록
GET/_emdash/api/taxonomies/{name}getTaxonomy분류체계 정의 가져오기
PUT/_emdash/api/taxonomies/{name}updateTaxonomy분류체계 정의 업데이트
DELETE/_emdash/api/taxonomies/{name}deleteTaxonomy분류체계, 용어 및 콘텐츠 할당 삭제
GET/_emdash/api/taxonomies/{name}/translationslistTaxonomyTranslations분류체계 정의의 모든 로케일 변형 목록
POST/_emdash/api/taxonomies/{name}/reorderreorderTerms한 형제 용어 그룹의 수동 순서 설정
GET/_emdash/api/taxonomies/{name}/termslistTerms분류체계 용어 목록
POST/_emdash/api/taxonomies/{name}/termscreateTerm용어 생성
GET/_emdash/api/taxonomies/{name}/terms/{slug}getTerm슬러그로 용어 가져오기
PUT/_emdash/api/taxonomies/{name}/terms/{slug}updateTerm용어 업데이트
DELETE/_emdash/api/taxonomies/{name}/terms/{slug}deleteTerm용어 삭제

메뉴

메서드경로작업요약
GET/_emdash/api/menuslistMenus항목 수와 함께 모든 메뉴 목록
POST/_emdash/api/menuscreateMenu메뉴 생성
GET/_emdash/api/menus/{name}getMenu모든 항목이 포함된 메뉴 가져오기
PUT/_emdash/api/menus/{name}updateMenu메뉴 업데이트
DELETE/_emdash/api/menus/{name}deleteMenu메뉴 및 항목 삭제
POST/_emdash/api/menus/{name}/itemscreateMenuItem메뉴에 항목 추가
PUT/_emdash/api/menus/{name}/items/{id}updateMenuItem메뉴 항목 업데이트
DELETE/_emdash/api/menus/{name}/items/{id}deleteMenuItem메뉴 항목 삭제
POST/_emdash/api/menus/{name}/reorderreorderMenuItems메뉴 항목 일괄 순서 변경

섹션

메서드경로작업요약
GET/_emdash/api/sectionslistSections섹션 목록
POST/_emdash/api/sectionscreateSection섹션 생성
GET/_emdash/api/sections/{slug}getSection슬러그로 섹션 가져오기
PUT/_emdash/api/sections/{slug}updateSection섹션 업데이트
DELETE/_emdash/api/sections/{slug}deleteSection섹션 삭제

위젯

메서드경로작업요약
GET/_emdash/api/widget-areaslistWidgetAreas모든 위젯 영역 목록
POST/_emdash/api/widget-areascreateWidgetArea위젯 영역 생성
GET/_emdash/api/widget-areas/{name}getWidgetArea위젯이 포함된 위젯 영역 가져오기
DELETE/_emdash/api/widget-areas/{name}deleteWidgetArea위젯 영역 및 위젯 삭제
POST/_emdash/api/widget-areas/{name}/widgetscreateWidget영역에 위젯 추가
PUT/_emdash/api/widget-areas/{name}/widgets/{id}updateWidget위젯 업데이트
DELETE/_emdash/api/widget-areas/{name}/widgets/{id}deleteWidget위젯 삭제
POST/_emdash/api/widget-areas/{name}/reorderreorderWidgets영역 내 위젯 순서 변경

설정

메서드경로작업요약
GET/_emdash/api/settingsgetSettings사이트 설정 가져오기
PUT/_emdash/api/settingsupdateSettings사이트 설정 업데이트

검색

메서드경로작업요약
GET/_emdash/api/searchsearch컬렉션 전체 전문 검색
GET/_emdash/api/search/suggestsearchSuggest자동 완성 검색 제안
POST/_emdash/api/search/rebuildrebuildSearchIndex컬렉션 검색 인덱스 재구축
POST/_emdash/api/search/enableenableSearch컬렉션 검색 활성화 또는 비활성화
GET/_emdash/api/search/statsgetSearchStats검색 인덱스 통계 가져오기

리디렉션

메서드경로작업요약
GET/_emdash/api/redirectslistRedirects리디렉션 목록
POST/_emdash/api/redirectscreateRedirect리디렉션 규칙 생성
GET/_emdash/api/redirects/{id}getRedirect리디렉션 가져오기
PUT/_emdash/api/redirects/{id}updateRedirect리디렉션 업데이트
DELETE/_emdash/api/redirects/{id}deleteRedirect리디렉션 삭제
GET/_emdash/api/redirects/404slistNotFoundEntries404 로그 항목 목록
POST/_emdash/api/redirects/404spruneNotFoundLog오래된 404 로그 항목 정리
DELETE/_emdash/api/redirects/404sclearNotFoundLog404 로그 항목 전체 지우기
GET/_emdash/api/redirects/404s/summarygetNotFoundSummary경로별로 그룹화된 404 요약 가져오기

사용자

메서드경로작업요약
GET/_emdash/api/admin/userslistUsers사용자 목록
GET/_emdash/api/admin/users/{id}getUser사용자 세부 정보 가져오기
PUT/_emdash/api/admin/users/{id}updateUser사용자 업데이트
POST/_emdash/api/admin/users/{id}/disabledisableUser사용자 계정 비활성화
POST/_emdash/api/admin/users/{id}/enableenableUser사용자 계정 활성화
GET/_emdash/api/admin/allowed-domainslistAllowedDomains허용된 이메일 도메인 목록
POST/_emdash/api/admin/allowed-domainscreateAllowedDomain허용된 이메일 도메인 추가
PUT/_emdash/api/admin/allowed-domains/{domain}updateAllowedDomain허용된 도메인 업데이트
DELETE/_emdash/api/admin/allowed-domains/{domain}deleteAllowedDomain허용된 도메인 제거

전송

메서드경로작업요약
GET/_emdash/api/admin/transfer/capabilitiesgetTransferCapabilities사이트 전송 기능 가져오기
GET/_emdash/api/admin/transfer/importslistTransferImports사이트 가져오기 목록
POST/_emdash/api/admin/transfer/importscreateTransferImport사이트 가져오기 생성
GET/_emdash/api/admin/transfer/imports/{id}getTransferImport사이트 가져오기 가져오기
GET/_emdash/api/admin/transfer/imports/{id}/missinglistTransferImportMissingFiles아직 업로드할 패키지 파일 목록
PUT/_emdash/api/admin/transfer/imports/{id}/files/{path}uploadTransferImportFile패키지 파일 1건 업로드
POST/_emdash/api/admin/transfer/imports/{id}/analyzeanalyzeTransferImport가져오기 분석 진행
GET/_emdash/api/admin/transfer/imports/{id}/plangetTransferImportPlan가져오기 계획 가져오기
POST/_emdash/api/admin/transfer/imports/{id}/cancelcancelTransferImport사이트 가져오기 취소
POST/_emdash/api/admin/transfer/imports/{id}/abandonabandonTransferImport실패 또는 취소된 가져오기 포기
POST/_emdash/api/admin/transfer/imports/{id}/executeexecuteTransferImport계획된 가져오기 시작
POST/_emdash/api/admin/transfer/imports/{id}/advanceadvanceTransferImport실행 중인 가져오기 진행
GET/_emdash/api/admin/transfer/imports/{id}/receiptgetTransferImportReceipt가져오기 영수증 가져오기
GET/_emdash/api/admin/transfer/exportslistTransferExports사이트 내보내기 목록
POST/_emdash/api/admin/transfer/exportscreateTransferExport사이트 내보내기 시작
GET/_emdash/api/admin/transfer/exports/{id}getTransferExport사이트 내보내기 가져오기
POST/_emdash/api/admin/transfer/exports/{id}/advanceadvanceTransferExport사이트 내보내기 진행
GET/_emdash/api/admin/transfer/exports/{id}/manifestgetTransferExportManifest내보내기 매니페스트 다운로드
GET/_emdash/api/admin/transfer/exports/{id}/files/{path}downloadTransferExportFile내보내기 파일 1건 다운로드
GET/_emdash/api/admin/transfer/exports/{id}/archivedownloadTransferExportArchive내보내기 아카이브 다운로드
GET/_emdash/api/admin/transfer/approvalslistTransferApprovals전송 승인 목록
POST/_emdash/api/admin/transfer/approvals/{id}/approveapproveTransferApproval전송 요청 승인
POST/_emdash/api/admin/transfer/approvals/{id}/denydenyTransferApproval전송 요청 거부

콘텐츠 수명 주기와 바이라인

콘텐츠 수명 주기 참조는 REST, MCP, CLI, 관리자 패널이 공유하는 상태, 리비전, 권한, 충돌, 훅 동작을 정의합니다.

콘텐츠 읽기는 가능한 경우 불투명한 _rev 토큰을 반환합니다. 읽기 이후 변경을 덮어쓰지 않으려면 PUT /content/{collection}/{id}에 _rev를 보내세요. 오래된 토큰은 충돌을 일으합니다. 재시도 전에 항목을 다시 읽으세요. CLI는 content update에서 이 검사를 필수로 하지만, REST 필드는 의도적으로 무조건 쓰기를 선택하는 클라이언트를 위해 선택 사항으로 남습니다.

항목 읽기 및 업데이트

변경하기 전에 항목을 읽으세요.

GET /_emdash/api/content/articles/01JARTICLE0000000000000000
Authorization: Bearer $EMDASH_TOKEN

응답에는 필드, 게시 상태, 리비전 토큰이 포함됩니다.

{
	"success": true,
	"data": {
		"item": {
			"id": "01JARTICLE0000000000000000",
			"type": "articles",
			"slug": "launch-notes",
			"status": "published",
			"data": { "title": "Launch notes" }
		},
		"_rev": "opaque-revision-token"
	}
}

변경이 필요한 필드만 해당 읽기에서 받은 토큰과 함께 보내세요.

PUT /_emdash/api/content/articles/01JARTICLE0000000000000000
Authorization: Bearer $EMDASH_TOKEN
Content-Type: application/json

{
	"data": { "title": "Updated launch notes" },
	"_rev": "opaque-revision-token"
}

게시된 항목을 변경하면 이전 버전은 라이브로 유지된 채 초안이 생성됩니다. compare 작업으로 두 버전을 검토한 뒤 초안을 게시하거나 버리세요. 게시 취소는 콘텐츠와 게시일을 유지하고, 보류 중인 예약을 취소하며, 항목을 라이브 사이트에서 제거합니다.

생성 및 업데이트 본문은 바이라인 크레딧을 받으며, 콘텐츠 응답에는 기본 바이라인과 순서가 있는 크레딧이 포함됩니다. 콘텐츠 목록은 저장된 바이라인 ID로 필터링할 수 있고, 선택적으로 작성자의 추론 바이라인을 포함할 수 있습니다. 바이라인 레코드 자체의 생성 및 관리는 공개 REST 계약이 아니라 MCP 바이라인 도구를 통해 가능합니다.

수명 주기 작업은 소프트 삭제와 영구 삭제를 구분합니다. 복원은 휴지통 콘텐츠를 예약 없는 초안으로 반환합니다. 영구 삭제는 휴지통 항목을 제거하며 되돌릴 수 없습니다. publish, unpublish, schedule, unschedule, compare, discard-draft, duplicate는 별도 작업이므로 클라이언트는 한 번에 하나의 상태 전환만 요청할 수 있습니다.

항목 편집 잠금

편집자가 항목을 열면 컬렉션은 7분 편집 잠금을 가질 수 있습니다. /content/{collection}/{id}/lock의 세 작업으로 읽기, 획득 또는 갱신, 임대 해제를 수행하세요.

읽기 또는 획득 응답은 잠금 활성화 여부, 호출자가 임대를 보유하는지, 현재 누가 보유하는지를 보여 줍니다.

{
	"success": true,
	"data": {
		"enabled": true,
		"heldByCaller": false,
		"holder": {
			"userId": "01JUSER000000000000000000",
			"userName": "Ada",
			"acquiredAt": "2026-05-01T09:12:04.117Z",
			"expiresAt": "2026-05-01T09:19:04.117Z"
		}
	}
}

컬렉션에서 편집 잠금이 비활성화되면 enabled는 false이고 임대는 잡히지 않습니다. 같은 잠금을 다시 획득하거나 항목을 저장하면 호출자가 보유한 임대가 연장됩니다.

획득 본문에는 하나의 편집 세션을 식별하는 불투명 token과, 다른 편집자의 임대를 대체할 때의 takeover: true를 포함할 수 있습니다. 잠금 해제 시 같은 토큰을 쿼리 매개변수로 전달하세요. 같은 계정의 두 번째 탭이 첫 탭의 임대를 실수로 해제할 수 없습니다.

다른 사용자가 임대를 보유하면 보호된 콘텐츠 쓰기는 409 ENTRY_LOCKED를 반환합니다. 오류 세부 정보에 보유자와 만료가 표시됩니다. 잠금을 재정의하려면 본문이 있는 쓰기에서는 JSON 본문에 "overrideLock": true를, 본문이 없는 DELETE에서는 ?overrideLock=true를 보내세요.

참조 선택

reference 필드는 관계를 통해 항목을 다른 컬렉션의 항목에 연결합니다. 값은 data의 일부가 아니며 번역 그룹을 키로 하므로, 항목의 모든 번역이 하나의 선택을 공유합니다.

생성 및 업데이트 본문은 references 아래에 선택을 담으며, 필드 슬러그를 키로 하고 표시 순서의 항목 ID를 최대 1000개 배열로 둡니다. EmDash는 항목과 같은 트랜잭션에서 선택을 기록합니다. 다음 업데이트는 항목의 작성자를 교체합니다.

PUT /_emdash/api/content/articles/01JARTICLE0000000000000000
Authorization: Bearer $EMDASH_TOKEN
Content-Type: application/json

{
	"data": { "title": "Updated launch notes" },
	"references": { "author": ["01JAUTHOR00000000000000000"] },
	"_rev": "opaque-revision-token"
}

관계의 자식 쪽에 바인딩된 필드는 작성 중인 항목을 가리키는 항목을 선택하며, 자체 순서는 없습니다. 관계 제한은 양쪽 끝에서 적용되므로, 연결된 항목에 허용보다 많은 부모를 주는 선택은 너무 많은 항목을 연결하는 경우와 함께 거부됩니다.

리비전을 유지하는 컬렉션에서는 게시된 항목에서 변경한 선택이 항목의 다른 보류 편집과 함께 초안에 스테이징됩니다. 항목 게시 시 라이브가 되고 초안과 함께 버려집니다. 게시 시 선택 전체가 관계 제한에 대해 다시 검사됩니다.

단일 항목 읽기는 필드 슬러그를 키로 한 references를 반환합니다. 각 필드는 연결된 항목의 첫 페이지(50개)를 담고, 더 많으면 nextCursor를 제공하며, 각 항목의 ID, 슬러그, 컬렉션, 표시 제목, 해석된 로케일, 번역 그룹을 보고합니다. 초안을 읽을 수 있는 호출자는 초안에 스테이징된 선택을 볼 수 있습니다. 콘텐츠 목록 작업에는 references가 포함되지 않습니다.

관계 정의와 링크 순회는 OpenAPI에 없고 공개 계약 밖인 관리자 경로입니다. 위 콘텐츠 작업으로 선택을 읽고 쓰고, 사이트에서는 getEmDashEntry()와 getEmDashReferences()로 렌더링하세요.

번역

공개 REST 계약은 콘텐츠 번역과 분류체계 정의 번역을 노출합니다. 콘텐츠 생성은 translationOf를 받으며, 분류체계 생성도 같은 필드로 로케일 변형을 추가합니다. 콘텐츠-용어 작업은 로케일을 인식하는 할당을 반환합니다.

GET /taxonomies/{name}은 locale을 생략하면 사이트 기본 로케일 정의를 반환하며, 기본 로케일에 정의가 없을 때만 가장 낮은 로케일 코드로 대체합니다. 업데이트는 다릅니다. locale을 생략하면 가장 낮은 로케일 코드의 정의를 변경합니다. 번역된 분류체계 업데이트가 의도한 정의에 도달하도록 locale을 전달하세요. 해당 로케일에 정의가 없으면 다른 로케일로 대체하지 않고 NOT_FOUND를 반환합니다. translations 작업은 공유 그룹의 모든 정의를 반환하고 translationOf가 받는 ID를 제공합니다.

label과 labelSingular는 한 로케일 정의에 속합니다. hierarchical과 collections는 분류체계에 속하며, 모든 로케일이 같은 값을 반환하고, 둘 중 하나를 보내는 업데이트는 모든 로케일에서 변경합니다. 다른 로케일에 이미 존재하는 이름의 정의를 만들면 요청이 translationOf를 보내든 아니든 해당 분류체계에 추가됩니다. 새 정의는 분류체계의 hierarchical과 collections를 따르며, 다른 값을 보내는 create는 VALIDATION_ERROR를 반환합니다.

분류체계 삭제는 정의의 모든 로케일, 모든 용어, 해당 용어의 콘텐츠 할당을 제거합니다. 콘텐츠 항목 자체는 삭제하지 않습니다.

용어 순서 변경 작업은 하나의 형제 그룹을 변경합니다. ids 배열은 그 그룹의 일부만 포함할 수 있으며, 나열된 용어는 기존 위치를 교환하고 생략된 용어는 그대로 둡니다. 예: [A, B, C]를 ids: ["C", "A"]로 재정렬하면 [C, B, A]가 됩니다. 재정렬은 부모 관계를 바꾸지 않으며, 하나의 용어 순서가 번역 그룹의 모든 로케일에 적용됩니다.

메뉴, 분류체계 용어, 바이라인 번역 경로는 공개 REST 계약에 없습니다. 지원되는 번역 목록은 MCP 서버의 menu_translations, taxonomy_term_translations, byline_translations로 이용할 수 있습니다.

미디어 엔드포인트

미디어 작업은 목록, 업로드, 메타데이터 업데이트, 이미지 교체, 폴더, 사용 정보, 사용 인덱스 유지를 다룹니다. 미디어 라이브러리 가이드가 사용자 워크플로와 사용 커버리지 의미를 설명합니다.

미디어 목록 및 검사

GET /media는 커서 또는 번호 페이지 페이지네이션, MIME 유형 및 파일명 필터, 폴더, 선택적 사용 요약을 지원합니다. 모든 폴더를 포함하려면 folderId를 생략하고, 메인 라이브러리만 보려면 folderId=unfiled를 전달하세요. 목록 또는 단일 항목 읽기에서 includeUsage=1을 설정하면 사용 정보를 포함합니다. 다른 값은 유효하지 않습니다.

usage.count는 현재 인덱싱된 소스가 미디어 항목을 참조하는 서로 다른 활성 콘텐츠 행 또는 로케일과, 이를 선택하는 각 사이트 설정(logo, favicon, seo.defaultOgImage)을 셉니다. 한 항목의 반복 참조는 한 번만 세고, 휴지통 항목은 세지 않습니다. 이 숫자는 초안을 읽을 수 있는 호출자에게만 보입니다. 다른 권한 있는 미디어 읽기는 count: null을 받습니다. 개수가 초안 콘텐츠를 드러낼 수 있기 때문입니다.

GET /media/{id}/usage는 참조하는 콘텐츠 항목을 페이지로 반환합니다. 모든 페이지에는 미디어 항목을 선택하는 사이트 설정 siteSettings(예: [{ "setting": "favicon" }])도 포함됩니다. 사이트 설정은 요청마다 저장된 설정에서 읽으며 사용 인덱싱에 의존하지 않습니다.

모든 사용 결과에는 커버리지 상태가 포함됩니다.

상태의미
complete등록된 모든 컬렉션이 현재 사용 커버리지를 가짐.
never등록된 컬렉션이 초기 사용 복구를 완료한 적 없음.
running복구 진행 중.
partial등록된 컬렉션 집합의 일부만 현재 커버리지를 가짐.
failed등록된 컬렉션 집합 전체에서 커버리지 실패.
stale인덱스가 설명하는 콘텐츠보다 오래됨.
unknown저장 상태가 이 EmDash 버전에서 인식되지 않음.

인덱싱된 필드 유형 내에서 영 개수를 완전으로 볼 수 있는 것은 complete뿐입니다. 동시 쓰기 중 개수는 참고용이며, 미디어 항목을 잠그거나 삭제가 안전함을 보장하지 않습니다. 사용 인덱싱은 이미지 및 파일 필드, 리피터 이미지 필드, Portable Text 이미지 및 갤러리 블록, EmDash 컬렉션에서 유지 블록 버전이 선언하는 미디어를 다룹니다. 사이트 로고, favicon, 기본 소셜 이미지 설정도 보고됩니다. 사용에는 사용자 정의 Portable Text 블록, 애플리케이션 코드, 렌더링된 HTML, 기타 설정, 메뉴, 위젯, 플러그인 데이터, 외부 사이트, 공급자 전용 자산은 포함되지 않습니다.

직접 멀티파트 업로드

멀티파트 요청의 file 필드로 파일을 POST하여 EmDash를 통해 보냅니다.

curl --request POST \
	--header "Authorization: Bearer $EMDASH_TOKEN" \
	--form "file=@./cover.jpg;type=image/jpeg" \
	https://example.com/_emdash/api/media

curl은 멀티파트 경계를 추가합니다. Content-Type 헤더는 수동으로 설정하지 마세요. OpenAPI MediaDirectUploadBody 스키마는 선택적 메타데이터 필드를 나열하고, 응답 스키마는 새 업로드와 중복 제거된 기존 항목을 구분합니다.

멀티파트 본문에는 이미지 width, height, 적용할 MIME 유형 허용 목록이 있는 fieldId, 저품질 플레이스홀더용 축소 thumbnail도 포함할 수 있습니다. 새 파일은 201 Created를 반환하며 즉시 사용 가능합니다. 동일 바이트는 기존 미디어 항목을 200 OK와 deduplicated: true로 반환합니다.

업로드 대상 흐름

클라이언트가 S3 호환 스토리지에 직접 업로드할 수 있을 때 업로드 대상 흐름을 사용하세요. 확인이 성공할 때까지 미디어 항목은 pending 상태로 표준 라이브러리에 나타나지 않습니다.

  1. 업로드 대상 요청

    POST /_emdash/api/media/upload-url
    Authorization: Bearer $EMDASH_TOKEN
    Content-Type: application/json
    
    {
    	"filename": "cover.jpg",
    	"contentType": "image/jpeg",
    	"size": 102400
    }

    응답은 uploadUrl, method, headers, mediaId, storageKey, 만료를 제공합니다. contentHash가 같은 MIME 유형과 크기의 기존 파일과 일치하면 응답은 existing: true를 설정합니다. 해당 미디어 항목을 사용하고 다른 복사본을 업로드하거나 확인하지 마세요.

  2. 바이트 업로드

    반환된 method와 headers를 사용하세요. 루트 상대 URL은 EmDash 사이트에 대해 해석하고 Bearer 토큰을 포함하세요. 다른 origin의 절대 URL에는 반환된 업로드 헤더만 보냅니다.

  3. 업로드 확인

    POST /_emdash/api/media/01JMEDIA000000000000000000/confirm
    Authorization: Bearer $EMDASH_TOKEN
    Content-Type: application/json
    
    {
    	"size": 102400,
    	"width": 1920,
    	"height": 1080
    }

    확인은 저장 객체를 검증하고 항목을 pending에서 ready로 변경합니다. 제공한 크기와 치수는 업로드된 파일과 일치해야 합니다.

로컬 스토리지와 네이티브 R2는 동일 origin EmDash 업로드 대상을 반환합니다. S3 호환 스토리지는 서명된 외부 URL을 반환할 수 있습니다. pending 항목은 확인 성공까지 표준 미디어 목록에서 제외됩니다.

업로드 오류

다음 오류는 다른 복구 조치가 필요합니다.

상태코드조치
400NO_FILE멀티파트 요청에 file 필드를 추가하거나 누락된 업로드 본문을 보냄.
400INVALID_TYPEpending 미디어 항목과 일치하는 허용 MIME 유형 사용.
400VALIDATION_ERROR누락 또는 잘못된 메타데이터(구성 크기 한도 초과 값 포함) 수정.
400FILE_NOT_FOUND확인 전에 반환된 대상에 객체 업로드.
400UPLOAD_SIZE_MISMATCH올바른 크기로 흐름 재시작. 선언, 업로드, 확인 크기가 일치해야 함.
400 또는 409INVALID_STATE재시도 전에 미디어 항목 읽기. pending이 아닐 수 있거나 확인 중 다른 요청이 변경했을 수 있음.
404NOT_FOUND기존 pending 미디어 ID 사용.
413PAYLOAD_TOO_LARGE파일 크기 줄이거나 다른 업로드 시작 전 maxUploadSize 증가.

미디어 폴더

폴더 이름은 trim되고 200자로 제한되며, Unicode 정규화 및 소문자화 후 비교됩니다. Photos, photos, PHOTOS 등은 충돌합니다. 폴더 삭제는 미디어를 메인 라이브러리로 되돌립니다. 미디어 삭제, 미디어 ID 또는 URL 변경, 사용 기록 변경은 하지 않습니다.

미디어 사용 복구

미디어 사용 활성화, 진행, 작업 큐, 삭제 정리, 복구는 /_emdash/api/admin/media-usage/ 아래 운영자 작업입니다. 세션 사용자는 schema:manage가 필요합니다. Bearer 토큰은 admin 스코프도 필요합니다.

추적이 꺼져 있으면 활성화 전에 직접 DB 쓰기를 일시 중지하세요. 설정 실행 중 EmDash는 API를 통한 콘텐츠 및 스키마 쓰기를 일시 차단하지만, DB에 직접 쓰는 다른 프로세스는 막을 수 없습니다.

  1. 직접 DB 쓰기를 중지하고 진행 중인 쓰기 완료를 기다림.
  2. 활성화 상태 읽기. expanded는 추적 꺼짐, activating은 EmDash가 컬렉션 준비 중, active는 새 미디어 참조 변경이 추적됨을 의미.
  3. { "writersDrained": true }로 활성화 요청 1회 전송.
  4. 활성화가 active가 될 때까지 반환된 nextRequestInMs마다 진행 요청을 하나씩 전송.
  5. 직접 DB 쓰기 재개.
  6. 역사 인덱싱이 ready이고 nextRequestInMs가 null이 될 때까지 진행 요청 계속.

쓰기 요청이 시간 초과되거나 409 또는 500을 반환하면 재시도 전에 활성화 및 진행 상태를 읽으세요. 완료된 배치는 기록된 채 유지됩니다. lastErrorCode가 설정되면 직접 쓰기를 중지한 채 보고된 문제를 해결하고 확인된 재시도 1회를 보냅니다. 활성화 시작 후에는 취소하거나 재설정할 수 없으므로 스테이징 복사본에서 절차를 테스트하고 최신 DB 백업을 유지하세요.

작업 목록 작업은 콘텐츠, 미디어 참조, 임대 토큰, 원시 DB 오류, 정확한 백로그 개수를 반환하지 않고 실패 또는 지연된 항목 인덱싱을 노출합니다. 한 항목 재시도는 멱등입니다. 409 WORK_LEASE_ACTIVE는 워커가 아직 항목을 처리 중임을 의미합니다. 응답에 details.leaseExpiresAt이 포함되므로 그 시각까지 기다린 뒤 항목을 다시 읽고 재시도하세요. 409 WORK_CHANGED는 다른 요청이 작업 항목을 변경했음을 의미합니다. 새 작업을 덮어쓰지 말고 현재 상태를 읽으세요.

복구 작업은 { "scope": "collection", "collection": "articles" } 또는 { "scope": "all" }을 받습니다. 전체 컬렉션 복구는 동기적이고 순차적으로 실행되어 대규모 사이트에서는 오래 걸릴 수 있습니다. 200 응답도 partial, failed, stale을 보고할 수 있습니다. 복구 완료로 간주하기 전에 data.status, 컬렉션별 상태, 소스 개수를 확인하세요.

사이트 전송

/_emdash/api/admin/transfer/ 아래 전송 작업은 사이트를 사이트 패키지로 내보내고 빈 사이트로 가져옵니다. 사이트 전송 가이드가 내보내기, 업로드, 분석, 실행, 영수증 워크플로를 설명합니다.

세션 사용자는 관리자만 가진 transfer:export 또는 transfer:import 권한이 필요합니다. Bearer 토큰은 각 작업에서 지정하는 admin 또는 transfer:export, transfer:analyze, transfer:execute 스코프가 필요합니다. 승인 작업은 로그인 세션만 받습니다. MCP site_export_start 및 site_import_start 도구가 만든 요청을 결정합니다. REST export 및 execute 작업은 승인을 받지 않습니다.

가져오기 실행 중, 실패 또는 취소 후 abandon될 때까지 대부분의 다른 쓰기 작업은 503 TRANSFER_IMPORT_IN_PROGRESS를 반환합니다. 가이드에 가져오기 중에도 사용 가능한 작업이 나열됩니다.

페이지네이션

목록 작업은 OpenAPI에서 페이지네이션 매개변수를 설명합니다. 대부분의 커서 페이지네이션 작업은 불투명 cursor와 1~100(기본 50)의 limit을 받습니다. 이전 응답의 nextCursor를 그대로 반환하세요. 검사하거나 구성하지 마세요. 일부 미디어 작업은 번호 페이지도 지원하고, 일부 전용 목록은 다른 한도를 사용하므로 생성 클라이언트는 각 작업 스키마를 따라야 합니다.

검색 토크나이저

검색 활성화 작업은 컬렉션마다 토크나이저를 저장합니다. 활성화된 컬렉션에서 변경하면 해당 컬렉션 인덱스가 재구축됩니다.

값용도
porter unicode61Porter 어간 추출이 유리한 영어 콘텐츠의 기본값.
unicode61단어 구분자를 쓰지만 영어 어간 추출을 쓰지 않는 언어.
trigram일본어, 중국어, 태국어, 크메르어, 라오어, 버마어 등 공백 없는 텍스트, 또는 부분 문자열 일치가 필요한 컬렉션. Unicode 3자 미만 쿼리는 일치 없음.

검색 비활성화는 다음 활성화를 위해 저장된 토크나이저를 유지합니다. 재구축 작업은 컬렉션의 저장 토크나이저와 필드 가중치를 사용합니다.

댓글 및 리디렉션

공개 댓글 제출은 검토 대기열에 들어갑니다. 관리자 댓글 작업은 모든 상태를 목록하고, 개수를 반환하고, 한 상태를 업데이트하고, 일괄 검토를 수행하고, 댓글을 영구 삭제합니다. 429 응답은 제출 속도 제한에 도달했음을 의미합니다.

리디렉션 작업은 리디렉션 규칙과 기록된 404 로그를 별도로 관리합니다. 정리(prune)는 요청 본문에서 선택한 항목을 제거하고, DELETE /redirects/404s는 로그 전체를 지웁니다. 둘 다 리디렉션 규칙은 삭제하지 않습니다.