curl --request POST \
--url https://api.outerlayer.ai/v1/apps/{appId}/custom-automations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Outerlayer-App-Id: <api-key>' \
--data '
{
"name": "<string>",
"trigger": {
"labels": [
"<string>"
],
"scope": "<string>",
"type": "issue_opened"
},
"dailyLimit": 5,
"instructions": null,
"signingSecret": "<string>",
"status": "on"
}
'import requests
url = "https://api.outerlayer.ai/v1/apps/{appId}/custom-automations"
payload = {
"name": "<string>",
"trigger": {
"labels": ["<string>"],
"scope": "<string>",
"type": "issue_opened"
},
"dailyLimit": 5,
"instructions": None,
"signingSecret": "<string>",
"status": "on"
}
headers = {
"X-Outerlayer-App-Id": "<api-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Outerlayer-App-Id': '<api-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: '<string>',
trigger: {labels: ['<string>'], scope: '<string>', type: 'issue_opened'},
dailyLimit: 5,
instructions: null,
signingSecret: '<string>',
status: 'on'
})
};
fetch('https://api.outerlayer.ai/v1/apps/{appId}/custom-automations', 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.outerlayer.ai/v1/apps/{appId}/custom-automations",
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([
'name' => '<string>',
'trigger' => [
'labels' => [
'<string>'
],
'scope' => '<string>',
'type' => 'issue_opened'
],
'dailyLimit' => 5,
'instructions' => null,
'signingSecret' => '<string>',
'status' => 'on'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Outerlayer-App-Id: <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.outerlayer.ai/v1/apps/{appId}/custom-automations"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"trigger\": {\n \"labels\": [\n \"<string>\"\n ],\n \"scope\": \"<string>\",\n \"type\": \"issue_opened\"\n },\n \"dailyLimit\": 5,\n \"instructions\": null,\n \"signingSecret\": \"<string>\",\n \"status\": \"on\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Outerlayer-App-Id", "<api-key>")
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.post("https://api.outerlayer.ai/v1/apps/{appId}/custom-automations")
.header("X-Outerlayer-App-Id", "<api-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"trigger\": {\n \"labels\": [\n \"<string>\"\n ],\n \"scope\": \"<string>\",\n \"type\": \"issue_opened\"\n },\n \"dailyLimit\": 5,\n \"instructions\": null,\n \"signingSecret\": \"<string>\",\n \"status\": \"on\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.outerlayer.ai/v1/apps/{appId}/custom-automations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Outerlayer-App-Id"] = '<api-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"trigger\": {\n \"labels\": [\n \"<string>\"\n ],\n \"scope\": \"<string>\",\n \"type\": \"issue_opened\"\n },\n \"dailyLimit\": 5,\n \"instructions\": null,\n \"signingSecret\": \"<string>\",\n \"status\": \"on\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"createdAt": "<string>",
"creator": {
"membershipId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"dailyLimit": 123,
"failureStreak": 1,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"instructions": "<string>",
"name": "<string>",
"noticesTo": "creator",
"off": {
"at": "<string>",
"reason": "failed_runs"
},
"status": "on",
"trigger": {
"labels": [
"<string>"
],
"scope": "<string>",
"tracker": "github",
"type": "issue_opened"
},
"updatedAt": "<string>",
"hookId": "<string>",
"nextDueAt": "<string>",
"signingSecret": {
"setAt": "<string>",
"value": "<string>"
},
"whose": "members"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}Add a custom automation to the factory
Adds an automation that acts when an issue is opened, or when an issue gets a label, in a repository, Linear team or Jira project of the factory. A stored automation is on unless status says off. An issue from a member builds at once. An issue from anyone else waits on the Work page for a member to choose Build. A webhook trigger gives the automation a URL, hookId in the answer. Each signed request files one issue that waits on the Work page. A Sentry or PagerDuty automation needs signingSecret. For an Any JSON automation, OuterLayer makes the secret and the answer to this request holds it in signingSecret.value. No later answer holds it. Answers 400 unknown_source when trigger.scope is not a source of the factory. GET /v1/apps/{appId}/automation-sources lists the sources.
curl --request POST \
--url https://api.outerlayer.ai/v1/apps/{appId}/custom-automations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Outerlayer-App-Id: <api-key>' \
--data '
{
"name": "<string>",
"trigger": {
"labels": [
"<string>"
],
"scope": "<string>",
"type": "issue_opened"
},
"dailyLimit": 5,
"instructions": null,
"signingSecret": "<string>",
"status": "on"
}
'import requests
url = "https://api.outerlayer.ai/v1/apps/{appId}/custom-automations"
payload = {
"name": "<string>",
"trigger": {
"labels": ["<string>"],
"scope": "<string>",
"type": "issue_opened"
},
"dailyLimit": 5,
"instructions": None,
"signingSecret": "<string>",
"status": "on"
}
headers = {
"X-Outerlayer-App-Id": "<api-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Outerlayer-App-Id': '<api-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: '<string>',
trigger: {labels: ['<string>'], scope: '<string>', type: 'issue_opened'},
dailyLimit: 5,
instructions: null,
signingSecret: '<string>',
status: 'on'
})
};
fetch('https://api.outerlayer.ai/v1/apps/{appId}/custom-automations', 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.outerlayer.ai/v1/apps/{appId}/custom-automations",
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([
'name' => '<string>',
'trigger' => [
'labels' => [
'<string>'
],
'scope' => '<string>',
'type' => 'issue_opened'
],
'dailyLimit' => 5,
'instructions' => null,
'signingSecret' => '<string>',
'status' => 'on'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-Outerlayer-App-Id: <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.outerlayer.ai/v1/apps/{appId}/custom-automations"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"trigger\": {\n \"labels\": [\n \"<string>\"\n ],\n \"scope\": \"<string>\",\n \"type\": \"issue_opened\"\n },\n \"dailyLimit\": 5,\n \"instructions\": null,\n \"signingSecret\": \"<string>\",\n \"status\": \"on\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Outerlayer-App-Id", "<api-key>")
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.post("https://api.outerlayer.ai/v1/apps/{appId}/custom-automations")
.header("X-Outerlayer-App-Id", "<api-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"trigger\": {\n \"labels\": [\n \"<string>\"\n ],\n \"scope\": \"<string>\",\n \"type\": \"issue_opened\"\n },\n \"dailyLimit\": 5,\n \"instructions\": null,\n \"signingSecret\": \"<string>\",\n \"status\": \"on\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.outerlayer.ai/v1/apps/{appId}/custom-automations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Outerlayer-App-Id"] = '<api-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"trigger\": {\n \"labels\": [\n \"<string>\"\n ],\n \"scope\": \"<string>\",\n \"type\": \"issue_opened\"\n },\n \"dailyLimit\": 5,\n \"instructions\": null,\n \"signingSecret\": \"<string>\",\n \"status\": \"on\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"createdAt": "<string>",
"creator": {
"membershipId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"dailyLimit": 123,
"failureStreak": 1,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"instructions": "<string>",
"name": "<string>",
"noticesTo": "creator",
"off": {
"at": "<string>",
"reason": "failed_runs"
},
"status": "on",
"trigger": {
"labels": [
"<string>"
],
"scope": "<string>",
"tracker": "github",
"type": "issue_opened"
},
"updatedAt": "<string>",
"hookId": "<string>",
"nextDueAt": "<string>",
"signingSecret": {
"setAt": "<string>",
"value": "<string>"
},
"whose": "members"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>"
}
}Authorizations
Body
The secret that Sentry or PagerDuty signs its requests with. Required to add a Sentry or PagerDuty automation. Send it again to replace the stored secret. OuterLayer never returns it. An Any JSON automation takes none, because OuterLayer makes its secret.
1 - 500