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 apermissions 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
presets
reader — safe read-only defaults
| 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 |
writer — reader + write operations
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 block, but creates a token for logging/auditing.
custom rules
for fine-grained control, useallow and deny lists with Api(METHOD /path) patterns:
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
allowis empty and the pipe uses a preset with defaults (reader/writer), the default list is checked - reject — if nothing matched, the request is blocked
examples
deny specific endpoints (keep full access otherwise):data access rules
data filtering uses the sameallow/deny lists with App(), Window(), and Content() rules:
| 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 |
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