{"openapi":"3.0.3","info":{"title":"PropSight Property Inspection API","description":"Enterprise REST API for managing property inspections programmatically. Create orders, track status, download reports, and monitor usage — all with a single API key.","version":"1.0.0","contact":{"name":"PropSight Developer Support","url":"https://propsight360.app/developers"},"license":{"name":"Proprietary"}},"servers":[{"url":"/api/v1","description":"Production API (relative to site origin)"}],"security":[{"ApiKeyAuth":[]}],"paths":{"/health":{"get":{"summary":"Health Check","description":"Returns the API health status, version, and current timestamp. No authentication required.","operationId":"getHealth","tags":["System"],"security":[],"responses":{"200":{"description":"API is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"healthy"},"version":{"type":"string","example":"1.0.0"},"timestamp":{"type":"string","format":"date-time","example":"2026-05-15T12:00:00.000Z"}},"required":["status","version","timestamp"]}}}}}}},"/orders":{"get":{"summary":"List Orders","description":"Retrieve a paginated list of inspection orders for your organization. Supports filtering by status, date range, full-text search, and sorting.","operationId":"listOrders","tags":["Orders"],"parameters":[{"name":"limit","in":"query","description":"Number of results per page (1-100, default 50)","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","description":"Number of results to skip (default 0)","schema":{"type":"integer","minimum":0,"default":0}},{"name":"status","in":"query","description":"Filter by order status","schema":{"type":"string","enum":["pending","link_sent","in_progress","submitted","approved","completed","flagged","cancelled"]}},{"name":"created_after","in":"query","description":"Filter orders created after this ISO 8601 date","schema":{"type":"string","format":"date-time"}},{"name":"created_before","in":"query","description":"Filter orders created before this ISO 8601 date","schema":{"type":"string","format":"date-time"}},{"name":"sort_by","in":"query","description":"Field to sort by","schema":{"type":"string","enum":["created_at","status","order_number"],"default":"created_at"}},{"name":"sort_order","in":"query","description":"Sort direction","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"responses":{"200":{"description":"Paginated list of orders","content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/OrderSummary"}},"pagination":{"$ref":"#/components/schemas/Pagination"}},"required":["orders","pagination"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"summary":"Create Order","description":"Create a new inspection order. Automatically generates a magic link for the homeowner and dispatches a webhook event. Supports idempotency keys to prevent duplicate orders.","operationId":"createOrder","tags":["Orders"],"parameters":[{"name":"X-Idempotency-Key","in":"header","description":"Unique key to ensure this request is processed only once. Cached for 24 hours.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderRequest"}}}},"responses":{"201":{"description":"Order created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderResponse"}}}},"400":{"description":"Missing required fields","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"required":{"type":"array","items":{"type":"string"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/orders/batch":{"post":{"summary":"Batch Create Orders","description":"Create up to 50 orders in a single request. Each order is processed independently — partial failures do not block other orders. Returns a 207 Multi-Status response with per-order results.","operationId":"batchCreateOrders","tags":["Orders"],"parameters":[{"name":"X-Idempotency-Key","in":"header","description":"Unique key for the entire batch request","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/CreateOrderRequest"},"minItems":1,"maxItems":50}},"required":["orders"]}}}},"responses":{"207":{"description":"Multi-status response with per-order results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchOrderResponse"}}}},"400":{"description":"Invalid request (empty array or exceeds 50 orders)"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/orders/{id}":{"get":{"summary":"Get Order Details","description":"Retrieve full details of a specific order including inspection data and photos.","operationId":"getOrder","tags":["Orders"],"parameters":[{"name":"id","in":"path","required":true,"description":"Order ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Order details with inspection and photos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderDetail"}}}},"400":{"description":"Invalid order ID"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Order not found"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/orders/{id}/report":{"get":{"summary":"Download Inspection Report","description":"Generate and download the PDF inspection report for a completed order. Returns a signed URL valid for 24 hours.","operationId":"getOrderReport","tags":["Orders"],"parameters":[{"name":"id","in":"path","required":true,"description":"Order ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"Report URL and metadata","content":{"application/json":{"schema":{"type":"object","properties":{"reportUrl":{"type":"string","format":"uri","description":"Signed URL to download the PDF report"},"filename":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}},"required":["reportUrl","filename","generatedAt","expiresAt"]}}}},"400":{"description":"Report not available (order not approved/completed)"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Order not found"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/usage":{"get":{"summary":"API Usage Statistics","description":"Retrieve API usage statistics for your organization including daily counts, endpoint breakdown, and per-key metrics.","operationId":"getUsageStats","tags":["Analytics"],"parameters":[{"name":"days","in":"query","description":"Number of days to look back (default 30)","schema":{"type":"integer","minimum":1,"maximum":365,"default":30}}],"responses":{"200":{"description":"Usage statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageStats"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalError"}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key generated from your PropSight client portal. Sandbox keys start with val_test_, production keys start with val_."}},"schemas":{"OrderSummary":{"type":"object","properties":{"id":{"type":"integer"},"orderNumber":{"type":"string"},"clientName":{"type":"string"},"inspectionType":{"type":"string"},"subjectAddress":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipCode":{"type":"string"},"homeownerName":{"type":"string"},"homeownerPhone":{"type":"string","nullable":true},"homeownerEmail":{"type":"string","nullable":true},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time","nullable":true}}},"Pagination":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of matching records"},"limit":{"type":"integer","description":"Results per page"},"offset":{"type":"integer","description":"Current offset"},"hasMore":{"type":"boolean","description":"Whether more results exist"}},"required":["total","limit","offset","hasMore"]},"CreateOrderRequest":{"type":"object","properties":{"orderNumber":{"type":"string","description":"Your unique order/loan number"},"clientName":{"type":"string","description":"Client or lender name"},"inspectionType":{"type":"string","description":"Type of inspection (default: Interior + Exterior)","default":"Interior + Exterior"},"subjectAddress":{"type":"string","description":"Property street address"},"city":{"type":"string"},"state":{"type":"string","description":"Two-letter state code"},"zipCode":{"type":"string"},"homeownerName":{"type":"string","description":"Name of the homeowner/borrower"},"homeownerPhone":{"type":"string","nullable":true,"description":"Homeowner phone number for SMS notifications"},"homeownerEmail":{"type":"string","nullable":true,"description":"Homeowner email for email notifications"},"callbackUrl":{"type":"string","nullable":true,"description":"Optional webhook URL for this specific order"},"formTemplateId":{"type":"integer","nullable":true,"description":"ID of a custom form template to use"}},"required":["orderNumber","clientName","subjectAddress","city","state","zipCode","homeownerName"]},"CreateOrderResponse":{"type":"object","properties":{"id":{"type":"integer","description":"Unique order ID"},"orderNumber":{"type":"string"},"status":{"type":"string","example":"link_sent"},"magicUrl":{"type":"string","format":"uri","description":"URL to send to the homeowner to begin their inspection"},"createdAt":{"type":"string","format":"date-time"},"sandbox":{"type":"boolean","description":"Present and true when created with a sandbox key"},"_sandbox_note":{"type":"string","description":"Informational note for sandbox orders"}},"required":["id","orderNumber","status","magicUrl","createdAt"]},"BatchOrderResponse":{"type":"object","properties":{"summary":{"type":"object","properties":{"total":{"type":"integer"},"succeeded":{"type":"integer"},"failed":{"type":"integer"}},"required":["total","succeeded","failed"]},"results":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","description":"Position in the input array"},"success":{"type":"boolean"},"order":{"$ref":"#/components/schemas/CreateOrderResponse"},"error":{"type":"string","description":"Error message if failed"}},"required":["index","success"]}}},"required":["summary","results"]},"OrderDetail":{"type":"object","properties":{"id":{"type":"integer"},"orderNumber":{"type":"string"},"clientName":{"type":"string"},"inspectionType":{"type":"string"},"subjectAddress":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zipCode":{"type":"string"},"homeownerName":{"type":"string"},"homeownerPhone":{"type":"string","nullable":true},"homeownerEmail":{"type":"string","nullable":true},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time","nullable":true},"inspection":{"type":"object","nullable":true,"description":"Inspection form data (null if not yet submitted)","properties":{"occupancy":{"type":"string"},"occupiedBy":{"type":"string"},"propertyType":{"type":"string"},"overallCondition":{"type":"string"},"bedrooms":{"type":"string"},"bathrooms":{"type":"string"},"numberOfStories":{"type":"string"},"basement":{"type":"string"},"finishedBasement":{"type":"string"},"hvac":{"type":"string"},"damage":{"type":"string"},"roofCondition":{"type":"string"},"yardMaintenance":{"type":"string"},"commentNeighborhood":{"type":"string"},"commentConditionRepairs":{"type":"string"},"commentRenovationsUpdates":{"type":"string"},"submittedAt":{"type":"string","format":"date-time"}}},"photos":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"section":{"type":"string"},"label":{"type":"string"},"storageUrl":{"type":"string"},"latitude":{"type":"number","nullable":true},"longitude":{"type":"number","nullable":true},"capturedAt":{"type":"string","format":"date-time","nullable":true},"aiQcStatus":{"type":"string","nullable":true}}}}}},"UsageStats":{"type":"object","properties":{"period":{"type":"object","properties":{"days":{"type":"integer"},"since":{"type":"string","format":"date-time"}}},"totalRequests":{"type":"integer"},"avgResponseTimeMs":{"type":"number"},"byEndpoint":{"type":"array","items":{"type":"object","properties":{"endpoint":{"type":"string"},"method":{"type":"string"},"count":{"type":"integer"},"avgResponseTimeMs":{"type":"number"}}}},"dailyCounts":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"count":{"type":"integer"}}}},"perKeyStats":{"type":"array","items":{"type":"object","properties":{"keyId":{"type":"integer"},"keyName":{"type":"string"},"count":{"type":"integer"}}}}}}},"responses":{"Unauthorized":{"description":"Authentication failed — missing or invalid API key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Missing x-api-key header"}}}},"Forbidden":{"description":"Access denied — insufficient permissions or deactivated key","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"This API key has read-only access. Write operations require a full-access key."}}}},"RateLimited":{"description":"Rate limit exceeded (100 requests per minute per key)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"retryAfter":{"type":"integer","description":"Seconds until limit resets"}}},"example":{"error":"Rate limit exceeded","retryAfter":42}}}},"InternalError":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}},"example":{"error":"Internal server error"}}}}}},"tags":[{"name":"System","description":"Health checks and system status"},{"name":"Orders","description":"Create, list, and manage inspection orders"},{"name":"Analytics","description":"API usage statistics and monitoring"}]}