curl --request GET \
--url https://app.tryordinal.com/api/v1/approvals \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.tryordinal.com/api/v1/approvals"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.tryordinal.com/api/v1/approvals', 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://app.tryordinal.com/api/v1/approvals",
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 := "https://app.tryordinal.com/api/v1/approvals"
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("https://app.tryordinal.com/api/v1/approvals")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.tryordinal.com/api/v1/approvals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"approvals": [
{
"id": "550e8400-e29b-41d4-a716-446655440200",
"status": "Requested",
"isBlocking": true,
"message": "Please review the messaging before we publish",
"dueDate": "2026-01-14T17:00:00.000Z",
"approvedAt": null,
"createdAt": "2026-01-05T10:30:00.000Z",
"updatedAt": "2026-01-05T10:30:00.000Z",
"postId": "550e8400-e29b-41d4-a716-446655440000",
"approver": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"email": "jane.smith@example.com",
"firstName": "Jane",
"lastName": "Smith",
"createdAt": "2025-01-01T00:00:00.000Z"
},
"requestedBy": {
"id": "550e8400-e29b-41d4-a716-446655440010",
"email": "john.doe@example.com",
"firstName": "John",
"lastName": "Doe",
"createdAt": "2025-01-01T00:00:00.000Z"
},
"post": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://app.tryordinal.com/your-workspace/posts/550e8400-e29b-41d4-a716-446655440000",
"title": "Launch announcement",
"status": "ForReview",
"channels": [
"LinkedIn",
"Twitter"
],
"publishDate": "2026-01-15",
"publishAt": "2026-01-15T14:00:00.000Z",
"isIdea": false,
"archivedAt": null
}
}
],
"nextCursor": "1736074200000:550e8400-e29b-41d4-a716-446655440200",
"hasMore": true
}{
"code": "BAD_REQUEST",
"message": "Bad Request",
"data": {
"errors": {
"publishAt": [
"Invalid date format"
],
"status": [
"Invalid enum value"
]
}
}
}{
"code": "UNAUTHORIZED",
"message": "Invalid or unauthorized API key"
}{
"code": "FORBIDDEN",
"message": "Engagement profiles cannot be used for analytics"
}List workspace approvals
List all approval requests across the workspace in one paginated stream. Use for incremental sync by external integrations instead of polling each post individually. Supports keyset pagination and filters by status, post, approver, requester, and date range. Approvals on archived posts are included; filter client-side with post.archivedAt. Soft-deleted approvals are omitted from results.
curl --request GET \
--url https://app.tryordinal.com/api/v1/approvals \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.tryordinal.com/api/v1/approvals"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.tryordinal.com/api/v1/approvals', 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://app.tryordinal.com/api/v1/approvals",
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 := "https://app.tryordinal.com/api/v1/approvals"
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("https://app.tryordinal.com/api/v1/approvals")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.tryordinal.com/api/v1/approvals")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"approvals": [
{
"id": "550e8400-e29b-41d4-a716-446655440200",
"status": "Requested",
"isBlocking": true,
"message": "Please review the messaging before we publish",
"dueDate": "2026-01-14T17:00:00.000Z",
"approvedAt": null,
"createdAt": "2026-01-05T10:30:00.000Z",
"updatedAt": "2026-01-05T10:30:00.000Z",
"postId": "550e8400-e29b-41d4-a716-446655440000",
"approver": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"email": "jane.smith@example.com",
"firstName": "Jane",
"lastName": "Smith",
"createdAt": "2025-01-01T00:00:00.000Z"
},
"requestedBy": {
"id": "550e8400-e29b-41d4-a716-446655440010",
"email": "john.doe@example.com",
"firstName": "John",
"lastName": "Doe",
"createdAt": "2025-01-01T00:00:00.000Z"
},
"post": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://app.tryordinal.com/your-workspace/posts/550e8400-e29b-41d4-a716-446655440000",
"title": "Launch announcement",
"status": "ForReview",
"channels": [
"LinkedIn",
"Twitter"
],
"publishDate": "2026-01-15",
"publishAt": "2026-01-15T14:00:00.000Z",
"isIdea": false,
"archivedAt": null
}
}
],
"nextCursor": "1736074200000:550e8400-e29b-41d4-a716-446655440200",
"hasMore": true
}{
"code": "BAD_REQUEST",
"message": "Bad Request",
"data": {
"errors": {
"publishAt": [
"Invalid date format"
],
"status": [
"Invalid enum value"
]
}
}
}{
"code": "UNAUTHORIZED",
"message": "Invalid or unauthorized API key"
}{
"code": "FORBIDDEN",
"message": "Engagement profiles cannot be used for analytics"
}Authorizations
API key authentication. Generate an API key from your workspace settings.
Query Parameters
Maximum number of approvals to return (1-100)
1 <= x <= 100Pagination cursor from the previous response's nextCursor. Format is timestampMs:approvalId. When paginating, pass the same sortBy and sortOrder as the initial request.
Field to sort results by. Use updatedAt for incremental sync so newly-updated approvals stream in order.
createdAt, updatedAt Sort order. Use asc with sortBy=updatedAt for incremental sync.
asc, desc Return approvals updated at or after this time. Pair with sortBy=updatedAt and sortOrder=asc for incremental sync from a saved checkpoint.
Return approvals updated at or before this time.
Return approvals created at or after this time.
Return approvals created at or before this time.
Filter by approval statuses. Repeat the parameter to match any of multiple values.
Requested, Approved Filter by post IDs. Repeat the parameter to match any of multiple values.
Filter by approver user IDs. Repeat the parameter to match any of multiple values.
Filter by IDs of users who requested the approval. Repeat the parameter to match any of multiple values.
Was this page helpful?