Documentation Index
Fetch the complete documentation index at: https://docs.screenpi.pe/llms.txt
Use this file to discover all available pages before exploring further.
overview
pipes can access the screenpipe API to read screen data, manage meetings, send notifications, and more. by default, pipes have full access to every endpoint — no restrictions.
if you want to limit what a pipe can do, add a permissions block to the YAML frontmatter in pipe.md. this is useful for:
- preventing accidents — a pipe that reads meetings shouldn’t be able to stop one
- least privilege — pipes from the store should only access what they need
- safety — deny destructive endpoints like
/data/delete-range
quick start
---
schedule: every 30m
permissions: reader
---
Summarize my screen activity...
that’s it. this pipe can only read data — it can’t start/stop meetings, delete data, or run raw SQL.
presets
reader — safe read-only defaults
allowed endpoints:
| method | endpoint | description |
|---|
| GET | /search | query screen/audio data |
| GET | /activity-summary | app usage overview |
| GET | /elements | UI element search |
| GET | /frames/* | screenshots (if allow_frames: true) |
| GET | /meetings | list meetings |
| GET | /meetings/* | get meeting details |
| GET | /meetings/status | check if in meeting |
| POST | /notify | send notifications |
| GET | /speakers | list speakers |
| POST | /speakers/update | update speaker names |
| GET | /pipes/info | pipe metadata |
| GET | /health | health check |
| GET | /connections/* | connection credentials |
everything else is denied.
writer — reader + write operations
includes all reader endpoints, plus:
| method | endpoint | description |
|---|
| POST | /meetings/start | start a manual meeting |
| POST | /meetings/stop | stop a manual meeting |
| PUT | /meetings/* | update meeting details |
| POST | /meetings/merge | merge meetings |
| POST | /memories | create memories |
| PUT | /memories/* | update memories |
| DELETE | /memories/* | delete memories |
admin — full access (explicit)
allows everything. functionally the same as no permissions block, but creates a token for logging/auditing.
custom rules
for fine-grained control, use allow and deny lists with Api(METHOD /path) patterns:
permissions:
allow:
- Api(GET /search)
- Api(GET /meetings/*)
- Api(POST /notify)
deny:
- Api(* /data/delete-*)
pattern syntax
| pattern | matches |
|---|
Api(GET /search) | exact: GET to /search |
Api(GET /meetings/*) | glob: GET to /meetings/42, /meetings/status, etc. |
Api(* /meetings/stop) | any method to /meetings/stop |
Api(POST /notify) | exact: POST to /notify |
Api(* /data/*) | any method to any /data/ subpath |
* in the method position matches GET, POST, PUT, DELETE, etc.
* in the path position matches any sequence of characters.
evaluation order
rules are evaluated in this order — first match wins:
- deny — if the request matches any deny rule, it’s blocked (403)
- allow — if the request matches any allow rule, it passes
- default allowlist — if
allow is empty and the pipe uses a preset with defaults (reader/writer), the default list is checked
- reject — if nothing matched, the request is blocked
deny always wins over allow, just like firewall rules.
examples
deny specific endpoints (keep full access otherwise):
permissions:
deny:
- Api(* /meetings/stop)
- Api(* /meetings/start)
- Api(DELETE /meetings/*)
- Api(* /data/delete-*)
allow only what you need (everything else denied):
permissions:
allow:
- Api(GET /search)
- Api(POST /notify)
reader defaults + custom deny:
permissions:
deny:
- Api(GET /frames/*)
this uses the reader defaults but also blocks screenshot access.
data access rules
data filtering uses the same allow/deny lists with App(), Window(), and Content() rules:
---
schedule: every 1h
permissions:
allow:
- Api(GET /search)
- App(Slack, Chrome)
- Window(*meeting*)
- Content(accessibility, audio)
deny:
- App(1Password, Signal)
- Window(*incognito*, *bank*)
- Content(input)
time: "09:00-17:00"
days: "Mon,Tue,Wed,Thu,Fri"
---
| rule type | syntax | description |
|---|
App(name) | App(Slack) or App(Slack, Chrome) | filter by app name (case-insensitive substring match) |
Window(glob) | Window(*meeting*) | filter by window title (glob pattern) |
Content(type) | Content(accessibility, audio) | filter content types: accessibility, ocr, audio, input |
time | "09:00-17:00" | daily time window — supports midnight wrap ("22:00-06:00") |
days | "Mon,Tue,Wed,Thu,Fri" | allowed days of the week |
deny rules always win over allow rules. if no rules of a given type exist, everything is allowed.
how it works
when a pipe has any restrictions (permissions block, data filters, etc.):
- screenpipe generates a unique token (
sp_pipe_*) for the pipe session
- the token is registered with the server middleware
- every API request from the pipe includes the token in
Authorization: Bearer sp_pipe_*
- the middleware checks
is_endpoint_allowed(method, path) before forwarding
- the Pi extension also enforces rules client-side (blocks curl commands before they run)
- when the pipe finishes, the token is cleaned up
pipes without any restrictions run without a token — full access, zero overhead.
common recipes
meeting-safe pipe
your pipe reads meeting data but should never interfere with active meetings:
---
schedule: every 1h
permissions:
deny:
- Api(* /meetings/start)
- Api(* /meetings/stop)
- Api(POST /meetings/merge)
- Api(POST /meetings/bulk-delete)
- Api(DELETE /meetings/*)
---
Summarize my meetings from the last hour...
read-only analytics pipe
---
schedule: daily
permissions:
allow:
- Api(GET /search)
- App(Chrome, Arc, Firefox)
- Content(accessibility)
---
Generate a daily browsing report...
work-hours-only pipe
---
schedule: every 30m
permissions:
time: "09:00-17:00"
days: "Mon,Tue,Wed,Thu,Fri"
---
Track my work activity...
full API access, but time and day restrictions limit when data is visible.
need help? ask in our discord