@inventorai/sdk 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +516 -0
  3. package/dist/client.d.ts +59 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +61 -0
  6. package/dist/errors/api-error.d.ts +12 -0
  7. package/dist/errors/api-error.d.ts.map +1 -0
  8. package/dist/errors/api-error.js +26 -0
  9. package/dist/http/client.d.ts +13 -0
  10. package/dist/http/client.d.ts.map +1 -0
  11. package/dist/http/client.js +89 -0
  12. package/dist/index.d.ts +31 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +72 -0
  15. package/dist/resources/address-lookup.d.ts +15 -0
  16. package/dist/resources/address-lookup.d.ts.map +1 -0
  17. package/dist/resources/address-lookup.js +21 -0
  18. package/dist/resources/asset-checks.d.ts +19 -0
  19. package/dist/resources/asset-checks.d.ts.map +1 -0
  20. package/dist/resources/asset-checks.js +15 -0
  21. package/dist/resources/branches.d.ts +11 -0
  22. package/dist/resources/branches.d.ts.map +1 -0
  23. package/dist/resources/branches.js +15 -0
  24. package/dist/resources/clients.d.ts +19 -0
  25. package/dist/resources/clients.d.ts.map +1 -0
  26. package/dist/resources/clients.js +27 -0
  27. package/dist/resources/compliance-forms.d.ts +8 -0
  28. package/dist/resources/compliance-forms.d.ts.map +1 -0
  29. package/dist/resources/compliance-forms.js +12 -0
  30. package/dist/resources/compliance.d.ts +28 -0
  31. package/dist/resources/compliance.d.ts.map +1 -0
  32. package/dist/resources/compliance.js +45 -0
  33. package/dist/resources/components.d.ts +8 -0
  34. package/dist/resources/components.d.ts.map +1 -0
  35. package/dist/resources/components.js +12 -0
  36. package/dist/resources/defects.d.ts +29 -0
  37. package/dist/resources/defects.d.ts.map +1 -0
  38. package/dist/resources/defects.js +39 -0
  39. package/dist/resources/hazards.d.ts +11 -0
  40. package/dist/resources/hazards.d.ts.map +1 -0
  41. package/dist/resources/hazards.js +12 -0
  42. package/dist/resources/hmo.d.ts +23 -0
  43. package/dist/resources/hmo.d.ts.map +1 -0
  44. package/dist/resources/hmo.js +21 -0
  45. package/dist/resources/inspection-ai.d.ts +16 -0
  46. package/dist/resources/inspection-ai.d.ts.map +1 -0
  47. package/dist/resources/inspection-ai.js +30 -0
  48. package/dist/resources/inspection-areas.d.ts +26 -0
  49. package/dist/resources/inspection-areas.d.ts.map +1 -0
  50. package/dist/resources/inspection-areas.js +39 -0
  51. package/dist/resources/inspection-elements.d.ts +22 -0
  52. package/dist/resources/inspection-elements.d.ts.map +1 -0
  53. package/dist/resources/inspection-elements.js +33 -0
  54. package/dist/resources/inspection-items.d.ts +25 -0
  55. package/dist/resources/inspection-items.d.ts.map +1 -0
  56. package/dist/resources/inspection-items.js +36 -0
  57. package/dist/resources/inspections.d.ts +42 -0
  58. package/dist/resources/inspections.d.ts.map +1 -0
  59. package/dist/resources/inspections.js +57 -0
  60. package/dist/resources/keys-fobs.d.ts +20 -0
  61. package/dist/resources/keys-fobs.d.ts.map +1 -0
  62. package/dist/resources/keys-fobs.js +30 -0
  63. package/dist/resources/meter-readings.d.ts +20 -0
  64. package/dist/resources/meter-readings.d.ts.map +1 -0
  65. package/dist/resources/meter-readings.js +30 -0
  66. package/dist/resources/modifiers.d.ts +41 -0
  67. package/dist/resources/modifiers.d.ts.map +1 -0
  68. package/dist/resources/modifiers.js +45 -0
  69. package/dist/resources/phrases.d.ts +27 -0
  70. package/dist/resources/phrases.d.ts.map +1 -0
  71. package/dist/resources/phrases.js +27 -0
  72. package/dist/resources/properties.d.ts +21 -0
  73. package/dist/resources/properties.d.ts.map +1 -0
  74. package/dist/resources/properties.js +30 -0
  75. package/dist/resources/property-templates.d.ts +11 -0
  76. package/dist/resources/property-templates.d.ts.map +1 -0
  77. package/dist/resources/property-templates.js +15 -0
  78. package/dist/resources/scheduler.d.ts +11 -0
  79. package/dist/resources/scheduler.d.ts.map +1 -0
  80. package/dist/resources/scheduler.js +24 -0
  81. package/dist/resources/stats.d.ts +10 -0
  82. package/dist/resources/stats.d.ts.map +1 -0
  83. package/dist/resources/stats.js +21 -0
  84. package/dist/resources/team.d.ts +18 -0
  85. package/dist/resources/team.d.ts.map +1 -0
  86. package/dist/resources/team.js +20 -0
  87. package/dist/resources/teams.d.ts +16 -0
  88. package/dist/resources/teams.d.ts.map +1 -0
  89. package/dist/resources/teams.js +18 -0
  90. package/dist/resources/user.d.ts +10 -0
  91. package/dist/resources/user.d.ts.map +1 -0
  92. package/dist/resources/user.js +12 -0
  93. package/dist/resources/vocabulary.d.ts +11 -0
  94. package/dist/resources/vocabulary.d.ts.map +1 -0
  95. package/dist/resources/vocabulary.js +12 -0
  96. package/dist/types/index.d.ts +887 -0
  97. package/dist/types/index.d.ts.map +1 -0
  98. package/dist/types/index.js +3 -0
  99. package/package.json +45 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Inventorai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,516 @@
1
+ # Inventorai TypeScript SDK
2
+
3
+ Official TypeScript/JavaScript SDK for the Inventorai API - AI-powered property inspection and management platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @inventorai/sdk
9
+ # or
10
+ yarn add @inventorai/sdk
11
+ # or
12
+ pnpm add @inventorai/sdk
13
+ ```
14
+
15
+ ## Requirements
16
+
17
+ - Node.js 16+
18
+ - TypeScript 5+ (for TypeScript projects)
19
+
20
+ ## Quick Start
21
+
22
+ ```typescript
23
+ import { InventoraiClient } from '@inventorai/sdk';
24
+
25
+ const client = new InventoraiClient({
26
+ apiToken: 'your-api-token-here'
27
+ });
28
+
29
+ // List properties
30
+ const properties = await client.properties.list({
31
+ filter: { status: 'active' },
32
+ include: ['landlord'],
33
+ per_page: 20
34
+ });
35
+
36
+ // Create a property
37
+ const property = await client.properties.create({
38
+ address_line_1: '123 High Street',
39
+ postcode: 'SW1A 1AA',
40
+ country: 'GB',
41
+ property_type: 'flat',
42
+ is_residential: true
43
+ });
44
+ ```
45
+
46
+ ## Configuration
47
+
48
+ ### Base URL
49
+
50
+ By default, the SDK uses `https://api.inventorai.co.uk/v1/team` — the third-party Team API surface, authenticated with a team API token. Override for local development:
51
+
52
+ ```typescript
53
+ const client = new InventoraiClient({
54
+ apiToken: 'your-api-token',
55
+ baseURL: 'https://api.inventorai.test/v1/team'
56
+ });
57
+ ```
58
+
59
+ ## Resources
60
+
61
+ ### Properties
62
+
63
+ ```typescript
64
+ // List properties with filters
65
+ const properties = await client.properties.list({
66
+ filter: { status: 'active', property_type: 'flat', search: 'London' },
67
+ include: ['landlord', 'inspections'],
68
+ sort: '-created_at',
69
+ per_page: 50
70
+ });
71
+
72
+ // Get single property
73
+ const property = await client.properties.get('01HZW4N8R7Q5K3JX0V9PT6S2P1', {
74
+ include: ['landlord', 'inspections']
75
+ });
76
+
77
+ // Create a property
78
+ const newProperty = await client.properties.create({
79
+ address_line_1: '10 Downing Street',
80
+ postcode: 'SW1A 2AA',
81
+ country: 'GB',
82
+ property_type: 'house',
83
+ is_hmo: false,
84
+ is_residential: true
85
+ });
86
+
87
+ // Get active tenancy
88
+ const tenancy = await client.properties.activeTenancy('01HZW4N8R7Q5K3JX0V9PT6S2P1');
89
+
90
+ // Upload / delete cover image
91
+ await client.properties.uploadCoverImage('01HZW4N8R7Q5K3JX0V9PT6S2P1', imageFile);
92
+ await client.properties.deleteCoverImage('01HZW4N8R7Q5K3JX0V9PT6S2P1');
93
+ ```
94
+
95
+ ### Inspections
96
+
97
+ ```typescript
98
+ // List inspections
99
+ const inspections = await client.inspections.list({
100
+ filter: { property_id: '01HZW4N8R7Q5K3JX0V9PT6S2P1', status: 'draft' }
101
+ });
102
+
103
+ // Create an inspection
104
+ const inspection = await client.inspections.create({
105
+ property_id: '01HZW4N8R7Q5K3JX0V9PT6S2P1',
106
+ type: 'move_in',
107
+ scheduled_at: '2026-04-01',
108
+ scribe_enabled: true
109
+ });
110
+
111
+ // Create with offline-built ULID + nested tree (sync a full structure in one call,
112
+ // reusing your own row IDs so offline mutations stay valid post-sync)
113
+ const offlineInspection = await client.inspections.create({
114
+ id: '01HZW4N8R7Q5K3JX0V9PT6S2EM',
115
+ property_id: '01HZW4N8R7Q5K3JX0V9PT6S2P1',
116
+ type: 'periodic',
117
+ scheduled_end_at: '2026-04-01T11:00:00Z',
118
+ areas: [{
119
+ id: '01HZW4N8R7Q5K3JX0V9PT6S2A1',
120
+ name: 'Living Room',
121
+ items: [{
122
+ id: '01HZW4N8R7Q5K3JX0V9PT6S2I1',
123
+ name: 'Sofa',
124
+ elements: [{ id: '01HZW4N8R7Q5K3JX0V9PT6S2E1', name: 'Cushion' }]
125
+ }]
126
+ }]
127
+ });
128
+
129
+ // Initialize from a property template (async server-side expansion)
130
+ await client.inspections.initialize({
131
+ property_id: '01HZW4N8R7Q5K3JX0V9PT6S2P1',
132
+ template_id: '01HZW4N8R7Q5K3JX0V9PT6S2T1',
133
+ type: 'move_in'
134
+ });
135
+
136
+ // Get with relations — one call returns the whole inspection tree.
137
+ // You almost never need the per-resource list() methods below for *reads* —
138
+ // pass everything you want through `include` and you'll get it inline.
139
+ const detail = await client.inspections.get(456, {
140
+ include: [
141
+ // property + tenancy context
142
+ 'property', 'property.currentTenancy.tenants', 'inspector',
143
+ // the area → item → element tree (photos auto-load when these are included)
144
+ 'areas.items.elements',
145
+ // optional sections
146
+ 'meterReadings', 'keysFobs',
147
+ 'assetChecks.propertyAsset.propertyArea',
148
+ 'complianceForms.sections.fields.responses',
149
+ ],
150
+ });
151
+
152
+ // The per-resource sections below (Inspection Areas, Items, Elements, …)
153
+ // are for **writes**: create, update, delete, duplicate, reorder, photo upload —
154
+ // and for mobile/offline sync where a client re-pulls one slice or pages a leaf
155
+ // (e.g. an HMO inspection with hundreds of items). For normal reads, prefer the
156
+ // `include` call above.
157
+
158
+ // Lifecycle
159
+ await client.inspections.begin(456);
160
+ await client.inspections.takeOver(456); // claim an inspection locked by another inspector
161
+ await client.inspections.takeBackToWeb(456); // hand a mobile-takeover inspection back to the web UI
162
+ await client.inspections.reschedule(456, { scheduled_at: '2026-04-15' });
163
+ await client.inspections.finalize(456);
164
+ await client.inspections.reopen(456); // reopen a finalised inspection for edits
165
+ await client.inspections.delete(456);
166
+
167
+ // Check existing / comparable
168
+ const existing = await client.inspections.checkExisting({ property_id: '01HZW4N8R7Q5K3JX0V9PT6S2P1', type: 'move_in' });
169
+ const comparable = await client.inspections.comparable({ property_id: '01HZW4N8R7Q5K3JX0V9PT6S2P1' });
170
+ ```
171
+
172
+ ### Inspection Areas
173
+
174
+ ```typescript
175
+ const areas = await client.inspectionAreas.list(inspectionId);
176
+ const area = await client.inspectionAreas.get(inspectionId, areaId);
177
+ const newArea = await client.inspectionAreas.create(inspectionId, {
178
+ name: 'Living Room', condition: 'good', cleanliness: 'clean'
179
+ });
180
+ await client.inspectionAreas.update(inspectionId, areaId, { condition: 'fair' });
181
+ await client.inspectionAreas.delete(inspectionId, areaId);
182
+ await client.inspectionAreas.duplicate(inspectionId, areaId);
183
+ await client.inspectionAreas.reorder(inspectionId, ['area1', 'area2', 'area3']);
184
+
185
+ // Photos
186
+ await client.inspectionAreas.uploadPhoto(inspectionId, areaId, photoFile);
187
+ await client.inspectionAreas.deletePhoto(inspectionId, areaId, photoId);
188
+ ```
189
+
190
+ ### Inspection Items
191
+
192
+ ```typescript
193
+ const items = await client.inspectionItems.list(inspectionId);
194
+ const item = await client.inspectionItems.create(inspectionId, {
195
+ area_id: areaId, name: 'Sofa', condition: 'good'
196
+ });
197
+ await client.inspectionItems.update(inspectionId, itemId, { condition: 'poor' });
198
+ await client.inspectionItems.delete(inspectionId, itemId);
199
+ await client.inspectionItems.duplicate(inspectionId, itemId);
200
+ await client.inspectionItems.uploadPhoto(inspectionId, itemId, photoFile);
201
+ ```
202
+
203
+ ### Inspection Elements
204
+
205
+ ```typescript
206
+ const elements = await client.inspectionElements.list(inspectionId);
207
+ const element = await client.inspectionElements.create(inspectionId, {
208
+ item_id: itemId, name: 'Cushion', condition: 'fair'
209
+ });
210
+ await client.inspectionElements.update(inspectionId, elementId, { condition: 'poor' });
211
+ await client.inspectionElements.delete(inspectionId, elementId);
212
+ await client.inspectionElements.uploadPhoto(inspectionId, elementId, photoFile);
213
+ ```
214
+
215
+ ### Defects
216
+
217
+ ```typescript
218
+ const defects = await client.defects.list(inspectionId);
219
+ const defect = await client.defects.create(inspectionId, {
220
+ defectable_type: 'item',
221
+ defectable_id: itemId,
222
+ title: 'Scratch on surface',
223
+ severity: 'minor', // nullable — omit if uncategorised
224
+ item_label: 'Top-left drawer' // optional free-text label for the affected part
225
+ });
226
+
227
+ // Contextual creation
228
+ await client.defects.createForArea(inspectionId, areaId, { title: 'Damp patch', severity: 'high' });
229
+ await client.defects.createForItem(inspectionId, itemId, { title: 'Broken handle', severity: 'medium', item_label: 'Right side' });
230
+ await client.defects.createForElement(inspectionId, elementId, { title: 'Stain', severity: 'low' });
231
+
232
+ await client.defects.update(inspectionId, defectId, { status: 'completed' });
233
+ await client.defects.delete(inspectionId, defectId);
234
+ await client.defects.uploadPhoto(inspectionId, defectId, photoFile);
235
+ ```
236
+
237
+ ### Meter Readings
238
+
239
+ ```typescript
240
+ const meters = await client.meterReadings.list(inspectionId);
241
+ const meter = await client.meterReadings.create(inspectionId, {
242
+ meter_type: 'gas', reading: 12345, meter_location: 'Under stairs'
243
+ });
244
+ await client.meterReadings.update(inspectionId, meterId, { reading: 12350 });
245
+ await client.meterReadings.delete(inspectionId, meterId);
246
+ await client.meterReadings.uploadPhoto(inspectionId, meterId, photoFile);
247
+ ```
248
+
249
+ ### Keys & Fobs
250
+
251
+ ```typescript
252
+ const keys = await client.keysFobs.list(inspectionId);
253
+ const key = await client.keysFobs.create(inspectionId, {
254
+ item_type: 'front_door_key', quantity: 2, description: 'Yale key'
255
+ });
256
+ await client.keysFobs.update(inspectionId, keyId, { quantity: 3 });
257
+ await client.keysFobs.delete(inspectionId, keyId);
258
+ await client.keysFobs.uploadPhoto(inspectionId, keyId, photoFile);
259
+ ```
260
+
261
+ ### Compliance
262
+
263
+ ```typescript
264
+ // List compliance forms on an inspection
265
+ const forms = await client.compliance.list(inspectionId);
266
+
267
+ // Attach / detach forms
268
+ await client.compliance.attach(inspectionId, formId);
269
+ await client.compliance.attachMultiple(inspectionId, [formId1, formId2]);
270
+ await client.compliance.detach(inspectionId, formId);
271
+
272
+ // Update responses
273
+ await client.compliance.updateResponse(inspectionId, fieldId, { value: 'Yes', notes: 'Checked at the meter' });
274
+ await client.compliance.removeSectionCopy(inspectionId, fieldId, 2);
275
+ await client.compliance.batchUpdateResponses(inspectionId, { 1: 'Yes', 2: 'No' });
276
+
277
+ // File uploads & section instances
278
+ await client.compliance.uploadFile(inspectionId, file);
279
+ await client.compliance.addSectionInstance(inspectionId, { form_id: formId, section_id: sectionId });
280
+ await client.compliance.removeSectionInstance(inspectionId, instanceId);
281
+
282
+ // Summary
283
+ const summary = await client.compliance.summary(inspectionId);
284
+ ```
285
+
286
+ ### Compliance Form Templates
287
+
288
+ ```typescript
289
+ const templates = await client.complianceForms.list();
290
+ ```
291
+
292
+ ### Inspection AI
293
+
294
+ ```typescript
295
+ await client.inspectionAi.enable(inspectionId);
296
+ await client.inspectionAi.disable(inspectionId);
297
+ const status = await client.inspectionAi.status(inspectionId);
298
+ await client.inspectionAi.retryCredits(inspectionId);
299
+ await client.inspectionAi.requestRetry(inspectionId);
300
+ const retryStatus = await client.inspectionAi.retryStatus(inspectionId);
301
+ await client.inspectionAi.submitFeedback(inspectionId, { rating: 5, comment: 'Great' });
302
+ ```
303
+
304
+ ### Property Templates (Blueprints)
305
+
306
+ ```typescript
307
+ const templates = await client.propertyTemplates.list();
308
+ const template = await client.propertyTemplates.get(789);
309
+ ```
310
+
311
+ ### Branches
312
+
313
+ ```typescript
314
+ const branches = await client.branches.list();
315
+ const branch = await client.branches.get(1);
316
+ ```
317
+
318
+ ### HMO (House in Multiple Occupation)
319
+
320
+ ```typescript
321
+ const summary = await client.hmo.summary(inspectionId);
322
+ const tenants = await client.hmo.tenants(inspectionId);
323
+
324
+ await client.hmo.assignTenantToArea(inspectionId, areaId, {
325
+ tenant_ids: ['tenant-1', 'tenant-2'],
326
+ is_shared: false,
327
+ room_identifier: 'Room 1'
328
+ });
329
+
330
+ await client.hmo.bulkAssignTenants(inspectionId, {
331
+ assignments: [
332
+ { area_id: 'area-1', tenant_ids: ['tenant-1'] },
333
+ { area_id: 'area-2', is_shared: true }
334
+ ]
335
+ });
336
+ ```
337
+
338
+ ### Components
339
+
340
+ ```typescript
341
+ const components = await client.components.list();
342
+ ```
343
+
344
+ ### Address Lookup
345
+
346
+ ```typescript
347
+ const results = await client.addressLookup.lookup('SW1A 1AA');
348
+ const bulk = await client.addressLookup.bulkLookup(['SW1A 1AA', 'EC1A 1BB']);
349
+ const details = await client.addressLookup.getDetails({ id: 'addr_123' });
350
+ const usage = await client.addressLookup.usage();
351
+ ```
352
+
353
+ ### Stats & Dashboard
354
+
355
+ ```typescript
356
+ const stats = await client.stats.index();
357
+ const teamStats = await client.stats.team();
358
+ const userStats = await client.stats.user();
359
+ const schedule = await client.stats.schedule();
360
+ ```
361
+
362
+ ### Phrases
363
+
364
+ ```typescript
365
+ const synced = await client.phrases.sync();
366
+ const results = await client.phrases.search({ q: 'good condition', category: 'item' });
367
+ await client.phrases.create({ text: 'In good working order', category: 'item' });
368
+ const generated = await client.phrases.generate({ query: 'clean carpet', category: 'item' });
369
+ await client.phrases.learn({ descriptions: ['Freshly painted walls'] });
370
+ const phraseStats = await client.phrases.stats();
371
+ ```
372
+
373
+ ### Clients
374
+
375
+ ```typescript
376
+ const clients = await client.clients.list({ scope: 'all', include: 'group' });
377
+ const one = await client.clients.get(clientId, { include: ['group', 'branches'] });
378
+ const groups = await client.clients.groups({ include: 'clients' });
379
+ const group = await client.clients.group(groupId);
380
+ ```
381
+
382
+ ### Hazards and Vocabulary
383
+
384
+ ```typescript
385
+ const hazards = await client.hazards.sync();
386
+ const vocabulary = await client.vocabulary.sync();
387
+ ```
388
+
389
+ ### Modifiers
390
+
391
+ ```typescript
392
+ const modifiers = await client.modifiers.list();
393
+ const types = await client.modifiers.types();
394
+ const forItem = await client.modifiers.forItem({ item_name: 'Sofa' });
395
+ const search = await client.modifiers.search({ q: 'leather' });
396
+ const disabled = await client.modifiers.disabled();
397
+ const master = await client.modifiers.master();
398
+ const sync = await client.modifiers.sync(); // full snapshot for offline caches
399
+
400
+ await client.modifiers.createCustom({ type: 'brand', value: 'IKEA' });
401
+ await client.modifiers.deleteCustom(modifierId);
402
+ await client.modifiers.disable(modifierId);
403
+ await client.modifiers.enable(modifierId);
404
+ const composed = await client.modifiers.compose({ items: ['Brown', 'Leather', 'Sofa'] });
405
+ ```
406
+
407
+ ### Asset Checks
408
+
409
+ Alarm and safety-equipment checks recorded against an inspection.
410
+
411
+ ```typescript
412
+ await client.assetChecks.update(inspectionId, assetCheckId, {
413
+ tested: 'yes', // yes | no | not_accessible
414
+ test_result: 'pass', // pass | fail | na
415
+ condition: 'good', // good | fair | poor | replace
416
+ notes: 'Sounded on test',
417
+ });
418
+ await client.assetChecks.uploadPhoto(inspectionId, assetCheckId, photoFile);
419
+ ```
420
+
421
+ ### Scheduler
422
+
423
+ ```typescript
424
+ const calendar = await client.scheduler.calendar({ month: '2026-04' });
425
+ await client.scheduler.weeklyAvailability(data);
426
+ const conflicts = await client.scheduler.checkConflicts(data);
427
+ const hours = await client.scheduler.officeHours();
428
+ const duration = await client.scheduler.estimateDuration(data);
429
+ ```
430
+
431
+ ## TypeScript Support
432
+
433
+ Full type definitions are included:
434
+
435
+ ```typescript
436
+ import {
437
+ Property, Inspection, InspectionArea, InspectionItem, InspectionElement,
438
+ Defect, MeterReading, KeyFob, ComplianceForm, PropertyTemplate, Branch,
439
+ CreatePropertyData, CreateInspectionData,
440
+ CreateInspectionAreaTree, CreateInspectionItemTree, CreateInspectionElementTree,
441
+ CreateDefectData, UpdateDefectData,
442
+ HmoTenantAssignment, HmoBulkAssignment,
443
+ PaginatedResponse
444
+ } from '@inventorai/sdk';
445
+ ```
446
+
447
+ ## Query Parameters
448
+
449
+ ### Filtering
450
+ ```typescript
451
+ const properties = await client.properties.list({
452
+ filter: { status: 'active', property_type: 'house' }
453
+ });
454
+ ```
455
+
456
+ ### Including Relationships
457
+ ```typescript
458
+ const property = await client.properties.get('01HZW4N8R7Q5K3JX0V9PT6S2P1', {
459
+ include: ['landlord', 'inspections']
460
+ });
461
+ ```
462
+
463
+ ### Sorting
464
+ ```typescript
465
+ const properties = await client.properties.list({
466
+ sort: '-created_at' // Prefix with - for descending
467
+ });
468
+ ```
469
+
470
+ ### Pagination
471
+ ```typescript
472
+ const properties = await client.properties.list({ per_page: 50, page: 2 });
473
+ ```
474
+
475
+ ## Error Handling
476
+
477
+ ```typescript
478
+ import { ApiError, AuthenticationError, RateLimitError } from '@inventorai/sdk';
479
+
480
+ try {
481
+ const properties = await client.properties.list();
482
+ } catch (error) {
483
+ if (error instanceof AuthenticationError) {
484
+ console.error('Authentication failed:', error.message);
485
+ } else if (error instanceof RateLimitError) {
486
+ console.error('Rate limit exceeded:', error.message);
487
+ } else if (error instanceof ApiError) {
488
+ console.error('API error:', error.message, error.statusCode);
489
+ }
490
+ }
491
+ ```
492
+
493
+ ## API Token
494
+
495
+ An active [Inventorai](https://app.inventorai.co.uk) subscription is required to use the API.
496
+
497
+ 1. Log in to Inventorai
498
+ 2. Go to **Team Settings** > **API**
499
+ 3. Create a new API token
500
+ 4. Store securely in environment variables
501
+
502
+ ```typescript
503
+ const client = new InventoraiClient({
504
+ apiToken: process.env.INVENTORAI_API_TOKEN!
505
+ });
506
+ ```
507
+
508
+ ## Support
509
+
510
+ - Documentation: https://docs.inventorai.co.uk
511
+ - API Reference: https://docs.inventorai.co.uk/api/overview
512
+ - Email: support@inventorai.co.uk
513
+
514
+ ## Licence
515
+
516
+ MIT Licence
@@ -0,0 +1,59 @@
1
+ import { Properties } from './resources/properties';
2
+ import { Inspections } from './resources/inspections';
3
+ import { InspectionAreas } from './resources/inspection-areas';
4
+ import { InspectionItems } from './resources/inspection-items';
5
+ import { InspectionElements } from './resources/inspection-elements';
6
+ import { Defects } from './resources/defects';
7
+ import { MeterReadings } from './resources/meter-readings';
8
+ import { AssetChecks } from './resources/asset-checks';
9
+ import { KeysFobs } from './resources/keys-fobs';
10
+ import { Compliance } from './resources/compliance';
11
+ import { ComplianceForms } from './resources/compliance-forms';
12
+ import { InspectionAi } from './resources/inspection-ai';
13
+ import { PropertyTemplates } from './resources/property-templates';
14
+ import { Branches } from './resources/branches';
15
+ import { Hmo } from './resources/hmo';
16
+ import { Components } from './resources/components';
17
+ import { AddressLookup } from './resources/address-lookup';
18
+ import { StatsResource } from './resources/stats';
19
+ import { Phrases } from './resources/phrases';
20
+ import { Modifiers } from './resources/modifiers';
21
+ import { Scheduler } from './resources/scheduler';
22
+ import { TeamResource } from './resources/team';
23
+ import { Clients } from './resources/clients';
24
+ import { Hazards } from './resources/hazards';
25
+ import { Vocabulary } from './resources/vocabulary';
26
+ export interface InventoraiClientOptions {
27
+ apiToken: string;
28
+ baseURL?: string;
29
+ }
30
+ export declare class InventoraiClient {
31
+ private httpClient;
32
+ properties: Properties;
33
+ inspections: Inspections;
34
+ inspectionAreas: InspectionAreas;
35
+ inspectionItems: InspectionItems;
36
+ inspectionElements: InspectionElements;
37
+ defects: Defects;
38
+ meterReadings: MeterReadings;
39
+ assetChecks: AssetChecks;
40
+ keysFobs: KeysFobs;
41
+ compliance: Compliance;
42
+ complianceForms: ComplianceForms;
43
+ inspectionAi: InspectionAi;
44
+ propertyTemplates: PropertyTemplates;
45
+ branches: Branches;
46
+ hmo: Hmo;
47
+ components: Components;
48
+ addressLookup: AddressLookup;
49
+ stats: StatsResource;
50
+ phrases: Phrases;
51
+ modifiers: Modifiers;
52
+ scheduler: Scheduler;
53
+ team: TeamResource;
54
+ clients: Clients;
55
+ hazards: Hazards;
56
+ vocabulary: Vocabulary;
57
+ constructor(options: InventoraiClientOptions);
58
+ }
59
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAa;IAExB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,EAAE,YAAY,CAAC;IAC3B,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,GAAG,CAAC;IACT,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;gBAElB,OAAO,EAAE,uBAAuB;CA8B7C"}
package/dist/client.js ADDED
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InventoraiClient = void 0;
4
+ const client_1 = require("./http/client");
5
+ const properties_1 = require("./resources/properties");
6
+ const inspections_1 = require("./resources/inspections");
7
+ const inspection_areas_1 = require("./resources/inspection-areas");
8
+ const inspection_items_1 = require("./resources/inspection-items");
9
+ const inspection_elements_1 = require("./resources/inspection-elements");
10
+ const defects_1 = require("./resources/defects");
11
+ const meter_readings_1 = require("./resources/meter-readings");
12
+ const asset_checks_1 = require("./resources/asset-checks");
13
+ const keys_fobs_1 = require("./resources/keys-fobs");
14
+ const compliance_1 = require("./resources/compliance");
15
+ const compliance_forms_1 = require("./resources/compliance-forms");
16
+ const inspection_ai_1 = require("./resources/inspection-ai");
17
+ const property_templates_1 = require("./resources/property-templates");
18
+ const branches_1 = require("./resources/branches");
19
+ const hmo_1 = require("./resources/hmo");
20
+ const components_1 = require("./resources/components");
21
+ const address_lookup_1 = require("./resources/address-lookup");
22
+ const stats_1 = require("./resources/stats");
23
+ const phrases_1 = require("./resources/phrases");
24
+ const modifiers_1 = require("./resources/modifiers");
25
+ const scheduler_1 = require("./resources/scheduler");
26
+ const team_1 = require("./resources/team");
27
+ const clients_1 = require("./resources/clients");
28
+ const hazards_1 = require("./resources/hazards");
29
+ const vocabulary_1 = require("./resources/vocabulary");
30
+ class InventoraiClient {
31
+ constructor(options) {
32
+ const baseURL = options.baseURL || 'https://api.inventorai.co.uk/v1/team';
33
+ this.httpClient = new client_1.HttpClient(options.apiToken, baseURL);
34
+ this.properties = new properties_1.Properties(this.httpClient);
35
+ this.inspections = new inspections_1.Inspections(this.httpClient);
36
+ this.inspectionAreas = new inspection_areas_1.InspectionAreas(this.httpClient);
37
+ this.inspectionItems = new inspection_items_1.InspectionItems(this.httpClient);
38
+ this.inspectionElements = new inspection_elements_1.InspectionElements(this.httpClient);
39
+ this.defects = new defects_1.Defects(this.httpClient);
40
+ this.meterReadings = new meter_readings_1.MeterReadings(this.httpClient);
41
+ this.assetChecks = new asset_checks_1.AssetChecks(this.httpClient);
42
+ this.keysFobs = new keys_fobs_1.KeysFobs(this.httpClient);
43
+ this.compliance = new compliance_1.Compliance(this.httpClient);
44
+ this.complianceForms = new compliance_forms_1.ComplianceForms(this.httpClient);
45
+ this.inspectionAi = new inspection_ai_1.InspectionAi(this.httpClient);
46
+ this.propertyTemplates = new property_templates_1.PropertyTemplates(this.httpClient);
47
+ this.branches = new branches_1.Branches(this.httpClient);
48
+ this.hmo = new hmo_1.Hmo(this.httpClient);
49
+ this.components = new components_1.Components(this.httpClient);
50
+ this.addressLookup = new address_lookup_1.AddressLookup(this.httpClient);
51
+ this.stats = new stats_1.StatsResource(this.httpClient);
52
+ this.phrases = new phrases_1.Phrases(this.httpClient);
53
+ this.modifiers = new modifiers_1.Modifiers(this.httpClient);
54
+ this.scheduler = new scheduler_1.Scheduler(this.httpClient);
55
+ this.team = new team_1.TeamResource(this.httpClient);
56
+ this.clients = new clients_1.Clients(this.httpClient);
57
+ this.hazards = new hazards_1.Hazards(this.httpClient);
58
+ this.vocabulary = new vocabulary_1.Vocabulary(this.httpClient);
59
+ }
60
+ }
61
+ exports.InventoraiClient = InventoraiClient;
@@ -0,0 +1,12 @@
1
+ export declare class ApiError extends Error {
2
+ statusCode?: number | undefined;
3
+ response?: any | undefined;
4
+ constructor(message: string, statusCode?: number | undefined, response?: any | undefined);
5
+ }
6
+ export declare class AuthenticationError extends ApiError {
7
+ constructor(message: string, statusCode?: number, response?: any);
8
+ }
9
+ export declare class RateLimitError extends ApiError {
10
+ constructor(message: string, statusCode?: number, response?: any);
11
+ }
12
+ //# sourceMappingURL=api-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-error.d.ts","sourceRoot":"","sources":["../../src/errors/api-error.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAS,SAAQ,KAAK;IAGxB,UAAU,CAAC,EAAE,MAAM;IACnB,QAAQ,CAAC,EAAE,GAAG;gBAFrB,OAAO,EAAE,MAAM,EACR,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,QAAQ,CAAC,EAAE,GAAG,YAAA;CAKxB;AAED,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG;CAIjE;AAED,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG;CAIjE"}