curl --request GET \
--url https://api2.endstate.io/v1/units \
--header 'Authorization: Bearer <token>'import requests
url = "https://api2.endstate.io/v1/units"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api2.endstate.io/v1/units', 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://api2.endstate.io/v1/units",
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://api2.endstate.io/v1/units"
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://api2.endstate.io/v1/units")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api2.endstate.io/v1/units")
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{
"units": [
{
"id": "33333333-3333-3333-3333-333333333333",
"external_id": "unit-001",
"name": "Example Unit",
"description": null,
"attributes": {
"custom_attribute": "value"
},
"created_at": "2026-05-16T12:00:00.000Z",
"redirect_url": null,
"collection": {
"id": "8e1a7f50-90ab-4cde-8012-3456789abcde",
"name": "Example Collection",
"external_id": "collection-001",
"contract": {
"address": "0x1111111111111111111111111111111111111111",
"chain_id": 84532,
"status": "active"
},
"token": {
"status": "active",
"serial": 5
}
},
"chips": [
{
"chip_id": "ABCDEF0123",
"is_test": false,
"scan_count": 0,
"created_at": "2026-05-16T12:00:00.000Z"
}
]
}
],
"pagination": {
"limit": 50,
"has_more": false,
"next_cursor": null
}
}{
"error": {
"code": "validation.failed",
"message": "The request failed schema validation. See `error.details` for per-field issues.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/validation-failed"
}
}{
"error": {
"code": "auth.unauthorized",
"message": "Credential is missing or malformed.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/auth-unauthorized"
}
}{
"error": {
"code": "auth.forbidden",
"message": "Credential is valid but does not have access to the requested resource or action.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/auth-forbidden"
}
}{
"error": {
"code": "rate_limit.exceeded",
"message": "Per-key rate limit exceeded.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/rate-limit-exceeded"
}
}{
"error": {
"code": "internal.error",
"message": "An unexpected server error occurred. Retry with exponential backoff and include `request_id` in any support request.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/internal-error"
}
}List units
Returns a cursor-paginated list of units, including each unit’s collection and issuance status. Use external_id to filter to one caller-supplied identifier, collection_id to list the units in one collection, and status and chip to narrow by issuance status and chip pairing. Filters combine, and the cursor pages through the filtered results.
curl --request GET \
--url https://api2.endstate.io/v1/units \
--header 'Authorization: Bearer <token>'import requests
url = "https://api2.endstate.io/v1/units"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api2.endstate.io/v1/units', 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://api2.endstate.io/v1/units",
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://api2.endstate.io/v1/units"
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://api2.endstate.io/v1/units")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api2.endstate.io/v1/units")
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{
"units": [
{
"id": "33333333-3333-3333-3333-333333333333",
"external_id": "unit-001",
"name": "Example Unit",
"description": null,
"attributes": {
"custom_attribute": "value"
},
"created_at": "2026-05-16T12:00:00.000Z",
"redirect_url": null,
"collection": {
"id": "8e1a7f50-90ab-4cde-8012-3456789abcde",
"name": "Example Collection",
"external_id": "collection-001",
"contract": {
"address": "0x1111111111111111111111111111111111111111",
"chain_id": 84532,
"status": "active"
},
"token": {
"status": "active",
"serial": 5
}
},
"chips": [
{
"chip_id": "ABCDEF0123",
"is_test": false,
"scan_count": 0,
"created_at": "2026-05-16T12:00:00.000Z"
}
]
}
],
"pagination": {
"limit": 50,
"has_more": false,
"next_cursor": null
}
}{
"error": {
"code": "validation.failed",
"message": "The request failed schema validation. See `error.details` for per-field issues.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/validation-failed"
}
}{
"error": {
"code": "auth.unauthorized",
"message": "Credential is missing or malformed.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/auth-unauthorized"
}
}{
"error": {
"code": "auth.forbidden",
"message": "Credential is valid but does not have access to the requested resource or action.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/auth-forbidden"
}
}{
"error": {
"code": "rate_limit.exceeded",
"message": "Per-key rate limit exceeded.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/rate-limit-exceeded"
}
}{
"error": {
"code": "internal.error",
"message": "An unexpected server error occurred. Retry with exponential backoff and include `request_id` in any support request.",
"request_id": "req_8e1a7f50-90ab-4cde-f012-3456789abcde",
"doc_url": "https://docs.endstate.io/errors/internal-error"
}
}Authorizations
Use Authorization: Bearer end_sk_* for partner API keys (e.g. end_sk_AbCd_example_api_key).
Query Parameters
Maximum number of records to return. Defaults to 50; maximum 100.
1 <= x <= 100Opaque cursor from the previous page.
1Filter to units with this external identifier.
1Filter to units in this collection.
Filter by issuance status, the unit's collection.token.status. pending also returns units that have no collection.
pending, active Filter to units with at least one paired chip (paired) or with none (unpaired).
paired, unpaired 
