curl --request GET \
--url http://localhost:3051/api/v1/jobs \
--header 'Authorization: Bearer <token>'import requests
url = "http://localhost:3051/api/v1/jobs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('http://localhost:3051/api/v1/jobs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3051",
CURLOPT_URL => "http://localhost:3051/api/v1/jobs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://localhost:3051/api/v1/jobs"
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))
}HttpResponse<String> response = Unirest.get("http://localhost:3051/api/v1/jobs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:3051/api/v1/jobs")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"jobs": [
{
"is_prohibited": true,
"job_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "pre",
"status": "queued",
"api_key_id": "<string>",
"api_key_name": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
}
],
"total": 123,
"limit": 123,
"offset": 123
}List jobs
Retrieve a paginated, filterable list of moderation jobs for your account.
curl --request GET \
--url http://localhost:3051/api/v1/jobs \
--header 'Authorization: Bearer <token>'import requests
url = "http://localhost:3051/api/v1/jobs"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('http://localhost:3051/api/v1/jobs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_PORT => "3051",
CURLOPT_URL => "http://localhost:3051/api/v1/jobs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "http://localhost:3051/api/v1/jobs"
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))
}HttpResponse<String> response = Unirest.get("http://localhost:3051/api/v1/jobs")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("http://localhost:3051/api/v1/jobs")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"jobs": [
{
"is_prohibited": true,
"job_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "pre",
"status": "queued",
"api_key_id": "<string>",
"api_key_name": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z"
}
],
"total": 123,
"limit": 123,
"offset": 123
}job:read scope. Requests without this scope receive a 403 FORBIDDEN response. See
authentication.created_at descending) and scoped to your account. Use limit
(max 100) and offset to page through results; total in the response is the unpaginated count.
Filters
| Parameter | Description |
|---|---|
type | Job modality: text, image, video, or audio. generate, pre, post and chat are non-moderation or retired values, kept so historical jobs stay filterable. |
decision | Moderation outcome: pass or reject. |
status | Job status. See below. |
search | Prefix-match on job_id. |
api_key_id | The API key a job was submitted with. Pass none for the jobs with no key. See below. |
from | Inclusive lower bound on created_at (ISO 8601). |
to | Exclusive upper bound on created_at (ISO 8601). |
API key attribution
Each job submitted with an API key records that key. Each row in the response carriesapi_key_id
and api_key_name, so you can split traffic by key. For example, you can use one key per
environment, customer, or service without keeping your own mapping.
Both fields are null on a job that no key submitted: one sent from the dashboard, and any job
created before key attribution shipped. Filter to exactly those with api_key_id=none.
api_key_name is resolved when you read the job, not stored on it. A key you renamed shows its
current name on every past job, and a key you deleted resolves to null. api_key_id is stored on
the job and never changes, so it stays correct in both cases. Use the id as the stable identifier.
Status filter
status accepts a comma-separated list of one or more job statuses:
| Status | Meaning |
|---|---|
queued | Accepted and being moderated. |
processing | Reserved. No moderation job reports it today. |
completed | Finished. See is_prohibited for the outcome. |
failed | Terminated with an error before a decision. |
queued for its whole run and then flips straight to completed or
failed; it never reports processing. queued and processing are both in-flight states and
completed and failed are terminal, so request both in-flight values to stay correct if that
changes:
GET /api/v1/jobs?status=queued,processing
400 INVALID_REQUEST.
Polling for completion
Webhooks are the primary, low-latency way to learn that a job finished. Register one when you submit, or via register webhook. Webhook delivery is best-effort, so use this endpoint as a cheap reconciliation safety net rather than your primary signal:- Poll
GET /api/v1/jobs?status=queued,processingon an interval. One request covers every outstanding job, regardless of how many you have in flight. That is far cheaper than polling each job individually with get job status. - A job that drops out of the in-flight list has reached a terminal state. Fetch the terminal set
(
status=completed,failed, optionally narrowed withfrom) to pick up any outcome whose webhook was missed. - Keep the interval modest. Every request counts toward your rate limit. Webhooks carry the fast path; reconciliation only needs to catch stragglers.
Example
curl -G "https://api.omnifence.ai/api/v1/jobs" \
-H "Authorization: Bearer $API_KEY" \
--data-urlencode "status=queued,processing" \
--data-urlencode "limit=100"
Authorizations
API key from the Omnifence dashboard
Query Parameters
1 <= x <= 100x >= 0Filter by job modality. text, image, video, audio are the active moderation modalities. generate and pre/post/chat are non-moderation or retired types, kept so historical jobs stay filterable.
pre, post, chat, text, image, video, audio, generate Filter by moderation decision.
pass, reject Filter by job status. Comma-separated list of: queued, processing, completed, failed. Example: status=queued,processing returns all in-flight jobs, which is useful for low-cost reconciliation polling alongside webhooks.
Prefix-match filter on job_id.
64Filter to jobs submitted with a single API key. Pass the key id, or the literal none to return only the jobs with no key attribution (dashboard submissions and jobs created before key attribution shipped).
128Inclusive lower bound on job created_at (ISO 8601).
Exclusive upper bound on job created_at (ISO 8601).