home / skills / openclaw / skills / fabric-api

This skill lets you read and write Fabric resources via HTTP API, enabling notepads, folders, bookmarks, and searches in your workspace.

npx playbooks add skill openclaw/skills --skill fabric-api

Review the files below or copy the command above to add this skill to your agents.

Files (3)
SKILL.md
5.1 KB
---
name: fabric-api
description: Create/search Fabric resources via HTTP API (notepads, folders, bookmarks, files).
homepage: https://fabric.so
metadata: {"clawdbot":{"emoji":"🧵","requires":{"env":["FABRIC_API_KEY"],"bins":["curl"]},"primaryEnv":"FABRIC_API_KEY"}}
---

# 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):

```json5
{
  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

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

### POST (JSON)

```bash
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.

```bash
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`

```bash
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`

```bash
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`).

```bash
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…”).

```bash
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.

Overview

This skill lets you create, search, and manage Fabric workspace resources via the Fabric HTTP API (notepads, folders, bookmarks, files). It handles common payload shapes, required fields, and recommended defaults so you can script or automate Fabric operations reliably. The skill expects an API key provided in FABRIC_API_KEY and uses the api.fabric.so base endpoints.

How this skill works

Requests are sent to https://api.fabric.so with X-Api-Key for auth and JSON payloads. The skill maps user inputs to the correct endpoints (e.g., POST /v2/notepads for notes, /v2/folders, /v2/bookmarks) and enforces required fields like parentId and proper tag shapes. It offers search and folder-browsing patterns and follows rate-limit and retry guidance to avoid duplicate creations.

When to use it

  • Create a new note/notepad with markdown content or structured ydoc content.
  • Create organizational folders or bookmarks into a specific workspace folder.
  • List or browse children of a folder to display or sync workspace contents.
  • Perform fuzzy searches across notes and resources when exact IDs aren’t available.
  • Assign or create tags safely during resource creation or via the tags API.

Best practices

  • Always include parentId; default to @alias::inbox when the destination is unspecified.
  • Create notes via POST /v2/notepads (not /v2/notes) and map title -> name, content -> text.
  • Send tags as an array of objects: each {"name":"tag"} or {"id":"<uuid>"}; never a string or nested array.
  • Use --fail-with-body (or equivalent) in debugging so 4xx response bodies are visible.
  • Back off with jitter on 429 responses and avoid blind retries for create calls to prevent duplicates.

Example use cases

  • Add a meeting note to the inbox: POST /v2/notepads with name, text, parentId:@alias::inbox and tags.
  • Create a project folder under a specific folder UUID using POST /v2/folders with parentId.
  • Save an article as a bookmark via POST /v2/bookmarks including url, name, parentId and tags.
  • List items inside a folder using POST /v2/resources/filter with parentId and pagination.
  • Search for 'design doc' notes using POST /v2/search with a text query and kind filter for notepad.

FAQ

What if I don’t supply a parentId?

The skill defaults to parentId: "@alias::inbox". Many create endpoints require parentId, so always verify intended destination.

How should I format tags to avoid validation errors?

Send tags as an array of objects where each item is either {"name":"tag name"} or {"id":"<uuid>"}; do not use strings or nested arrays.