{"openapi":"3.0.3","info":{"title":"YachtInspect Export API","version":"1.0.0","description":"Read-only export of findings and their actions for a single YachtInspect project.\n\n**Scope.** An API key is minted against exactly one company AND one project (vessel). Neither is a request parameter — there is no way to reach another project with a given key.\n\n**Actions.** A finding's actions are delivered in two places: its `checklist` array, embedded in the finding (checklist items have no stable id and cannot be addressed individually), and its comment thread at `/v1/findings/{id}/comments`, which includes system-generated status-change entries flagged with `system_triggered`.\n\n**Hidden findings** are excluded from every endpoint.\n\n**Pagination.** Cursor-based. Follow `next_page_token` until it is null. A page may contain fewer rows than `limit` and still have a next page — page until the token is null, not until a short page arrives.\n\n**Privacy.** Creator and editor display names are returned; email addresses and avatar URLs are never returned."},"servers":[{"url":"https://yachtinspect.quickinspect.me/api"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Project","description":"The vessel/project the key is pinned to."},{"name":"Findings","description":"Findings and their checklist actions."},{"name":"Comments","description":"Per-finding comment thread and status history."},{"name":"Attachments","description":"Photos and documents, with signed URLs."}],"paths":{"/v1":{"get":{"tags":["Project"],"summary":"Service discovery","description":"Public. No API key required.","security":[],"responses":{"200":{"description":"Service metadata"}}}},"/v1/openapi.json":{"get":{"tags":["Project"],"summary":"This document","description":"Public. No API key required.","security":[],"responses":{"200":{"description":"OpenAPI document"}}}},"/v1/project":{"get":{"tags":["Project"],"summary":"The project this key is scoped to","description":"Vessel identity, classification, propulsion, survey, claim and client detail. Fields are allow-listed; budget, internal hours and drawing files are deliberately not exposed.","responses":{"200":{"description":"The project","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Project"}}}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/v1/findings":{"get":{"tags":["Findings"],"summary":"List findings","description":"Ordered ascending by `date_created`, or by `last_edited_date` when `updated_since` is given. Those two modes are mutually exclusive: `updated_since` cannot be combined with `from`/`to`.\n\nUse `updated_since` for incremental sync — the app writes `last_edited_date` on every save, including creation.","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/PageToken"},{"name":"from","in":"query","description":"Inclusive lower bound on `date_created` (ISO-8601).","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","description":"Exclusive upper bound on `date_created` (ISO-8601).","schema":{"type":"string","format":"date-time"}},{"name":"updated_since","in":"query","description":"Return findings whose `last_edited_date` is at or after this instant, ordered by it. Cannot be combined with from/to.","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","schema":{"type":"string","enum":["Open","To be reviewed","Closed","Accepted as is","Cancelled","Shipyard confirmed rectification"]}},{"name":"system","in":"query","description":"Exact match on the finding's system.","schema":{"type":"string","maxLength":200}},{"name":"priority","in":"query","description":"Exact match on the finding's priority.","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"A page of findings","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Finding"}},"next_page_token":{"type":"string","nullable":true}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/v1/findings/{id}/comments":{"get":{"tags":["Comments"],"summary":"List a finding's comments","description":"Ascending by `created_at`. Includes system-generated entries (status changes), flagged with `system_triggered`. A finding outside this key's project returns 404.","parameters":[{"$ref":"#/components/parameters/FindingId"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/PageToken"},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page of comments","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}},"next_page_token":{"type":"string","nullable":true}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}},"/v1/findings/{id}/attachments":{"get":{"tags":["Attachments"],"summary":"List a finding's attachments","description":"Photos and documents with short-lived (15 minute) signed download URLs: the finding's location image, its files, and the photos, videos, voice notes and documents attached to its comments (source \"comment\", matched by comment_id). Not cursor-paginated: `limit` caps the rows across all sources and `truncated` reports whether the cap was hit. A row whose URL could not be signed returns `download_url: null` with a `download_error` rather than failing the request.","parameters":[{"$ref":"#/components/parameters/FindingId"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"The finding's attachments","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}},"finding_id":{"type":"string"},"truncated":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An API key minted under Lists → API Access, sent as `Authorization: Bearer yi_live_...`. The key is shown once at creation and only its hash is stored."}},"parameters":{"Limit":{"name":"limit","in":"query","description":"Rows per page, 1–500. Default 100.","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},"PageToken":{"name":"page_token","in":"query","description":"Opaque cursor from the previous response's next_page_token.","schema":{"type":"string"}},"FindingId":{"name":"id","in":"path","required":true,"description":"Finding document id.","schema":{"type":"string"}}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["invalid_request","unauthorized","forbidden","not_found","rate_limited","internal"]},"message":{"type":"string"}}}}},"ChecklistItem":{"type":"object","description":"An action item on a finding. Has NO stable id: `index` is the position in the finding's checklist array and is stable only while the list is not reordered. Correlate on it, do not key on it.","properties":{"index":{"type":"integer"},"title":{"type":"string"},"done":{"type":"boolean"},"date_created":{"type":"string","format":"date-time","nullable":true},"date_closed":{"type":"string","format":"date-time","nullable":true},"created_by":{"type":"string","nullable":true},"created_by_name":{"type":"string","nullable":true}}},"Finding":{"type":"object","properties":{"id":{"type":"string"},"finding_number":{"type":"integer","nullable":true},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","nullable":true,"enum":["Open","To be reviewed","Closed","Accepted as is","Cancelled","Shipyard confirmed rectification",null]},"previous_status":{"type":"string","nullable":true},"priority":{"type":"string","nullable":true},"system":{"type":"string","nullable":true},"date_of_finding":{"type":"string","format":"date-time","nullable":true},"date_created":{"type":"string","format":"date-time","nullable":true},"last_edited_date":{"type":"string","format":"date-time","nullable":true},"start_date":{"type":"string","format":"date-time","nullable":true},"due_date":{"type":"string","format":"date-time","nullable":true},"corrective_measure":{"type":"string"},"location_details":{"type":"string"},"location_level_1":{"type":"string","nullable":true},"location_level_2":{"type":"string","nullable":true},"location_level_3":{"type":"string","nullable":true},"location_level_4":{"type":"string","nullable":true},"location_level_5":{"type":"string","nullable":true},"location_lat_lng":{"type":"object","nullable":true,"properties":{"latitude":{"type":"number"},"longitude":{"type":"number"}}},"numeric_value":{"type":"number","nullable":true},"nfc_information":{"type":"string","nullable":true},"shipyard_reference":{"type":"string","nullable":true},"created_by":{"type":"string","nullable":true},"created_by_name":{"type":"string","nullable":true},"created_by_company_name":{"type":"string","nullable":true},"last_edited_by":{"type":"string","nullable":true},"last_edited_by_name":{"type":"string","nullable":true},"last_edited_by_company_name":{"type":"string","nullable":true},"inspection_id":{"type":"string","nullable":true},"project_id":{"type":"string","nullable":true},"company_id":{"type":"string","nullable":true},"assignee_ids":{"type":"array","items":{"type":"string"}},"checklist":{"type":"array","items":{"$ref":"#/components/schemas/ChecklistItem"}},"checklist_total":{"type":"integer"},"checklist_open":{"type":"integer"},"last_comment":{"type":"object","nullable":true,"description":"Denormalized summary. Full thread at /v1/findings/{id}/comments.","properties":{"text":{"type":"string"},"author_name":{"type":"string","nullable":true},"author_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"system_triggered":{"type":"boolean"}}},"has_location_details_image":{"type":"boolean"},"marker_count":{"type":"integer"}}},"Comment":{"type":"object","properties":{"id":{"type":"string"},"finding_id":{"type":"string"},"text":{"type":"string"},"created_at":{"type":"string","format":"date-time","nullable":true},"author_id":{"type":"string","nullable":true},"author_name":{"type":"string","nullable":true},"system_triggered":{"type":"boolean","description":"True for entries the app generates itself, such as status changes."},"has_image":{"type":"boolean"},"has_audio":{"type":"boolean"},"has_video":{"type":"boolean"},"has_file":{"type":"boolean"},"file_name":{"type":"string","nullable":true}}},"Attachment":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"The findingsFiles document id. Null for location_details_image and comment rows (a comment row is identified by comment_id + content_kind)."},"source":{"type":"string","enum":["location_details_image","findings_file","comment"]},"comment_id":{"type":"string","nullable":true,"description":"For source \"comment\": the comment this file is attached to (see /v1/findings/{id}/comments)."},"title":{"type":"string","nullable":true},"description_short":{"type":"string","nullable":true},"description_long":{"type":"string","nullable":true},"file_name":{"type":"string","nullable":true},"content_kind":{"type":"string","enum":["image","video","audio","file"]},"custom_index":{"type":"integer","nullable":true},"folder_path":{"type":"string","nullable":true},"blur_hash":{"type":"string","nullable":true},"excluded_from_reports":{"type":"boolean"},"captured_at":{"type":"string","format":"date-time","nullable":true},"uploaded_at":{"type":"string","format":"date-time","nullable":true},"uploaded_by":{"type":"string","nullable":true},"uploaded_by_name":{"type":"string","nullable":true},"uploaded_by_company_name":{"type":"string","nullable":true},"download_url":{"type":"string","nullable":true},"download_url_expires_at":{"type":"string","format":"date-time","nullable":true},"download_error":{"type":"string","nullable":true,"enum":["unrecognized_storage_reference","foreign_bucket","signing_failed",null]}}},"Project":{"type":"object","description":"Allow-listed project/vessel metadata.","properties":{"id":{"type":"string"},"name":{"type":"string"},"company_id":{"type":"string","nullable":true},"customer_project_id":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"is_closed":{"type":"boolean"},"date_created":{"type":"string","format":"date-time","nullable":true},"current_milestone":{"type":"string","nullable":true},"project_progress":{"type":"number","nullable":true},"findings_counter":{"type":"number","nullable":true},"findings_counter_is_corrected":{"type":"number","nullable":true},"inspections_counter":{"type":"number","nullable":true},"issues_counter":{"type":"number","nullable":true},"vessel":{"type":"object","additionalProperties":true},"classification":{"type":"object","additionalProperties":true},"propulsion":{"type":"object","additionalProperties":true},"survey":{"type":"object","additionalProperties":true},"claim":{"type":"object","additionalProperties":true},"client":{"type":"object","additionalProperties":true}}}}}}