API reference

Location

Where each transaction belongs (a store, a property, a department, a territory: the business chooses what to call them), once it tracks locations (Settings › Advanced). An invoice, bill or expense has one (location_id), and the profit and loss can show a column for each.

The location object

object string
Always "location".
id id
The location's id (a UUID). Use it to fetch it, or to refer to it from other things.
name string
Its name.
full_name string
Its name with what it sits under, like "West / Downtown".
parent_id id or null
The location it sits under, or null at the top.
active boolean
False once it's made inactive in TallyPip (it's kept, with its history, but left out of pickers).
created_at timestamp
When it was added, in UTC.

Example

{
  "object": "location",
  "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
  "name": "Downtown",
  "full_name": "Downtown",
  "parent_id": null,
  "active": true,
  "created_at": "2026-10-06T14:30:00.000Z"
}

List locations

GET /api/v1/locations

Locations (or what the business calls them: stores, properties…), newest first.

Key: any (Read only works).

Query

limit integer
How many, 1 to 100 (default 25).
starting_after id
The last id of the page before, for the next page (when has_more is true).

Newest first. Answers a list: { object: "list", url, has_more, data }.

Request

curl https://tallypip.com/api/v1/locations?limit=3 \
  -H "Authorization: Bearer tpk_your_key"

Answer: 200

{
  "object": "list",
  "url": "/api/v1/locations",
  "has_more": false,
  "data": [
    {
      "object": "location",
      "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
      "name": "Downtown",
      "full_name": "Downtown",
      "parent_id": null,
      "active": true,
      "created_at": "2026-10-06T14:30:00.000Z"
    }
  ]
}

Try it

With your own key (Settings › Connected apps). It stays in this page only, and reading can't change anything.

Create a location

POST /api/v1/locations

Add a location (or a sub-location, with parent_id).

Key: Read and change.

Body (JSON)

Answers 201 with the new location. Refused with 400 and the reason (nothing is saved); send an Idempotency-Key so a retry can't make it twice.

Request

curl https://tallypip.com/api/v1/locations \
  -H "Authorization: Bearer tpk_your_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: <a new id for each change>" \
  -d '{
    "name": "Downtown"
  }'

Answer: 201

{
  "object": "location",
  "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
  "name": "Downtown",
  "full_name": "Downtown",
  "parent_id": null,
  "active": true,
  "created_at": "2026-10-06T14:30:00.000Z"
}

Retrieve a location

GET /api/v1/locations/{id}

One location.

Key: any (Read only works).

Request

curl https://tallypip.com/api/v1/locations/3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191 \
  -H "Authorization: Bearer tpk_your_key"

Answer: 200

{
  "object": "location",
  "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
  "name": "Downtown",
  "full_name": "Downtown",
  "parent_id": null,
  "active": true,
  "created_at": "2026-10-06T14:30:00.000Z"
}

Try it

With your own key (Settings › Connected apps). It stays in this page only, and reading can't change anything.

Update a location

PATCH /api/v1/locations/{id}

Change a location: its name, what it sits under, or make it inactive.

Key: Read and change.

Body (JSON)

Send only what changes. Answers 200 with the location as it is now. Refused with 400 and the reason (nothing is changed).

Request

curl -X PATCH https://tallypip.com/api/v1/locations/3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191 \
  -H "Authorization: Bearer tpk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Downtown (Main St)"
  }'

Answer: 200

{
  "object": "location",
  "id": "3f6c1e2a-8b4d-4c1e-9a7b-2d5e6f708191",
  "name": "Downtown",
  "full_name": "Downtown",
  "parent_id": null,
  "active": true,
  "created_at": "2026-10-06T14:30:00.000Z"
}