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-apiReview the files below or copy the command above to add this skill to your agents.
---
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.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.
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.
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.