A project is the central organizing unit in PrintHeritage. Every monitoring campaign — whether it tracks temperature fluctuations in a medieval chapel or vibration readings from a stone bridge — lives inside a project. Projects hold your sensor datasets, define who has access, and serve as the shared workspace your team collaborates within. You can create as many projects as needed, each fully isolated with its own members and data.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/joaomonteir0/printheritage/llms.txt
Use this file to discover all available pages before exploring further.
The Project Model
Each project is stored as a PostgreSQL row with a JSONBdatasets column that holds all sensor readings. The table below describes every field on the Project model.
| Field | Type | Description |
|---|---|---|
id | UUID | Auto-generated unique identifier for the project. |
name | String | Human-readable project name. Required. Used for full-text search. |
description | String | Optional free-text description of the monitoring site or campaign. |
datasets | JSONB | Array of dataset objects (see Dataset structure). Defaults to []. |
owner_id | UUID (FK → users.id) | The user who created the project. |
created_at | DateTime | UTC timestamp set automatically at creation. |
A legacy
sensor_data field (also JSONB) is still present on the Project model and is surfaced in API responses via ProjectResponse.sensor_data. It predates the structured datasets array and should be treated as read-only. All new data ingestion targets the datasets field exclusively.Project Ownership
When you callPOST /projects, the API automatically creates a ProjectPermission record linking you to the new project with:
statusset toACCEPTED(no invitation flow required for the owner)access_levelcopied from your currentglobal_role
owner_id field on the project is also set to your user ID, and the project owner cannot be removed from the member list — attempting to do so returns HTTP 400.
The Datasets Field
Thedatasets column is a JSONB array where each element represents one named sensor feed. The structure of a single dataset object is:
PATCH /projects/{project_id}/data with a payload that matches an existing dataset by id or label, the existing entry is updated in place. If no match is found, a new dataset entry is appended and a fresh UUID is assigned by the server.
Project Lifecycle
Create the project
Call
POST /projects with a name and optional description. The project is created and you are automatically added as its first member.Invite team members
Use
POST /projects/{project_id}/invite to send invitations by email, assigning each invitee an access_level. Invitees see the invitation in their inbox and can accept or reject it.Ingest sensor data
Upload CSV or XLSX files, or configure a polling API endpoint, through the data resource modal. Each source becomes a named dataset within the project’s
datasets array.Favorites
Any team member with anACCEPTED ProjectPermission can mark a project as a favorite by calling PATCH /projects/{project_id}/favorite. This toggles the is_favorite boolean on their ProjectPermission row — it is a per-user preference and does not affect other members’ views.
Favorited projects are sorted to the top of the GET /projects listing, before all non-favorited projects within the same recency order.
Searching Projects
Pass a?q= query parameter to GET /projects to filter results by project name using a case-insensitive ILIKE match: