curl --request POST \
--url https://api.mixpeek.com/v1/alerts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Namespace: <api-key>' \
--data '
{
"description": "Alerts when new videos match known safety incidents",
"enabled": true,
"name": "Safety Incident Detector",
"notification_config": {
"channels": [
{
"channel_id": "wh_safety_team",
"channel_type": "webhook"
}
],
"include_matches": true,
"include_scores": true
},
"retriever_id": "ret_safety_search"
}
'import requests
url = "https://api.mixpeek.com/v1/alerts"
payload = {
"description": "Alerts when new videos match known safety incidents",
"enabled": True,
"name": "Safety Incident Detector",
"notification_config": {
"channels": [
{
"channel_id": "wh_safety_team",
"channel_type": "webhook"
}
],
"include_matches": True,
"include_scores": True
},
"retriever_id": "ret_safety_search"
}
headers = {
"Authorization": "Bearer <token>",
"X-Namespace": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
'X-Namespace': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
description: 'Alerts when new videos match known safety incidents',
enabled: true,
name: 'Safety Incident Detector',
notification_config: {
channels: [{channel_id: 'wh_safety_team', channel_type: 'webhook'}],
include_matches: true,
include_scores: true
},
retriever_id: 'ret_safety_search'
})
};
fetch('https://api.mixpeek.com/v1/alerts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.mixpeek.com/v1/alerts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'description' => 'Alerts when new videos match known safety incidents',
'enabled' => true,
'name' => 'Safety Incident Detector',
'notification_config' => [
'channels' => [
[
'channel_id' => 'wh_safety_team',
'channel_type' => 'webhook'
]
],
'include_matches' => true,
'include_scores' => true
],
'retriever_id' => 'ret_safety_search'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Namespace: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.mixpeek.com/v1/alerts"
payload := strings.NewReader("{\n \"description\": \"Alerts when new videos match known safety incidents\",\n \"enabled\": true,\n \"name\": \"Safety Incident Detector\",\n \"notification_config\": {\n \"channels\": [\n {\n \"channel_id\": \"wh_safety_team\",\n \"channel_type\": \"webhook\"\n }\n ],\n \"include_matches\": true,\n \"include_scores\": true\n },\n \"retriever_id\": \"ret_safety_search\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-Namespace", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.mixpeek.com/v1/alerts")
.header("Authorization", "Bearer <token>")
.header("X-Namespace", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"description\": \"Alerts when new videos match known safety incidents\",\n \"enabled\": true,\n \"name\": \"Safety Incident Detector\",\n \"notification_config\": {\n \"channels\": [\n {\n \"channel_id\": \"wh_safety_team\",\n \"channel_type\": \"webhook\"\n }\n ],\n \"include_matches\": true,\n \"include_scores\": true\n },\n \"retriever_id\": \"ret_safety_search\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixpeek.com/v1/alerts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["X-Namespace"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"description\": \"Alerts when new videos match known safety incidents\",\n \"enabled\": true,\n \"name\": \"Safety Incident Detector\",\n \"notification_config\": {\n \"channels\": [\n {\n \"channel_id\": \"wh_safety_team\",\n \"channel_type\": \"webhook\"\n }\n ],\n \"include_matches\": true,\n \"include_scores\": true\n },\n \"retriever_id\": \"ret_safety_search\"\n}"
response = http.request(request)
puts response.read_body{
"alert_id": "alt_safety_001",
"description": "Alerts when new videos match known safety incidents",
"enabled": true,
"name": "Safety Incident Detector",
"notification_config": {
"channels": [
{
"channel_id": "wh_safety_team",
"channel_type": "webhook"
}
],
"include_matches": true,
"include_scores": true
},
"retriever_id": "ret_safety_search"
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}Create Alert
Create a new alert that monitors document ingestion and sends notifications.
Alerts attach retrievers to collections. When new documents are ingested, the alert runs the retriever and sends notifications if matches are found.
Key Components:
retriever_id: References a retriever that defines query logic (filters, scoring, limits)notification_config: Defines where to send notifications (webhook, Slack, email)
Note: The retriever owns all query semantics. The alert’s job is simply to run the retriever and notify if results exist.
curl --request POST \
--url https://api.mixpeek.com/v1/alerts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Namespace: <api-key>' \
--data '
{
"description": "Alerts when new videos match known safety incidents",
"enabled": true,
"name": "Safety Incident Detector",
"notification_config": {
"channels": [
{
"channel_id": "wh_safety_team",
"channel_type": "webhook"
}
],
"include_matches": true,
"include_scores": true
},
"retriever_id": "ret_safety_search"
}
'import requests
url = "https://api.mixpeek.com/v1/alerts"
payload = {
"description": "Alerts when new videos match known safety incidents",
"enabled": True,
"name": "Safety Incident Detector",
"notification_config": {
"channels": [
{
"channel_id": "wh_safety_team",
"channel_type": "webhook"
}
],
"include_matches": True,
"include_scores": True
},
"retriever_id": "ret_safety_search"
}
headers = {
"Authorization": "Bearer <token>",
"X-Namespace": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
'X-Namespace': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
description: 'Alerts when new videos match known safety incidents',
enabled: true,
name: 'Safety Incident Detector',
notification_config: {
channels: [{channel_id: 'wh_safety_team', channel_type: 'webhook'}],
include_matches: true,
include_scores: true
},
retriever_id: 'ret_safety_search'
})
};
fetch('https://api.mixpeek.com/v1/alerts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.mixpeek.com/v1/alerts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'description' => 'Alerts when new videos match known safety incidents',
'enabled' => true,
'name' => 'Safety Incident Detector',
'notification_config' => [
'channels' => [
[
'channel_id' => 'wh_safety_team',
'channel_type' => 'webhook'
]
],
'include_matches' => true,
'include_scores' => true
],
'retriever_id' => 'ret_safety_search'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Namespace: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.mixpeek.com/v1/alerts"
payload := strings.NewReader("{\n \"description\": \"Alerts when new videos match known safety incidents\",\n \"enabled\": true,\n \"name\": \"Safety Incident Detector\",\n \"notification_config\": {\n \"channels\": [\n {\n \"channel_id\": \"wh_safety_team\",\n \"channel_type\": \"webhook\"\n }\n ],\n \"include_matches\": true,\n \"include_scores\": true\n },\n \"retriever_id\": \"ret_safety_search\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-Namespace", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.mixpeek.com/v1/alerts")
.header("Authorization", "Bearer <token>")
.header("X-Namespace", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"description\": \"Alerts when new videos match known safety incidents\",\n \"enabled\": true,\n \"name\": \"Safety Incident Detector\",\n \"notification_config\": {\n \"channels\": [\n {\n \"channel_id\": \"wh_safety_team\",\n \"channel_type\": \"webhook\"\n }\n ],\n \"include_matches\": true,\n \"include_scores\": true\n },\n \"retriever_id\": \"ret_safety_search\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.mixpeek.com/v1/alerts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["X-Namespace"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"description\": \"Alerts when new videos match known safety incidents\",\n \"enabled\": true,\n \"name\": \"Safety Incident Detector\",\n \"notification_config\": {\n \"channels\": [\n {\n \"channel_id\": \"wh_safety_team\",\n \"channel_type\": \"webhook\"\n }\n ],\n \"include_matches\": true,\n \"include_scores\": true\n },\n \"retriever_id\": \"ret_safety_search\"\n}"
response = http.request(request)
puts response.read_body{
"alert_id": "alt_safety_001",
"description": "Alerts when new videos match known safety incidents",
"enabled": true,
"name": "Safety Incident Detector",
"notification_config": {
"channels": [
{
"channel_id": "wh_safety_team",
"channel_type": "webhook"
}
],
"include_matches": true,
"include_scores": true
},
"retriever_id": "ret_safety_search"
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}{
"error": {
"details": {
"id": "ns_123",
"resource": "namespace"
},
"message": "Namespace not found",
"type": "NotFoundError"
},
"status": 404,
"success": false
}Authorizations
Mixpeek API key, sent as Authorization: Bearer mxp_sk_.... Create one in Studio under Settings → API Keys, or with an admin key via POST /v1/organizations/users/{user_email}/api-keys. A missing header returns 403; an invalid or revoked key returns 401.
Namespace id (ns_...), not the namespace name. This scopes the request rather than authenticating it, and it is required on every operation marked x-mixpeek-namespace-scoped.
Body
Keys this body does not declare are ignored, and the response's warnings name them, until 2026-11-02; from 2026-11-02 they are refused with 422 extra_forbidden naming the accepted keys.
Request model to create an alert.
Creates a new alert that can be attached to collections to monitor for matching content and send notifications when matches are found.
Note: The alert references a retriever that contains all query logic (filters, min_score, limits, collection targeting). The alert's job is simply to run that retriever and notify if results exist.
Human-readable name for the alert
1 - 200"Safety Incident Detector"
"Prohibited Content Alert"
How and where to send notifications when alert triggers
Show child attributes
Show child attributes
{
"channels": [
{
"channel_id": "wh_safety_team",
"channel_type": "webhook"
},
{
"channel_id": "sl_alerts",
"channel_type": "slack"
}
],
"include_matches": true,
"include_scores": true
}
Optional description of what this alert monitors
1000"Alerts when new videos match known safety incidents"
Trigger source: 'retriever' (runs a retriever) or 'system' (built-in metric)
retriever, system ID of the retriever to execute (source=retriever only). The retriever defines filters, scoring, limits.
"ret_safety_search"
source=retriever: fire on 'results' (narrowed by min_count and threshold when set) or 'no_results'
results, no_results With trigger_on='results': the fewest rows that fire the alert (default 1).
x >= 13
With trigger_on='results': fire only when the first result meets this comparison.
Show child attributes
Show child attributes
Retriever inputs the alert runs with. The sweep uses exactly these; at ingest, inputs mapped from the document override them.
{ "window_minutes": 60 }
Suppress further fires for this many seconds after a fire. 0 means none.
0 <= x <= 25920003600
While the condition stays true, notify again at this interval. Unset means once per rise.
60 <= x <= 259200021600
Built-in data-plane condition to watch (source=system only)
Show child attributes
Show child attributes
Org-level namespace scoping (all vs selected)
Show child attributes
Show child attributes
Whether the alert is active and will execute
Additional user-defined metadata for the alert
Response
Successful Response
Response model for a single alert.
Human-readable name for the alert
1 - 200"Safety Incident Detector"
"Prohibited Content Alert"
How and where to send notifications when alert triggers
Show child attributes
Show child attributes
{
"channels": [
{
"channel_id": "wh_safety_team",
"channel_type": "webhook"
},
{
"channel_id": "sl_alerts",
"channel_type": "slack"
}
],
"include_matches": true,
"include_scores": true
}
Unique identifier for the alert
"alt_abc123xyz789"
Namespace this alert belongs to
"ns_production"
Optional description of what this alert monitors
1000"Alerts when new videos match known safety incidents"
Trigger source: 'retriever' (runs a retriever) or 'system' (built-in metric)
retriever, system ID of the retriever to execute (source=retriever only). The retriever defines filters, scoring, limits.
"ret_safety_search"
For source=retriever: fire on 'results' (matches found, narrowed by min_count and threshold when set) or 'no_results' (retriever went dark).
results, no_results With trigger_on='results': fire only when the retriever returns at least this many rows.
x >= 13
With trigger_on='results': fire only when the first result meets this comparison.
Show child attributes
Show child attributes
Retriever inputs this alert runs with. The sweep runs the retriever with exactly these, so a templated window such as {{time_ago(minutes=INPUT.window_minutes)}} keeps its window. At ingest, inputs mapped from the document override keys set here.
{ "window_minutes": 60 }
After the alert fires, further fires within this many seconds are suppressed, on every path. 0 means no cooldown.
0 <= x <= 25920003600
While the condition stays true, notify again at this interval. Unset means notify once per rise. Never fires inside cooldown_seconds.
60 <= x <= 259200021600
When the alert last notified. Set by the platform; read-only.
Built-in data-plane condition to watch (source=system only)
Show child attributes
Show child attributes
Org-level namespace scoping (all vs selected). When omitted, the alert is scoped to its own namespace_id.
Show child attributes
Show child attributes
Whether the alert is active and will execute
Timestamp when the alert was created
Timestamp when the alert was last updated
Additional user-defined metadata for the alert
Was this page helpful?

