ima-claude 2.20.0 → 2.26.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 (80) hide show
  1. package/README.md +74 -9
  2. package/dist/cli.js +2 -1
  3. package/package.json +1 -1
  4. package/plugins/ima-claude/.claude-plugin/plugin.json +2 -2
  5. package/plugins/ima-claude/agents/explorer.md +29 -15
  6. package/plugins/ima-claude/agents/implementer.md +58 -13
  7. package/plugins/ima-claude/agents/memory.md +19 -19
  8. package/plugins/ima-claude/agents/reviewer.md +84 -34
  9. package/plugins/ima-claude/agents/tester.md +59 -16
  10. package/plugins/ima-claude/agents/wp-developer.md +66 -21
  11. package/plugins/ima-claude/hooks/bootstrap.sh +42 -44
  12. package/plugins/ima-claude/hooks/prompt_coach_digest.md +14 -17
  13. package/plugins/ima-claude/hooks/prompt_coach_system.md +10 -12
  14. package/plugins/ima-claude/personalities/README.md +17 -6
  15. package/plugins/ima-claude/personalities/enable-efficient.md +61 -0
  16. package/plugins/ima-claude/personalities/enable-terse.md +71 -0
  17. package/plugins/ima-claude/skills/agentic-workflows/SKILL.md +35 -71
  18. package/plugins/ima-claude/skills/architect/SKILL.md +54 -168
  19. package/plugins/ima-claude/skills/compound-bridge/SKILL.md +41 -94
  20. package/plugins/ima-claude/skills/design-to-code/SKILL.md +43 -78
  21. package/plugins/ima-claude/skills/discourse/SKILL.md +79 -194
  22. package/plugins/ima-claude/skills/discourse-admin/SKILL.md +41 -103
  23. package/plugins/ima-claude/skills/docs-organize/SKILL.md +63 -203
  24. package/plugins/ima-claude/skills/ember-discourse/SKILL.md +90 -200
  25. package/plugins/ima-claude/skills/espocrm/SKILL.md +14 -23
  26. package/plugins/ima-claude/skills/espocrm-api/SKILL.md +79 -192
  27. package/plugins/ima-claude/skills/functional-programmer/SKILL.md +33 -237
  28. package/plugins/ima-claude/skills/gh-cli/SKILL.md +26 -65
  29. package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +71 -104
  30. package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +32 -22
  31. package/plugins/ima-claude/skills/ima-brand/SKILL.md +18 -23
  32. package/plugins/ima-claude/skills/ima-copywriting/SKILL.md +68 -179
  33. package/plugins/ima-claude/skills/ima-doc2pdf/SKILL.md +32 -102
  34. package/plugins/ima-claude/skills/ima-editorial-scorecard/SKILL.md +38 -63
  35. package/plugins/ima-claude/skills/ima-editorial-workflow/SKILL.md +69 -114
  36. package/plugins/ima-claude/skills/ima-email-creator/SKILL.md +16 -22
  37. package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +21 -37
  38. package/plugins/ima-claude/skills/ima-git/SKILL.md +81 -0
  39. package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +39 -120
  40. package/plugins/ima-claude/skills/jquery/SKILL.md +107 -233
  41. package/plugins/ima-claude/skills/js-fp/SKILL.md +75 -296
  42. package/plugins/ima-claude/skills/js-fp-api/SKILL.md +52 -162
  43. package/plugins/ima-claude/skills/js-fp-react/SKILL.md +47 -270
  44. package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +55 -209
  45. package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +59 -204
  46. package/plugins/ima-claude/skills/livecanvas/SKILL.md +19 -32
  47. package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +92 -162
  48. package/plugins/ima-claude/skills/mcp-context7/SKILL.md +32 -64
  49. package/plugins/ima-claude/skills/mcp-gitea/SKILL.md +98 -188
  50. package/plugins/ima-claude/skills/mcp-github/SKILL.md +60 -124
  51. package/plugins/ima-claude/skills/mcp-memory/SKILL.md +1 -177
  52. package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +58 -115
  53. package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +32 -87
  54. package/plugins/ima-claude/skills/mcp-serena/SKILL.md +54 -80
  55. package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +40 -63
  56. package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +75 -116
  57. package/plugins/ima-claude/skills/php-authnet/SKILL.md +32 -65
  58. package/plugins/ima-claude/skills/php-fp/SKILL.md +50 -129
  59. package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +25 -73
  60. package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +103 -463
  61. package/plugins/ima-claude/skills/playwright/SKILL.md +69 -220
  62. package/plugins/ima-claude/skills/prompt-starter/SKILL.md +33 -83
  63. package/plugins/ima-claude/skills/prompt-starter/references/code-review.md +38 -0
  64. package/plugins/ima-claude/skills/py-fp/SKILL.md +78 -384
  65. package/plugins/ima-claude/skills/quasar-fp/SKILL.md +54 -255
  66. package/plugins/ima-claude/skills/quickstart/SKILL.md +7 -11
  67. package/plugins/ima-claude/skills/rails/SKILL.md +63 -184
  68. package/plugins/ima-claude/skills/resume-session/SKILL.md +14 -35
  69. package/plugins/ima-claude/skills/rg/SKILL.md +61 -146
  70. package/plugins/ima-claude/skills/ruby-fp/SKILL.md +66 -163
  71. package/plugins/ima-claude/skills/save-session/SKILL.md +10 -39
  72. package/plugins/ima-claude/skills/scorecard/SKILL.md +42 -40
  73. package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +42 -71
  74. package/plugins/ima-claude/skills/skill-creator/SKILL.md +79 -250
  75. package/plugins/ima-claude/skills/task-master/SKILL.md +11 -31
  76. package/plugins/ima-claude/skills/task-planner/SKILL.md +44 -153
  77. package/plugins/ima-claude/skills/task-runner/SKILL.md +61 -143
  78. package/plugins/ima-claude/skills/unit-testing/SKILL.md +59 -134
  79. package/plugins/ima-claude/skills/wp-ddev/SKILL.md +38 -120
  80. package/plugins/ima-claude/skills/wp-local/SKILL.md +26 -108
@@ -12,111 +12,55 @@ description: >-
12
12
 
13
13
  # EspoCRM REST API (v9.x)
14
14
 
15
- Patterns for the EspoCRM REST API. External integrations, data pipelines, and automation.
16
-
17
- **Base URL**: `https://{your-site}/api/v1/`
18
- **Content-Type**: `application/json` (all requests)
19
- **Parent skill**: `espocrm` (router — Salesforce mapping, shared context)
20
- **Companion skills**: `php-fp` (PHP integrations), `js-fp-api` (Node integrations)
21
- **Live docs**: Context7 `/espocrm/documentation`
15
+ **Base URL**: `https://{your-site}/api/v1/` **Content-Type**: `application/json`
16
+ **Parent skill**: `espocrm` | **Companion skills**: `php-fp`, `js-fp-api` | **Live docs**: Context7 `/espocrm/documentation`
22
17
 
23
18
  ---
24
19
 
25
20
  ## Authentication
26
21
 
27
- Three methods, in order of recommendation:
28
-
29
- ### 1. API Key (Simple, Recommended for Dev/Internal)
30
-
31
- Create an API User at Administration > API Users. Authentication method: "API Key". Assign a Role for scope.
22
+ | Context | Method |
23
+ |---|---|
24
+ | Dev/testing, internal scripts | API Key |
25
+ | Production integrations | HMAC |
26
+ | Frontend SPA, session flows | Token auth |
27
+ | Never | Basic auth with plaintext password |
32
28
 
29
+ ### API Key
30
+ Create API User at Administration > API Users, auth method "API Key", assign Role.
33
31
  ```
34
32
  X-Api-Key: {key_from_api_user_detail_view}
35
33
  ```
36
34
 
37
- One header. Done. Use when transport is already secured (HTTPS, internal network).
38
-
39
- ### 2. HMAC (Production, Most Secure)
40
-
41
- Create an API User with "HMAC" auth. Both API Key and Secret Key are generated. Secret never leaves your server.
42
-
35
+ ### HMAC (Production)
36
+ Create API User with "HMAC" auth. Both API Key and Secret Key generated.
43
37
  ```
44
38
  X-Hmac-Authorization: base64(apiKey + ':' + hmacSha256(METHOD + ' /' + uri, secretKey))
45
39
  ```
46
-
47
- Where `METHOD` is uppercase (GET, POST, PUT, DELETE) and `uri` is the path after `/api/v1/`.
40
+ `METHOD` = uppercase verb; `uri` = path after `/api/v1/`.
48
41
 
49
42
  ```php
50
- // PHP
51
- $string = $method . ' /' . $uri;
52
- $hash = hash_hmac('sha256', $string, $secretKey);
43
+ $hash = hash_hmac('sha256', $method . ' /' . $uri, $secretKey);
53
44
  $header = base64_encode($apiKey . ':' . $hash);
54
- // X-Hmac-Authorization: $header
55
45
  ```
56
46
 
57
47
  ```javascript
58
- // Node.js
59
48
  import { createHmac } from 'node:crypto';
60
49
  const hash = createHmac('sha256', secretKey).update(`${method} /${uri}`).digest('hex');
61
50
  const header = Buffer.from(`${apiKey}:${hash}`).toString('base64');
62
- // X-Hmac-Authorization: header
63
51
  ```
64
52
 
65
- ### 3. Basic / Token Auth (Session-Based Only)
66
-
53
+ ### Token Auth (Session only)
67
54
  ```
68
55
  Espo-Authorization: base64(username + ':' + token)
69
56
  ```
70
-
71
- Obtain token via `GET App/user` with initial credentials. Only for session flows (SPA, frontend). Never for server-to-server.
72
-
73
- ### Auth Decision
74
-
75
- | Context | Method |
76
- |---|---|
77
- | Dev/testing, internal scripts | API Key |
78
- | Production integrations | HMAC |
79
- | Frontend SPA, session flows | Token auth |
80
- | Never | Basic auth with plaintext password |
57
+ Obtain token via `GET App/user`. Never use for server-to-server.
81
58
 
82
59
  ---
83
60
 
84
61
  ## CRUD Operations
85
62
 
86
- All entity types share the same endpoint pattern. Replace `{Entity}` with the type name (Account, Contact, Lead, CMyCustomEntity, etc.).
87
-
88
- ### List Records
89
- ```
90
- GET {Entity}
91
- ```
92
- Returns `{"list": [...], "total": N}`. Total is `-1` if more records exist (pagination needed), `-2` if count disabled.
93
-
94
- ### Read One Record
95
- ```
96
- GET {Entity}/{id}
97
- ```
98
-
99
- ### Create
100
- ```
101
- POST {Entity}
102
- {"name": "Acme Corp", "assignedUserId": "someUserId"}
103
- ```
104
- Returns the created record with generated `id`. Use `X-Skip-Duplicate-Check: true` to bypass duplicate detection.
105
-
106
- ### Update (Partial)
107
- ```
108
- PUT {Entity}/{id}
109
- {"status": "Closed Won"}
110
- ```
111
- Only send changed fields. Returns full updated record.
112
-
113
- ### Delete
114
- ```
115
- DELETE {Entity}/{id}
116
- ```
117
- Returns `true`.
118
-
119
- ### Endpoint Summary
63
+ Replace `{Entity}` with type name (Account, Contact, Lead, custom, etc.).
120
64
 
121
65
  | Operation | Method | Path |
122
66
  |---|---|---|
@@ -137,71 +81,61 @@ Returns `true`.
137
81
  | Attachment down | GET | `Attachment/file/{id}` |
138
82
  | OpenAPI spec | GET | `OpenApi` |
139
83
 
84
+ - List returns `{"list": [...], "total": N}`. Total `-1` = more exist (paginate), `-2` = count disabled.
85
+ - Create: add `X-Skip-Duplicate-Check: true` to bypass dupe detection.
86
+ - Update: send only changed fields. Returns full record.
87
+ - Delete: returns `true`.
88
+
140
89
  ---
141
90
 
142
91
  ## Filtering & Search
143
92
 
144
- Parameters go as query params or as a single JSON-encoded `searchParams` param.
145
-
146
- ### Core Parameters
93
+ Params as query params or JSON-encoded `searchParams` param.
147
94
 
148
95
  | Param | Type | Purpose |
149
96
  |---|---|---|
150
97
  | `select` | string | Comma-separated fields: `id,name,status` |
151
- | `maxSize` | int | Records per page (max 200, default varies) |
98
+ | `maxSize` | int | Records per page (max 200) |
152
99
  | `offset` | int | Pagination offset |
153
100
  | `orderBy` | string | Sort field |
154
101
  | `order` | string | `asc` or `desc` |
155
- | `where` | array | Filter conditions (see below) |
102
+ | `where` | array | Filter conditions |
156
103
  | `primaryFilter` | string | Named server-side filter (`open`, `onlyMy`, etc.) |
157
- | `boolFilterList` | array | Boolean toggles: `["onlyMy", "followed"]` |
104
+ | `boolFilterList` | array | `["onlyMy", "followed"]` |
158
105
 
159
106
  v9.0+ aliases (WAF-safe): `attributeSelect` for `select`, `whereGroup` for `where`.
160
107
 
161
108
  ### WHERE Operators
162
109
 
163
- Each filter is `{"type": "...", "attribute": "...", "value": "..."}`. Multiple items in the `where` array are implicitly ANDed. Use `{"type": "or", "value": [...]}` for OR logic.
110
+ Each filter: `{"type": "...", "attribute": "...", "value": "..."}`. Multiple items ANDed. Use `{"type": "or", "value": [...]}` for OR.
164
111
 
165
- **Operator categories**: equality (`equals`, `notEquals`), comparison (`greaterThan`, `lessThan`, `greaterThanOrEquals`, `lessThanOrEquals`), null (`isNull`, `isNotNull`), boolean (`isTrue`, `isFalse`), string (`contains`, `notContains`, `startsWith`, `endsWith`, `like`, `notLike`), set (`in`, `notIn`), relationship (`linkedWith`, `notLinkedWith`, `isLinked`, `isNotLinked`), date helpers (`today`, `past`, `future`, `lastSevenDays`, `currentMonth`, `lastMonth`, `currentYear`, `between`, `lastXDays`, `nextXDays`), logical (`or`, `and`).
112
+ - **Equality**: `equals`, `notEquals`
113
+ - **Comparison**: `greaterThan`, `lessThan`, `greaterThanOrEquals`, `lessThanOrEquals`
114
+ - **Null**: `isNull`, `isNotNull`
115
+ - **Boolean**: `isTrue`, `isFalse`
116
+ - **String**: `contains`, `notContains`, `startsWith`, `endsWith`, `like`, `notLike`
117
+ - **Set**: `in`, `notIn`
118
+ - **Relationship**: `linkedWith`, `notLinkedWith`, `isLinked`, `isNotLinked`
119
+ - **Date**: `today`, `past`, `future`, `lastSevenDays`, `currentMonth`, `lastMonth`, `currentYear`, `between`, `lastXDays`, `nextXDays`
120
+ - **Logical**: `or`, `and`
166
121
 
167
- Full operator reference with examples: `references/where-operators.md`
122
+ Full reference with examples: `references/where-operators.md`
168
123
 
169
124
  ---
170
125
 
171
126
  ## Relationships
172
127
 
173
- Link names are visible at Administration > Entity Manager > {Entity} > Relationships (4th column).
128
+ Link names visible at Administration > Entity Manager > {Entity} > Relationships (4th column).
174
129
 
175
- ### List Related Records
176
130
  ```
177
131
  GET Account/{id}/contacts?select=id,name,emailAddress&maxSize=50
178
- ```
179
- Same search params as list endpoint.
180
-
181
- ### Link Records
182
- ```
183
- POST Account/{id}/contacts
184
- {"id": "contactId"}
185
- ```
186
-
187
- Multiple at once:
188
- ```json
189
- {"ids": ["id1", "id2", "id3"]}
190
- ```
191
-
192
- Mass relate by filter:
193
- ```json
194
- {"massRelate": true, "where": [{"type": "equals", "attribute": "status", "value": "Active"}]}
132
+ POST Account/{id}/contacts {"id": "contactId"}
133
+ POST Account/{id}/contacts {"ids": ["id1", "id2"]}
134
+ POST Account/{id}/contacts {"massRelate": true, "where": [...]}
135
+ DELETE Account/{id}/contacts {"id": "contactId"}
136
+ DELETE Account/{id}/contacts {"ids": ["id1", "id2"]}
195
137
  ```
196
138
 
197
- ### Unlink Records
198
- ```
199
- DELETE Account/{id}/contacts
200
- {"id": "contactId"}
201
- ```
202
-
203
- Multiple: `{"ids": ["id1", "id2"]}`.
204
-
205
139
  ---
206
140
 
207
141
  ## Webhooks
@@ -211,139 +145,93 @@ Multiple: `{"ids": ["id1", "id2"]}`.
211
145
  POST Webhook
212
146
  {"event": "Contact.create", "url": "https://your-server.com/hook"}
213
147
  ```
214
- Returns `{"id": "webhookId", "secretKey": "generatedKey"}`. Save both for signature verification.
148
+ Returns `{"id": "webhookId", "secretKey": "generatedKey"}`. Save both.
215
149
 
216
150
  ### Event Types
217
- - `{Entity}.create` — record created (all attributes in payload)
218
- - `{Entity}.update` — record updated (only changed attributes)
219
- - `{Entity}.delete` — record removed (ID only)
151
+ - `{Entity}.create` — all attributes in payload
152
+ - `{Entity}.update` — only changed attributes
153
+ - `{Entity}.delete` — ID only
220
154
  - `{Entity}.fieldUpdate.{field}` — specific field changed
221
155
 
222
- ### Payload Format
223
- Always an array (even for single events):
224
- ```json
225
- [{"id": "abc123", "name": "Updated Name", "status": "Active"}]
226
- ```
156
+ Payload is always an array: `[{"id": "abc123", ...}]`
227
157
 
228
158
  ### Signature Verification
229
- The `Signature` header contains: `base64(webhookId + ':' + hmacSha256(rawBody, secretKey))`.
230
-
159
+ `Signature` header = `base64(webhookId + ':' + hmacSha256(rawBody, secretKey))`.
231
160
  ```php
232
161
  $expected = base64_encode($webhookId . ':' . hash_hmac('sha256', $rawBody, $secretKey));
233
162
  $valid = hash_equals($expected, $_SERVER['HTTP_SIGNATURE']);
234
163
  ```
235
164
 
236
165
  ### Lifecycle
237
- - Processed by scheduled job "Process Webhook Queue" (default: every 5 min)
238
- - Failed deliveries are retried automatically
239
- - Persistent failures deactivate the webhook
240
- - Config: `webhookAllowedAddressList` in `data/config.php` for internal URLs
241
-
242
- ### Delete
243
- ```
244
- DELETE Webhook/{id}
245
- ```
166
+ Processed by "Process Webhook Queue" scheduled job (default 5 min). Failed deliveries retried; persistent failures deactivate webhook. Add internal URLs to `webhookAllowedAddressList` in `data/config.php`.
246
167
 
247
168
  ---
248
169
 
249
170
  ## Mass Operations
250
171
 
251
- ### Mass Update
172
+ ### Mass Update / Delete
252
173
  ```
253
174
  POST Lead/action/massUpdate
254
- ```
255
-
256
- By IDs:
257
- ```json
258
- {"ids": ["id1", "id2"], "data": {"assignedUserId": "userId", "status": "In Process"}}
259
- ```
260
-
261
- By filter:
262
- ```json
263
- {"where": [{"type": "equals", "attribute": "status", "value": "New"}], "data": {"status": "Assigned"}}
264
- ```
265
-
266
- ### Mass Delete
267
- ```
268
175
  POST Lead/action/massDelete
269
176
  ```
270
- Same payload patterns — `ids` array or `where` filter.
177
+ By IDs: `{"ids": ["id1", "id2"], "data": {"status": "Assigned"}}`
178
+ By filter: `{"where": [...], "data": {"status": "Assigned"}}`
271
179
 
272
- ### No Bulk Create
273
- There is no native batch create endpoint. For bulk ingestion:
274
- 1. Loop individual POST requests with reasonable pacing
275
- 2. Use the built-in Import feature (Administration > Import) for CSV
276
- 3. Write a custom API action for batch processing if volume demands it
180
+ No native batch create — loop individual POSTs, use Administration > Import for CSV, or write custom API action for high volume.
277
181
 
278
- ### Important
279
- API Before-Save Scripts (Formula) are **not executed** during mass update operations.
182
+ **Note**: API Before-Save Scripts (Formula) are NOT executed during mass update.
280
183
 
281
184
  ---
282
185
 
283
186
  ## Error Handling
284
187
 
285
- ### Status Codes
286
-
287
188
  | Code | Meaning | Action |
288
189
  |---|---|---|
289
190
  | 200 | Success | — |
290
191
  | 400 | Bad Request | Check required fields, validation |
291
192
  | 401 | Unauthorized | Check auth headers/credentials |
292
193
  | 403 | Forbidden | Check API User role/ACL |
293
- | 404 | Not Found | Record doesn't exist or no read access |
294
- | 409 | Conflict | Duplicate detected or record locked |
194
+ | 404 | Not Found | Record missing or no read access |
195
+ | 409 | Conflict | Duplicate or record locked |
295
196
  | 500 | Server Error | Check `data/log` on server |
296
197
 
297
- ### Error Details
298
- Error reason is in the `X-Status-Reason` response header (not always in the body).
299
-
300
- ### Duplicate Detection (409)
301
- ```json
302
- {"reason": "Duplicate", "data": {"idList": ["existingId1"]}}
303
- ```
304
- Bypass with `X-Skip-Duplicate-Check: true` header.
198
+ Error reason in `X-Status-Reason` response header. Duplicate 409 body: `{"reason": "Duplicate", "data": {"idList": ["existingId1"]}}`. Bypass with `X-Skip-Duplicate-Check: true`.
305
199
 
306
200
  ---
307
201
 
308
- ## Performance Best Practices
202
+ ## Performance
309
203
 
310
- 1. **Select only needed fields** — `?select=id,name,status` avoids loading all attributes
311
- 2. **Skip total count** — `X-No-Total: true` header skips the COUNT query on list requests
312
- 3. **Paginate** use `offset` + `maxSize` (keep maxSize at 50-100)
313
- 4. **Use primary filters** — server-optimized named filters are faster than complex WHERE
314
- 5. **Minimal API User roles** — dedicated API users with only required scopes
315
- 6. **No native rate limiter** — implement at reverse proxy level (nginx, Apache) if needed
316
- 7. **OpenAPI spec** — `GET OpenApi` returns full schema for your instance including custom entities (v9.3+, admin only)
204
+ 1. `?select=id,name,status` load only needed fields
205
+ 2. `X-No-Total: true` header skip COUNT query on lists
206
+ 3. Paginate with `offset` + `maxSize` (keep at 50100)
207
+ 4. Use `primaryFilter` — server-optimized, faster than complex WHERE
208
+ 5. Dedicated API users with minimal scopes only
209
+ 6. No native rate limiter — implement at reverse proxy (nginx/Apache)
210
+ 7. `GET OpenApi` full schema for your instance incl. custom entities (v9.3+, admin)
317
211
 
318
212
  ---
319
213
 
320
214
  ## Client Libraries
321
215
 
322
- ### PHP (Official — Preferred)
323
-
324
- `composer require espocrm/php-espo-api-client`
325
-
326
- Class: `Espo\ApiClient\Client`. Constructor takes base URL. Auth via `setApiKey()` or `setApiKey()` + `setSecretKey()` for HMAC. All requests through `$client->request(METHOD, path, params, payload)`.
216
+ ### PHP (Official)
217
+ ```
218
+ composer require espocrm/php-espo-api-client
219
+ ```
220
+ `Espo\ApiClient\Client` constructor takes base URL. Auth via `setApiKey()` / `setApiKey()` + `setSecretKey()` for HMAC. All requests: `$client->request(METHOD, path, params, payload)`.
327
221
 
328
222
  ### Node.js
329
-
330
- No official npm package. Build a thin client around `fetch` with:
331
- - Base URL + `/api/v1/` prefix
332
- - `X-Api-Key` header (or compute HMAC per-request)
333
- - `Content-Type: application/json`
334
- - Search params as JSON-encoded `searchParams` query param
335
- - Error extraction from `X-Status-Reason` header on non-2xx responses
223
+ No official npm package. Build thin client around `fetch`:
224
+ - Base URL + `/api/v1/` prefix, `X-Api-Key` or per-request HMAC, `Content-Type: application/json`
225
+ - JSON-encode `searchParams` as query param; extract errors from `X-Status-Reason` header
336
226
 
337
227
  ---
338
228
 
339
- ## Field Types & API Representation
229
+ ## Field Types
340
230
 
341
231
  | Field Type | JSON Type | Example |
342
232
  |---|---|---|
343
- | varchar | string | `"name": "Test"` |
344
- | text | string | `"description": "Long text"` |
345
- | int | number | `"quantity": 5` |
346
- | float | number | `"rate": 4.5` |
233
+ | varchar, text | string | `"name": "Test"` |
234
+ | int, float | number | `"quantity": 5`, `"rate": 4.5` |
347
235
  | boolean | boolean | `"isActive": true` |
348
236
  | enum | string | `"status": "New"` |
349
237
  | multiEnum | string[] | `"tags": ["A", "B"]` |
@@ -352,9 +240,8 @@ No official npm package. Build a thin client around `fetch` with:
352
240
  | currency | number + string | `"amount": 1000, "amountCurrency": "USD"` |
353
241
  | link | string (ID) | `"accountId": "someId"` |
354
242
  | linkMultiple | string[] + object | `"teamsIds": ["id1"], "teamsNames": {"id1": "Sales"}` |
355
- | email | string | `"emailAddress": "test@example.com"` |
356
- | phone | string | `"phoneNumber": "+1234567890"` |
243
+ | email, phone | string | `"emailAddress": "test@example.com"` |
357
244
  | address | multiple fields | `"billingAddressStreet": "123 Main", "billingAddressCity": "NYC"` |
358
245
  | file | string (ID) | `"fileId": "attachmentId"` |
359
246
 
360
- All datetime values are UTC. Date format: `YYYY-MM-DD`. Datetime: `YYYY-MM-DD HH:mm:ss`.
247
+ All datetimes UTC. Date: `YYYY-MM-DD`. Datetime: `YYYY-MM-DD HH:mm:ss`.