openapi: 3.1.0 info: title: inou Health API version: 1.0.0 description: Access health data — dossiers, entries, labs, journals, trackers, and categories. servers: - url: https://inou.com security: - oauth2: [] components: securitySchemes: oauth2: type: oauth2 flows: authorizationCode: authorizationUrl: https://inou.com/oauth/authorize tokenUrl: https://inou.com/oauth/token scopes: {} schemas: Error: type: object properties: error: type: string Dossier: type: object properties: id: type: string name: type: string date_of_birth: type: string sex: type: string enum: [male, female, other] categories: type: array items: type: string self: type: boolean description: True if this dossier belongs to the authenticated user. DossierDetail: type: object properties: id: type: string name: type: string Entry: type: object properties: id: type: string parent_id: type: string category: type: string type: type: string summary: type: string ordinal: type: integer timestamp: type: integer description: Unix timestamp (seconds). EntryDetail: type: object properties: id: type: string parent_id: type: string category: type: string type: type: string summary: type: string ordinal: type: integer timestamp: type: integer tags: type: string data: type: object description: Parsed JSON data (only when detail=full). children: type: array items: type: object properties: id: type: string type: type: string summary: type: string ordinal: type: integer Journal: type: object properties: id: type: string type: type: string summary: type: string timestamp: type: integer Tracker: type: object properties: id: type: string category: type: string type: type: string question: type: string active: type: boolean dismissed: type: boolean time_of_day: type: string Category: type: object properties: id: type: integer key: type: string description: Machine-readable category name. name: type: string description: Translated display name. types: type: array items: type: string paths: /api/v1/dossiers: get: operationId: listDossiers summary: List accessible dossiers description: Returns all dossiers the authenticated user has access to, including their own. responses: "200": description: Array of dossiers. content: application/json: schema: type: array items: $ref: "#/components/schemas/Dossier" "401": description: Unauthorized. content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/dossiers/{dossier_id}: get: operationId: getDossier summary: Get a single dossier parameters: - name: dossier_id in: path required: true schema: type: string responses: "200": description: Dossier detail. content: application/json: schema: $ref: "#/components/schemas/DossierDetail" "403": description: Access denied. content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Not found. content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/dossiers/{dossier_id}/entries: get: operationId: listEntries summary: List entries for a dossier description: Query entries by category, type, date range, or parent. Returns summaries — use the single-entry endpoint with detail=full for complete data. parameters: - name: dossier_id in: path required: true schema: type: string - name: category in: query description: Filter by category name (e.g. "labs", "imaging", "medication"). schema: type: string - name: type in: query description: Filter by entry type within the category. schema: type: string - name: parent in: query description: Filter by parent entry ID (for navigating hierarchies). schema: type: string - name: search_key in: query description: Filter by search key (e.g. LOINC code for labs). schema: type: string - name: from in: query description: Start timestamp (Unix seconds). schema: type: integer - name: to in: query description: End timestamp (Unix seconds). schema: type: integer - name: limit in: query description: Maximum number of results. schema: type: integer responses: "200": description: Array of entries. content: application/json: schema: type: array items: $ref: "#/components/schemas/Entry" "403": description: Access denied. content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/dossiers/{dossier_id}/entries/{entry_id}: get: operationId: getEntry summary: Get a single entry with optional full detail parameters: - name: dossier_id in: path required: true schema: type: string - name: entry_id in: path required: true schema: type: string - name: detail in: query description: Set to "full" to include the data field and children. schema: type: string enum: [full] responses: "200": description: Entry with optional data and children. content: application/json: schema: $ref: "#/components/schemas/EntryDetail" "404": description: Not found. content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/dossiers/{dossier_id}/journal: get: operationId: listJournals summary: List journal entries parameters: - name: dossier_id in: path required: true schema: type: string - name: days in: query description: Look-back period in days (default 30). schema: type: integer - name: type in: query description: Filter by journal type. schema: type: string responses: "200": description: Journal entries. content: application/json: schema: type: object properties: journals: type: array items: $ref: "#/components/schemas/Journal" "403": description: Access denied. content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/dossiers/{dossier_id}/trackers: get: operationId: listTrackers summary: List tracker prompts parameters: - name: dossier_id in: path required: true schema: type: string - name: active in: query description: Set to "true" to return only active trackers. schema: type: string enum: ["true"] - name: category in: query description: Filter by category name. schema: type: string - name: type in: query description: Filter by tracker type. schema: type: string responses: "200": description: Array of trackers. content: application/json: schema: type: array items: $ref: "#/components/schemas/Tracker" "403": description: Access denied. content: application/json: schema: $ref: "#/components/schemas/Error" /api/v1/categories: get: operationId: listCategories summary: List all data categories description: Returns all 28 categories with translated names and available types. responses: "200": description: Array of categories. content: application/json: schema: type: array items: $ref: "#/components/schemas/Category" /api/v1/categories/{name}/types: get: operationId: listCategoryTypes summary: List types for a category parameters: - name: name in: path required: true description: Category name (e.g. "labs", "imaging"). schema: type: string responses: "200": description: Array of type strings. content: application/json: schema: type: array items: type: string "404": description: Category not found. content: application/json: schema: $ref: "#/components/schemas/Error"