判断 MarginNote 是否注册了该接口
const caps = await mn.api('/capabilities');
const has = caps.routes.some(r => r.path === '/notes/{id}/edits');
mn.log(caps.bridgeApiVersion, caps.apiFingerprint, caps.routeCount);{
"routes": [
{
"path": "/status",
"method": "GET",
"requiresMax": false
},
{
"path": "/capabilities",
"method": "GET",
"requiresMax": false
},
{
"path": "/sync/legacy/status",
"method": "GET",
"requiresMax": false
}
],
"legacySync": {
"databaseAndDocumentsCompleteIndependently": true,
"databaseCarries": [
"study_set_structure",
"mind_map_cards",
"excerpts",
"handwriting",
"blank_pages",
"fold_and_layout_state",
"book_configuration"
],
"documentHashVerification": {
"default": false,
"expensive": true,
"externalFileProvidersAreNotReopened": true,
"query": "verifyHash=1"
},
"documentLaneCarries": [
"original_document_bytes"
],
"documentStatusRoute": "/documents/{id}/sync-status",
"eventsRoute": "/sync/legacy/events?afterSequence={sequence}&limit={1..200}",
"inventoryAffectsNormalSyncStatus": false,
"inventoryAllowsCellularAccess": false,
"inventoryAuthoritative": false,
"inventoryMayConsumeCloudKitQuota": true,
"inventoryObserveOnly": true,
"inventoryReturnsRecordIdentifiers": false,
"inventoryRoute": "/sync/legacy/inventory",
"inventoryServerResultConsistency": "eventually_consistent_query",
"inventoryUsesSyncQueue": false,
"lanes": [
"cloudkit",
"documents"
],
"recheckDirectlyEditsUserContent": false,
"recheckMayApplyPendingRemoteChanges": true,
"recheckRoute": "/sync/legacy/recheck",
"statusRoute": "/sync/legacy/status"
},
"accessPolicy": {
"readOnlyRequiresMax": false,
"routeField": "requiresMax",
"setupNavigationAndTemporaryExportRequireMax": false,
"userDataStillRequiresBearerToken": true,
"writeRequiresMax": true
},
"anchorModes": [
"page_text",
"block"
],
"noteMetadata": {
"maxNoteIds": 200,
"patchFields": {
"fillIndex": {
"scope": "source_annotation_style_not_mind_map_card_transparency",
"values": [
-1,
0,
1,
2
],
"semantics": [
{
"fillIndex": -1,
"id": "legacy_adaptive",
"regionSelection": "outline_only",
"textSelection": "fill_and_underline"
},
{
"fillIndex": 0,
"id": "fill_and_stroke",
"regionSelection": "fill_and_outline",
"textSelection": "fill_and_underline"
},
{
"fillIndex": 1,
"id": "fill_only",
"regionSelection": "fill_only",
"textSelection": "fill_only"
},
{
"fillIndex": 2,
"id": "stroke_only",
"regionSelection": "outline_only",
"textSelection": "underline_only"
}
]
},
"colorIndex": {
"max": 15,
"min": 0
}
},
"palette": {
"colorIndexRange": [
0,
15
],
"count": 16,
"representations": [
"hex",
"rgba"
],
"route": "/study-sets/{id}/note-palette"
}
},
"reviewDeckCards": {
"contentSelectorField": "questionContentId",
"contentSelectorSemantics": "copies_exact_native_part_into_review_card_front",
"contentSelectorSource": "POST /notes/batch-get parts[].contentId",
"customTextAndContentSelectorMutuallyExclusive": true,
"customTextField": "question",
"questionModes": [
"automatic",
"custom_text",
"content_part"
],
"requiresConfirm": true,
"route": "/decks/{id}/cards"
},
"routeCount": 87,
"noteCopy": {
"target": "existing_parent_card",
"modes": [
"reference",
"clone"
],
"semantics": {
"clone": {
"contentSynchronized": false,
"description": "Creates independent cards and remaps links within the cloned branch."
},
"reference": {
"contentSynchronized": true,
"description": "Creates MarginNote reference cards that stay synchronized with their source cards."
}
},
"scope": "selected_roots_and_all_mind_map_descendants",
"requiresConfirm": true,
"route": "/notes/copy",
"maxSourceRoots": 50
},
"bridgeApiVersion": "0.61",
"presets": [
"book-breakdown",
"source-structure",
"exam-general",
"dictionary"
],
"guideVersion": "0.61",
"apiFingerprint": "17b754d41172",
"guide": {
"sha256": "c58ca54dfa21245e25cd863c5cbc2084f94d69c188e15f22fa86bbfd4809512a",
"refreshPolicy": "fetch_at_session_start_when_version_or_sha256_differs",
"rotatesToken": false,
"usesExistingBearer": true,
"installRequired": false,
"version": "0.61",
"route": "/guide"
},
"noteTitles": {
"preview": "display_title_or_first_text",
"previewTextLimitUTF16": 64,
"previewTruncationMarker": "…",
"previewTruncationMarkerExcludedFromLimit": true,
"routes": [
"GET /study-sets/{id}/tree",
"POST /notes/batch-get"
],
"title": "full_display_title_without_body_fallback",
"untitledValue": ""
},
"guideHash": "c58ca54dfa21245e25cd863c5cbc2084f94d69c188e15f22fa86bbfd4809512a",
"noteHashtags": {
"ancestors": "derived_not_materialized",
"caseSensitive": false,
"doNotUseForWriting": "/notes/{id}/text",
"hierarchySeparator": "/",
"inlineTextEncodingSupported": false,
"maxHashtags": 100,
"maxNoteIds": 200,
"operations": [
"add",
"remove",
"replace"
],
"readFields": [
"hashtags",
"hashtagPaths"
],
"recursiveRemoveFlag": "includeDescendants",
"removeDefault": "exact_full_path",
"storedValue": "one_complete_leaf_path",
"textEditMisuseError": "HASHTAG_ROUTE_REQUIRED",
"treeRoute": "/study-sets/{id}/hashtags",
"writeRoute": "/notes/hashtags"
}
}能力与状态
获取能力清单
返回 MarginNote 实际注册的全部路由,以及各主题的上限与语义。
读该接口可取得各项上限与取值枚举,例如标签操作的取值、元数据的取值范围、
手写会话的上限。Request Body 的写法未收录,见 GET /guide。
GET
/
capabilities
判断 MarginNote 是否注册了该接口
const caps = await mn.api('/capabilities');
const has = caps.routes.some(r => r.path === '/notes/{id}/edits');
mn.log(caps.bridgeApiVersion, caps.apiFingerprint, caps.routeCount);{
"routes": [
{
"path": "/status",
"method": "GET",
"requiresMax": false
},
{
"path": "/capabilities",
"method": "GET",
"requiresMax": false
},
{
"path": "/sync/legacy/status",
"method": "GET",
"requiresMax": false
}
],
"legacySync": {
"databaseAndDocumentsCompleteIndependently": true,
"databaseCarries": [
"study_set_structure",
"mind_map_cards",
"excerpts",
"handwriting",
"blank_pages",
"fold_and_layout_state",
"book_configuration"
],
"documentHashVerification": {
"default": false,
"expensive": true,
"externalFileProvidersAreNotReopened": true,
"query": "verifyHash=1"
},
"documentLaneCarries": [
"original_document_bytes"
],
"documentStatusRoute": "/documents/{id}/sync-status",
"eventsRoute": "/sync/legacy/events?afterSequence={sequence}&limit={1..200}",
"inventoryAffectsNormalSyncStatus": false,
"inventoryAllowsCellularAccess": false,
"inventoryAuthoritative": false,
"inventoryMayConsumeCloudKitQuota": true,
"inventoryObserveOnly": true,
"inventoryReturnsRecordIdentifiers": false,
"inventoryRoute": "/sync/legacy/inventory",
"inventoryServerResultConsistency": "eventually_consistent_query",
"inventoryUsesSyncQueue": false,
"lanes": [
"cloudkit",
"documents"
],
"recheckDirectlyEditsUserContent": false,
"recheckMayApplyPendingRemoteChanges": true,
"recheckRoute": "/sync/legacy/recheck",
"statusRoute": "/sync/legacy/status"
},
"accessPolicy": {
"readOnlyRequiresMax": false,
"routeField": "requiresMax",
"setupNavigationAndTemporaryExportRequireMax": false,
"userDataStillRequiresBearerToken": true,
"writeRequiresMax": true
},
"anchorModes": [
"page_text",
"block"
],
"noteMetadata": {
"maxNoteIds": 200,
"patchFields": {
"fillIndex": {
"scope": "source_annotation_style_not_mind_map_card_transparency",
"values": [
-1,
0,
1,
2
],
"semantics": [
{
"fillIndex": -1,
"id": "legacy_adaptive",
"regionSelection": "outline_only",
"textSelection": "fill_and_underline"
},
{
"fillIndex": 0,
"id": "fill_and_stroke",
"regionSelection": "fill_and_outline",
"textSelection": "fill_and_underline"
},
{
"fillIndex": 1,
"id": "fill_only",
"regionSelection": "fill_only",
"textSelection": "fill_only"
},
{
"fillIndex": 2,
"id": "stroke_only",
"regionSelection": "outline_only",
"textSelection": "underline_only"
}
]
},
"colorIndex": {
"max": 15,
"min": 0
}
},
"palette": {
"colorIndexRange": [
0,
15
],
"count": 16,
"representations": [
"hex",
"rgba"
],
"route": "/study-sets/{id}/note-palette"
}
},
"reviewDeckCards": {
"contentSelectorField": "questionContentId",
"contentSelectorSemantics": "copies_exact_native_part_into_review_card_front",
"contentSelectorSource": "POST /notes/batch-get parts[].contentId",
"customTextAndContentSelectorMutuallyExclusive": true,
"customTextField": "question",
"questionModes": [
"automatic",
"custom_text",
"content_part"
],
"requiresConfirm": true,
"route": "/decks/{id}/cards"
},
"routeCount": 87,
"noteCopy": {
"target": "existing_parent_card",
"modes": [
"reference",
"clone"
],
"semantics": {
"clone": {
"contentSynchronized": false,
"description": "Creates independent cards and remaps links within the cloned branch."
},
"reference": {
"contentSynchronized": true,
"description": "Creates MarginNote reference cards that stay synchronized with their source cards."
}
},
"scope": "selected_roots_and_all_mind_map_descendants",
"requiresConfirm": true,
"route": "/notes/copy",
"maxSourceRoots": 50
},
"bridgeApiVersion": "0.61",
"presets": [
"book-breakdown",
"source-structure",
"exam-general",
"dictionary"
],
"guideVersion": "0.61",
"apiFingerprint": "17b754d41172",
"guide": {
"sha256": "c58ca54dfa21245e25cd863c5cbc2084f94d69c188e15f22fa86bbfd4809512a",
"refreshPolicy": "fetch_at_session_start_when_version_or_sha256_differs",
"rotatesToken": false,
"usesExistingBearer": true,
"installRequired": false,
"version": "0.61",
"route": "/guide"
},
"noteTitles": {
"preview": "display_title_or_first_text",
"previewTextLimitUTF16": 64,
"previewTruncationMarker": "…",
"previewTruncationMarkerExcludedFromLimit": true,
"routes": [
"GET /study-sets/{id}/tree",
"POST /notes/batch-get"
],
"title": "full_display_title_without_body_fallback",
"untitledValue": ""
},
"guideHash": "c58ca54dfa21245e25cd863c5cbc2084f94d69c188e15f22fa86bbfd4809512a",
"noteHashtags": {
"ancestors": "derived_not_materialized",
"caseSensitive": false,
"doNotUseForWriting": "/notes/{id}/text",
"hierarchySeparator": "/",
"inlineTextEncodingSupported": false,
"maxHashtags": 100,
"maxNoteIds": 200,
"operations": [
"add",
"remove",
"replace"
],
"readFields": [
"hashtags",
"hashtagPaths"
],
"recursiveRemoveFlag": "includeDescendants",
"removeDefault": "exact_full_path",
"storedValue": "one_complete_leaf_path",
"textEditMisuseError": "HASHTAG_ROUTE_REQUIRED",
"treeRoute": "/study-sets/{id}/hashtags",
"writeRoute": "/notes/hashtags"
}
}响应
200 - application/json
路由清单与各项上限。示例摘自真机实录,只保留开头部分。
路由清单与各项上限。字段比此处列出的多,另有若干按主题分组的对象,分别说明标签操作、元数据级别、手写会话、同步诊断各自的上限与语义。