Move API reference to DEVELOPERS.md

This commit is contained in:
eduard256
2026-04-05 10:15:47 +00:00
2 changed files with 369 additions and 266 deletions
+368
View File
@@ -0,0 +1,368 @@
# Strix for Developers
Strix is a single static binary with embedded web UI and SQLite camera database. No config files, no external dependencies (except optional `ffmpeg` for H264/H265 screenshot conversion). Designed to run alongside your project the same way [go2rtc](https://github.com/AlexxIT/go2rtc) does.
## Binary
Download from [GitHub Releases](https://github.com/eduard256/Strix/releases). Two platforms: `linux/amd64` and `linux/arm64`.
```bash
chmod +x strix-linux-amd64
./strix-linux-amd64
```
The binary needs `cameras.db` in the working directory. Download it from [StrixCamDB](https://github.com/eduard256/StrixCamDB/releases):
```bash
curl -fsSL https://github.com/eduard256/StrixCamDB/releases/latest/download/cameras.db -o cameras.db
./strix-linux-amd64
```
## Docker
```bash
docker run -d --name strix --network host eduard256/strix:latest
```
Database is already embedded in the image.
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `STRIX_LISTEN` | `:4567` | HTTP listen address |
| `STRIX_DB_PATH` | `cameras.db` | Path to SQLite database |
| `STRIX_LOG_LEVEL` | `info` | `trace`, `debug`, `info`, `warn`, `error` |
| `STRIX_FRIGATE_URL` | auto-discovery | Frigate URL, e.g. `http://localhost:5000` |
| `STRIX_GO2RTC_URL` | auto-discovery | go2rtc URL, e.g. `http://localhost:1984` |
## Integration Flow
Typical automation flow using the API:
```
1. Probe device GET /api/probe?ip=192.168.1.100
2. Search database GET /api/search?q=hikvision
3. Build stream URLs GET /api/streams?ids=b:hikvision&ip=192.168.1.100&user=admin&pass=12345
4. Test streams POST /api/test {sources: {streams: [...]}}
5. Poll results GET /api/test?id=xxx
6. Generate config POST /api/generate {mainStream: "rtsp://...", subStream: "rtsp://..."}
```
All endpoints return JSON. CORS is enabled. No authentication.
---
## API Reference
### System
#### `GET /api`
```json
{"version": "2.0.0", "platform": "amd64"}
```
#### `GET /api/health`
```json
{"version": "2.0.0", "uptime": "1h30m0s"}
```
#### `GET /api/log`
Returns in-memory log in `application/jsonlines` format. Passwords are masked automatically.
#### `DELETE /api/log`
Clears in-memory log. Returns `204`.
---
### Search
#### `GET /api/search?q={query}`
Search camera database by brand, model, or preset name. Empty `q` returns all presets + first brands (limit 50).
```bash
curl "localhost:4567/api/search?q=hikvision"
```
```json
{
"results": [
{"type": "brand", "id": "b:hikvision", "name": "Hikvision"},
{"type": "model", "id": "m:hikvision:DS-2CD2032", "name": "Hikvision: DS-2CD2032"}
]
}
```
Result types:
| Type | ID format | Description |
|------|-----------|-------------|
| `preset` | `p:{preset_id}` | Curated URL pattern sets (e.g. "ONVIF", "Popular RTSP") |
| `brand` | `b:{brand_id}` | All URL patterns for a brand |
| `model` | `m:{brand_id}:{model}` | URL patterns for a specific model |
Multi-word queries match independently: `hikvision DS-2CD` matches brand "Hikvision" AND model containing "DS-2CD".
#### `GET /api/streams`
Build full stream URLs from database patterns with credentials and placeholders substituted.
| Param | Required | Description |
|-------|----------|-------------|
| `ids` | yes | Comma-separated IDs from search results |
| `ip` | yes | Camera IP address |
| `user` | no | Username (URL-encoded automatically) |
| `pass` | no | Password (URL-encoded automatically) |
| `channel` | no | Channel number, default `0` |
| `ports` | no | Comma-separated port filter (only return URLs matching these ports) |
```bash
curl "localhost:4567/api/streams?ids=b:hikvision&ip=192.168.1.100&user=admin&pass=12345"
```
```json
{
"streams": [
"rtsp://admin:12345@192.168.1.100/Streaming/Channels/101",
"rtsp://admin:12345@192.168.1.100/Streaming/Channels/102",
"http://admin:12345@192.168.1.100/ISAPI/Streaming/channels/101/picture"
]
}
```
Maximum 20,000 URLs per request. URLs are deduplicated.
---
### Testing
#### `POST /api/test`
Create a test session. 20 parallel workers connect to each URL, extract codecs, capture screenshots.
```bash
curl -X POST localhost:4567/api/test -d '{
"sources": {
"streams": [
"rtsp://admin:12345@192.168.1.100/Streaming/Channels/101",
"rtsp://admin:12345@192.168.1.100/Streaming/Channels/102"
]
}
}'
```
```json
{"session_id": "a1b2c3d4e5f6g7h8"}
```
#### `GET /api/test`
List all active and completed sessions.
```json
{
"sessions": [
{
"session_id": "a1b2c3d4",
"status": "running",
"total": 604,
"tested": 341,
"alive": 191,
"with_screenshot": 191
}
]
}
```
#### `GET /api/test?id={session_id}`
Get session details with full results. Poll this endpoint to track progress.
```json
{
"session_id": "a1b2c3d4",
"status": "done",
"total": 604,
"tested": 604,
"alive": 375,
"with_screenshot": 375,
"results": [
{
"source": "rtsp://admin:***@192.168.1.100/Streaming/Channels/101",
"codecs": ["H264", "PCMA"],
"width": 1920,
"height": 1080,
"latency_ms": 45,
"screenshot": "api/test/screenshot?id=a1b2c3d4&i=0"
}
]
}
```
- `status`: `running` or `done`
- `codecs`: detected media codecs (H264, H265, PCMA, PCMU, OPUS, etc.)
- `width`, `height`: resolution extracted from JPEG screenshot
- `screenshot`: relative URL to fetch the JPEG image
- Sessions expire 30 minutes after completion
#### `DELETE /api/test?id={session_id}`
Cancel a running session and delete it.
```json
{"status": "deleted"}
```
#### `GET /api/test/screenshot?id={session_id}&i={index}`
Returns raw JPEG image. `Content-Type: image/jpeg`.
---
### Config Generation
#### `POST /api/generate`
Generate Frigate config from stream URLs.
```bash
curl -X POST localhost:4567/api/generate -d '{
"mainStream": "rtsp://admin:12345@192.168.1.100/Streaming/Channels/101",
"subStream": "rtsp://admin:12345@192.168.1.100/Streaming/Channels/102",
"name": "front_door",
"objects": ["person", "car"]
}'
```
```json
{
"config": "mqtt:\n enabled: false\n\nrecord:\n enabled: true\n\ngo2rtc:\n streams:\n ...",
"added": [1, 2, 3, 4, 5]
}
```
- `config`: complete Frigate YAML
- `added`: 1-based line numbers of new lines (for highlighting in UI)
**Merge into existing config** -- pass `existingConfig` field:
```json
{
"mainStream": "rtsp://...",
"existingConfig": "go2rtc:\n streams:\n existing_cam:\n - rtsp://...\n\ncameras:\n existing_cam:\n ..."
}
```
Strix finds the right insertion points in go2rtc streams and cameras sections. Camera and stream names are deduplicated automatically.
<details>
<summary>Full request schema</summary>
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `mainStream` | string | **yes** | Main stream URL |
| `subStream` | string | no | Sub stream URL for detect role |
| `name` | string | no | Camera name (auto-generated from IP if empty) |
| `existingConfig` | string | no | Existing Frigate YAML to merge into |
| `objects` | string[] | no | Objects to track (default: `["person"]`) |
| `go2rtc` | object | no | `{mainStreamName, subStreamName, mainStreamSource, subStreamSource}` |
| `frigate` | object | no | `{mainStreamPath, subStreamPath, mainStreamInputArgs, subStreamInputArgs}` |
| `detect` | object | no | `{enabled, fps, width, height}` |
| `record` | object | no | `{enabled, retain_days, mode, alerts_days, detections_days, pre_capture, post_capture}` |
| `motion` | object | no | `{enabled, threshold, contour_area}` |
| `snapshots` | object | no | `{enabled}` |
| `audio` | object | no | `{enabled, filters[]}` |
| `ffmpeg` | object | no | `{hwaccel, gpu}` |
| `live` | object | no | `{height, quality}` |
| `birdseye` | object | no | `{enabled, mode}` |
| `onvif` | object | no | `{host, port, user, password, autotracking, required_zones[]}` |
| `ptz` | object | no | `{enabled, presets{}}` |
| `notifications` | object | no | `{enabled}` |
| `ui` | object | no | `{order, dashboard}` |
</details>
---
### Probe
#### `GET /api/probe?ip={ip}`
Probe a network device. Runs 6 checks in parallel within 100ms: port scan, ICMP ping, ARP + OUI vendor lookup, reverse DNS, mDNS/HomeKit query, HTTP probe.
```bash
curl "localhost:4567/api/probe?ip=192.168.1.100"
```
```json
{
"ip": "192.168.1.100",
"reachable": true,
"latency_ms": 2.5,
"type": "standard",
"probes": {
"ping": {"latency_ms": 2.5},
"ports": {"open": [80, 554, 8080]},
"dns": {"hostname": "ipcam.local"},
"arp": {"mac": "C0:56:E3:AA:BB:CC", "vendor": "Hikvision"},
"mdns": null,
"http": {"port": 80, "status_code": 401, "server": "Hikvision-Webs"}
}
}
```
- `type`: `standard`, `homekit`, or `unreachable`
- `ports.open`: scanned from 189 ports known in the camera database
- `arp.vendor`: looked up from OUI table in SQLite database
- HomeKit cameras return `mdns` with `name`, `model`, `category` (`camera` or `doorbell`), `device_id`, `paired`, `port`
- ICMP ping requires `CAP_NET_RAW` capability. Falls back to port scan only.
---
### Frigate
#### `GET /api/frigate/config`
Get current Frigate config. Frigate is discovered automatically by probing known addresses (`localhost:5000`, `ccab4aaf-frigate:5000`) or via `STRIX_FRIGATE_URL`.
```json
{"connected": true, "url": "http://localhost:5000", "config": "mqtt:\n enabled: false\n ..."}
```
```json
{"connected": false, "config": ""}
```
#### `POST /api/frigate/config/save?save_option={option}`
Save config to Frigate. Request body is plain text (YAML config).
| Option | Description |
|--------|-------------|
| `saveonly` | Save config without restart (default) |
| `restart` | Save config and restart Frigate |
---
### go2rtc
#### `PUT /api/go2rtc/streams?name={name}&src={source}`
Add a stream to go2rtc. Proxied to local go2rtc instance (discovered automatically or via `STRIX_GO2RTC_URL`).
```bash
curl -X PUT "localhost:4567/api/go2rtc/streams?name=front_door&src=rtsp://admin:12345@192.168.1.100/Streaming/Channels/101"
```
```json
{"success": true}
```
```json
{"success": false, "error": "go2rtc not found"}
```
+1 -266
View File
@@ -118,269 +118,4 @@ Three entity types:
- **Brands** -- all URL patterns for a brand (e.g. "Hikvision", "Dahua")
- **Models** -- URL patterns for a specific model within a brand
## API Reference
All endpoints return JSON. CORS enabled. Base path: `/`.
### System
#### `GET /api`
```json
{"version": "2.0.0", "platform": "amd64"}
```
#### `GET /api/health`
```json
{"version": "2.0.0", "uptime": "1h30m0s"}
```
#### `GET /api/log`
Returns in-memory log in `application/jsonlines` format.
#### `DELETE /api/log`
Clears in-memory log. Returns `204`.
### Search
#### `GET /api/search?q={query}`
Search camera database. Empty `q` returns all presets + first brands.
```bash
curl "localhost:4567/api/search?q=hikvision"
```
```json
{
"results": [
{"type": "brand", "id": "b:hikvision", "name": "Hikvision"},
{"type": "model", "id": "m:hikvision:DS-2CD2032", "name": "Hikvision: DS-2CD2032"}
]
}
```
Types: `preset`, `brand`, `model`. ID prefixes: `p:`, `b:`, `m:brandId:model`.
#### `GET /api/streams?ids={ids}&ip={ip}&user={user}&pass={pass}&channel={n}&ports={ports}`
Build stream URLs from database patterns.
| Param | Required | Description |
|-------|----------|-------------|
| `ids` | yes | Comma-separated IDs from search results |
| `ip` | yes | Camera IP address |
| `user` | no | Username |
| `pass` | no | Password |
| `channel` | no | Channel number (default 0) |
| `ports` | no | Comma-separated port filter |
```bash
curl "localhost:4567/api/streams?ids=b:hikvision&ip=192.168.1.100&user=admin&pass=12345"
```
```json
{
"streams": [
"rtsp://admin:12345@192.168.1.100/Streaming/Channels/101",
"rtsp://admin:12345@192.168.1.100/Streaming/Channels/102",
"http://admin:12345@192.168.1.100/ISAPI/Streaming/channels/101/picture"
]
}
```
### Testing
#### `POST /api/test`
Create a test session. Launches 20 parallel workers.
```bash
curl -X POST localhost:4567/api/test -d '{
"sources": {
"streams": [
"rtsp://admin:12345@192.168.1.100/Streaming/Channels/101",
"rtsp://admin:12345@192.168.1.100/Streaming/Channels/102"
]
}
}'
```
```json
{"session_id": "a1b2c3d4e5f6g7h8"}
```
#### `GET /api/test`
List all sessions.
```json
{
"sessions": [
{"session_id": "a1b2c3d4", "status": "running", "total": 604, "tested": 341, "alive": 191, "with_screenshot": 191}
]
}
```
#### `GET /api/test?id={session_id}`
Get session details with results.
```json
{
"session_id": "a1b2c3d4",
"status": "done",
"total": 604,
"tested": 604,
"alive": 375,
"with_screenshot": 375,
"results": [
{
"source": "rtsp://admin:***@192.168.1.100/Streaming/Channels/101",
"codecs": ["H264", "PCMA"],
"width": 1920,
"height": 1080,
"latency_ms": 45,
"screenshot": "api/test/screenshot?id=a1b2c3d4&i=0"
}
]
}
```
Status: `running` or `done`.
#### `DELETE /api/test?id={session_id}`
Cancel and delete session.
#### `GET /api/test/screenshot?id={session_id}&i={index}`
Returns JPEG image. `Content-Type: image/jpeg`.
### Config Generation
#### `POST /api/generate`
Generate Frigate config.
```bash
curl -X POST localhost:4567/api/generate -d '{
"mainStream": "rtsp://admin:12345@192.168.1.100/Streaming/Channels/101",
"subStream": "rtsp://admin:12345@192.168.1.100/Streaming/Channels/102",
"name": "front_door",
"objects": ["person", "car"]
}'
```
```json
{
"config": "mqtt:\n enabled: false\n\nrecord:\n ...",
"added": [1, 2, 3, 4]
}
```
`added` -- 1-based line numbers of new lines. Useful for highlighting in UI.
To merge into existing config, pass `existingConfig`:
```json
{
"mainStream": "rtsp://...",
"existingConfig": "go2rtc:\n streams:\n ...\ncameras:\n ..."
}
```
Strix finds the right insertion points, deduplicates camera and stream names.
<details>
<summary>Full request schema</summary>
| Field | Type | Description |
|-------|------|-------------|
| `mainStream` | string | **Required.** Main stream URL |
| `subStream` | string | Sub stream URL |
| `name` | string | Camera name |
| `existingConfig` | string | Existing Frigate YAML to merge into |
| `objects` | string[] | Objects to track (default: `["person"]`) |
| `go2rtc` | object | Override stream names/sources |
| `frigate` | object | Override Frigate input paths/args |
| `detect` | object | `{enabled, fps, width, height}` |
| `record` | object | `{enabled, retain_days, mode, alerts_days, detections_days, pre_capture, post_capture}` |
| `motion` | object | `{enabled, threshold, contour_area}` |
| `snapshots` | object | `{enabled}` |
| `audio` | object | `{enabled, filters[]}` |
| `ffmpeg` | object | `{hwaccel, gpu}` |
| `live` | object | `{height, quality}` |
| `birdseye` | object | `{enabled, mode}` |
| `onvif` | object | `{host, port, user, password, autotracking, required_zones[]}` |
| `ptz` | object | `{enabled, presets{}}` |
| `notifications` | object | `{enabled}` |
| `ui` | object | `{order, dashboard}` |
</details>
### Probe
#### `GET /api/probe?ip={ip}`
Probe a network device. Runs all checks in parallel within 100ms.
```bash
curl "localhost:4567/api/probe?ip=192.168.1.100"
```
```json
{
"ip": "192.168.1.100",
"reachable": true,
"latency_ms": 2.5,
"type": "standard",
"probes": {
"ping": {"latency_ms": 2.5},
"ports": {"open": [80, 554, 8080]},
"dns": {"hostname": "ipcam.local"},
"arp": {"mac": "C0:56:E3:AA:BB:CC", "vendor": "Hikvision"},
"mdns": null,
"http": {"port": 80, "status_code": 401, "server": "Hikvision-Webs"}
}
}
```
Type: `standard`, `homekit`, or `unreachable`.
HomeKit cameras return `mdns` with `name`, `model`, `category`, `device_id`, `paired`, `port`.
### Frigate
#### `GET /api/frigate/config`
Get Frigate config. Frigate is discovered automatically via known candidates or `STRIX_FRIGATE_URL`.
```json
{"connected": true, "url": "http://localhost:5000", "config": "mqtt:\n ..."}
```
```json
{"connected": false, "config": ""}
```
#### `POST /api/frigate/config/save?save_option={option}`
Save config to Frigate. Body: plain text (YAML). Options: `saveonly`, `restart`.
### go2rtc
#### `PUT /api/go2rtc/streams?name={name}&src={source}`
Add stream to go2rtc. Proxied to local go2rtc instance.
```bash
curl -X PUT "localhost:4567/api/go2rtc/streams?name=front_door&src=rtsp://admin:12345@192.168.1.100/Streaming/Channels/101"
```
```json
{"success": true}
```
**Developers:** integrate [Strix HTTP API](DEVELOPERS.md) into your smart home platform.