extractia-sdk 1.1.0 → 1.2.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 +257 -58
- package/dist/extractia-sdk.browser.js +29 -9
- package/dist/extractia-sdk.browser.js.map +2 -2
- package/dist/extractia-sdk.cjs.js +66 -10
- package/dist/extractia-sdk.cjs.js.map +3 -3
- package/dist/extractia-sdk.esm.js +66 -10
- package/dist/extractia-sdk.esm.js.map +3 -3
- package/dist/index.d.ts +167 -3
- package/package.json +2 -1
- package/src/analytics.js +19 -0
- package/src/apiClient.js +46 -46
- package/src/browser-entry.js +5 -5
- package/src/documents.js +14 -6
- package/src/index.d.ts +167 -3
- package/src/index.js +3 -0
- package/src/ocrTools.js +26 -7
- package/src/subusers.js +85 -0
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ Works in Node.js ≥ 18 and modern browsers via the provided UMD build.
|
|
|
23
23
|
- [Exports](#exports)
|
|
24
24
|
- [OCR Tools](#ocr-tools)
|
|
25
25
|
- [Credits & Analytics](#credits--analytics)
|
|
26
|
+
- [Sub-Users](#sub-users)
|
|
26
27
|
6. [TypeScript](#typescript)
|
|
27
28
|
7. [Rate Limits & Quotas](#rate-limits--quotas)
|
|
28
29
|
8. [Changelog](#changelog)
|
|
@@ -56,13 +57,21 @@ pnpm add extractia-sdk
|
|
|
56
57
|
## Quick Start
|
|
57
58
|
|
|
58
59
|
```js
|
|
59
|
-
import {
|
|
60
|
+
import {
|
|
61
|
+
setToken,
|
|
62
|
+
suggestFields,
|
|
63
|
+
createTemplate,
|
|
64
|
+
processImage,
|
|
65
|
+
} from "extractia-sdk";
|
|
60
66
|
|
|
61
67
|
// 1. Authenticate
|
|
62
68
|
setToken("ext_YOUR_API_TOKEN_HERE");
|
|
63
69
|
|
|
64
70
|
// 2. Let AI suggest fields for your document type
|
|
65
|
-
const fields = await suggestFields(
|
|
71
|
+
const fields = await suggestFields(
|
|
72
|
+
"Invoice",
|
|
73
|
+
"header data plus all line items with product and quantity",
|
|
74
|
+
);
|
|
66
75
|
|
|
67
76
|
// 3. Create a template from the suggestions
|
|
68
77
|
const template = await createTemplate({ label: "Invoice", fields });
|
|
@@ -175,9 +184,9 @@ Returns the profile and usage metrics of the authenticated user.
|
|
|
175
184
|
|
|
176
185
|
```js
|
|
177
186
|
const profile = await getMyProfile();
|
|
178
|
-
console.log(profile.email);
|
|
187
|
+
console.log(profile.email); // 'user@example.com'
|
|
179
188
|
console.log(profile.formTemplatesCount); // 5
|
|
180
|
-
console.log(profile.documentsCount);
|
|
189
|
+
console.log(profile.documentsCount); // 42
|
|
181
190
|
```
|
|
182
191
|
|
|
183
192
|
---
|
|
@@ -187,8 +196,8 @@ console.log(profile.documentsCount); // 42
|
|
|
187
196
|
Updates the webhook URL. After each successful extraction, Extractia
|
|
188
197
|
sends a `POST` to this URL with the document payload.
|
|
189
198
|
|
|
190
|
-
| Parameter | Type | Required | Description
|
|
191
|
-
| --------- | -------- | -------- |
|
|
199
|
+
| Parameter | Type | Required | Description |
|
|
200
|
+
| --------- | -------- | -------- | ---------------------------------------------- |
|
|
192
201
|
| `url` | `string` | ✅ | Webhook URL (pass empty string `""` to remove) |
|
|
193
202
|
|
|
194
203
|
**Returns:** `Promise<void>`
|
|
@@ -257,10 +266,10 @@ Results can be passed directly to `createTemplate`.
|
|
|
257
266
|
|
|
258
267
|
**Consumes AI credits.**
|
|
259
268
|
|
|
260
|
-
| Parameter | Type | Required | Description
|
|
261
|
-
| ------------------- | -------- | -------- |
|
|
262
|
-
| `templateName` | `string` | ✅ | Document type name (e.g. `"Invoice"`, `"Driver's License"`)
|
|
263
|
-
| `extractionContext` | `string` | — | Natural-language hint about what to extract or detect
|
|
269
|
+
| Parameter | Type | Required | Description |
|
|
270
|
+
| ------------------- | -------- | -------- | ----------------------------------------------------------- |
|
|
271
|
+
| `templateName` | `string` | ✅ | Document type name (e.g. `"Invoice"`, `"Driver's License"`) |
|
|
272
|
+
| `extractionContext` | `string` | — | Natural-language hint about what to extract or detect |
|
|
264
273
|
|
|
265
274
|
```js
|
|
266
275
|
// Basic usage
|
|
@@ -269,18 +278,24 @@ const fields = await suggestFields("Receipt");
|
|
|
269
278
|
// With context — AI will only return what you describe
|
|
270
279
|
const fields = await suggestFields(
|
|
271
280
|
"Purchase Order",
|
|
272
|
-
"I need the supplier name, PO number, and all ordered products with quantity and unit price"
|
|
281
|
+
"I need the supplier name, PO number, and all ordered products with quantity and unit price",
|
|
273
282
|
);
|
|
274
283
|
|
|
275
284
|
const template = await createTemplate({ label: "Purchase Order", fields });
|
|
276
285
|
```
|
|
277
286
|
|
|
278
287
|
The returned array follows the `FormField` shape:
|
|
288
|
+
|
|
279
289
|
```json
|
|
280
290
|
[
|
|
281
|
-
{ "label": "PO Number",
|
|
282
|
-
{ "label": "Supplier",
|
|
283
|
-
{
|
|
291
|
+
{ "label": "PO Number", "type": "TEXT", "required": true },
|
|
292
|
+
{ "label": "Supplier", "type": "TEXT", "required": true },
|
|
293
|
+
{
|
|
294
|
+
"label": "Order Items",
|
|
295
|
+
"type": "LIST",
|
|
296
|
+
"required": false,
|
|
297
|
+
"listLabel": "Product"
|
|
298
|
+
}
|
|
284
299
|
]
|
|
285
300
|
```
|
|
286
301
|
|
|
@@ -294,11 +309,16 @@ Creates a new template.
|
|
|
294
309
|
const template = await createTemplate({
|
|
295
310
|
label: "Purchase Order",
|
|
296
311
|
fields: [
|
|
297
|
-
{ label: "PO Number",
|
|
298
|
-
{ label: "Vendor",
|
|
312
|
+
{ label: "PO Number", type: "TEXT", required: true },
|
|
313
|
+
{ label: "Vendor", type: "TEXT", required: true },
|
|
299
314
|
{ label: "Total Amount", type: "CURRENCY", required: true },
|
|
300
|
-
{ label: "Order Date",
|
|
301
|
-
{
|
|
315
|
+
{ label: "Order Date", type: "DATE", required: false },
|
|
316
|
+
{
|
|
317
|
+
label: "Line Items",
|
|
318
|
+
type: "LIST",
|
|
319
|
+
required: false,
|
|
320
|
+
listLabel: "Product",
|
|
321
|
+
},
|
|
302
322
|
],
|
|
303
323
|
});
|
|
304
324
|
console.log(template.id); // 'tpl_newid'
|
|
@@ -313,9 +333,9 @@ Updates an existing template's label and/or fields.
|
|
|
313
333
|
```js
|
|
314
334
|
const updated = await updateTemplate("tpl_abc123", {
|
|
315
335
|
fields: [
|
|
316
|
-
{ label: "Vendor",
|
|
317
|
-
{ label: "Total",
|
|
318
|
-
{ label: "Due Date",
|
|
336
|
+
{ label: "Vendor", type: "TEXT", required: true },
|
|
337
|
+
{ label: "Total", type: "CURRENCY", required: true },
|
|
338
|
+
{ label: "Due Date", type: "DATE", required: false },
|
|
319
339
|
],
|
|
320
340
|
});
|
|
321
341
|
```
|
|
@@ -359,7 +379,7 @@ Returns a paginated list of documents for a given template (newest first by defa
|
|
|
359
379
|
|
|
360
380
|
```js
|
|
361
381
|
const page = await getDocumentsByTemplateId("tpl_abc123", {
|
|
362
|
-
preconformed: false,
|
|
382
|
+
preconformed: false, // only unreviewed
|
|
363
383
|
index: 0,
|
|
364
384
|
});
|
|
365
385
|
|
|
@@ -376,12 +396,14 @@ for (const doc of page.content) {
|
|
|
376
396
|
|
|
377
397
|
Returns a single document by template and document ID.
|
|
378
398
|
|
|
379
|
-
| Option | Type | Default | Description
|
|
380
|
-
| -------------- | --------- | ------- |
|
|
381
|
-
| `includeImage` | `boolean` | `false` | Include the base64 source image
|
|
399
|
+
| Option | Type | Default | Description |
|
|
400
|
+
| -------------- | --------- | ------- | ------------------------------- |
|
|
401
|
+
| `includeImage` | `boolean` | `false` | Include the base64 source image |
|
|
382
402
|
|
|
383
403
|
```js
|
|
384
|
-
const doc = await getDocumentById("tpl_abc123", "doc_xyz789", {
|
|
404
|
+
const doc = await getDocumentById("tpl_abc123", "doc_xyz789", {
|
|
405
|
+
includeImage: true,
|
|
406
|
+
});
|
|
385
407
|
console.log(doc.imageBase64); // the original scan
|
|
386
408
|
```
|
|
387
409
|
|
|
@@ -393,7 +415,7 @@ Returns the N most-recent documents across **all templates**. Useful for dashboa
|
|
|
393
415
|
|
|
394
416
|
```js
|
|
395
417
|
const recent = await getRecentDocuments(5);
|
|
396
|
-
recent.forEach(doc => console.log(doc.createdAt, doc.formTemplateId));
|
|
418
|
+
recent.forEach((doc) => console.log(doc.createdAt, doc.formTemplateId));
|
|
397
419
|
```
|
|
398
420
|
|
|
399
421
|
---
|
|
@@ -424,7 +446,10 @@ await updateDocumentStatus("doc_xyz789", "APPROVED");
|
|
|
424
446
|
Saves reviewer annotations on a document. Pass `""` to clear.
|
|
425
447
|
|
|
426
448
|
```js
|
|
427
|
-
await updateDocumentNotes(
|
|
449
|
+
await updateDocumentNotes(
|
|
450
|
+
"doc_xyz789",
|
|
451
|
+
"Verified against original: amounts match.",
|
|
452
|
+
);
|
|
428
453
|
await updateDocumentNotes("doc_xyz789", ""); // clear notes
|
|
429
454
|
```
|
|
430
455
|
|
|
@@ -435,16 +460,16 @@ await updateDocumentNotes("doc_xyz789", ""); // clear notes
|
|
|
435
460
|
Corrects or overwrites the extracted field data programmatically. Optionally
|
|
436
461
|
marks the document as preconformed (reviewed) in the same call.
|
|
437
462
|
|
|
438
|
-
| Option
|
|
439
|
-
|
|
|
440
|
-
| `preconformed`
|
|
463
|
+
| Option | Type | Default | Description |
|
|
464
|
+
| -------------- | --------- | ------- | ----------------------------------- |
|
|
465
|
+
| `preconformed` | `boolean` | `false` | Mark document as reviewed/confirmed |
|
|
441
466
|
|
|
442
467
|
```js
|
|
443
468
|
// Fix a wrong extraction and confirm
|
|
444
469
|
await updateDocumentData(
|
|
445
470
|
"doc_xyz789",
|
|
446
|
-
{ "Total Amount": 1250.
|
|
447
|
-
{ preconformed: true }
|
|
471
|
+
{ "Total Amount": 1250.0, "Invoice Number": "INV-1042" },
|
|
472
|
+
{ preconformed: true },
|
|
448
473
|
);
|
|
449
474
|
```
|
|
450
475
|
|
|
@@ -548,9 +573,9 @@ Returns all extracted data as a UTF-8 CSV string with BOM (Excel-compatible).
|
|
|
548
573
|
Each row is one document; columns are the extracted fields plus `preconformed`
|
|
549
574
|
and `uploadedAt`.
|
|
550
575
|
|
|
551
|
-
| Option
|
|
552
|
-
|
|
|
553
|
-
| `fields`
|
|
576
|
+
| Option | Type | Description |
|
|
577
|
+
| -------- | ---------- | ------------------------------------------------ |
|
|
578
|
+
| `fields` | `string[]` | Optional column subset. Dot-notation for nested. |
|
|
554
579
|
|
|
555
580
|
```js
|
|
556
581
|
// Export everything
|
|
@@ -570,13 +595,13 @@ const csv = await exportDocumentsCsv("tpl_abc123", {
|
|
|
570
595
|
Returns all documents as a plain JSON array. Each element is the extracted
|
|
571
596
|
field map plus three metadata keys:
|
|
572
597
|
|
|
573
|
-
- `_id` — document ID
|
|
574
|
-
- `_preconformed` — whether the document was reviewed
|
|
598
|
+
- `_id` — document ID
|
|
599
|
+
- `_preconformed` — whether the document was reviewed
|
|
575
600
|
- `_uploadedAt` — ISO timestamp
|
|
576
601
|
|
|
577
602
|
```js
|
|
578
603
|
const records = await exportDocumentsJson("tpl_abc123");
|
|
579
|
-
records.forEach(doc => {
|
|
604
|
+
records.forEach((doc) => {
|
|
580
605
|
console.log(doc._id, doc["Invoice Number"], doc["Total Amount"]);
|
|
581
606
|
});
|
|
582
607
|
|
|
@@ -592,13 +617,64 @@ writeFileSync("invoices.json", JSON.stringify(records, null, 2));
|
|
|
592
617
|
OCR Tools let you ask AI yes/no questions, classify documents into labels, or
|
|
593
618
|
extract free-form text from any image — without a template.
|
|
594
619
|
|
|
620
|
+
> **Credit consumption:** every OCR Agent run deducts **1 document** from the user's monthly (or add-on) document quota **plus AI credits** based on the token count of the AI analysis (calculated as `ceil(totalTokens / 1000)` credits).
|
|
621
|
+
|
|
622
|
+
#### Dynamic parameters (`{{?N}}` syntax)
|
|
623
|
+
|
|
624
|
+
Prompts can include numbered placeholders of the form `{{?1}}`, `{{?2}}`, etc.
|
|
625
|
+
At run time you supply the actual values; the AI receives the substituted text.
|
|
626
|
+
|
|
627
|
+
```js
|
|
628
|
+
// Tool with two dynamic parameters
|
|
629
|
+
const checker = await createOcrTool({
|
|
630
|
+
name: "Property Ownership Check",
|
|
631
|
+
prompt:
|
|
632
|
+
"Does this document appear to be a proof of ownership for the property at {{?1}} in the name of {{?2}}?",
|
|
633
|
+
outputType: "YES_NO",
|
|
634
|
+
parameterDefinitions: [
|
|
635
|
+
{
|
|
636
|
+
key: 1,
|
|
637
|
+
label: "Property address",
|
|
638
|
+
description: "Full street address",
|
|
639
|
+
maxChars: 200,
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
key: 2,
|
|
643
|
+
label: "Owner name",
|
|
644
|
+
description: "Full legal name of the owner",
|
|
645
|
+
maxChars: 150,
|
|
646
|
+
},
|
|
647
|
+
],
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
// Run with values
|
|
651
|
+
const result = await runOcrTool(checker.id, imageBase64, {
|
|
652
|
+
params: { 1: "123 Main St, Buenos Aires", 2: "Juan García" },
|
|
653
|
+
});
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
Each `ParameterDefinition` has:
|
|
657
|
+
|
|
658
|
+
| Field | Type | Required | Description |
|
|
659
|
+
| ------------- | -------- | -------- | ------------------------------------------------------- |
|
|
660
|
+
| `key` | `number` | ✅ | 1-based index matching `{{?N}}` in the prompt |
|
|
661
|
+
| `label` | `string` | ✅ | Human-friendly name shown in the UI and API errors |
|
|
662
|
+
| `description` | `string` | | Optional hint shown to the user when filling values |
|
|
663
|
+
| `maxChars` | `number` | | Character limit for this parameter (1–500, default 200) |
|
|
664
|
+
|
|
665
|
+
**Validation rules:**
|
|
666
|
+
|
|
667
|
+
- Every `{{?N}}` placeholder in the prompt must have a matching `ParameterDefinition`.
|
|
668
|
+
- A `400 Bad Request` is returned if a required parameter is missing or exceeds its `maxChars` limit.
|
|
669
|
+
- The fully substituted prompt must not exceed **3 000 characters** total; adjust individual `maxChars` values accordingly.
|
|
670
|
+
|
|
595
671
|
#### `getOcrTools()`
|
|
596
672
|
|
|
597
673
|
Returns all OCR tool configurations owned by the authenticated user.
|
|
598
674
|
|
|
599
675
|
```js
|
|
600
676
|
const tools = await getOcrTools();
|
|
601
|
-
tools.forEach(t => console.log(t.id, t.name, t.outputType));
|
|
677
|
+
tools.forEach((t) => console.log(t.id, t.name, t.outputType));
|
|
602
678
|
```
|
|
603
679
|
|
|
604
680
|
---
|
|
@@ -607,18 +683,20 @@ tools.forEach(t => console.log(t.id, t.name, t.outputType));
|
|
|
607
683
|
|
|
608
684
|
Creates a new OCR tool configuration.
|
|
609
685
|
|
|
610
|
-
| Field
|
|
611
|
-
|
|
|
612
|
-
| `name`
|
|
613
|
-
| `prompt`
|
|
614
|
-
| `outputType`
|
|
615
|
-
| `labels`
|
|
686
|
+
| Field | Type | Required | Description |
|
|
687
|
+
| ---------------------- | ------------------------------- | -------- | --------------------------------------------------------- |
|
|
688
|
+
| `name` | `string` | ✅ | Human-friendly display name |
|
|
689
|
+
| `prompt` | `string` | ✅ | Natural-language instruction for the AI (max 3 000 chars) |
|
|
690
|
+
| `outputType` | `"YES_NO" \| "LABEL" \| "TEXT"` | ✅ | Expected output shape |
|
|
691
|
+
| `labels` | `string[]` | ⚠️ | Required when `outputType === "LABEL"` |
|
|
692
|
+
| `parameterDefinitions` | `ParameterDefinition[]` | | Dynamic parameter definitions for `{{?N}}` placeholders |
|
|
616
693
|
|
|
617
694
|
```js
|
|
618
695
|
// YES/NO check
|
|
619
696
|
const checker = await createOcrTool({
|
|
620
697
|
name: "Proof of Residence Check",
|
|
621
|
-
prompt:
|
|
698
|
+
prompt:
|
|
699
|
+
"Does this document appear to be a valid proof of residence? Look for an address, official stamp, and the person's name.",
|
|
622
700
|
outputType: "YES_NO",
|
|
623
701
|
});
|
|
624
702
|
|
|
@@ -627,13 +705,21 @@ const classifier = await createOcrTool({
|
|
|
627
705
|
name: "Document Type Classifier",
|
|
628
706
|
prompt: "What type of document is this?",
|
|
629
707
|
outputType: "LABEL",
|
|
630
|
-
labels: [
|
|
708
|
+
labels: [
|
|
709
|
+
"invoice",
|
|
710
|
+
"id_card",
|
|
711
|
+
"receipt",
|
|
712
|
+
"proof_of_residence",
|
|
713
|
+
"contract",
|
|
714
|
+
"other",
|
|
715
|
+
],
|
|
631
716
|
});
|
|
632
717
|
|
|
633
718
|
// Free-form extraction
|
|
634
719
|
const extractor = await createOcrTool({
|
|
635
720
|
name: "Serial Number Extractor",
|
|
636
|
-
prompt:
|
|
721
|
+
prompt:
|
|
722
|
+
"Extract the serial number or product code printed on the label. Return only the code, nothing else.",
|
|
637
723
|
outputType: "TEXT",
|
|
638
724
|
});
|
|
639
725
|
```
|
|
@@ -646,7 +732,8 @@ Updates an existing OCR tool configuration.
|
|
|
646
732
|
|
|
647
733
|
```js
|
|
648
734
|
await updateOcrTool("tool_abc", {
|
|
649
|
-
prompt:
|
|
735
|
+
prompt:
|
|
736
|
+
"Does this document show a current address dated within the last 3 months?",
|
|
650
737
|
});
|
|
651
738
|
```
|
|
652
739
|
|
|
@@ -662,24 +749,36 @@ await deleteOcrTool("tool_abc");
|
|
|
662
749
|
|
|
663
750
|
---
|
|
664
751
|
|
|
665
|
-
#### `runOcrTool(id, base64Image)`
|
|
752
|
+
#### `runOcrTool(id, base64Image, options?)`
|
|
666
753
|
|
|
667
754
|
Runs an OCR tool against a base64-encoded image. Max image size: **5 MB**.
|
|
668
755
|
|
|
669
|
-
**Consumes AI credits
|
|
756
|
+
**Consumes 1 document credit + AI credits** (based on token usage).
|
|
757
|
+
|
|
758
|
+
The AI output language matches the language of the prompt / parameter values automatically.
|
|
759
|
+
|
|
760
|
+
| Option | Type | Description |
|
|
761
|
+
| -------- | ------------------------ | ------------------------------------------------ |
|
|
762
|
+
| `params` | `Record<string, string>` | Values for `{{?N}}` placeholders, keyed by `"N"` |
|
|
670
763
|
|
|
671
764
|
```js
|
|
672
765
|
import { readFileSync } from "fs";
|
|
673
766
|
const image = readFileSync("./id-card.jpg").toString("base64");
|
|
674
767
|
|
|
675
768
|
const result = await runOcrTool("tool_residence_check", image);
|
|
676
|
-
console.log(result.answer);
|
|
769
|
+
console.log(result.answer); // "YES"
|
|
677
770
|
console.log(result.explanation); // "The document shows a full address, an official municipal stamp, and the applicant's name."
|
|
678
771
|
|
|
679
772
|
// Document classification
|
|
680
773
|
const type = await runOcrTool("tool_classifier", image);
|
|
681
774
|
console.log(type.answer); // "id_card"
|
|
682
775
|
|
|
776
|
+
// With dynamic parameters
|
|
777
|
+
const ownership = await runOcrTool("tool_ownership_check", image, {
|
|
778
|
+
params: { 1: "Av. Corrientes 1234, CABA", 2: "María López" },
|
|
779
|
+
});
|
|
780
|
+
console.log(ownership.answer); // "YES"
|
|
781
|
+
|
|
683
782
|
// Full workflow: classify first, then extract
|
|
684
783
|
const { answer: docType } = await runOcrTool("tool_classifier", invoiceBase64);
|
|
685
784
|
if (docType === "invoice") {
|
|
@@ -687,6 +786,14 @@ if (docType === "invoice") {
|
|
|
687
786
|
}
|
|
688
787
|
```
|
|
689
788
|
|
|
789
|
+
**Error responses:**
|
|
790
|
+
|
|
791
|
+
| HTTP | Condition |
|
|
792
|
+
| ---- | ------------------------------------------------------------------------------------------------------ |
|
|
793
|
+
| 400 | Missing required parameter, value exceeds `maxChars`, or prompt exceeds 3 000 chars after substitution |
|
|
794
|
+
| 402 | Document quota exhausted — upgrade plan or purchase add-on docs |
|
|
795
|
+
| 402 | AI credits exhausted — purchase add-on credits |
|
|
796
|
+
|
|
690
797
|
---
|
|
691
798
|
|
|
692
799
|
### Credits & Analytics
|
|
@@ -708,20 +815,101 @@ console.log(`Total available: ${balance.totalBalance}`);
|
|
|
708
815
|
|
|
709
816
|
Returns a paginated history of AI credit consumption events (newest first).
|
|
710
817
|
|
|
711
|
-
| Option
|
|
712
|
-
|
|
|
713
|
-
| `page`
|
|
714
|
-
| `size`
|
|
818
|
+
| Option | Type | Default | Description |
|
|
819
|
+
| ------ | -------- | ------- | --------------------- |
|
|
820
|
+
| `page` | `number` | `0` | Zero-based page index |
|
|
821
|
+
| `size` | `number` | `20` | Page size (max 100) |
|
|
715
822
|
|
|
716
823
|
```js
|
|
717
824
|
const history = await getCreditsHistory({ page: 0, size: 10 });
|
|
718
|
-
history.content.forEach(entry => {
|
|
825
|
+
history.content.forEach((entry) => {
|
|
719
826
|
console.log(entry.timestamp, entry.operation, entry.creditsConsumed);
|
|
720
827
|
});
|
|
721
828
|
```
|
|
722
829
|
|
|
723
830
|
---
|
|
724
831
|
|
|
832
|
+
## Sub-Users
|
|
833
|
+
|
|
834
|
+
> Requires a **Pro or higher** plan. The plan determines the maximum number of sub-users allowed.
|
|
835
|
+
|
|
836
|
+
Sub-users can log in to the web app and operate within the permissions you grant them.
|
|
837
|
+
Available permissions: `"upload"` · `"view"` · `"template"` · `"settings"` · `"export"` · `"api"`
|
|
838
|
+
|
|
839
|
+
### Document History
|
|
840
|
+
|
|
841
|
+
```js
|
|
842
|
+
import { getDocumentHistory } from 'extractia-sdk';
|
|
843
|
+
|
|
844
|
+
const log = await getDocumentHistory({ page: 0, size: 20 });
|
|
845
|
+
log.content.forEach((entry) => {
|
|
846
|
+
console.log(entry.templateName, entry.status, entry.uploadDate);
|
|
847
|
+
if (entry.status === 'FAILURE') console.error(entry.errorMessage);
|
|
848
|
+
});
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
### List Sub-Users
|
|
852
|
+
|
|
853
|
+
```js
|
|
854
|
+
import { getSubUsers } from 'extractia-sdk';
|
|
855
|
+
|
|
856
|
+
const users = await getSubUsers();
|
|
857
|
+
// [{ username: 'agent_carlos', permissions: ['upload','view'], suspended: false }]
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
### Create a Sub-User
|
|
861
|
+
|
|
862
|
+
```js
|
|
863
|
+
import { createSubUser } from 'extractia-sdk';
|
|
864
|
+
|
|
865
|
+
const sub = await createSubUser({
|
|
866
|
+
username: 'agent_carlos',
|
|
867
|
+
password: 'SecurePass1',
|
|
868
|
+
permissions: ['upload', 'view'],
|
|
869
|
+
});
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
**Error codes:**
|
|
873
|
+
| Code | Reason |
|
|
874
|
+
|------|--------|
|
|
875
|
+
| `403` | Plan does not allow sub-users or limit reached |
|
|
876
|
+
| `409` | Username already in use |
|
|
877
|
+
| `400` | Missing fields or password matches the main account |
|
|
878
|
+
|
|
879
|
+
### Update Permissions or Password
|
|
880
|
+
|
|
881
|
+
Only the fields you include are changed. Omit `password` to keep it unchanged.
|
|
882
|
+
|
|
883
|
+
```js
|
|
884
|
+
import { updateSubUser } from 'extractia-sdk';
|
|
885
|
+
|
|
886
|
+
await updateSubUser('agent_carlos', {
|
|
887
|
+
permissions: ['upload', 'view', 'export'],
|
|
888
|
+
// password: 'NewPass99', ← optional
|
|
889
|
+
});
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
### Delete a Sub-User
|
|
893
|
+
|
|
894
|
+
```js
|
|
895
|
+
import { deleteSubUser } from 'extractia-sdk';
|
|
896
|
+
|
|
897
|
+
await deleteSubUser('agent_carlos');
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
### Suspend / Reactivate
|
|
901
|
+
|
|
902
|
+
A suspended sub-user cannot log in. Calling the same method again reactivates them.
|
|
903
|
+
|
|
904
|
+
```js
|
|
905
|
+
import { toggleSuspendSubUser } from 'extractia-sdk';
|
|
906
|
+
|
|
907
|
+
const state = await toggleSuspendSubUser('agent_carlos');
|
|
908
|
+
console.log(state.suspended); // true | false
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
---
|
|
912
|
+
|
|
725
913
|
## TypeScript
|
|
726
914
|
|
|
727
915
|
The SDK ships with a full `index.d.ts` declaration file — no `@types` package needed.
|
|
@@ -780,6 +968,17 @@ Purchase extra document packs or upgrade your plan from the dashboard to continu
|
|
|
780
968
|
|
|
781
969
|
## Changelog
|
|
782
970
|
|
|
971
|
+
### v1.2.0
|
|
972
|
+
|
|
973
|
+
- **New:** `getDocumentHistory(opts?)` — paginated log of all document processing events (successes and failures)
|
|
974
|
+
- **New:** `getSubUsers()` — list all sub-users under your account
|
|
975
|
+
- **New:** `createSubUser({ username, password, permissions })` — create a sub-user (Pro+ plans)
|
|
976
|
+
- **New:** `updateSubUser(username, updates)` — change permissions or password of a sub-user
|
|
977
|
+
- **New:** `deleteSubUser(username)` — permanently remove a sub-user
|
|
978
|
+
- **New:** `toggleSuspendSubUser(username)` — suspend or reactivate a sub-user
|
|
979
|
+
- **Updated:** `getMyProfile()` response now includes `documentsAvailableThisMonth` and `extraDocsAvailable` quota fields
|
|
980
|
+
- Updated TypeScript declarations: `AppUserProfile`, `DocumentAuditEntry`, `SubUser` interfaces; all new function signatures
|
|
981
|
+
|
|
783
982
|
### v1.1.0
|
|
784
983
|
|
|
785
984
|
- **New:** `suggestFields(templateName, context?)` — AI-powered field suggestions
|
|
@@ -2671,7 +2671,7 @@ var ExtractiaSDK = (() => {
|
|
|
2671
2671
|
|
|
2672
2672
|
// src/apiClient.js
|
|
2673
2673
|
var token = null;
|
|
2674
|
-
var DEFAULT_BASE_URL = "https://
|
|
2674
|
+
var DEFAULT_BASE_URL = "https://api.extractia.info/api/public";
|
|
2675
2675
|
var api = axios_default.create({
|
|
2676
2676
|
baseURL: DEFAULT_BASE_URL,
|
|
2677
2677
|
timeout: 6e4
|
|
@@ -2788,11 +2788,15 @@ var ExtractiaSDK = (() => {
|
|
|
2788
2788
|
}
|
|
2789
2789
|
async function getDocumentById(templateId, docId, options = {}) {
|
|
2790
2790
|
const params = { includeImage: options.includeImage ? 1 : 0 };
|
|
2791
|
-
const res = await apiClient_default.get(`/templates/${templateId}/documents/${docId}`, {
|
|
2791
|
+
const res = await apiClient_default.get(`/templates/${templateId}/documents/${docId}`, {
|
|
2792
|
+
params
|
|
2793
|
+
});
|
|
2792
2794
|
return res.data;
|
|
2793
2795
|
}
|
|
2794
2796
|
async function getRecentDocuments(size = 10) {
|
|
2795
|
-
const res = await apiClient_default.get("/documents/recent", {
|
|
2797
|
+
const res = await apiClient_default.get("/documents/recent", {
|
|
2798
|
+
params: { size: Math.min(size, 50) }
|
|
2799
|
+
});
|
|
2796
2800
|
return res.data;
|
|
2797
2801
|
}
|
|
2798
2802
|
async function deleteDocument(documentId) {
|
|
@@ -2800,11 +2804,15 @@ var ExtractiaSDK = (() => {
|
|
|
2800
2804
|
return res.data;
|
|
2801
2805
|
}
|
|
2802
2806
|
async function processImage(templateId, base64Image) {
|
|
2803
|
-
const res = await apiClient_default.post(`/templates/${templateId}/process`, {
|
|
2807
|
+
const res = await apiClient_default.post(`/templates/${templateId}/process`, {
|
|
2808
|
+
image: base64Image
|
|
2809
|
+
});
|
|
2804
2810
|
return res.data;
|
|
2805
2811
|
}
|
|
2806
2812
|
async function processImagesMultipage(templateId, base64ImagesArray) {
|
|
2807
|
-
const res = await apiClient_default.post(`/templates/${templateId}/process-multipage`, {
|
|
2813
|
+
const res = await apiClient_default.post(`/templates/${templateId}/process-multipage`, {
|
|
2814
|
+
images: base64ImagesArray
|
|
2815
|
+
});
|
|
2808
2816
|
return res.data;
|
|
2809
2817
|
}
|
|
2810
2818
|
async function generateDocumentSummary(docId) {
|
|
@@ -2833,7 +2841,8 @@ var ExtractiaSDK = (() => {
|
|
|
2833
2841
|
}
|
|
2834
2842
|
async function exportDocumentsCsv(templateId, options = {}) {
|
|
2835
2843
|
const params = {};
|
|
2836
|
-
if (options.fields && options.fields.length > 0)
|
|
2844
|
+
if (options.fields && options.fields.length > 0)
|
|
2845
|
+
params.fields = options.fields.join(",");
|
|
2837
2846
|
const res = await apiClient_default.get(`/templates/${templateId}/documents/export/csv`, {
|
|
2838
2847
|
params,
|
|
2839
2848
|
responseType: "text"
|
|
@@ -2849,7 +2858,8 @@ var ExtractiaSDK = (() => {
|
|
|
2849
2858
|
var analytics_exports = {};
|
|
2850
2859
|
__export(analytics_exports, {
|
|
2851
2860
|
getCreditsBalance: () => getCreditsBalance,
|
|
2852
|
-
getCreditsHistory: () => getCreditsHistory
|
|
2861
|
+
getCreditsHistory: () => getCreditsHistory,
|
|
2862
|
+
getDocumentHistory: () => getDocumentHistory
|
|
2853
2863
|
});
|
|
2854
2864
|
async function getCreditsBalance() {
|
|
2855
2865
|
const res = await apiClient_default.get("/me/credits");
|
|
@@ -2861,6 +2871,12 @@ var ExtractiaSDK = (() => {
|
|
|
2861
2871
|
});
|
|
2862
2872
|
return res.data;
|
|
2863
2873
|
}
|
|
2874
|
+
async function getDocumentHistory({ page = 0, size = 20 } = {}) {
|
|
2875
|
+
const res = await apiClient_default.get("/me/documents/history", {
|
|
2876
|
+
params: { page, size: Math.min(size, 100) }
|
|
2877
|
+
});
|
|
2878
|
+
return res.data;
|
|
2879
|
+
}
|
|
2864
2880
|
|
|
2865
2881
|
// src/ocrTools.js
|
|
2866
2882
|
var ocrTools_exports = {};
|
|
@@ -2887,8 +2903,12 @@ var ExtractiaSDK = (() => {
|
|
|
2887
2903
|
const res = await apiClient_default.delete(`/ocr-tools/${id}`);
|
|
2888
2904
|
return res.data;
|
|
2889
2905
|
}
|
|
2890
|
-
async function runOcrTool(id, base64Image) {
|
|
2891
|
-
const
|
|
2906
|
+
async function runOcrTool(id, base64Image, options = {}) {
|
|
2907
|
+
const body = { image: base64Image };
|
|
2908
|
+
if (options.params && Object.keys(options.params).length > 0) {
|
|
2909
|
+
body.params = options.params;
|
|
2910
|
+
}
|
|
2911
|
+
const res = await apiClient_default.post(`/ocr-tools/${id}/run`, body);
|
|
2892
2912
|
return res.data;
|
|
2893
2913
|
}
|
|
2894
2914
|
|