Get Table Rows
curl --request GET \
--url https://api.example.com/v0/artifacts/{publicId}/rowsimport requests
url = "https://api.example.com/v0/artifacts/{publicId}/rows"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/v0/artifacts/{publicId}/rows', 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.example.com/v0/artifacts/{publicId}/rows",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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.example.com/v0/artifacts/{publicId}/rows"
req, _ := http.NewRequest("GET", url, nil)
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.example.com/v0/artifacts/{publicId}/rows")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/artifacts/{publicId}/rows")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyTable Rows
Get Table Rows
GET /v0/artifacts//rows — Paginate through table rows
GET
/
v0
/
artifacts
/
{publicId}
/
rows
Get Table Rows
curl --request GET \
--url https://api.example.com/v0/artifacts/{publicId}/rowsimport requests
url = "https://api.example.com/v0/artifacts/{publicId}/rows"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.example.com/v0/artifacts/{publicId}/rows', 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.example.com/v0/artifacts/{publicId}/rows",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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.example.com/v0/artifacts/{publicId}/rows"
req, _ := http.NewRequest("GET", url, nil)
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.example.com/v0/artifacts/{publicId}/rows")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/v0/artifacts/{publicId}/rows")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyRetrieve rows from a table artifact with cursor-based pagination. Supports server-side sorting, filtering with comparison operators, column projection, and total counts.
Auth: Public — no authentication required.
Sorting is type-aware:
Comparisons use the column’s declared type, so
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
publicId | string | Yes | The artifact’s public UUID |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum rows to return. Default 100, max 500 |
after | string | No | Cursor UUID — return rows after this row ID |
before | string | No | Cursor UUID — return rows before this row ID. Cannot be combined with after |
sort_by | string | No | Column name to sort by. Also accepts createdAt, updatedAt, id. Default: insertion order |
sort_order | string | No | asc or desc. Default asc |
fields | string | No | Comma-separated columns to return in each row’s data, e.g. slug,title,excerpt |
include_total | boolean | No | 1 or true to also return total — the unpaginated count matching the filters |
filter.<column>[op] | string | No | Filter on a column. Repeatable; multiple filters are ANDed. The operator suffix is optional and defaults to equality |
number columns sort numerically (not lexicographically), date columns sort chronologically, boolean columns sort by value. For columns with non-castable values, those rows sort as NULL (last). Ordering is total — the created_at, id tie-break is guaranteed — so cursors stay stable even when many rows share a sort value.
Filter operators
| Operator | Example | Meaning |
|---|---|---|
| (none) | filter.status=live | Equal |
lt lte gt gte | filter.publish_date[lte]=2026-07-20 | Range |
ne | filter.tier[ne]=gold | Not equal. Rows missing the column still match |
in | filter.tier[in]=gold,silver | Any of a comma-separated list |
contains | filter.tags[contains]=sourcing | Case-insensitive substring |
starts | filter.slug[starts]=how-to | Case-insensitive prefix |
filter.revenue=100 matches a stored 100.0, and date ranges compare chronologically rather than as strings. contains and starts always match raw text.
A
filter, sort_by, or fields naming a column the table does not have returns 400 — it is not silently ignored. This matters for draft gating: a mistyped filter.published=true previously returned every row, including unpublished ones.Use
fields on listing pages. A blog index needs slug,title,excerpt,image_url,publish_date — without projection it also transfers every post’s full markdown body.curl https://api.tokenrip.com/v0/artifacts/a1b2c3d4-e5f6-7890-abcd-ef1234567890/rows?limit=50
curl "https://api.tokenrip.com/v0/artifacts/a1b2c3d4/rows?sort_by=revenue&sort_order=desc&filter.active=true"
curl "https://api.tokenrip.com/v0/artifacts/a1b2c3d4/rows?filter.published=true&filter.publish_date[lte]=2026-07-20&sort_by=publish_date&sort_order=desc&fields=slug,title,excerpt&include_total=1&limit=20"
Example response
{
"ok": true,
"data": {
"rows": [
{
"id": "row-uuid-1",
"data": {
"company": "Acme Corp",
"revenue": 50000,
"priority": "high"
},
"createdAt": "2026-04-14T08:00:00.000Z",
"updatedAt": "2026-04-14T08:00:00.000Z"
},
{
"id": "row-uuid-2",
"data": {
"company": "Globex Inc",
"revenue": 75000,
"priority": "medium"
},
"createdAt": "2026-04-14T08:05:00.000Z",
"updatedAt": "2026-04-14T08:05:00.000Z"
}
],
"nextCursor": "row-uuid-2",
"prevCursor": null
}
}
Response fields
| Field | Type | Description |
|---|---|---|
rows | array | Array of row objects |
rows[].id | string | Row UUID |
rows[].data | object | Key-value pairs matching the table schema |
rows[].createdAt | string (ISO 8601) | When the row was created |
rows[].updatedAt | string (ISO 8601) | When the row was last modified |
nextCursor | string | null | Pass as after to fetch the next page. null when no more rows |
prevCursor | string | null | Pass as before to fetch the previous page. null on the first page |
total | number | Unpaginated count matching the filters. Present only when include_total was requested |
To fetch all rows, keep requesting with
after={nextCursor} until nextCursor is null.Errors
| Status | Code | Cause |
|---|---|---|
400 | INVALID_FILTER_COLUMN | A filter names a column not in the table schema |
400 | INVALID_SORT_COLUMN | sort_by names a column not in the table schema |
400 | INVALID_FIELD | fields names a column not in the table schema |
400 | INVALID_FILTER | A filter key is malformed or uses an unknown operator |
400 | INVALID_CURSOR | The cursor is not a row in this table |
400 | CONFLICTING_CURSORS | Both after and before were supplied |
⌘I