curl --request GET \
--url https://api.citadel.example/api/v1/runs \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.citadel.example/api/v1/runs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.citadel.example/api/v1/runs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.citadel.example/api/v1/runs"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"data": [
{
"run_id": "0199a3d0-4b5c-7d6e-8f70-8192a3b4c5d6",
"workflow": "Payout",
"network": "mainnet",
"status": "completed",
"event": "payout",
"idempotency_key": "payout-981",
"failure_reason": null,
"started_at": "2026-10-08T12:00:00Z",
"finished_at": "2026-10-08T12:01:30Z",
"outputs": {
"amount": "50000000",
"to": "TC6A9sQD2tCSaR1wcBXZtrvGkFyoLgRHHF"
}
}
],
"next_cursor": null
}List workflow runs
The workflow runs on one network, newest first. Each row is the body GET /runs/{id}
reads. Use it to reconcile your POST /events calls, or to catch up after missed run.*
webhooks.
Every run a workflow started is listed: by your event, and by Citadel itself (a deposit,
a schedule). A run’s event and idempotency_key are those of the POST /events/{name}
call that started it, and null for a run Citadel started. The steps inside a run (a
loop’s iterations, a workflow it calls) are part of that run, not rows of their own.
network is required. Paged with a cursor — see Lists and pagination. Needs the read
scope. A key limited to vaults is refused with 403 vault_limited.
curl --request GET \
--url https://api.citadel.example/api/v1/runs \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.citadel.example/api/v1/runs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.citadel.example/api/v1/runs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.citadel.example/api/v1/runs"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"data": [
{
"run_id": "0199a3d0-4b5c-7d6e-8f70-8192a3b4c5d6",
"workflow": "Payout",
"network": "mainnet",
"status": "completed",
"event": "payout",
"idempotency_key": "payout-981",
"failure_reason": null,
"started_at": "2026-10-08T12:00:00Z",
"finished_at": "2026-10-08T12:01:30Z",
"outputs": {
"amount": "50000000",
"to": "TC6A9sQD2tCSaR1wcBXZtrvGkFyoLgRHHF"
}
}
],
"next_cursor": null
}Authorizations
An API key minted in the console (ctd_…). Authenticates; never authorizes funds. A key
carries scopes (read, wallets.write, transactions.write, events.write,
webhooks.write, policy.write) and may be limited to vaults, to IP addresses, and in
lifetime — see Authentication.
Query Parameters
The network the data lives on. Required — there is no default network: without it,
422 network_required. A wallet named by its id on another network: 422 network_mismatch.
The network the data lives on. Required wherever it appears in a request — there is no
default network. One your installation does not serve: 422 network_not_served.
mainnet, testnet Only the runs of workflows with this name.
One status, or several separated by commas (completed,failed).
"failed,cancelled"
Only the runs started by POST /events/{name} with this name. Case-insensitive, like the event door.
^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$Only the runs started by POST /events/{name} calls with this idempotency key.
Only rows Citadel recorded at this time or later (created_at). An ISO 8601 date-time.
Only rows Citadel recorded before this time (created_at). An ISO 8601 date-time.
Rows per page, 1 to 100. Out of range, 422.
1 <= x <= 100The next_cursor of the page before; absent for the first page. Send the same filters
with it. A cursor this API did not issue answers 422 invalid_cursor.