curl --request POST \
--url https://api.example.com/api/v1/runs/{id}/deny \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reason": "Not approved for execution"
}
'import requests
url = "https://api.example.com/api/v1/runs/{id}/deny"
payload = { "reason": "Not approved for execution" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({reason: 'Not approved for execution'})
};
fetch('https://api.example.com/api/v1/runs/{id}/deny', 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.example.com/api/v1/runs/{id}/deny",
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([
'reason' => 'Not approved for execution'
]),
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.example.com/api/v1/runs/{id}/deny"
payload := strings.NewReader("{\n \"reason\": \"Not approved for execution\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.example.com/api/v1/runs/{id}/deny")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"Not approved for execution\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/runs/{id}/deny")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reason\": \"Not approved for execution\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"children_count": 1,
"title": "<string>",
"goal": "<string>",
"workflow": {
"slug": "<string>",
"name": "<string>",
"graph_name": "<string>",
"node_count": 123,
"edge_count": 123
},
"automation": {
"id": "<string>",
"name": "<string>",
"trigger_id": "<string>"
},
"repository": {
"name": "fabro-sh/fabro",
"origin_url": "https://github.com/fabro-sh/fabro.git",
"provider": "github"
},
"created_by": {
"kind": "user",
"identity": {
"issuer": "<string>",
"subject": "<string>"
},
"login": "<string>",
"auth_method": "github",
"avatar_url": "<string>"
},
"origin": {
"kind": "api"
},
"labels": {},
"lifecycle": {
"status": {
"kind": "submitted"
},
"approval": {
"state": "pending",
"requested_at": "2023-11-07T05:31:56Z",
"decided_at": "2023-11-07T05:31:56Z",
"denial_reason": "<string>"
},
"pending_control": "cancel",
"queue_position": 123,
"error": {
"message": "Stage 'apply-changes' exceeded maximum retries."
},
"archived": true,
"archived_at": "2023-11-07T05:31:56Z"
},
"sandbox": {
"kind": "planned",
"plan": {
"provider": "local",
"image": "<string>",
"snapshot": "<string>"
},
"instance": {
"provider": "local",
"runtime": {
"id": "<string>",
"working_directory": "<string>",
"repo_cloned": true,
"clone_origin_url": "<string>",
"clone_branch": "<string>",
"workspace_root": "<string>",
"repos_root": "<string>",
"primary_repo_path": "<string>",
"primary_repo_link": "<string>"
},
"image": "<string>",
"snapshot": "<string>"
},
"failure": {
"provider": "<string>",
"error": "<string>",
"causes": [
"<string>"
],
"duration_ms": 1
}
},
"models": [
{
"provider": "<string>",
"name": "<string>"
}
],
"source_directory": "<string>",
"timestamps": {
"created_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"last_event_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
},
"timing": {
"wall_time_ms": 420000,
"inference_time_ms": 120000,
"tool_time_ms": 60000,
"active_time_ms": 180000
},
"billing": {
"total_usd_micros": 123
},
"size": "XS",
"ask_fabro": {
"available": true,
"unavailable_reason": "no_sandbox",
"default_model": "<string>"
},
"diff": {
"files_changed": 42,
"additions": 567,
"deletions": 234
},
"pull_request": {
"owner": "fabro-sh",
"repo": "fabro",
"number": 123,
"html_url": "https://github.com/fabro-sh/fabro/pull/123"
},
"current_question": {
"text": "Accept or push for another round?"
},
"superseded_by": "<string>",
"retried_from": "<string>",
"links": {
"web": "<string>"
},
"parent_id": "<string>"
}{
"errors": [
{
"status": "404",
"title": "Not Found",
"detail": "Run not found.",
"code": "access_token_expired",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
],
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"leftover_env_keys": [
"<string>"
],
"removed_env_keys": [
"<string>"
]
}{
"errors": [
{
"status": "404",
"title": "Not Found",
"detail": "Run not found.",
"code": "access_token_expired",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
],
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"leftover_env_keys": [
"<string>"
],
"removed_env_keys": [
"<string>"
]
}Deny Run
Denies a pending run that requires pre-execution approval and fails it with approval_denied.
curl --request POST \
--url https://api.example.com/api/v1/runs/{id}/deny \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"reason": "Not approved for execution"
}
'import requests
url = "https://api.example.com/api/v1/runs/{id}/deny"
payload = { "reason": "Not approved for execution" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({reason: 'Not approved for execution'})
};
fetch('https://api.example.com/api/v1/runs/{id}/deny', 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.example.com/api/v1/runs/{id}/deny",
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([
'reason' => 'Not approved for execution'
]),
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.example.com/api/v1/runs/{id}/deny"
payload := strings.NewReader("{\n \"reason\": \"Not approved for execution\"\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.example.com/api/v1/runs/{id}/deny")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reason\": \"Not approved for execution\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/runs/{id}/deny")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reason\": \"Not approved for execution\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"children_count": 1,
"title": "<string>",
"goal": "<string>",
"workflow": {
"slug": "<string>",
"name": "<string>",
"graph_name": "<string>",
"node_count": 123,
"edge_count": 123
},
"automation": {
"id": "<string>",
"name": "<string>",
"trigger_id": "<string>"
},
"repository": {
"name": "fabro-sh/fabro",
"origin_url": "https://github.com/fabro-sh/fabro.git",
"provider": "github"
},
"created_by": {
"kind": "user",
"identity": {
"issuer": "<string>",
"subject": "<string>"
},
"login": "<string>",
"auth_method": "github",
"avatar_url": "<string>"
},
"origin": {
"kind": "api"
},
"labels": {},
"lifecycle": {
"status": {
"kind": "submitted"
},
"approval": {
"state": "pending",
"requested_at": "2023-11-07T05:31:56Z",
"decided_at": "2023-11-07T05:31:56Z",
"denial_reason": "<string>"
},
"pending_control": "cancel",
"queue_position": 123,
"error": {
"message": "Stage 'apply-changes' exceeded maximum retries."
},
"archived": true,
"archived_at": "2023-11-07T05:31:56Z"
},
"sandbox": {
"kind": "planned",
"plan": {
"provider": "local",
"image": "<string>",
"snapshot": "<string>"
},
"instance": {
"provider": "local",
"runtime": {
"id": "<string>",
"working_directory": "<string>",
"repo_cloned": true,
"clone_origin_url": "<string>",
"clone_branch": "<string>",
"workspace_root": "<string>",
"repos_root": "<string>",
"primary_repo_path": "<string>",
"primary_repo_link": "<string>"
},
"image": "<string>",
"snapshot": "<string>"
},
"failure": {
"provider": "<string>",
"error": "<string>",
"causes": [
"<string>"
],
"duration_ms": 1
}
},
"models": [
{
"provider": "<string>",
"name": "<string>"
}
],
"source_directory": "<string>",
"timestamps": {
"created_at": "2023-11-07T05:31:56Z",
"started_at": "2023-11-07T05:31:56Z",
"last_event_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
},
"timing": {
"wall_time_ms": 420000,
"inference_time_ms": 120000,
"tool_time_ms": 60000,
"active_time_ms": 180000
},
"billing": {
"total_usd_micros": 123
},
"size": "XS",
"ask_fabro": {
"available": true,
"unavailable_reason": "no_sandbox",
"default_model": "<string>"
},
"diff": {
"files_changed": 42,
"additions": 567,
"deletions": 234
},
"pull_request": {
"owner": "fabro-sh",
"repo": "fabro",
"number": 123,
"html_url": "https://github.com/fabro-sh/fabro/pull/123"
},
"current_question": {
"text": "Accept or push for another round?"
},
"superseded_by": "<string>",
"retried_from": "<string>",
"links": {
"web": "<string>"
},
"parent_id": "<string>"
}{
"errors": [
{
"status": "404",
"title": "Not Found",
"detail": "Run not found.",
"code": "access_token_expired",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
],
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"leftover_env_keys": [
"<string>"
],
"removed_env_keys": [
"<string>"
]
}{
"errors": [
{
"status": "404",
"title": "Not Found",
"detail": "Run not found.",
"code": "access_token_expired",
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
],
"request_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"leftover_env_keys": [
"<string>"
],
"removed_env_keys": [
"<string>"
]
}Authorizations
Raw dev token passed as Authorization: Bearer fabro_dev_... when server.auth.methods includes dev-token.
Path Parameters
Unique run identifier (ULID).
Body
Request body for denying a pending run approval request.
Optional human-readable reason for denying execution. Empty or whitespace-only values are stored as absent.
"Not approved for execution"
Response
Run denied
Canonical public run shape.
Number of runs currently linked to this run as their orchestration parent.
x >= 0Show child attributes
Show child attributes
Show child attributes
Show child attributes
Durable repository metadata for a run.
Show child attributes
Show child attributes
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
- Option 6
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Sandbox lifecycle record for a run. A run can have a requested sandbox plan before it has an initialized sandbox instance.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Run-level timing rollup. Wall time is the run's clock duration; active timing sums work across stage visits.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Run size bucket derived from current best-effort billed usage.
XS, S, M, L, XL Readiness and defaults for starting an Ask Fabro session on this run.
Show child attributes
Show child attributes
Cheap aggregate file and line counts for a run diff.
Show child attributes
Show child attributes
Minimal GitHub pull request link associated with a run.
Show child attributes
Show child attributes
A pending human-in-the-loop question summary.
Show child attributes
Show child attributes
Run ID that superseded this run via rewind, if any.
Source run ID when this run was created by manual retry.
Show child attributes
Show child attributes
Current orchestration parent run ID, if linked.