curl --request PUT \
--url https://api.duvo.ai/v2/triggers/{agentId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"integration_slug": "<string>",
"trigger_type": "<string>",
"filter_config": {},
"enabled": true
}
'import requests
url = "https://api.duvo.ai/v2/triggers/{agentId}"
payload = {
"integration_slug": "<string>",
"trigger_type": "<string>",
"filter_config": {},
"enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
integration_slug: '<string>',
trigger_type: '<string>',
filter_config: {},
enabled: true
})
};
fetch('https://api.duvo.ai/v2/triggers/{agentId}', 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.duvo.ai/v2/triggers/{agentId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'integration_slug' => '<string>',
'trigger_type' => '<string>',
'filter_config' => [
],
'enabled' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.duvo.ai/v2/triggers/{agentId}"
payload := strings.NewReader("{\n \"integration_slug\": \"<string>\",\n \"trigger_type\": \"<string>\",\n \"filter_config\": {},\n \"enabled\": true\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.put("https://api.duvo.ai/v2/triggers/{agentId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"integration_slug\": \"<string>\",\n \"trigger_type\": \"<string>\",\n \"filter_config\": {},\n \"enabled\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.duvo.ai/v2/triggers/{agentId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"integration_slug\": \"<string>\",\n \"trigger_type\": \"<string>\",\n \"filter_config\": {},\n \"enabled\": true\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"agent_id": "<string>",
"user_id": "<string>",
"integration_slug": "<string>",
"trigger_type": "<string>",
"filter_config": {},
"integration_instance_id": "<string>",
"enabled": true,
"auto_disabled_at": "<string>",
"auto_disabled_reason": "<string>",
"consecutive_missing_connection_failures": 4503599627370495,
"first_missing_connection_failure_at": "<string>",
"last_missing_connection_failure_at": "<string>",
"created_at": "<string>",
"updated_at": "<string>",
"webhook_status": "registered",
"webhook_error": "<string>"
}{
"error": "<string>",
"message": "<string>",
"code": "<string>",
"integration_instance_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>",
"message": "<string>",
"code": "<string>",
"integration_instance_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}{
"error": "<string>",
"message": "<string>"
}Upsert Agent Trigger
Create or update the authenticated user’s trigger for an integration on an agent. The integration must already be connected to the agent (its OAuth connection set up in the Duvo dashboard). Set enabled: false to pause a trigger without deleting it. An agent holds one trigger per integration for a user, so a save with a different trigger_type replaces the existing one — except when that trigger is an @mention trigger, which is managed from the agent’s mention setting and answers 409 (mention_trigger_protected) here. @mention triggers are best managed from that setting throughout: this route leaves an existing one’s filter_config untouched, and refuses to create a teams_mention trigger without a filter_config.tenantId (400, mention_trigger_workspace_required) — a Slack mention trigger has no equivalent field to supply.
curl --request PUT \
--url https://api.duvo.ai/v2/triggers/{agentId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"integration_slug": "<string>",
"trigger_type": "<string>",
"filter_config": {},
"enabled": true
}
'import requests
url = "https://api.duvo.ai/v2/triggers/{agentId}"
payload = {
"integration_slug": "<string>",
"trigger_type": "<string>",
"filter_config": {},
"enabled": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
integration_slug: '<string>',
trigger_type: '<string>',
filter_config: {},
enabled: true
})
};
fetch('https://api.duvo.ai/v2/triggers/{agentId}', 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.duvo.ai/v2/triggers/{agentId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'integration_slug' => '<string>',
'trigger_type' => '<string>',
'filter_config' => [
],
'enabled' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.duvo.ai/v2/triggers/{agentId}"
payload := strings.NewReader("{\n \"integration_slug\": \"<string>\",\n \"trigger_type\": \"<string>\",\n \"filter_config\": {},\n \"enabled\": true\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.put("https://api.duvo.ai/v2/triggers/{agentId}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"integration_slug\": \"<string>\",\n \"trigger_type\": \"<string>\",\n \"filter_config\": {},\n \"enabled\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.duvo.ai/v2/triggers/{agentId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"integration_slug\": \"<string>\",\n \"trigger_type\": \"<string>\",\n \"filter_config\": {},\n \"enabled\": true\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"agent_id": "<string>",
"user_id": "<string>",
"integration_slug": "<string>",
"trigger_type": "<string>",
"filter_config": {},
"integration_instance_id": "<string>",
"enabled": true,
"auto_disabled_at": "<string>",
"auto_disabled_reason": "<string>",
"consecutive_missing_connection_failures": 4503599627370495,
"first_missing_connection_failure_at": "<string>",
"last_missing_connection_failure_at": "<string>",
"created_at": "<string>",
"updated_at": "<string>",
"webhook_status": "registered",
"webhook_error": "<string>"
}{
"error": "<string>",
"message": "<string>",
"code": "<string>",
"integration_instance_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>",
"message": "<string>",
"code": "<string>",
"integration_instance_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}{
"error": "<string>",
"message": "<string>"
}Authorizations
API key authentication. Get your API key from the Duvo dashboard.
Path Parameters
The agent's unique identifier
Body
Integration slug the trigger fires for (e.g. gmail, outlook, linear-native, google-drive).
Trigger type within the integration (e.g. email_received). Discover valid values via the trigger types endpoint. Integrations that enumerate their trigger types (Microsoft Teams, Google Drive, Google Sheets) reject anything else with 400 (trigger_type_unsupported), except a save that pauses a trigger already carrying that type.
Integration-specific filter config (e.g. sender/subject filters). Shape comes from the integration's filter schema. Replaces the trigger's current config, so send the whole object — except on an @mention trigger, whose config is managed from the agent's mention setting and is left as it is.
Show child attributes
Show child attributes
Whether the trigger is active. Defaults to true.
Response
Default Response
Show child attributes
Show child attributes
0 <= x <= 9007199254740991Whether the upstream webhook this trigger needs is registered. Null when the save needed no webhook work: every trigger type but Jira today, and a Jira save with enabled: false. Every enabled Jira save reconciles, so saving again retries a failed registration. registered means Duvo holds a current subscription covering this trigger's projects. connection_required means the Jira Connection this trigger is bound to names no Atlassian site, so there is nothing to register against; reconnect Jira and save again. project_not_found means Jira found no project for one of filter_config.project_keys that the Connection can open, so that key is left out of the webhook; check the keys and save again. failed means Atlassian refused or the call did not complete; see webhook_error and retry. The trigger row is saved in every case; anything but registered means it will not fire yet.
registered, connection_required, project_not_found, failed On failed, a stable reason code for the refusal (for example http_403, rejected_by_jira). conflict_other_binding means the Connection's Jira account already sends events to another Duvo Connection, in this team or another, and Jira allows one per account; connect a different Jira account. issue_created_unconfirmed means Jira has not yet confirmed that the webhook sends new issues, so they may not start Runs; Duvo tries again about every two hours, and saving again tries at once. Null otherwise.
Was this page helpful?