curl --request GET \
--url https://api.getoneprofile.ai/tables/{table_id}/status/ \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.getoneprofile.ai/tables/{table_id}/status/"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.getoneprofile.ai/tables/{table_id}/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.getoneprofile.ai/tables/{table_id}/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 => [
"X-API-Key: <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.getoneprofile.ai/tables/{table_id}/status/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<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.getoneprofile.ai/tables/{table_id}/status/")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getoneprofile.ai/tables/{table_id}/status/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"active_runs": [
{
"cells_awaiting": 123,
"cells_done": 123,
"cells_failed": 123,
"cells_no_data": 123,
"cells_skipped": 123,
"cells_total": 123,
"completed_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"row_scope": {
"kind": "all_rows",
"record_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"rows": 123
},
"started_at": "2023-11-07T05:31:56Z",
"status": "pending",
"table_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"trigger": "cell_edited",
"column_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"column_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"credits_charged": 0,
"export_retry_attempt": 0
}
],
"columns": {
"count": 123,
"max_updated_at": "2023-11-07T05:31:56Z"
},
"rows": {
"count": 123
},
"table_updated_at": "2023-11-07T05:31:56Z",
"ui_prefs": {
"count": 123,
"max_updated_at": "2023-11-07T05:31:56Z"
},
"last_finished_run": {
"cells_awaiting": 123,
"cells_done": 123,
"cells_failed": 123,
"cells_no_data": 123,
"cells_skipped": 123,
"cells_total": 123,
"completed_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"row_scope": {
"kind": "all_rows",
"record_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"rows": 123
},
"started_at": "2023-11-07T05:31:56Z",
"status": "pending",
"table_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"trigger": "cell_edited",
"column_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"column_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"credits_charged": 0,
"export_retry_attempt": 0
},
"paused_runs": [
{
"cells_awaiting": 123,
"cells_done": 123,
"cells_failed": 123,
"cells_no_data": 123,
"cells_skipped": 123,
"cells_total": 123,
"completed_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"row_scope": {
"kind": "all_rows",
"record_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"rows": 123
},
"started_at": "2023-11-07T05:31:56Z",
"status": "pending",
"table_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"trigger": "cell_edited",
"column_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"column_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"credits_charged": 0,
"export_retry_attempt": 0
}
]
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>",
"issues": [
{
"input": "<string>",
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}Get table change status
A table’s active runs plus change watermarks for rows, columns, display preferences, and the definition, in one response.
NOT A POLLING TARGET. The grid now receives changes over the change feed (GET /tables/{table_id}/events/) and fetches this once on load for its initial active-run state. It remains useful to any client that wants a cheap point-in-time snapshot without opening a stream.
Preferences are watermarked separately from columns so a hide, pin, resize, or recolour refreshes the column list alone. A client comparing two responses must compare for inequality, never ordering: max timestamps can move backward when the newest row or column is hard-deleted (the counts catch deletes). All timestamps are server-generated; never compare them to the client clock. There is deliberately no table-existence 404: an unknown or foreign table returns empty runs and null/zero watermarks, which leaks nothing (same no-leak contract as the active-runs endpoint). The org-scoped definition read gates the row aggregate, so a foreign table ID never reaches the (potentially large) row index.
curl --request GET \
--url https://api.getoneprofile.ai/tables/{table_id}/status/ \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.getoneprofile.ai/tables/{table_id}/status/"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.getoneprofile.ai/tables/{table_id}/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.getoneprofile.ai/tables/{table_id}/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 => [
"X-API-Key: <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.getoneprofile.ai/tables/{table_id}/status/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<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.getoneprofile.ai/tables/{table_id}/status/")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getoneprofile.ai/tables/{table_id}/status/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"active_runs": [
{
"cells_awaiting": 123,
"cells_done": 123,
"cells_failed": 123,
"cells_no_data": 123,
"cells_skipped": 123,
"cells_total": 123,
"completed_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"row_scope": {
"kind": "all_rows",
"record_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"rows": 123
},
"started_at": "2023-11-07T05:31:56Z",
"status": "pending",
"table_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"trigger": "cell_edited",
"column_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"column_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"credits_charged": 0,
"export_retry_attempt": 0
}
],
"columns": {
"count": 123,
"max_updated_at": "2023-11-07T05:31:56Z"
},
"rows": {
"count": 123
},
"table_updated_at": "2023-11-07T05:31:56Z",
"ui_prefs": {
"count": 123,
"max_updated_at": "2023-11-07T05:31:56Z"
},
"last_finished_run": {
"cells_awaiting": 123,
"cells_done": 123,
"cells_failed": 123,
"cells_no_data": 123,
"cells_skipped": 123,
"cells_total": 123,
"completed_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"row_scope": {
"kind": "all_rows",
"record_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"rows": 123
},
"started_at": "2023-11-07T05:31:56Z",
"status": "pending",
"table_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"trigger": "cell_edited",
"column_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"column_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"credits_charged": 0,
"export_retry_attempt": 0
},
"paused_runs": [
{
"cells_awaiting": 123,
"cells_done": 123,
"cells_failed": 123,
"cells_no_data": 123,
"cells_skipped": 123,
"cells_total": 123,
"completed_at": "2023-11-07T05:31:56Z",
"created_at": "2023-11-07T05:31:56Z",
"error": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"row_scope": {
"kind": "all_rows",
"record_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"rows": 123
},
"started_at": "2023-11-07T05:31:56Z",
"status": "pending",
"table_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"trigger": "cell_edited",
"column_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"column_ids": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"credits_charged": 0,
"export_retry_attempt": 0
}
]
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>",
"issues": [
{
"input": "<string>",
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}Authorizations
Path Parameters
Response
Successful Response
A point-in-time snapshot: active runs plus the four change watermarks.
Every active (pending/running/cancelling) run, newest first.
Show child attributes
Show child attributes
The columns change watermark: column count plus newest column write.
Show child attributes
Show child attributes
The rows watermark: the authoritative row counter.
There is no cell-write watermark here. Freshness is a per-cell fact now, and every cell write is already announced on the change feed as a delta the client applies directly, so a polled max(updated_at) over 100M cell rows would buy an index on the hottest table in the schema to answer a question nothing asks.
Show child attributes
Show child attributes
The definition's updated_at. Moves on rename/description edits AND on row-count maintenance (the counter lives on the definition row), so not a rename-only signal. Null only for an unknown table (the no-leak empty status).
Watermark of the team's display preferences: moves on a recolour, or on an API key's hide, pin or resize. A person's own hide, pin or resize is theirs alone and moves nothing here. Deliberately separate from columns: a display change must refresh the column list alone, never the rows page and stats that a definition change refreshes.
Show child attributes
Show child attributes
The newest run that has finished, whatever its outcome. Present so a client can distinguish a table whose last run FAILED from one that is simply idle. Before this, both answered with no runs at all and the footer reported the table up to date moments after a run failed.
Show child attributes
Show child attributes
Runs most recently stopped because the credit balance ran out mid-run: terminal, but the grid's most important fact until a fresh run supersedes them. Empty when nothing is paused.
Show child attributes
Show child attributes
Was this page helpful?