docs/mintlify/docs-mintlify-mig-tmp/pipe-permissions.mdx
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:
/data/delete-range---
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.
reader — safe read-only defaultspermissions: reader
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 operationspermissions: writer
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)permissions: admin
allows everything. functionally the same as no permissions block, but creates a token for logging/auditing.
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 | 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.
rules are evaluated in this order — first match wins:
allow is empty and the pipe uses a preset with defaults (reader/writer), the default list is checkeddeny always wins over allow, just like firewall rules.
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 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(ocr, 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(ocr, audio) | filter content types: ocr, audio, input, accessibility |
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.
when a pipe has any restrictions (permissions block, data filters, etc.):
sp_pipe_*) for the pipe sessionAuthorization: Bearer sp_pipe_*is_endpoint_allowed(method, path) before forwardingpipes without any restrictions run without a token — full access, zero overhead.
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...
---
schedule: daily
permissions:
allow:
- Api(GET /search)
- App(Chrome, Arc, Firefox)
- Content(ocr)
---
Generate a daily browsing report...
---
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