ima-claude 2.20.0 → 2.25.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.
- package/README.md +48 -9
- package/dist/cli.js +1 -1
- package/package.json +1 -1
- package/plugins/ima-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/ima-claude/agents/explorer.md +29 -15
- package/plugins/ima-claude/agents/implementer.md +58 -13
- package/plugins/ima-claude/agents/memory.md +19 -19
- package/plugins/ima-claude/agents/reviewer.md +56 -34
- package/plugins/ima-claude/agents/tester.md +59 -16
- package/plugins/ima-claude/agents/wp-developer.md +66 -21
- package/plugins/ima-claude/hooks/bootstrap.sh +42 -44
- package/plugins/ima-claude/hooks/prompt_coach_digest.md +14 -17
- package/plugins/ima-claude/hooks/prompt_coach_system.md +10 -12
- package/plugins/ima-claude/personalities/README.md +17 -6
- package/plugins/ima-claude/personalities/enable-efficient.md +61 -0
- package/plugins/ima-claude/personalities/enable-terse.md +71 -0
- package/plugins/ima-claude/skills/agentic-workflows/SKILL.md +35 -71
- package/plugins/ima-claude/skills/architect/SKILL.md +54 -168
- package/plugins/ima-claude/skills/compound-bridge/SKILL.md +41 -94
- package/plugins/ima-claude/skills/design-to-code/SKILL.md +43 -78
- package/plugins/ima-claude/skills/discourse/SKILL.md +79 -194
- package/plugins/ima-claude/skills/discourse-admin/SKILL.md +41 -103
- package/plugins/ima-claude/skills/docs-organize/SKILL.md +63 -203
- package/plugins/ima-claude/skills/ember-discourse/SKILL.md +90 -200
- package/plugins/ima-claude/skills/espocrm/SKILL.md +14 -23
- package/plugins/ima-claude/skills/espocrm-api/SKILL.md +79 -192
- package/plugins/ima-claude/skills/functional-programmer/SKILL.md +33 -237
- package/plugins/ima-claude/skills/gh-cli/SKILL.md +26 -65
- package/plugins/ima-claude/skills/ima-bootstrap/SKILL.md +71 -104
- package/plugins/ima-claude/skills/ima-bootstrap/references/ima-brand.md +32 -22
- package/plugins/ima-claude/skills/ima-brand/SKILL.md +18 -23
- package/plugins/ima-claude/skills/ima-copywriting/SKILL.md +68 -179
- package/plugins/ima-claude/skills/ima-doc2pdf/SKILL.md +32 -102
- package/plugins/ima-claude/skills/ima-editorial-scorecard/SKILL.md +38 -63
- package/plugins/ima-claude/skills/ima-editorial-workflow/SKILL.md +69 -114
- package/plugins/ima-claude/skills/ima-email-creator/SKILL.md +16 -22
- package/plugins/ima-claude/skills/ima-forms-expert/SKILL.md +21 -37
- package/plugins/ima-claude/skills/jira-checkpoint/SKILL.md +39 -120
- package/plugins/ima-claude/skills/jquery/SKILL.md +107 -233
- package/plugins/ima-claude/skills/js-fp/SKILL.md +75 -296
- package/plugins/ima-claude/skills/js-fp-api/SKILL.md +52 -162
- package/plugins/ima-claude/skills/js-fp-react/SKILL.md +47 -270
- package/plugins/ima-claude/skills/js-fp-vue/SKILL.md +55 -209
- package/plugins/ima-claude/skills/js-fp-wordpress/SKILL.md +59 -204
- package/plugins/ima-claude/skills/livecanvas/SKILL.md +19 -32
- package/plugins/ima-claude/skills/mcp-atlassian/SKILL.md +92 -162
- package/plugins/ima-claude/skills/mcp-context7/SKILL.md +32 -64
- package/plugins/ima-claude/skills/mcp-gitea/SKILL.md +98 -188
- package/plugins/ima-claude/skills/mcp-github/SKILL.md +60 -124
- package/plugins/ima-claude/skills/mcp-memory/SKILL.md +1 -177
- package/plugins/ima-claude/skills/mcp-qdrant/SKILL.md +58 -115
- package/plugins/ima-claude/skills/mcp-sequential/SKILL.md +32 -87
- package/plugins/ima-claude/skills/mcp-serena/SKILL.md +54 -80
- package/plugins/ima-claude/skills/mcp-tavily/SKILL.md +40 -63
- package/plugins/ima-claude/skills/mcp-vestige/SKILL.md +75 -116
- package/plugins/ima-claude/skills/php-authnet/SKILL.md +32 -65
- package/plugins/ima-claude/skills/php-fp/SKILL.md +50 -129
- package/plugins/ima-claude/skills/php-fp-wordpress/SKILL.md +25 -73
- package/plugins/ima-claude/skills/phpunit-wp/SKILL.md +103 -463
- package/plugins/ima-claude/skills/playwright/SKILL.md +69 -220
- package/plugins/ima-claude/skills/prompt-starter/SKILL.md +33 -83
- package/plugins/ima-claude/skills/prompt-starter/references/code-review.md +38 -0
- package/plugins/ima-claude/skills/py-fp/SKILL.md +78 -384
- package/plugins/ima-claude/skills/quasar-fp/SKILL.md +54 -255
- package/plugins/ima-claude/skills/quickstart/SKILL.md +7 -11
- package/plugins/ima-claude/skills/rails/SKILL.md +63 -184
- package/plugins/ima-claude/skills/resume-session/SKILL.md +14 -35
- package/plugins/ima-claude/skills/rg/SKILL.md +61 -146
- package/plugins/ima-claude/skills/ruby-fp/SKILL.md +66 -163
- package/plugins/ima-claude/skills/save-session/SKILL.md +10 -39
- package/plugins/ima-claude/skills/scorecard/SKILL.md +24 -38
- package/plugins/ima-claude/skills/skill-analyzer/SKILL.md +42 -71
- package/plugins/ima-claude/skills/skill-creator/SKILL.md +79 -250
- package/plugins/ima-claude/skills/task-master/SKILL.md +11 -31
- package/plugins/ima-claude/skills/task-planner/SKILL.md +44 -153
- package/plugins/ima-claude/skills/task-runner/SKILL.md +61 -143
- package/plugins/ima-claude/skills/unit-testing/SKILL.md +59 -134
- package/plugins/ima-claude/skills/wp-ddev/SKILL.md +38 -120
- 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
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
102
|
+
| `where` | array | Filter conditions |
|
|
156
103
|
| `primaryFilter` | string | Named server-side filter (`open`, `onlyMy`, etc.) |
|
|
157
|
-
| `boolFilterList` | array |
|
|
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
|
|
110
|
+
Each filter: `{"type": "...", "attribute": "...", "value": "..."}`. Multiple items ANDed. Use `{"type": "or", "value": [...]}` for OR.
|
|
164
111
|
|
|
165
|
-
**
|
|
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
|
|
122
|
+
Full reference with examples: `references/where-operators.md`
|
|
168
123
|
|
|
169
124
|
---
|
|
170
125
|
|
|
171
126
|
## Relationships
|
|
172
127
|
|
|
173
|
-
Link names
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
|
148
|
+
Returns `{"id": "webhookId", "secretKey": "generatedKey"}`. Save both.
|
|
215
149
|
|
|
216
150
|
### Event Types
|
|
217
|
-
- `{Entity}.create` —
|
|
218
|
-
- `{Entity}.update` —
|
|
219
|
-
- `{Entity}.delete` —
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
177
|
+
By IDs: `{"ids": ["id1", "id2"], "data": {"status": "Assigned"}}`
|
|
178
|
+
By filter: `{"where": [...], "data": {"status": "Assigned"}}`
|
|
271
179
|
|
|
272
|
-
|
|
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
|
-
|
|
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
|
|
294
|
-
| 409 | Conflict | Duplicate
|
|
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
|
-
|
|
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
|
|
202
|
+
## Performance
|
|
309
203
|
|
|
310
|
-
1.
|
|
311
|
-
2.
|
|
312
|
-
3.
|
|
313
|
-
4.
|
|
314
|
-
5.
|
|
315
|
-
6.
|
|
316
|
-
7.
|
|
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 50–100)
|
|
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
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
331
|
-
-
|
|
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
|
|
229
|
+
## Field Types
|
|
340
230
|
|
|
341
231
|
| Field Type | JSON Type | Example |
|
|
342
232
|
|---|---|---|
|
|
343
|
-
| varchar | string | `"name": "Test"` |
|
|
344
|
-
|
|
|
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
|
|
247
|
+
All datetimes UTC. Date: `YYYY-MM-DD`. Datetime: `YYYY-MM-DD HH:mm:ss`.
|