Who can approve a project, and where it sits in the approval workflow
curl --request GET \
--url https://api.zivio.net/api/v4/projects/{id}/approval_status \
--header 'Authorization: Bearer <token>' \
--header 'zivio-tenant-id: <api-key>'import requests
url = "https://api.zivio.net/api/v4/projects/{id}/approval_status"
headers = {
"Authorization": "Bearer <token>",
"zivio-tenant-id": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {Authorization: 'Bearer <token>', 'zivio-tenant-id': '<api-key>'}
};
fetch('https://api.zivio.net/api/v4/projects/{id}/approval_status', 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.zivio.net/api/v4/projects/{id}/approval_status",
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>",
"zivio-tenant-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"
"net/http"
"io"
)
func main() {
url := "https://api.zivio.net/api/v4/projects/{id}/approval_status"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("zivio-tenant-id", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.zivio.net/api/v4/projects/{id}/approval_status")
.header("Authorization", "Bearer <token>")
.header("zivio-tenant-id", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zivio.net/api/v4/projects/{id}/approval_status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
request["zivio-tenant-id"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"project_id": 123,
"project_title": "Website Redesign",
"state": "pending",
"approved": false,
"current_approval_level": 0,
"approval_levels": [
{
"level": 0,
"step_name": "Finance",
"current": true,
"approvers": [
{
"id": 34,
"name": "Jane Smith",
"requested_at": "2026-07-01T12:00:00Z",
"approved_at": null,
"rejected_at": null
}
]
}
]
}{
"error": "invalid_token",
"error_description": "The access token provided is expired, revoked, malformed, or invalid for other reasons"
}{
"error": "insufficient_scope",
"error_description": "The request requires higher privileges than provided by the access token",
"required_scope": "project_approvals:read",
"provided_scopes": [
"welcome:read"
]
}{
"message": "Not found"
}Projects
Who can approve a project, and where it sits in the approval workflow
Returns the project’s approval progress: state, current approval level, and the approvers at each level with when they were requested and whether they have approved or rejected. Readable by anyone who can see the project — use this to answer “who can approve this project?”; use GET /projects/approvals for “what is awaiting MY approval?”.
GET
/
projects
/
{id}
/
approval_status
Who can approve a project, and where it sits in the approval workflow
curl --request GET \
--url https://api.zivio.net/api/v4/projects/{id}/approval_status \
--header 'Authorization: Bearer <token>' \
--header 'zivio-tenant-id: <api-key>'import requests
url = "https://api.zivio.net/api/v4/projects/{id}/approval_status"
headers = {
"Authorization": "Bearer <token>",
"zivio-tenant-id": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {Authorization: 'Bearer <token>', 'zivio-tenant-id': '<api-key>'}
};
fetch('https://api.zivio.net/api/v4/projects/{id}/approval_status', 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.zivio.net/api/v4/projects/{id}/approval_status",
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>",
"zivio-tenant-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"
"net/http"
"io"
)
func main() {
url := "https://api.zivio.net/api/v4/projects/{id}/approval_status"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("zivio-tenant-id", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.zivio.net/api/v4/projects/{id}/approval_status")
.header("Authorization", "Bearer <token>")
.header("zivio-tenant-id", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.zivio.net/api/v4/projects/{id}/approval_status")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
request["zivio-tenant-id"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"project_id": 123,
"project_title": "Website Redesign",
"state": "pending",
"approved": false,
"current_approval_level": 0,
"approval_levels": [
{
"level": 0,
"step_name": "Finance",
"current": true,
"approvers": [
{
"id": 34,
"name": "Jane Smith",
"requested_at": "2026-07-01T12:00:00Z",
"approved_at": null,
"rejected_at": null
}
]
}
]
}{
"error": "invalid_token",
"error_description": "The access token provided is expired, revoked, malformed, or invalid for other reasons"
}{
"error": "insufficient_scope",
"error_description": "The request requires higher privileges than provided by the access token",
"required_scope": "project_approvals:read",
"provided_scopes": [
"welcome:read"
]
}{
"message": "Not found"
}Authorizations
OAuth 2.0 client credentials. The access token from POST /oauth/token is sent as a bearer token. Request only the scopes you need.
Your Zivio organisation identifier. The regional API endpoints serve every Zivio organisation, so each request must identify yours.
Path Parameters
Project ID
Response
Approval progress for the project
The response is of type object.

