Magic-Mark — API Reference
Authentication
All endpoints require a Strapi admin token:
Authorization: Bearer <admin-token>Endpoints
GET /magic-mark/bookmarks
List bookmarks visible to the caller.
Query params:
collection— Strapi collection UID (e.g.api::article.article)ownerId— filter by owner user IDsharedWith— filter by role name or user email
curl -H "Authorization: Bearer <token>" \
"http://localhost:1337/magic-mark/bookmarks?collection=api::article.article"Response:
{
"data": [
{
"id": 1,
"name": "Pending review",
"emoji": "📝",
"collection": "api::article.article",
"owner": { "id": 5, "email": "editor@example.com" },
"visibility": "roles",
"sharedRoles": ["Editor"],
"sharedUsers": [],
"pinned": false,
"position": 3,
"query": {
"filters": { "status": "pending" },
"sort": [{ "createdAt": "desc" }],
"search": null,
"pagination": { "page": 1, "pageSize": 25 }
},
"createdAt": "2026-04-20T14:00:00Z",
"updatedAt": "2026-04-20T14:00:00Z"
}
],
"meta": { "total": 1 }
}POST /magic-mark/bookmarks
Create a bookmark.
curl -X POST -H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Drafts",
"emoji": "📝",
"collection": "api::article.article",
"query": {
"filters": { "status": "draft" },
"sort": [{ "updatedAt": "desc" }]
},
"visibility": "private"
}' \
http://localhost:1337/magic-mark/bookmarksGET /magic-mark/bookmarks/:id
Get a single bookmark by ID. Caller must have access (owner or shared).
PUT /magic-mark/bookmarks/:id
Update. Only owner can modify. Any field can be updated:
{
"name": "New name",
"emoji": "🎯",
"query": { ... },
"visibility": "roles",
"sharedRoles": ["Editor", "Manager"]
}DELETE /magic-mark/bookmarks/:id
Delete. Owner only.
POST /magic-mark/bookmarks/:id/pin / /unpin
Toggle pin. Pinned bookmarks appear at the top of the sidebar.
POST /magic-mark/bookmarks/reorder
Bulk reorder:
POST /magic-mark/bookmarks/reorder
{
"collection": "api::article.article",
"order": [5, 3, 1, 7] // bookmark IDs in desired order
}POST /magic-mark/bookmarks/:id/apply
Return a Strapi Content Manager URL with the query applied (useful for deep-linking):
curl -H "Authorization: Bearer <token>" \
-X POST http://localhost:1337/magic-mark/bookmarks/5/applyResponse:
{
"url": "/admin/content-manager/collection-types/api::article.article?filters[status]=draft&sort=updatedAt:desc"
}Query schema
The query object stores the full Content Manager state:
interface BookmarkQuery {
filters?: Record<string, unknown>; // Strapi filter syntax
sort?: Array<Record<string, 'asc' | 'desc'>>;
search?: string;
pagination?: {
page?: number;
pageSize?: number;
};
populate?: string | string[] | Record<string, unknown>;
locale?: string;
status?: 'draft' | 'published';
}Query history (Premium / Advanced)
GET /magic-mark/history
Recent queries (auto-saved as user applies filters).
curl -H "Authorization: Bearer <token>" \
"http://localhost:1337/magic-mark/history?limit=20"Response: array of query objects with appliedAt timestamps.
POST /magic-mark/history/:id/save-as-bookmark
Convert a history entry into a bookmark.
Analytics (Advanced)
GET /magic-mark/analytics
Bookmark usage stats.
{
"totalBookmarks": 247,
"activeBookmarks": 189,
"topBookmarks": [
{ "id": 1, "name": "Drafts", "applicationsLast30Days": 456 },
{ "id": 7, "name": "Featured", "applicationsLast30Days": 321 }
],
"timeSaved": { "hours": 127, "applications": 3421 }
}timeSaved estimates the time saved by using bookmarks vs manually recreating queries.
Error codes
| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_QUERY | Query schema validation failed |
| 401 | UNAUTHORIZED | Admin token required |
| 403 | FORBIDDEN | No access to this bookmark |
| 404 | NOT_FOUND | Bookmark does not exist |
| 409 | LIMIT_REACHED | User exceeded tier bookmark limit |
| 422 | INVALID_COLLECTION | Collection UID doesn't exist |
Service API (server-side)
// Inside your Strapi code
const service = strapi.plugin('magic-mark').service('bookmarks');
// List a user's bookmarks
const list = await service.listForUser(userId, { collection: 'api::article.article' });
// Create
const bookmark = await service.create({
ownerId: userId,
name: 'Drafts',
emoji: '📝',
collection: 'api::article.article',
query: { filters: { status: 'draft' } },
visibility: 'private',
});
// Share with roles
await service.share(bookmark.id, { visibility: 'roles', roles: ['Editor'] });Next: Examples →