Awesome-openclaw-skills fabric-api

Create/search Fabric resources via HTTP API (notepads, folders, bookmarks, files).

install
source · Clone the upstream repo
git clone https://github.com/sundial-org/awesome-openclaw-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/sundial-org/awesome-openclaw-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/fabric-api" ~/.claude/skills/sundial-org-awesome-openclaw-skills-fabric-api && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/sundial-org/awesome-openclaw-skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/fabric-api" ~/.openclaw/skills/sundial-org-awesome-openclaw-skills-fabric-api && rm -rf "$T"
manifest: skills/fabric-api/SKILL.md
source content

Fabric API (HTTP via curl)

Use this skill to read/write content in a user's Fabric workspace using the Fabric HTTP API (

https://api.fabric.so
).

Critical gotchas (read first)

  • "Notes" are created via POST
    /v2/notepads
    (not
    /v2/notes
    ).
  • Most create endpoints require
    parentId
    :
    • A UUID or one of:
      @alias::inbox
      ,
      @alias::bin
      .
  • Notepad create requires:
    • parentId
    • AND either
      text
      (markdown string) or
      ydoc
      (advanced/structured).
  • tags
    must be an array of objects, each either:
    • { "name": "tag name" }
      or
      { "id": "<uuid>" }
    • Never nested arrays; never strings.

When the user doesn't specify a destination folder: default to

parentId: "@alias::inbox"
.

Setup (Clawdbot)

This skill expects the API key in:

  • FABRIC_API_KEY

Recommended config (use

apiKey
; Clawdbot will inject
FABRIC_API_KEY
because
primaryEnv
is set):

{
  skills: {
    entries: {
      "fabric-api": {
        enabled: true,
        apiKey: "YOUR_FABRIC_API_KEY"
      }
    }
  }
}

HTTP basics

  • Base:
    https://api.fabric.so
  • Auth:
    X-Api-Key: $FABRIC_API_KEY
  • JSON:
    Content-Type: application/json

For debugging: prefer

--fail-with-body
so 4xx bodies are shown.

Canonical curl templates (use heredocs to avoid quoting bugs)

GET

curl -sS --fail-with-body "https://api.fabric.so/v2/user/me" \
  -H "X-Api-Key: $FABRIC_API_KEY"

POST (JSON)

curl -sS --fail-with-body -X POST "https://api.fabric.so/v2/ENDPOINT" \
  -H "X-Api-Key: $FABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{ "replace": "me" }
JSON

Core workflows

1) Create a notepad (note)

Endpoint:

POST /v2/notepads

  • Map user-provided "title" →
    name
    in the API payload.
  • Always include
    parentId
    .
  • Use
    text
    for markdown content.
curl -sS --fail-with-body -X POST "https://api.fabric.so/v2/notepads" \
  -H "X-Api-Key: $FABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "name": "Calendar Test Note",
  "text": "Created via Clawdbot",
  "parentId": "@alias::inbox",
  "tags": [{"name":"calendar"},{"name":"draft"}]
}
JSON

If tags cause validation trouble, omit them and create/assign later via

/v2/tags
.

2) Create a folder

Endpoint:

POST /v2/folders

curl -sS --fail-with-body -X POST "https://api.fabric.so/v2/folders" \
  -H "X-Api-Key: $FABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "name": "My new folder",
  "parentId": "@alias::inbox",
  "description": null
}
JSON

3) Create a bookmark

Endpoint:

POST /v2/bookmarks

curl -sS --fail-with-body -X POST "https://api.fabric.so/v2/bookmarks" \
  -H "X-Api-Key: $FABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "url": "https://example.com",
  "parentId": "@alias::inbox",
  "name": "Example",
  "tags": [{"name":"reading"}]
}
JSON

4) Browse resources (list children of a folder)

Endpoint:

POST /v2/resources/filter

Use this to list what's inside a folder (use a folder UUID as

parentId
).

curl -sS --fail-with-body -X POST "https://api.fabric.so/v2/resources/filter" \
  -H "X-Api-Key: $FABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "parentId": "PARENT_UUID_HERE",
  "limit": 50,
  "order": { "property": "modifiedAt", "direction": "DESC" }
}
JSON

5) Search

Endpoint:

POST /v2/search

Use search when the user gives a fuzzy description (“the note about…”).

curl -sS --fail-with-body -X POST "https://api.fabric.so/v2/search" \
  -H "X-Api-Key: $FABRIC_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "queries": [
    {
      "mode": "text",
      "text": "meeting notes",
      "filters": { "kinds": ["notepad"] }
    }
  ],
  "pagination": { "page": 1, "pageSize": 20 },
  "sort": { "field": "modifiedAt", "order": "desc" }
}
JSON

Tags (safe patterns)

List tags

GET /v2/tags?limit=100

Create tag

POST /v2/tags
with
{ "name": "tag name", "description": null, "resourceId": null }

Assign tags on create

Use

tags: [{"name":"x"}]
or
tags: [{"id":"<uuid>"}]
only.

Rate limiting + retries

If you get

429 Too Many Requests
:

  • Back off (sleep + jitter) and retry.
  • Avoid tight loops; do pagination slowly.

Do not blindly retry create requests without idempotency (you may create duplicates).

Troubleshooting quick map

  • 404 Not Found
    : almost always wrong endpoint, wrong resourceId/parentId, or permissions.
  • 400 Bad Request
    : schema validation; check required fields and tag shape.
  • 403 Forbidden
    : subscription/permission limits.
  • 429 Too Many Requests
    : back off + retry.

API reference

The OpenAPI schema lives here:

  • {baseDir}/fabric-api.yaml

When in doubt, consult it before guessing endpoint names or payload shapes.