Data model

Pets

An animal companion of the contact. Top-N species enum (dog/cat/bird/...) plus species_other for exotic cases. Optional breed, born_at, colour, notes.

Model name: pet
Endpoints: 5
Max page size: 200

Fields

Per-field validation rules. Values that violate any constraint are rejected with 400 before they reach the database.

FieldTypeConstraints
namestring
max length80
breedstring
max length120
colorstring
max length80
notesstring
max length2000
born_atstring
max length32
speciesenum
enumdog | cat | bird | fish | rabbit | hamster | guinea_pig | reptile | horse | other
parent_idstring
max length64ref →contactowned
species_otherstring
max length80

Mutability

Which fields can you send, and when? Anything without a marker is server-managed - sending it isn't an error, it's silently ignored.

Create-only - read from POST body.Patchable - read from PATCH body.Server-managed - ignored on the body.
FieldCreatePatch
name
breed
color
notes
born_at
species
parent_id
species_other

Fields marked create-only but not patchable are immutable after creation. Server-managed fields include id, timestamps, ownership, and status.

Filtering & sorting

Combinable on list endpoints. Repeating a filter key produces an IN clause; prefixing a sort key with - reverses direction. Example: ?status=open&status=blocked&sort=-created_at.

Filter keys

parent_iddata__parent_id
speciesdata__species
statusstatus
is_archivedis_archived
owned_byowned_by

Sort keys

created_atcreated_at
namedata__name
born_atdata__born_at

Default: name

Endpoints

Each endpoint below lists its HTTP method, path, and the PAT scope it needs. Code samples cover curl, JavaScript, TypeScript, Python, Rust, Java, and WebSocket.

GET/xapi2/data/petpet:list

List objects

Returns a paginated list of objects you can read. Default page size is 20; pass ?limit= to change (capped per type). Use ?after=<id> for keyset pagination on created_at-sorted lists, or ?offset= for offset paging.

curl -H "Authorization: Bearer pat_…" \
"https://friendship-tracker.com/xapi2/data/pet?limit=20"
GET/xapi2/data/pet/{id}pet:read

Read one

Returns the object by id. 404 if it does not exist or you cannot read it (the two cases are intentionally conflated).

curl -H "Authorization: Bearer pat_…" \
https://friendship-tracker.com/xapi2/data/pet/OBJECT_ID
POST/xapi2/data/petpet:create

Create

Creates a new object. Body is a flat JSON dict of field values. Server-side fields (id, timestamps, ownership) are filled automatically; only fields listed below as creatable are read from the body.

curl -H "Authorization: Bearer pat_…" \
-H "Content-Type: application/json" \
-X POST https://friendship-tracker.com/xapi2/data/pet \
-d '{"name": "…"}'
PATCH/xapi2/data/pet/{id}pet:update

Update

Partial update. Only fields included in the body are touched; everything else is preserved. Same allow-list as create, minus the fields that are immutable post-create.

curl -H "Authorization: Bearer pat_…" \
-H "Content-Type: application/json" \
-X PATCH https://friendship-tracker.com/xapi2/data/pet/OBJECT_ID \
-d '{"name": "…"}'
DELETE/xapi2/data/pet/{id}pet:delete

Delete

Removes the object. It vanishes from every default list immediately and stops being returned by read / list.

curl -H "Authorization: Bearer pat_…" \
-X DELETE https://friendship-tracker.com/xapi2/data/pet/OBJECT_ID

Use in CLI

The same endpoints are also exposed via the Friendship Tracker CLI. For scripts, CI, and bulk imports it's usually the faster path.

friendshipcli pet list --limit 5
friendshipcli pet get <id>
friendshipcli pet create --parent-id "Hello"
friendshipcli pet upsert --unique parent_id --csv items.csv
friendshipcli pet schema # fields & limits

Full command reference, profiles, CSV import, auto-retry, NDJSON streaming → /docs/cli