콘텐츠로 이동

REST API 참조

EmDash는 콘텐츠 관리, 미디어 업로드 및 스키마 작업을 위한 REST API를 /_emdash/api/에서 제공합니다.

API 요청에는 Bearer 토큰을 통한 인증이 필요합니다:

Authorization: Bearer <token>

토큰은 관리자 인터페이스 또는 프로그래밍 방식으로 생성할 수 있습니다.

모든 응답은 일관된 형식을 따릅니다:

// Success
{
"success": true,
"data": { ... }
}
// 오류
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "사람이 읽을 수 있는 메시지",
"details": { ... }
}
}
GET /_emdash/api/content/:collection
매개변수유형설명
collectionstring컬렉션 슬러그 (경로)
cursorstring페이지네이션 커서 (쿼리)
limitnumber페이지당 항목 수 (쿼리, 기본값: 50)
statusstring상태별 필터 (쿼리)
orderBystring정렬 기준 필드 (쿼리)
orderstring정렬 방향: asc 또는 desc (쿼리)
{
"success": true,
"data": {
"items": [
{
"id": "01HXK5MZSN...",
"type": "posts",
"slug": "hello-world",
"data": { "title": "안녕하세요", ... },
"status": "published",
"createdAt": "2025-01-24T12:00:00Z",
"updatedAt": "2025-01-24T12:00:00Z"
}
],
"nextCursor": "eyJpZCI6..."
}
}
GET /_emdash/api/content/:collection/:id
{
"success": true,
"data": {
"item": {
"id": "01HXK5MZSN...",
"type": "posts",
"slug": "hello-world",
"data": { "title": "안녕하세요", ... },
"status": "published",
"createdAt": "2025-01-24T12:00:00Z",
"updatedAt": "2025-01-24T12:00:00Z"
}
}
}
POST /_emdash/api/content/:collection
Content-Type: application/json
{
"data": {
"title": "New Post",
"content": [...]
},
"slug": "new-post",
"status": "draft"
}
{
"success": true,
"data": {
"item": { ... }
}
}
PUT /_emdash/api/content/:collection/:id
Content-Type: application/json
{
"data": {
"title": "Updated Title"
},
"status": "published"
}
DELETE /_emdash/api/content/:collection/:id
{
"success": true,
"data": {
"success": true
}
}
GET /_emdash/api/media
매개변수유형설명
cursorstring페이지네이션 커서
limitnumber페이지당 항목 수 (기본값: 20)
mimeTypestringMIME 유형 접두사로 필터링
{
"success": true,
"data": {
"items": [
{
"id": "01HXK5MZSN...",
"filename": "photo.jpg",
"mimeType": "image/jpeg",
"size": 102400,
"width": 1920,
"height": 1080,
"url": "https://cdn.example.com/photo.jpg",
"createdAt": "2025-01-24T12:00:00Z"
}
],
"nextCursor": "eyJpZCI6..."
}
}
GET /_emdash/api/media/:id
POST /_emdash/api/media
Content-Type: application/json
{
"filename": "photo.jpg",
"mimeType": "image/jpeg",
"size": 102400,
"width": 1920,
"height": 1080,
"storageKey": "uploads/photo.jpg"
}
PUT /_emdash/api/media/:id
Content-Type: application/json
{
"alt": "Photo description",
"caption": "Photo caption"
}
DELETE /_emdash/api/media/:id
GET /_emdash/api/media/file/:key

실제 파일 내용을 제공합니다. 로컬 저장소 전용입니다.

GET /_emdash/api/content/:collection/:entryId/revisions
매개변수유형설명
limitnumber반환할 최대 리비전 수 (기본값: 50)
{
"success": true,
"data": {
"items": [
{
"id": "01HXK5MZSN...",
"collection": "posts",
"entryId": "01HXK5MZSN...",
"data": { ... },
"createdAt": "2025-01-24T12:00:00Z"
}
],
"total": 5
}
}
GET /_emdash/api/revisions/:revisionId
POST /_emdash/api/revisions/:revisionId/restore

콘텐츠를 이 리비전의 상태로 복원하고 새 리비전을 생성합니다.

GET /_emdash/api/schema/collections
{
"success": true,
"data": {
"items": [
{
"id": "01HXK5MZSN...",
"slug": "posts",
"label": "Posts",
"labelSingular": "Post",
"supports": ["drafts", "revisions", "preview"]
}
]
}
}
GET /_emdash/api/schema/collections/:slug
매개변수유형설명
includeFieldsboolean필드 정의 포함 여부 (쿼리)
POST /_emdash/api/schema/collections
Content-Type: application/json
{
"slug": "products",
"label": "Products",
"labelSingular": "Product",
"description": "Product catalog",
"supports": ["drafts", "revisions"]
}
PATCH /_emdash/api/schema/collections/:slug
Content-Type: application/json
DELETE /_emdash/api/schema/collections/:slug
매개변수유형설명
forceboolean컬렉션에 콘텐츠가 있어도 삭제 (쿼리)
GET /_emdash/api/schema/collections/:slug/fields
POST /_emdash/api/schema/collections/:slug/fields
Content-Type: application/json
{
"slug": "price",
"label": "Price",
"type": "number",
"required": true,
"validation": {
"min": 0
}
}
PATCH /_emdash/api/schema/collections/:collectionSlug/fields/:fieldSlug
Content-Type: application/json
DELETE /_emdash/api/schema/collections/:collectionSlug/fields/:fieldSlug
POST /_emdash/api/schema/collections/:slug/fields/reorder
Content-Type: application/json
{
"fieldSlugs": ["title", "content", "author", "publishedAt"]
}
GET /_emdash/api/schema
Accept: application/json
GET /_emdash/api/schema?format=typescript
Accept: text/typescript

모든 컬렉션에 대한 TypeScript 인터페이스를 반환합니다.

GET /_emdash/api/plugins
GET /_emdash/api/plugins/:pluginId
POST /_emdash/api/plugins/:pluginId/enable
POST /_emdash/api/plugins/:pluginId/disable
코드HTTP 상태설명
NOT_FOUND404리소스를 찾을 수 없음
VALIDATION_ERROR400잘못된 입력 데이터
UNAUTHORIZED401토큰이 없거나 유효하지 않음
FORBIDDEN403권한 부족
CONTENT_LIST_ERROR500콘텐츠 목록 조회 실패
CONTENT_CREATE_ERROR500콘텐츠 생성 실패
CONTENT_UPDATE_ERROR500콘텐츠 업데이트 실패
CONTENT_DELETE_ERROR500콘텐츠 삭제 실패
MEDIA_LIST_ERROR500미디어 목록 조회 실패
MEDIA_CREATE_ERROR500미디어 생성 실패
SCHEMA_ERROR400스키마 작업 실패
DUPLICATE_SLUG409슬러그가 이미 존재함
RESERVED_SLUG400슬러그가 예약됨
GET /_emdash/api/search?q=hello+world
매개변수유형설명
qstring검색어 (필수)
collectionsstring쉼표로 구분된 컬렉션 슬러그
statusstring상태별 필터 (기본값: published)
limitnumber최대 결과 수 (기본값: 20)
cursorstring페이지네이션 커서
{
"results": [
{
"collection": "posts",
"id": "01HXK5MZSN...",
"slug": "hello-world",
"title": "안녕하세요",
"snippet": "...this is a <mark>hello</mark>
<mark>world</mark>
example...",
"score": 0.95
}
],
"nextCursor": "eyJvZmZzZXQiOjIwfQ"
}
GET /_emdash/api/search/suggest?q=hel&limit=5

자동 완성을 위한 접두사 일치 제목을 반환합니다.

POST /_emdash/api/search/rebuild

모든 또는 특정 컬렉션에 대한 FTS 인덱스를 재구축합니다.

GET /_emdash/api/search/stats

컬렉션별 인덱싱된 문서 수를 반환합니다.

GET /_emdash/api/sections
GET /_emdash/api/sections?source=theme
GET /_emdash/api/sections?search=newsletter
GET /_emdash/api/sections/:slug
POST /_emdash/api/sections
Content-Type: application/json
{
"slug": "my-section",
"title": "My Section",
"keywords": ["keyword1"],
"content": [...]
}
PUT /_emdash/api/sections/:slug
DELETE /_emdash/api/sections/:slug
GET /_emdash/api/settings
POST /_emdash/api/settings
Content-Type: application/json
{
"siteTitle": "내 사이트",
"tagline": "훌륭한 사이트",
"postsPerPage": 10
}
GET /_emdash/api/menus
GET /_emdash/api/menus/:name
POST /_emdash/api/menus
Content-Type: application/json
{
"name": "footer",
"label": "Footer Navigation"
}
PUT /_emdash/api/menus/:name
DELETE /_emdash/api/menus/:name
POST /_emdash/api/menus/:name/items
Content-Type: application/json
{
"type": "page",
"referenceCollection": "pages",
"referenceId": "page_about",
"label": "About Us"
}
POST /_emdash/api/menus/:name/reorder
Content-Type: application/json
{
"items": [
{ "id": "item_1", "parentId": null, "sortOrder": 0 },
{ "id": "item_2", "parentId": null, "sortOrder": 1 },
{ "id": "item_3", "parentId": "item_2", "sortOrder": 0 }
]
}
GET /_emdash/api/taxonomies
POST /_emdash/api/taxonomies
Content-Type: application/json
{
"name": "genre",
"label": "Genres",
"labelSingular": "Genre",
"hierarchical": true,
"collections": ["books", "movies"]
}
GET /_emdash/api/taxonomies/:name/terms
POST /_emdash/api/taxonomies/:name/terms
Content-Type: application/json
{
"slug": "tutorials",
"label": "튜토리얼",
"parentId": "term_abc",
"description": "실전 가이드"
}
PUT /_emdash/api/taxonomies/:name/terms/:slug
DELETE /_emdash/api/taxonomies/:name/terms/:slug
POST /_emdash/api/content/:collection/:id/terms/:taxonomy
Content-Type: application/json
{
"termIds": ["term_news", "term_featured"]
}
GET /_emdash/api/widget-areas
GET /_emdash/api/widget-areas/:name
POST /_emdash/api/widget-areas
Content-Type: application/json
{
"name": "sidebar",
"label": "메인 사이드바",
"description": "게시물 페이지에 표시됩니다"
}
DELETE /_emdash/api/widget-areas/:name
POST /_emdash/api/widget-areas/:name/widgets
Content-Type: application/json
{
"type": "content",
"title": "소개",
"content": [...]
}
PUT /_emdash/api/widget-areas/:name/widgets/:id
DELETE /_emdash/api/widget-areas/:name/widgets/:id
POST /_emdash/api/widget-areas/:name/reorder
Content-Type: application/json
{
"widgetIds": ["widget_1", "widget_2", "widget_3"]
}
GET /_emdash/api/admin/users
GET /_emdash/api/admin/users?role=40
GET /_emdash/api/admin/users?search=john
GET /_emdash/api/admin/users/:id
PATCH /_emdash/api/admin/users/:id
Content-Type: application/json
{
"name": "John Doe",
"role": 40
}
POST /_emdash/api/admin/users/:id/enable
POST /_emdash/api/admin/users/:id/disable
GET /_emdash/api/setup/status

설정이 완료되었는지와 사용자가 존재하는지 여부를 반환합니다.

POST /_emdash/api/auth/passkey/options

WebAuthn 인증 옵션을 가져옵니다.

POST /_emdash/api/auth/passkey/verify
Content-Type: application/json
{
"id": "credential-id",
"rawId": "...",
"response": {...},
"type": "public-key"
}

패스키를 확인하고 세션을 생성합니다.

POST /_emdash/api/auth/magic-link/send
Content-Type: application/json
{
"email": "user@example.com"
}
GET /_emdash/api/auth/magic-link/verify?token=xxx
POST /_emdash/api/auth/logout
GET /_emdash/api/auth/me
POST /_emdash/api/auth/invite
Content-Type: application/json
{
"email": "newuser@example.com",
"role": 30
}
GET /_emdash/api/auth/passkey

사용자의 패스키 목록을 조회합니다.

POST /_emdash/api/auth/passkey/register/options
POST /_emdash/api/auth/passkey/register/verify

새로운 패스키를 등록합니다.

PATCH /_emdash/api/auth/passkey/:id
Content-Type: application/json
{
"name": "MacBook Pro"
}

패스키 이름을 변경합니다.

DELETE /_emdash/api/auth/passkey/:id

패스키를 삭제합니다.

POST /_emdash/api/import/wordpress/analyze
Content-Type: multipart/form-data
file: <WXR file>
POST /_emdash/api/import/wordpress/execute
Content-Type: application/json
{
"analysisId": "...",
"options": {
"includeMedia": true,
"includeTaxonomies": true,
"includeMenus": true
}
}

API 엔드포인트는 배포 구성에 따라 요청 제한이 적용될 수 있습니다. 제한이 적용되면 응답에 다음이 포함됩니다:

HTTP/1.1 429 Too Many Requests
Retry-After: 60

이 API는 브라우저 요청을 위한 CORS를 지원합니다. 배포 시 허용된 출처를 구성하세요.