REST API 레퍼런스

이 페이지

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

인증

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

Authorization: Bearer <token>

관리 인터페이스를 통해 또는 프로그래밍 방식으로 토큰을 생성합니다.

응답 형식

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

// 성공
{
  "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": "Hello World", ... },
        "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": "Hello World", ... },
      "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"]
}

스키마 내보내기

스키마 내보내기 (JSON)

GET /_emdash/api/schema
Accept: application/json

스키마 내보내기 (TypeScript)

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": "Hello World",
      "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": "My Site",
  "tagline": "A great site",
  "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": "Tutorials",
  "parentId": "term_abc",
  "description": "How-to guides"
}

용어 업데이트

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": "Main Sidebar",
  "description": "Appears on posts"
}

위젯 영역 삭제

DELETE /_emdash/api/widget-areas/:name

위젯 추가

POST /_emdash/api/widget-areas/:name/widgets
Content-Type: application/json

{
  "type": "content",
  "title": "About",
  "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": "[email protected]"
}
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": "[email protected]",
  "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

패스키를 삭제합니다.

가져오기 엔드포인트

WordPress 내보내기 분석

POST /_emdash/api/import/wordpress/analyze
Content-Type: multipart/form-data

file: <WXR file>

WordPress 가져오기 실행

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

CORS

API는 브라우저 요청을 위한 CORS를 지원합니다. 배포에서 허용된 오리진을 구성합니다.