EmDash expõe uma API REST em /_emdash/api/ para gerenciamento de conteúdo, upload de mídia e operações de esquema.
Autenticação
As requisições da API requerem autenticação via token Bearer no cabeçalho Authorization:
Authorization: Bearer <token>
Gere tokens através da interface de administração ou programaticamente.
Formato de resposta
Todas as respostas seguem um formato consistente. Uma resposta bem-sucedida envolve o resultado em data:
{
"success": true,
"data": { ... }
}
Uma resposta de erro inclui um código, mensagem e detalhes opcionais:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable message",
"details": { ... }
}
}
Endpoints de Conteúdo
Listar Conteúdo
GET /_emdash/api/content/:collection
Parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
collection | string | Slug da coleção (caminho) |
cursor | string | Cursor de paginação (query) |
limit | number | Itens por página (query, padrão: 50) |
status | string | Filtrar por status (query) |
orderBy | string | Campo para ordenar (query) |
order | string | Direção da ordenação: asc ou desc (query) |
Resposta
{
"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..."
}
}
Obter Conteúdo
GET /_emdash/api/content/:collection/:id
Resposta
{
"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"
}
}
}
Criar Conteúdo
POST /_emdash/api/content/:collection
Content-Type: application/json
Corpo da Requisição
{
"data": {
"title": "New Post",
"content": [...]
},
"slug": "new-post",
"status": "draft"
}
Resposta
{
"success": true,
"data": {
"item": { ... }
}
}
Atualizar Conteúdo
PUT /_emdash/api/content/:collection/:id
Content-Type: application/json
Corpo da Requisição
{
"data": {
"title": "Updated Title"
},
"status": "published"
}
Excluir Conteúdo
DELETE /_emdash/api/content/:collection/:id
Resposta
{
"success": true,
"data": {
"success": true
}
}
Endpoints de Mídia
Listar Mídia
GET /_emdash/api/media
Parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
cursor | string | Cursor de paginação |
limit | number | Itens por página (padrão: 20) |
mimeType | string | Filtrar por prefixo de tipo MIME |
Resposta
{
"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..."
}
}
Obter Mídia
GET /_emdash/api/media/:id
Criar Mídia
POST /_emdash/api/media
Content-Type: application/json
Corpo da Requisição
{
"filename": "photo.jpg",
"mimeType": "image/jpeg",
"size": 102400,
"width": 1920,
"height": 1080,
"storageKey": "uploads/photo.jpg"
}
Atualizar Mídia
PUT /_emdash/api/media/:id
Content-Type: application/json
Corpo da Requisição
{
"alt": "Photo description",
"caption": "Photo caption"
}
Excluir Mídia
DELETE /_emdash/api/media/:id
Obter Arquivo de Mídia
GET /_emdash/api/media/file/:key
Serve o conteúdo real do arquivo. Apenas para armazenamento local.
Endpoints de Revisões
Listar Revisões
GET /_emdash/api/content/:collection/:entryId/revisions
Parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
limit | number | Máximo de revisões a retornar (padrão: 50) |
Resposta
{
"success": true,
"data": {
"items": [
{
"id": "01HXK5MZSN...",
"collection": "posts",
"entryId": "01HXK5MZSN...",
"data": { ... },
"createdAt": "2025-01-24T12:00:00Z"
}
],
"total": 5
}
}
Obter Revisão
GET /_emdash/api/revisions/:revisionId
Restaurar Revisão
POST /_emdash/api/revisions/:revisionId/restore
Restaura o conteúdo para o estado desta revisão e cria uma nova revisão.
Endpoints de Esquema
Listar Coleções
GET /_emdash/api/schema/collections
Resposta
{
"success": true,
"data": {
"items": [
{
"id": "01HXK5MZSN...",
"slug": "posts",
"label": "Posts",
"labelSingular": "Post",
"supports": ["drafts", "revisions", "preview"]
}
]
}
}
Obter Coleção
GET /_emdash/api/schema/collections/:slug
Parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
includeFields | boolean | Incluir definições de campos (query) |
Criar Coleção
POST /_emdash/api/schema/collections
Content-Type: application/json
Corpo da Requisição
{
"slug": "products",
"label": "Products",
"labelSingular": "Product",
"description": "Product catalog",
"supports": ["drafts", "revisions"]
}
Atualizar Coleção
PUT /_emdash/api/schema/collections/:slug
Content-Type: application/json
Excluir Coleção
DELETE /_emdash/api/schema/collections/:slug
Parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
force | boolean | Excluir mesmo se a coleção tiver conteúdo (query) |
Listar Campos
GET /_emdash/api/schema/collections/:slug/fields
Criar Campo
POST /_emdash/api/schema/collections/:slug/fields
Content-Type: application/json
Corpo da Requisição
{
"slug": "price",
"label": "Price",
"type": "number",
"required": true,
"validation": {
"min": 0
}
}
Atualizar Campo
PUT /_emdash/api/schema/collections/:collectionSlug/fields/:fieldSlug
Content-Type: application/json
Excluir Campo
DELETE /_emdash/api/schema/collections/:collectionSlug/fields/:fieldSlug
Reordenar Campos
POST /_emdash/api/schema/collections/:slug/fields/reorder
Content-Type: application/json
Corpo da Requisição
{
"fieldSlugs": ["title", "content", "author", "publishedAt"]
}
Exportação de Esquema
Exportar Esquema (JSON)
GET /_emdash/api/schema
Accept: application/json
Exportar Esquema (TypeScript)
GET /_emdash/api/schema?format=typescript
Accept: text/typescript
Retorna interfaces TypeScript para todas as coleções.
Endpoints de Plugins
Listar Plugins
GET /_emdash/api/admin/plugins
Obter Plugin
GET /_emdash/api/admin/plugins/:id
Ativar Plugin
POST /_emdash/api/admin/plugins/:id/enable
Desativar Plugin
POST /_emdash/api/admin/plugins/:id/disable
Códigos de Erro
| Código | Status HTTP | Descrição |
|---|---|---|
NOT_FOUND | 404 | Recurso não encontrado |
VALIDATION_ERROR | 400 | Dados de entrada inválidos |
UNAUTHORIZED | 401 | Token ausente ou inválido |
FORBIDDEN | 403 | Permissões insuficientes |
CONTENT_LIST_ERROR | 500 | Falha ao listar conteúdo |
CONTENT_CREATE_ERROR | 500 | Falha ao criar conteúdo |
CONTENT_UPDATE_ERROR | 500 | Falha ao atualizar conteúdo |
CONTENT_DELETE_ERROR | 500 | Falha ao excluir conteúdo |
MEDIA_LIST_ERROR | 500 | Falha ao listar mídia |
MEDIA_CREATE_ERROR | 500 | Falha ao criar mídia |
SCHEMA_CREATE_ERROR | 500 | Operação de esquema falhou |
SLUG_CONFLICT | 409 | Slug já existe |
RESERVED_SLUG | 400 | Slug está reservado |
Endpoints de Pesquisa
Pesquisa Global
GET /_emdash/api/search?q=hello+world
Parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
q | string | Consulta de pesquisa (obrigatório) |
collections | string | Slugs de coleções separados por vírgula |
status | string | Filtrar por status (padrão: published) |
limit | number | Máximo de resultados (padrão: 20) |
cursor | string | Cursor de paginação |
Resposta
{
"success": true,
"data": {
"items": [
{
"collection": "posts",
"id": "01HXK5MZSN...",
"slug": "hello-world",
"locale": "en",
"title": "Hello World",
"snippet": "...this is a <mark>hello</mark> <mark>world</mark> example...",
"score": 0.95
}
],
"nextCursor": "eyJvZmZzZXQiOjIwfQ"
}
}
Sugestões de Pesquisa
GET /_emdash/api/search/suggest?q=hel&limit=5
Retorna títulos correspondentes ao prefixo para autocompletar.
Reconstruir Índice de Pesquisa
POST /_emdash/api/search/rebuild
Reconstrói o índice FTS para todas ou coleções específicas.
Estatísticas de Pesquisa
GET /_emdash/api/search/stats
Retorna contagens de documentos indexados por coleção.
Endpoints de Seções
Listar Seções
GET /_emdash/api/sections
GET /_emdash/api/sections?source=theme
GET /_emdash/api/sections?search=newsletter
Obter Seção
GET /_emdash/api/sections/:slug
Criar Seção
POST /_emdash/api/sections
Content-Type: application/json
{
"slug": "my-section",
"title": "My Section",
"keywords": ["keyword1"],
"content": [...]
}
Atualizar Seção
PUT /_emdash/api/sections/:slug
Excluir Seção
DELETE /_emdash/api/sections/:slug
Endpoints de Configurações
Obter Todas as Configurações
GET /_emdash/api/settings
Atualizar Configurações
POST /_emdash/api/settings
Content-Type: application/json
{
"siteTitle": "My Site",
"tagline": "A great site",
"postsPerPage": 10
}
Endpoints de Menus
Listar Menus
GET /_emdash/api/menus
Obter Menu
GET /_emdash/api/menus/:name
Criar Menu
POST /_emdash/api/menus
Content-Type: application/json
{
"name": "footer",
"label": "Footer Navigation"
}
Atualizar Menu
PUT /_emdash/api/menus/:name
Excluir Menu
DELETE /_emdash/api/menus/:name
Adicionar Item de Menu
POST /_emdash/api/menus/:name/items
Content-Type: application/json
{
"type": "page",
"referenceCollection": "pages",
"referenceId": "page_about",
"label": "About Us"
}
Reordenar Itens de Menu
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 }
]
}
Endpoints de Taxonomias
Listar Definições de Taxonomias
GET /_emdash/api/taxonomies
Criar Taxonomia
POST /_emdash/api/taxonomies
Content-Type: application/json
{
"name": "genre",
"label": "Genres",
"labelSingular": "Genre",
"hierarchical": true,
"collections": ["books", "movies"]
}
Listar Termos
GET /_emdash/api/taxonomies/:name/terms
Criar Termo
POST /_emdash/api/taxonomies/:name/terms
Content-Type: application/json
{
"slug": "tutorials",
"label": "Tutorials",
"parentId": "term_abc",
"description": "How-to guides"
}
Atualizar Termo
PUT /_emdash/api/taxonomies/:name/terms/:slug
Excluir Termo
DELETE /_emdash/api/taxonomies/:name/terms/:slug
Definir Termos de Entrada
POST /_emdash/api/content/:collection/:id/terms/:taxonomy
Content-Type: application/json
{
"termIds": ["term_news", "term_featured"]
}
Endpoints de Áreas de Widgets
Listar Áreas de Widgets
GET /_emdash/api/widget-areas
Obter Área de Widget
GET /_emdash/api/widget-areas/:name
Criar Área de Widget
POST /_emdash/api/widget-areas
Content-Type: application/json
{
"name": "sidebar",
"label": "Main Sidebar",
"description": "Appears on posts"
}
Excluir Área de Widget
DELETE /_emdash/api/widget-areas/:name
Adicionar Widget
POST /_emdash/api/widget-areas/:name/widgets
Content-Type: application/json
{
"type": "content",
"title": "About",
"content": [...]
}
Atualizar Widget
PUT /_emdash/api/widget-areas/:name/widgets/:id
Excluir Widget
DELETE /_emdash/api/widget-areas/:name/widgets/:id
Reordenar Widgets
POST /_emdash/api/widget-areas/:name/reorder
Content-Type: application/json
{
"widgetIds": ["widget_1", "widget_2", "widget_3"]
}
Endpoints de Gerenciamento de Usuários
Listar Usuários
GET /_emdash/api/admin/users
GET /_emdash/api/admin/users?role=40
GET /_emdash/api/admin/users?search=john
Obter Usuário
GET /_emdash/api/admin/users/:id
Atualizar Usuário
PUT /_emdash/api/admin/users/:id
Content-Type: application/json
{
"name": "John Doe",
"role": 40
}
Ativar Usuário
POST /_emdash/api/admin/users/:id/enable
Desativar Usuário
POST /_emdash/api/admin/users/:id/disable
Endpoints de Autenticação
Status de Configuração
GET /_emdash/api/setup/status
Retorna se a configuração está completa e se existem usuários.
Login com Passkey
POST /_emdash/api/auth/passkey/options
Obtém opções de autenticação WebAuthn.
POST /_emdash/api/auth/passkey/verify
Content-Type: application/json
{
"id": "credential-id",
"rawId": "...",
"response": {...},
"type": "public-key"
}
Verifica a passkey e cria a sessão.
Link Mágico
POST /_emdash/api/auth/magic-link/send
Content-Type: application/json
{
"email": "user@example.com"
}
GET /_emdash/api/auth/magic-link/verify?token=xxx
Logout
POST /_emdash/api/auth/logout
Usuário Atual
GET /_emdash/api/auth/me
Convidar Usuário
POST /_emdash/api/auth/invite
Content-Type: application/json
{
"email": "newuser@example.com",
"role": 30
}
Gerenciamento de Passkeys
GET /_emdash/api/auth/passkey
Lista as passkeys do usuário.
POST /_emdash/api/auth/passkey/register/options
POST /_emdash/api/auth/passkey/register/verify
Registra uma nova passkey.
PATCH /_emdash/api/auth/passkey/:id
Content-Type: application/json
{
"name": "MacBook Pro"
}
Renomeia a passkey.
DELETE /_emdash/api/auth/passkey/:id
Exclui a passkey.
Endpoints de Importação
Analisar Exportação do WordPress
POST /_emdash/api/import/wordpress/analyze
Content-Type: multipart/form-data
file: <WXR file>
Executar Importação do WordPress
POST /_emdash/api/import/wordpress/execute
Content-Type: application/json
{
"analysisId": "...",
"options": {
"includeMedia": true,
"includeTaxonomies": true,
"includeMenus": true
}
}
Limitação de Taxa
Os endpoints da API podem ter limitação de taxa com base na configuração de implantação. Quando limitado, as respostas incluem:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
CORS
A API suporta CORS para requisições de navegadores. Configure as origens permitidas em sua implantação.