@anyformat/sdk 0.2.2 → 1.0.0-rc.2

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/dist/index.d.cts CHANGED
@@ -6,6 +6,13 @@ interface Auth {
6
6
  * @default 'header'
7
7
  */
8
8
  in?: 'header' | 'query' | 'cookie';
9
+ /**
10
+ * A unique identifier for the security scheme.
11
+ *
12
+ * Defined only when there are multiple security schemes whose `Auth`
13
+ * shape would otherwise be identical.
14
+ */
15
+ key?: string;
9
16
  /**
10
17
  * Header or query parameter name.
11
18
  *
@@ -312,6 +319,82 @@ interface TDataShape {
312
319
  type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
313
320
  type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, TResponseStyle extends ResponseStyle = 'fields'> = OmitKeys<RequestOptions<TResponse, TResponseStyle, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & ([TData] extends [never] ? unknown : Omit<TData, 'url'>);
314
321
 
322
+ /**
323
+ * AllOfCheck
324
+ *
325
+ * AND combinator — passes iff every sub-check passes.
326
+ *
327
+ * Tri-state: FAIL if any child fails; else INCONCLUSIVE if any child is
328
+ * inconclusive; else PASS. Children are the same closed ``Check`` union
329
+ * (mutual recursion via forward ref) so combinators nest by construction —
330
+ * the CheckBuilder UI restricts nesting to a single level for MVP.
331
+ *
332
+ * ``max_length=32`` bounds runaway fan-out per combinator. Practical rules
333
+ * stay well below the cap; a legitimate use case wanting more should motivate
334
+ * the raise rather than land silently. Nesting-depth is bounded by pydantic's
335
+ * own recursion during parse.
336
+ */
337
+ type AllOfCheck = {
338
+ /**
339
+ * Checks
340
+ */
341
+ checks: Array<RangeCheck | DateCheck | ArithmeticCheck | ComparisonCheck | OneOfCheck | RegexCheck | RequiredCheck | ConfidenceCheck | ExpressionCheck | ValidationCheck | AllOfCheck | AnyOfCheck>;
342
+ /**
343
+ * Type
344
+ */
345
+ type: 'all_of';
346
+ };
347
+ /**
348
+ * AnyOfCheck
349
+ *
350
+ * OR combinator — passes iff any sub-check passes.
351
+ *
352
+ * Tri-state: PASS if any child passes; else INCONCLUSIVE if any child is
353
+ * inconclusive; else FAIL.
354
+ *
355
+ * ``max_length=32`` — see :class:`AllOfCheck` for the rationale.
356
+ */
357
+ type AnyOfCheck = {
358
+ /**
359
+ * Checks
360
+ */
361
+ checks: Array<RangeCheck | DateCheck | ArithmeticCheck | ComparisonCheck | OneOfCheck | RegexCheck | RequiredCheck | ConfidenceCheck | ExpressionCheck | ValidationCheck | AllOfCheck | AnyOfCheck>;
362
+ /**
363
+ * Type
364
+ */
365
+ type: 'any_of';
366
+ };
367
+ /**
368
+ * ArithmeticCheck
369
+ */
370
+ type ArithmeticCheck = {
371
+ /**
372
+ * Equals
373
+ *
374
+ * The field whose value the result must equal. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
375
+ */
376
+ equals: string;
377
+ /**
378
+ * Operands
379
+ *
380
+ * The fields combined by `operator`. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
381
+ */
382
+ operands: Array<string>;
383
+ /**
384
+ * Operator
385
+ */
386
+ operator?: 'sum' | 'subtract' | 'product';
387
+ /**
388
+ * Tolerance
389
+ *
390
+ * Absolute slack allowed around `equals`.
391
+ */
392
+ tolerance?: number;
393
+ /**
394
+ * Type
395
+ */
396
+ type: 'arithmetic';
397
+ };
315
398
  /**
316
399
  * Block
317
400
  *
@@ -360,9 +443,9 @@ type Block = {
360
443
  /**
361
444
  * Layout Confidence
362
445
  *
363
- * 0-100 YOLO layout detection confidence for this block.
446
+ * 0-1 layout detection confidence for this block. `null` when no layout detector ran — the `lite` tier gets its layout from the OCR response, which reports no confidence in the type it assigned.
364
447
  */
365
- layout_confidence: number;
448
+ layout_confidence?: number | null;
366
449
  /**
367
450
  * Page
368
451
  *
@@ -375,6 +458,12 @@ type Block = {
375
458
  * 0-100 parse confidence calibrated from LLM logprobs. `null` when logprobs were unavailable (e.g. text-bytes strategy).
376
459
  */
377
460
  parse_confidence?: number | null;
461
+ /**
462
+ * Regions
463
+ *
464
+ * The layout detections this block is made of, each with the words printed inside it. A block the detector reported as one box has one region, that box. Empty only for a block parsed before detections were reported, or one that has no box at all.
465
+ */
466
+ regions?: Array<Detection>;
378
467
  /**
379
468
  * Rows
380
469
  *
@@ -403,17 +492,25 @@ type BooleanField = {
403
492
  *
404
493
  * Free-form description shown to the extraction model.
405
494
  */
406
- description: string;
407
- /**
408
- * Lookup
409
- */
410
- lookup?: boolean;
495
+ description?: string;
411
496
  /**
412
497
  * Name
413
498
  *
414
499
  * Field name. Used as the key in the extraction response.
415
500
  */
416
501
  name: string;
502
+ /**
503
+ * Persistent Id
504
+ *
505
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
506
+ */
507
+ persistent_id?: string | null;
508
+ /**
509
+ * Source
510
+ *
511
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
512
+ */
513
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
417
514
  };
418
515
  /**
419
516
  * ClassificationResult
@@ -430,9 +527,9 @@ type ClassificationResult = {
430
527
  /**
431
528
  * Confidence
432
529
  *
433
- * 0-100 model confidence in the verdict.
530
+ * 0-100 model confidence in the verdict. `null` when the verdict carries no score, because nothing was measured.
434
531
  */
435
- confidence: number;
532
+ confidence: number | null;
436
533
  /**
437
534
  * Evidence
438
535
  *
@@ -459,7 +556,7 @@ type ClassifyCategory = {
459
556
  /**
460
557
  * Name
461
558
  *
462
- * Display name shown to the LLM.
559
+ * Display name shown to the LLM; classification and routing key off it, so it must be unique across categories.
463
560
  */
464
561
  name: string;
465
562
  };
@@ -484,282 +581,639 @@ type ClassifyNode = {
484
581
  /**
485
582
  * User Prompt
486
583
  *
487
- * Optional prompt prefix for the classifier.
584
+ * Optional extra instructions inserted between the classifier's system prompt and the document text.
488
585
  */
489
586
  user_prompt?: string | null;
490
587
  };
491
588
  /**
492
- * DateField
589
+ * ComparisonCheck
493
590
  */
494
- type DateField = {
591
+ type ComparisonCheck = {
495
592
  /**
496
- * Data Type
593
+ * Left
594
+ *
595
+ * The left-hand field. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
497
596
  */
498
- data_type: 'date';
597
+ left: string;
499
598
  /**
500
- * Description
501
- *
502
- * Free-form description shown to the extraction model.
599
+ * Op
503
600
  */
504
- description: string;
601
+ op: '==' | '!=' | '>' | '>=' | '<' | '<=';
505
602
  /**
506
- * Lookup
603
+ * Right
507
604
  */
508
- lookup?: boolean;
605
+ right: ({
606
+ source: 'field';
607
+ } & FieldOperand) | ({
608
+ source: 'literal';
609
+ } & LiteralOperand);
509
610
  /**
510
- * Name
511
- *
512
- * Field name. Used as the key in the extraction response.
611
+ * Type
513
612
  */
514
- name: string;
613
+ type: 'comparison';
515
614
  };
516
615
  /**
517
- * DatetimeField
616
+ * ConfidenceCheck
518
617
  */
519
- type DatetimeField = {
618
+ type ConfidenceCheck = {
520
619
  /**
521
- * Data Type
620
+ * Field
621
+ *
622
+ * The field whose extraction confidence to compare. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
522
623
  */
523
- data_type: 'datetime';
624
+ field: string;
524
625
  /**
525
- * Description
626
+ * Op
627
+ */
628
+ op: '<' | '<=' | '>' | '>=' | '==' | '!=';
629
+ /**
630
+ * Threshold
526
631
  *
527
- * Free-form description shown to the extraction model.
632
+ * Confidence percentile 0..100.
528
633
  */
529
- description: string;
634
+ threshold: number;
530
635
  /**
531
- * Lookup
636
+ * Type
637
+ */
638
+ type: 'confidence';
639
+ };
640
+ /**
641
+ * DatasetUploadFileV3
642
+ *
643
+ * Per-file entry in a dataset-upload response.
644
+ */
645
+ type DatasetUploadFileV3 = {
646
+ /**
647
+ * Id
648
+ *
649
+ * Unique identifier of the file (hyphenated UUID).
532
650
  */
533
- lookup?: boolean;
651
+ id: string;
534
652
  /**
535
653
  * Name
536
654
  *
537
- * Field name. Used as the key in the extraction response.
655
+ * Filename the file is stored under.
538
656
  */
539
657
  name: string;
658
+ /**
659
+ * Original Name
660
+ *
661
+ * The name you uploaded, present only when the file was auto-renamed (`on_conflict=rename` resolving a collision). `null` when the stored `name` is the name you sent.
662
+ */
663
+ original_name?: string | null;
540
664
  };
541
665
  /**
542
- * Edge
666
+ * DatasetUploadResponseV3
543
667
  *
544
- * A directed edge between two nodes. ``branch`` carries the source-port label
545
- * used for routing out of ``classify`` (category id) or ``splitter`` (rule id) nodes.
668
+ * Response for `POST /v3/workflows/{workflow_id}/dataset/upload/`.
669
+ *
670
+ * One dataset document packet, all-or-nothing. `document_packet_id` is the
671
+ * stable handle for the deferred ground-truth-edit follow-up.
546
672
  */
547
- type Edge = {
673
+ type DatasetUploadResponseV3 = {
548
674
  /**
549
- * Branch
675
+ * Document Packet Id
550
676
  *
551
- * Source-port label for branch routing. Required when leaving a classify or splitter node by category/rule.
677
+ * Unique identifier of the created dataset document packet (hyphenated UUID).
552
678
  */
553
- branch?: string | null;
679
+ document_packet_id: string;
554
680
  /**
555
- * Source
681
+ * Files
682
+ *
683
+ * Files in the packet, in the order they were provided.
556
684
  */
557
- source: string;
685
+ files: Array<DatasetUploadFileV3>;
558
686
  /**
559
- * Target
687
+ * Ground Truth Saved
688
+ *
689
+ * Whether ground truth was supplied and saved for this document packet.
560
690
  */
561
- target: string;
691
+ ground_truth_saved: boolean;
562
692
  };
563
693
  /**
564
- * EnumField
694
+ * DateCheck
565
695
  */
566
- type EnumField = {
696
+ type DateCheck = {
567
697
  /**
568
- * Data Type
698
+ * Earliest
569
699
  */
570
- data_type: 'enum';
700
+ earliest?: string | null;
571
701
  /**
572
- * Description
702
+ * Field
573
703
  *
574
- * Free-form description shown to the extraction model.
704
+ * The date field. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
575
705
  */
576
- description: string;
706
+ field: string;
577
707
  /**
578
- * Enum Options
708
+ * Latest
579
709
  */
580
- enum_options: Array<EnumOption>;
710
+ latest?: string | null;
711
+ /**
712
+ * Type
713
+ */
714
+ type: 'date';
715
+ };
716
+ /**
717
+ * DateField
718
+ */
719
+ type DateField = {
720
+ /**
721
+ * Data Type
722
+ */
723
+ data_type: 'date';
581
724
  /**
582
- * Lookup
725
+ * Description
726
+ *
727
+ * Free-form description shown to the extraction model.
583
728
  */
584
- lookup?: boolean;
729
+ description?: string;
585
730
  /**
586
731
  * Name
587
732
  *
588
733
  * Field name. Used as the key in the extraction response.
589
734
  */
590
735
  name: string;
736
+ /**
737
+ * Persistent Id
738
+ *
739
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
740
+ */
741
+ persistent_id?: string | null;
742
+ /**
743
+ * Source
744
+ *
745
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
746
+ */
747
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
591
748
  };
592
749
  /**
593
- * EnumOption
750
+ * DatetimeField
594
751
  */
595
- type EnumOption = {
752
+ type DatetimeField = {
753
+ /**
754
+ * Data Type
755
+ */
756
+ data_type: 'datetime';
596
757
  /**
597
758
  * Description
598
759
  *
599
- * Free-form description shown to the model.
760
+ * Free-form description shown to the extraction model.
600
761
  */
601
- description: string;
762
+ description?: string;
602
763
  /**
603
764
  * Name
765
+ *
766
+ * Field name. Used as the key in the extraction response.
604
767
  */
605
768
  name: string;
769
+ /**
770
+ * Persistent Id
771
+ *
772
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
773
+ */
774
+ persistent_id?: string | null;
775
+ /**
776
+ * Source
777
+ *
778
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
779
+ */
780
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
606
781
  };
607
782
  /**
608
- * Evidence
783
+ * Detection
609
784
  *
610
- * A snippet of source text supporting an extracted value, with the page it came from.
785
+ * One layout detection a block is made of: where it is and what is printed inside it.
786
+ *
787
+ * A block is often the fusion of several detections, and a consumer that has to point at what
788
+ * the page prints needs the parts, not only their union.
611
789
  */
612
- type Evidence = {
790
+ type Detection = {
613
791
  /**
614
- * Page Number
792
+ * Bbox
615
793
  *
616
- * 1-indexed page number where the snippet was found.
794
+ * Normalised bounding box in [0, 1] page coordinates with keys `x0`/`y0`/`x1`/`y1`.
617
795
  */
618
- page_number: number;
796
+ bbox: {
797
+ [key: string]: number;
798
+ };
619
799
  /**
620
800
  * Text
621
801
  *
622
- * The exact source-text snippet that supports the extracted value.
802
+ * The words the page prints inside this box.
623
803
  */
624
804
  text: string;
805
+ /**
806
+ * Type
807
+ *
808
+ * What the layout detector called this box.
809
+ */
810
+ type: string;
625
811
  };
626
812
  /**
627
- * ExtractNode
813
+ * DocumentPacketDetailV3
814
+ *
815
+ * A packet with its per-file breakdown and latest run reference.
628
816
  */
629
- type ExtractNode = {
817
+ type DocumentPacketDetailV3 = {
630
818
  /**
631
- * Context Tracker
819
+ * Created At
820
+ *
821
+ * Timestamp when the packet was created (ISO 8601).
632
822
  */
633
- context_tracker?: string;
823
+ created_at?: string | null;
634
824
  /**
635
- * Schema for the fields this node extracts. Required. The backend executor populates this from the ORM field tree before constructing the typed node; nothing else should be able to build an ExtractNode without it.
825
+ * Files
826
+ *
827
+ * Files in this packet.
636
828
  */
637
- extraction_schema: ExtractionSchema;
829
+ files: Array<DocumentPacketFileV3>;
638
830
  /**
639
831
  * Id
640
832
  *
641
- * Stable identifier for this node within the graph.
833
+ * Unique identifier of the document packet (hyphenated UUID).
642
834
  */
643
835
  id: string;
644
836
  /**
645
- * Lookup File Uploads
837
+ * Latest Run Id
646
838
  *
647
- * Inline lookup-file content for the typed create call. The backend uploads each entry to S3 and stores the resulting URI in ``lookup_files``; this field is never persisted in GraphNode.config.
839
+ * Id of the packet's most recent run (hyphenated UUID); `null` until the packet has been run.
648
840
  */
649
- lookup_file_uploads?: Array<LookupFileUpload>;
841
+ latest_run_id?: string | null;
650
842
  /**
651
- * Lookup Files
843
+ * Metadata
652
844
  *
653
- * Smart-lookup reference document URIs persisted on the extract node.
845
+ * Free-form JSON supplied at packet creation. No schema is enforced; the extract operator may source datapoints from a top-level key whose name matches a schema field. `null` when no metadata was attached.
654
846
  */
655
- lookup_files?: Array<string>;
656
- /**
657
- * Lookup Schema
658
- *
659
- * Typed schema of fields the smart-lookup pass should produce. The *backend* derives this from the field tree (FieldWorkflowVersion rows whose source is SMART_LOOKUP) and attaches it to the node before the message hits the wire — the worker then reads it directly off the node, with no DB round-trip. Default empty: a node without smart-lookup fields carries an empty list.
660
- */
661
- lookup_schema?: Array<({
662
- data_type: 'string';
663
- } & StringField) | ({
664
- data_type: 'integer';
665
- } & IntegerField) | ({
666
- data_type: 'float';
667
- } & FloatField) | ({
668
- data_type: 'boolean';
669
- } & BooleanField) | ({
670
- data_type: 'date';
671
- } & DateField) | ({
672
- data_type: 'datetime';
673
- } & DatetimeField) | ({
674
- data_type: 'enum';
675
- } & EnumField) | ({
676
- data_type: 'multi_select';
677
- } & MultiSelectField) | ({
678
- data_type: 'object';
679
- } & ObjectField)>;
847
+ metadata?: {
848
+ [key: string]: unknown;
849
+ } | null;
680
850
  /**
681
- * Lookup Suggestion
851
+ * Name
682
852
  *
683
- * Free-form hint shown to the smart-lookup matcher.
853
+ * Human-readable name of the packet.
684
854
  */
685
- lookup_suggestion?: string | null;
855
+ name?: string | null;
686
856
  /**
687
- * Mode
857
+ * Processing status. Non-terminal: `not_started`, `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.
688
858
  */
689
- mode?: 'standard' | 'agentic' | 'max';
859
+ status: DocumentPacketStatus;
690
860
  /**
691
- * Page Sum Verification Enabled
861
+ * Updated At
862
+ *
863
+ * Timestamp when the packet was last updated (ISO 8601).
692
864
  */
693
- page_sum_verification_enabled?: boolean;
865
+ updated_at?: string | null;
694
866
  /**
695
- * Row Extractor Enabled
867
+ * Workflow Id
868
+ *
869
+ * The workflow this packet belongs to (hyphenated UUID).
696
870
  */
697
- row_extractor_enabled?: boolean;
871
+ workflow_id: string;
872
+ };
873
+ /**
874
+ * DocumentPacketFileV3
875
+ *
876
+ * Slim per-file projection inside a packet.
877
+ */
878
+ type DocumentPacketFileV3 = {
698
879
  /**
699
- * Type
880
+ * Id
881
+ *
882
+ * Unique identifier of the file (hyphenated UUID).
700
883
  */
701
- type: 'extract';
884
+ id: string;
702
885
  /**
703
- * Use Images
886
+ * Name
887
+ *
888
+ * Filename the file is stored under. Filenames are unique within a workflow: a name that collides with an existing file is auto-renamed by inserting a ` (n)` counter before the extension (e.g. `invoice.pdf` → `invoice (1).pdf`).
704
889
  */
705
- use_images?: boolean;
890
+ name: string;
706
891
  };
707
892
  /**
708
- * ExtractedField
893
+ * DocumentPacketStatus
709
894
  *
710
- * One extracted field's value, confidence, and supporting evidence.
895
+ * Extraction lifecycle of a packet. Non-terminal: ``not_started``
896
+ * (no run yet), ``queued``, ``in_progress``. Terminal: ``processed``
897
+ * (success), ``error``, ``cancelled``.
898
+ */
899
+ type DocumentPacketStatus = 'not_started' | 'queued' | 'in_progress' | 'processed' | 'error' | 'cancelled';
900
+ /**
901
+ * DocumentPacketSummaryV3
902
+ *
903
+ * Slim packet projection returned by list pages.
711
904
  */
712
- type ExtractedField = {
905
+ type DocumentPacketSummaryV3 = {
713
906
  /**
714
- * Confidence
907
+ * Created At
715
908
  *
716
- * Model confidence in the extracted value, on a 0-100 scale. `null` when the backend did not produce a confidence (e.g. manual entry).
909
+ * Timestamp when the packet was created (ISO 8601).
717
910
  */
718
- confidence?: number | null;
911
+ created_at?: string | null;
719
912
  /**
720
- * Evidence
913
+ * Id
721
914
  *
722
- * Source-text snippets the model used to derive this value.
915
+ * Unique identifier of the document packet (hyphenated UUID).
723
916
  */
724
- evidence?: Array<Evidence>;
917
+ id: string;
725
918
  /**
726
- * Value
919
+ * Name
727
920
  *
728
- * The extracted value. Type depends on the field's `data_type` (string, number, date, etc.). `null` when extraction could not produce a value.
921
+ * Human-readable name of the packet.
729
922
  */
730
- value: unknown | null;
923
+ name?: string | null;
731
924
  /**
732
- * Value Override
925
+ * Processing status. Non-terminal: `not_started`, `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.
926
+ */
927
+ status: DocumentPacketStatus;
928
+ /**
929
+ * Updated At
733
930
  *
734
- * A human-supplied override of the extracted `value`, if one was set during verification. `null` when no override exists.
931
+ * Timestamp when the packet was last updated (ISO 8601).
735
932
  */
736
- value_override?: unknown | null;
933
+ updated_at?: string | null;
737
934
  /**
738
- * Verification Status
935
+ * Workflow Id
739
936
  *
740
- * Verification state for this datapoint (e.g. `not_verified`, `verified`). `null` when not yet reviewed.
937
+ * The workflow this packet belongs to (hyphenated UUID).
741
938
  */
742
- verification_status?: string | null;
939
+ workflow_id: string;
743
940
  };
744
941
  /**
745
- * Extraction
942
+ * Edge
746
943
  *
747
- * One unit of extracted data. For linear (parse->extract) workflows there
748
- * is exactly one entry with `split_name=null` and `partition=null`. For split
749
- * workflows there is one entry per (split, partition) pair; join with
750
- * `splits[]` by `split_name` to look up geometry.
944
+ * A directed edge between two nodes. ``branch`` carries the source-port label
945
+ * used for routing out of ``classify`` (category id) or ``splitter`` (rule id) nodes.
751
946
  */
752
- type Extraction = {
947
+ type Edge = {
753
948
  /**
754
- * Fields
949
+ * Branch
755
950
  *
756
- * Extracted fields keyed by field name. Same shape as the legacy top-level `extraction`.
951
+ * Source-port label for branch routing. Required when leaving a classify or splitter node by category/rule.
757
952
  */
758
- fields: {
759
- [key: string]: ExtractedField | Array<{
760
- [key: string]: ExtractedField;
761
- }>;
762
- };
953
+ branch?: string | null;
954
+ /**
955
+ * Source
956
+ */
957
+ source: string;
958
+ /**
959
+ * Target
960
+ */
961
+ target: string;
962
+ };
963
+ /**
964
+ * Edit
965
+ *
966
+ * One edit node's filled form for one file of the collection: the values
967
+ * written into the document's fields, plus a short-lived link to the filled
968
+ * PDF. One entry per file the edit node processed.
969
+ */
970
+ type Edit = {
971
+ /**
972
+ * Download Url
973
+ *
974
+ * Presigned link to the filled PDF, valid for 15 minutes from the moment this response was built. Re-read the results endpoint for a fresh link. `null` when no filled PDF was stored.
975
+ */
976
+ download_url?: string | null;
977
+ /**
978
+ * Fields
979
+ *
980
+ * Every form field detected in the document, filled or not, in document order.
981
+ */
982
+ fields?: Array<EditFormField>;
983
+ /**
984
+ * File Id
985
+ *
986
+ * The UUID of the file this form was filled from.
987
+ */
988
+ file_id: string;
989
+ /**
990
+ * File Name
991
+ *
992
+ * The file's display name.
993
+ */
994
+ file_name: string;
995
+ /**
996
+ * Unmatched Instructions
997
+ *
998
+ * Instruction fragments, quoted verbatim, that matched no field in this document.
999
+ */
1000
+ unmatched_instructions?: Array<string>;
1001
+ };
1002
+ /**
1003
+ * EditFormField
1004
+ *
1005
+ * One form field the edit node detected, with the value it wrote in.
1006
+ */
1007
+ type EditFormField = {
1008
+ /**
1009
+ * Bbox
1010
+ *
1011
+ * The field's fillable area as a normalised bounding box in [0, 1] page coordinates, keys `x0`/`y0`/`x1`/`y1`.
1012
+ */
1013
+ bbox: {
1014
+ [key: string]: number;
1015
+ };
1016
+ /**
1017
+ * Confidence
1018
+ *
1019
+ * Raw, uncalibrated 0-100 match score for pairing an instruction with this field. It grades how surely the instruction addresses the field, not whether the written value is correct, and it is not a probability. `null` when no instruction addressed this field, because nothing was measured.
1020
+ */
1021
+ confidence: number | null;
1022
+ /**
1023
+ * Form Field Id
1024
+ *
1025
+ * Stable identifier for this form field within the document, in the form `p<page>_f<index>`.
1026
+ */
1027
+ form_field_id: string;
1028
+ /**
1029
+ * Kind
1030
+ *
1031
+ * `checkbox` for a tick target, `text` for anything else.
1032
+ */
1033
+ kind: string;
1034
+ /**
1035
+ * Label
1036
+ *
1037
+ * The field's own printed caption, verbatim from the document.
1038
+ */
1039
+ label: string;
1040
+ /**
1041
+ * Page
1042
+ *
1043
+ * 1-indexed page number the field sits on.
1044
+ */
1045
+ page: number;
1046
+ /**
1047
+ * State
1048
+ *
1049
+ * `empty` if the field was blank in the source document and therefore fillable, `prefilled` if the document already carried a value. Prefilled fields are never overwritten, so they always read back with `value: null`.
1050
+ */
1051
+ state: string;
1052
+ /**
1053
+ * Value
1054
+ *
1055
+ * The value written into the field — the literal string `true`/`false` for a `checkbox`. `null` when no instruction addressed this field.
1056
+ */
1057
+ value: string | null;
1058
+ };
1059
+ /**
1060
+ * EnumField
1061
+ */
1062
+ type EnumField = {
1063
+ /**
1064
+ * Data Type
1065
+ */
1066
+ data_type: 'enum';
1067
+ /**
1068
+ * Description
1069
+ *
1070
+ * Free-form description shown to the extraction model.
1071
+ */
1072
+ description?: string;
1073
+ /**
1074
+ * Enum Options
1075
+ */
1076
+ enum_options: Array<EnumOption>;
1077
+ /**
1078
+ * Name
1079
+ *
1080
+ * Field name. Used as the key in the extraction response.
1081
+ */
1082
+ name: string;
1083
+ /**
1084
+ * Persistent Id
1085
+ *
1086
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
1087
+ */
1088
+ persistent_id?: string | null;
1089
+ /**
1090
+ * Source
1091
+ *
1092
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
1093
+ */
1094
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
1095
+ };
1096
+ /**
1097
+ * EnumOption
1098
+ */
1099
+ type EnumOption = {
1100
+ /**
1101
+ * Description
1102
+ *
1103
+ * Free-form description shown to the model.
1104
+ */
1105
+ description: string;
1106
+ /**
1107
+ * Name
1108
+ */
1109
+ name: string;
1110
+ };
1111
+ /**
1112
+ * Evidence
1113
+ *
1114
+ * A snippet of source text supporting an extracted value, with the page it came from.
1115
+ *
1116
+ * When ``text`` starts with ``metadata.``, the value was sourced from the
1117
+ * packet's caller-supplied metadata (not the document): the remainder is
1118
+ * the JSON path into that metadata, and ``page_number`` is ``0``. Encoded
1119
+ * in ``text`` on purpose — same wire shape as document evidence, no schema
1120
+ * change for SDK consumers.
1121
+ */
1122
+ type Evidence = {
1123
+ /**
1124
+ * Page Number
1125
+ *
1126
+ * 1-indexed page number where the snippet was found.
1127
+ */
1128
+ page_number: number;
1129
+ /**
1130
+ * Text
1131
+ *
1132
+ * The exact source-text snippet that supports the extracted value.
1133
+ */
1134
+ text: string;
1135
+ };
1136
+ /**
1137
+ * ExpressionCheck
1138
+ *
1139
+ * A CEL expression over the whole extraction, evaluated in a sandbox.
1140
+ *
1141
+ * The expression reads one root variable ``data`` and addresses fields by
1142
+ * extracted name (``data.total``, ``data.lineas.map(l, l.importe)``), never by
1143
+ * ``persistent_id`` — so ``field_ids`` returns ``[]`` for it, and a field
1144
+ * rename silently breaks the rule. An expression the evaluator cannot parse,
1145
+ * cannot answer with a boolean, or prices above its evaluation budget reports
1146
+ * ``inconclusive``.
1147
+ *
1148
+ * ADR platform/0036 records why the CEL parser stays out of this package, so
1149
+ * ``expression`` is unvalidated here.
1150
+ */
1151
+ type ExpressionCheck = {
1152
+ /**
1153
+ * Expression
1154
+ */
1155
+ expression: string;
1156
+ /**
1157
+ * Type
1158
+ */
1159
+ type: 'expression';
1160
+ };
1161
+ /**
1162
+ * ExtractedField
1163
+ *
1164
+ * One extracted field's value, confidence, and supporting evidence.
1165
+ */
1166
+ type ExtractedField$1 = {
1167
+ /**
1168
+ * Confidence
1169
+ *
1170
+ * Model confidence in the extracted value, on a 0-100 scale. `null` when the backend did not produce a confidence (e.g. manual entry).
1171
+ */
1172
+ confidence?: number | null;
1173
+ /**
1174
+ * Evidence
1175
+ *
1176
+ * Source-text snippets the model used to derive this value.
1177
+ */
1178
+ evidence?: Array<Evidence>;
1179
+ /**
1180
+ * Value
1181
+ *
1182
+ * The extracted value, always as a string — a field declared `integer` returns `"3"`, not `3`. Values are stored as text, so `data_type` governs how the field is extracted and validated, not the JSON type you get back; parse it yourself, minding that a document may write a number as `1.026,00`. `null` when extraction produced no value.
1183
+ */
1184
+ value: unknown | null;
1185
+ /**
1186
+ * Value Override
1187
+ *
1188
+ * A human-supplied override of the extracted `value`, if one was set during verification. `null` when no override exists.
1189
+ */
1190
+ value_override?: unknown | null;
1191
+ /**
1192
+ * Verification Status
1193
+ *
1194
+ * Verification state for this datapoint (e.g. `not_verified`, `verified`). `null` when not yet reviewed.
1195
+ */
1196
+ verification_status?: string | null;
1197
+ };
1198
+ /**
1199
+ * Extraction
1200
+ *
1201
+ * One unit of extracted data. For linear (parse->extract) workflows there
1202
+ * is exactly one entry with `split_name=null` and `partition=null`. For split
1203
+ * workflows there is one entry per (split, partition) pair; join with
1204
+ * `splits[]` by `split_name` to look up geometry.
1205
+ */
1206
+ type Extraction = {
1207
+ /**
1208
+ * Fields
1209
+ *
1210
+ * Extracted fields keyed by field name. Same shape as the legacy top-level `extraction`.
1211
+ */
1212
+ fields: {
1213
+ [key: string]: ExtractedField$1 | Array<{
1214
+ [key: string]: ExtractedField$1;
1215
+ }>;
1216
+ };
763
1217
  /**
764
1218
  * Partition
765
1219
  *
@@ -772,20 +1226,21 @@ type Extraction = {
772
1226
  * The split category this extraction belongs to. `null` for linear workflows.
773
1227
  */
774
1228
  split_name?: string | null;
1229
+ /**
1230
+ * Validations
1231
+ *
1232
+ * Configured validation verdicts and automatic extraction review warnings. Unresolved chunk fields have a null value and an inconclusive warning with candidate values and evidence, even without a validate node.
1233
+ */
1234
+ validations?: Array<Validation>;
775
1235
  };
776
1236
  /**
777
1237
  * ExtractionSchema
778
1238
  *
779
- * Schema describing what an extract node produces. Modeled as a typed
780
- * object (not a bare ``list[AnyField]``) so metadata can be added later
781
- * (versioning, derived flags, output-shape hints) without another
782
- * wire-format break.
1239
+ * Schema describing what an extract node produces.
783
1240
  *
784
- * Every extraction schema must declare at least one field. The backend
785
- * executor populates this list from ``FieldWorkflowVersion`` rows
786
- * *before* constructing the typed ExtractNode; extract nodes without
787
- * any assigned fields are skipped at the executor layer rather than
788
- * sent to the worker with an empty schema.
1241
+ * Modeled as a typed object (not a bare ``list[AnyField]``) so metadata
1242
+ * can be added later (versioning, derived flags, output-shape hints)
1243
+ * without another wire-format break. At least one field is required.
789
1244
  */
790
1245
  type ExtractionSchema = {
791
1246
  /**
@@ -793,25 +1248,7 @@ type ExtractionSchema = {
793
1248
  *
794
1249
  * Field definitions making up this extract's output.
795
1250
  */
796
- fields: Array<({
797
- data_type: 'string';
798
- } & StringField) | ({
799
- data_type: 'integer';
800
- } & IntegerField) | ({
801
- data_type: 'float';
802
- } & FloatField) | ({
803
- data_type: 'boolean';
804
- } & BooleanField) | ({
805
- data_type: 'date';
806
- } & DateField) | ({
807
- data_type: 'datetime';
808
- } & DatetimeField) | ({
809
- data_type: 'enum';
810
- } & EnumField) | ({
811
- data_type: 'multi_select';
812
- } & MultiSelectField) | ({
813
- data_type: 'object';
814
- } & ObjectField)>;
1251
+ fields: Array<StringField | IntegerField | FloatField | BooleanField | DateField | DatetimeField | EnumField | MultiSelectField | ObjectField>;
815
1252
  };
816
1253
  /**
817
1254
  * FilePages
@@ -851,17 +1288,25 @@ type FloatField = {
851
1288
  *
852
1289
  * Free-form description shown to the extraction model.
853
1290
  */
854
- description: string;
855
- /**
856
- * Lookup
857
- */
858
- lookup?: boolean;
1291
+ description?: string;
859
1292
  /**
860
1293
  * Name
861
1294
  *
862
1295
  * Field name. Used as the key in the extraction response.
863
1296
  */
864
1297
  name: string;
1298
+ /**
1299
+ * Persistent Id
1300
+ *
1301
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
1302
+ */
1303
+ persistent_id?: string | null;
1304
+ /**
1305
+ * Source
1306
+ *
1307
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
1308
+ */
1309
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
865
1310
  };
866
1311
  /**
867
1312
  * Hyperlink
@@ -895,17 +1340,48 @@ type IntegerField = {
895
1340
  *
896
1341
  * Free-form description shown to the extraction model.
897
1342
  */
898
- description: string;
899
- /**
900
- * Lookup
901
- */
902
- lookup?: boolean;
1343
+ description?: string;
903
1344
  /**
904
1345
  * Name
905
1346
  *
906
1347
  * Field name. Used as the key in the extraction response.
907
1348
  */
908
1349
  name: string;
1350
+ /**
1351
+ * Persistent Id
1352
+ *
1353
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
1354
+ */
1355
+ persistent_id?: string | null;
1356
+ /**
1357
+ * Source
1358
+ *
1359
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
1360
+ */
1361
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
1362
+ };
1363
+ /**
1364
+ * KnowledgeNode
1365
+ *
1366
+ * Terminal knowledge sink — its presence opts the workflow into the
1367
+ * knowledge base (priced separately, so absent by default).
1368
+ *
1369
+ * The backend reacts to parse callbacks by ingesting parsed markdown into
1370
+ * the workflow's navigable corpus; core never executes this node — the
1371
+ * execution builder keeps it and its edges off the worker message. Emits
1372
+ * nothing downstream.
1373
+ */
1374
+ type KnowledgeNode = {
1375
+ /**
1376
+ * Id
1377
+ *
1378
+ * Stable identifier for this node within the graph.
1379
+ */
1380
+ id: string;
1381
+ /**
1382
+ * Type
1383
+ */
1384
+ type: 'knowledge';
909
1385
  };
910
1386
  /**
911
1387
  * LookupFileUpload
@@ -913,9 +1389,9 @@ type IntegerField = {
913
1389
  * Inline lookup-file content carried on the typed create call.
914
1390
  *
915
1391
  * The backend reads ``filename`` + ``content`` (base64-encoded bytes),
916
- * uploads the file to S3 during workflow create, and stores the resulting
917
- * URI in ``ExtractNode.lookup_files``. This field is stripped from the
918
- * persisted ``GraphNode.config`` — it is create-input only.
1392
+ * uploads the file, and stores the resulting URI in
1393
+ * ``ExtractNode.lookup_files``. Create-input only — not persisted on
1394
+ * the node after upload.
919
1395
  */
920
1396
  type LookupFileUpload = {
921
1397
  /**
@@ -942,24 +1418,37 @@ type MultiSelectField = {
942
1418
  *
943
1419
  * Free-form description shown to the extraction model.
944
1420
  */
945
- description: string;
1421
+ description?: string;
946
1422
  /**
947
1423
  * Enum Options
948
1424
  */
949
1425
  enum_options: Array<EnumOption>;
950
- /**
951
- * Lookup
952
- */
953
- lookup?: boolean;
954
1426
  /**
955
1427
  * Name
956
1428
  *
957
1429
  * Field name. Used as the key in the extraction response.
958
1430
  */
959
1431
  name: string;
1432
+ /**
1433
+ * Persistent Id
1434
+ *
1435
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
1436
+ */
1437
+ persistent_id?: string | null;
1438
+ /**
1439
+ * Source
1440
+ *
1441
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
1442
+ */
1443
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
960
1444
  };
961
1445
  /**
962
1446
  * ObjectField
1447
+ *
1448
+ * A repeating group — the way a table or line-item list is modelled.
1449
+ *
1450
+ * There is no separate list type: one ``object`` field describes the shape of
1451
+ * a single row, and the extraction returns an array of those rows.
963
1452
  */
964
1453
  type ObjectField = {
965
1454
  /**
@@ -971,11 +1460,7 @@ type ObjectField = {
971
1460
  *
972
1461
  * Free-form description shown to the extraction model.
973
1462
  */
974
- description: string;
975
- /**
976
- * Lookup
977
- */
978
- lookup?: boolean;
1463
+ description?: string;
979
1464
  /**
980
1465
  * Name
981
1466
  *
@@ -985,36 +1470,243 @@ type ObjectField = {
985
1470
  /**
986
1471
  * Nested Fields
987
1472
  *
988
- * Child fields of this object. Only one level of nesting is supported — an object field's children must be non-object types.
1473
+ * Columns of one row. The extracted value is an array of objects with these keys, one entry per row found. Only one level of nesting is supported — an object field's children must be non-object types.
989
1474
  */
990
- nested_fields: Array<({
991
- data_type: 'string';
992
- } & StringField) | ({
993
- data_type: 'integer';
994
- } & IntegerField) | ({
995
- data_type: 'float';
996
- } & FloatField) | ({
997
- data_type: 'boolean';
998
- } & BooleanField) | ({
999
- data_type: 'date';
1000
- } & DateField) | ({
1001
- data_type: 'datetime';
1002
- } & DatetimeField) | ({
1003
- data_type: 'enum';
1004
- } & EnumField) | ({
1005
- data_type: 'multi_select';
1006
- } & MultiSelectField)>;
1007
- };
1008
- /**
1009
- * ParseNode
1010
- */
1011
- type ParseNode = {
1475
+ nested_fields: Array<StringField | IntegerField | FloatField | BooleanField | DateField | DatetimeField | EnumField | MultiSelectField>;
1012
1476
  /**
1013
- * Cache
1477
+ * Persistent Id
1478
+ *
1479
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
1480
+ */
1481
+ persistent_id?: string | null;
1482
+ /**
1483
+ * Source
1484
+ *
1485
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
1486
+ */
1487
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
1488
+ };
1489
+ /**
1490
+ * OneOfCheck
1491
+ */
1492
+ type OneOfCheck = {
1493
+ /**
1494
+ * Allowed
1495
+ */
1496
+ allowed: Array<string>;
1497
+ /**
1498
+ * Case Sensitive
1499
+ */
1500
+ case_sensitive?: boolean;
1501
+ /**
1502
+ * Field
1503
+ *
1504
+ * The field to test. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
1505
+ */
1506
+ field: string;
1507
+ /**
1508
+ * Type
1509
+ */
1510
+ type: 'one_of';
1511
+ };
1512
+ /**
1513
+ * ParseResult
1514
+ *
1515
+ * Parsed markdown for a file.
1516
+ */
1517
+ type ParseResult = {
1518
+ /**
1519
+ * Blocks
1520
+ *
1521
+ * Structured per-block representation of the parsed document. One entry per `<a id></a>` anchor in document order, with type-specific structured data (`rows` for tables, `image_base64` for pictures) surfaced as first-class fields so consumers don't have to HTML-parse.
1522
+ */
1523
+ blocks?: Array<Block>;
1524
+ /**
1525
+ * Layout Confidence
1526
+ *
1527
+ * Document-level YOLO layout confidence on a 0-1 scale, char-weighted mean across all blocks. `null` if no annotated sections.
1528
+ */
1529
+ layout_confidence?: number | null;
1530
+ /**
1531
+ * Markdown
1532
+ *
1533
+ * Document content rendered as structured markdown. Each block is preceded by an empty `<a id="p{page}_b{idx}"></a>` anchor (invisible in any markdown renderer; the id joins to `blocks[].id` and can be used as an in-page link target). Image hydration for picture/figure blocks happens client-side. `null` if parsing failed.
1534
+ */
1535
+ markdown: string | null;
1536
+ /**
1537
+ * Parse Confidence
1538
+ *
1539
+ * Document-level parse confidence on a 0-100 scale, char-weighted mean of per-block LLM logprob scores. `null` when no blocks have logprob-based confidence.
1540
+ */
1541
+ parse_confidence?: number | null;
1542
+ /**
1543
+ * Text
1544
+ *
1545
+ * `markdown` with `<img>` tags removed and runs of blank lines collapsed. Block anchors are deliberately kept, so on a document whose pictures are markdown images rather than `<img>` tags this is `markdown` verbatim — read one or the other, not both. `null` if `markdown` is null.
1546
+ */
1547
+ text?: string | null;
1548
+ };
1549
+ /**
1550
+ * PublicEditNode
1551
+ *
1552
+ * Terminal form-filler. ``reference_uris`` is resolved server-side at run
1553
+ * time from ``reference_document_ids`` — omitted here, and any client-supplied
1554
+ * value is discarded rather than trusted.
1555
+ */
1556
+ type PublicEditNode = {
1557
+ /**
1558
+ * Font
1559
+ *
1560
+ * Typeface the filled values are written in.
1561
+ */
1562
+ font?: 'sans' | 'serif' | 'mono';
1563
+ /**
1564
+ * Id
1565
+ *
1566
+ * Stable identifier for this node within the graph.
1567
+ */
1568
+ id: string;
1569
+ /**
1570
+ * Instructions
1571
+ *
1572
+ * Free-text values to map onto the fillable fields detected on the upstream parse's PDF, e.g. 'Name: ACME SL; Date: 2026-01-01; I accept the terms: yes'. Takes precedence over a reference document where both address the same field.
1573
+ */
1574
+ instructions?: string | null;
1575
+ /**
1576
+ * Output Mode
1577
+ *
1578
+ * 'flattened' paints the values on and the PDF is final. 'editable' leaves each value in a live form field a reviewer can correct in any PDF viewer.
1579
+ */
1580
+ output_mode?: 'flattened' | 'editable';
1581
+ /**
1582
+ * Reference Document Ids
1583
+ *
1584
+ * Ids of reference documents this node fills from, uploaded to the workflow beforehand. Every id must belong to this workflow and be fully resolved, or the run is refused rather than filled from a partial reference.
1585
+ */
1586
+ reference_document_ids?: Array<string>;
1587
+ /**
1588
+ * Type
1589
+ */
1590
+ type: 'edit';
1591
+ };
1592
+ /**
1593
+ * PublicExtractNode
1594
+ */
1595
+ type PublicExtractNode = {
1596
+ /**
1597
+ * Schema for the fields this node extracts. Required.
1598
+ */
1599
+ extraction_schema: ExtractionSchema;
1600
+ /**
1601
+ * Id
1602
+ *
1603
+ * Stable identifier for this node within the graph.
1604
+ */
1605
+ id: string;
1606
+ /**
1607
+ * Lookup File Uploads
1608
+ *
1609
+ * Inline lookup-file content for the typed create call. Each entry is uploaded and the resulting URI is appended to ``lookup_files``; this field is create-input only.
1610
+ */
1611
+ lookup_file_uploads?: Array<LookupFileUpload>;
1612
+ /**
1613
+ * Lookup Files
1614
+ *
1615
+ * Smart-lookup reference document URIs persisted on the extract node.
1616
+ */
1617
+ lookup_files?: Array<string>;
1618
+ /**
1619
+ * Lookup Reasoning Effort
1620
+ *
1621
+ * Reasoning effort for the smart-lookup matcher (gpt-5 family): minimal | low | medium | high. None = model default. Higher effort improves match reliability on noisy join keys at higher latency/cost.
1622
+ */
1623
+ lookup_reasoning_effort?: 'minimal' | 'low' | 'medium' | 'high' | null;
1624
+ /**
1625
+ * Lookup Suggestion
1626
+ *
1627
+ * Free-form hint shown to the smart-lookup matcher.
1628
+ */
1629
+ lookup_suggestion?: string | null;
1630
+ /**
1631
+ * Mode
1632
+ *
1633
+ * Extraction tier. 'standard' (default): single-pass extraction — the best balance for simple documents and layouts. 'agentic': multi-step extraction that maps every table to the schema and reasons across sections — for dense or cross-page tables; extra cost per page. 'lite' (shown as 'Fast' in the app): standard extraction, faster and cheaper; quality may vary on complex layouts.
1634
+ */
1635
+ mode?: 'standard' | 'agentic' | 'lite';
1636
+ /**
1637
+ * Type
1638
+ */
1639
+ type: 'extract';
1640
+ /**
1641
+ * Use Images
1642
+ *
1643
+ * Standard/lite modes: send each PDF page's rendered image alongside its parsed text so the model can read layout the text missed — adds vision cost on every page.
1644
+ */
1645
+ use_images?: boolean;
1646
+ };
1647
+ /**
1648
+ * PublicIfElseNode
1649
+ */
1650
+ type PublicIfElseNode = {
1651
+ /**
1652
+ * Condition
1653
+ */
1654
+ condition: ({
1655
+ type: 'range';
1656
+ } & RangeCheck) | ({
1657
+ type: 'date';
1658
+ } & DateCheck) | ({
1659
+ type: 'arithmetic';
1660
+ } & ArithmeticCheck) | ({
1661
+ type: 'comparison';
1662
+ } & ComparisonCheck) | ({
1663
+ type: 'one_of';
1664
+ } & OneOfCheck) | ({
1665
+ type: 'regex';
1666
+ } & RegexCheck) | ({
1667
+ type: 'required';
1668
+ } & RequiredCheck) | ({
1669
+ type: 'confidence';
1670
+ } & ConfidenceCheck) | ({
1671
+ type: 'expression';
1672
+ } & ExpressionCheck) | ({
1673
+ type: 'validation';
1674
+ } & ValidationCheck) | ({
1675
+ type: 'all_of';
1676
+ } & AllOfCheck) | ({
1677
+ type: 'any_of';
1678
+ } & AnyOfCheck);
1679
+ /**
1680
+ * Id
1681
+ *
1682
+ * Stable identifier for this node within the graph.
1683
+ */
1684
+ id: string;
1685
+ /**
1686
+ * Type
1687
+ */
1688
+ type: 'if_else';
1689
+ };
1690
+ /**
1691
+ * PublicParseNode
1692
+ */
1693
+ type PublicParseNode = {
1694
+ /**
1695
+ * Cache
1696
+ *
1697
+ * Reuse parsed output when the same file was already parsed with the same mode and settings — a hit skips the whole parse. Disable to force a fresh parse.
1014
1698
  */
1015
1699
  cache?: boolean;
1700
+ /**
1701
+ * Effort
1702
+ *
1703
+ * Agentic mode: quality/cost preset. 'low' = several times cheaper but more errors on dense or low-contrast tables, 'mid' (default) = balanced, 'accurate' = highest fidelity. (Distinct from lite `ocr_effort`.)
1704
+ */
1705
+ effort?: 'low' | 'mid' | 'accurate';
1016
1706
  /**
1017
1707
  * Figure Enhancement
1708
+ *
1709
+ * Standard mode: extract structured data from charts and images — extra processing per figure. Ignored in agentic and in lite.
1018
1710
  */
1019
1711
  figure_enhancement?: boolean;
1020
1712
  /**
@@ -1025,111 +1717,295 @@ type ParseNode = {
1025
1717
  id: string;
1026
1718
  /**
1027
1719
  * Mode
1720
+ *
1721
+ * Parse tier. 'standard' (default): page-by-page parsing with reading-order correction — the best quality/speed balance for most documents and tables. 'agentic': adaptive parsing that works hardest on dense tables (50+ rows, many columns) — highest fidelity on complex documents; extra cost per page. 'lite' (shown as 'Fast' in the app): OCR-only tier — accurate OCR, no LLM call; use standard or agentic when the output needs LLM correction. 'flash': the PDF's own text layer plus layout grounding, no model call — the cheapest and fastest tier; a page with no text layer is OCR'd by default (see scanned_pages).
1028
1722
  */
1029
- mode?: 'standard' | 'agentic';
1723
+ mode?: 'standard' | 'agentic' | 'lite' | 'flash';
1724
+ /**
1725
+ * Ocr Effort
1726
+ *
1727
+ * Lite mode: 'high' (default) = the strongest OCR — best accuracy on complex layouts, tables, and handwriting. 'medium' = faster and cheaper, for clean digital documents. (Distinct from agentic `effort`.)
1728
+ */
1729
+ ocr_effort?: 'medium' | 'high';
1030
1730
  /**
1031
1731
  * Prompt Hint
1032
1732
  *
1033
- * Free-form hint shown to the parse model to bias output.
1733
+ * Free-form hint that biases the parse output. Standard and agentic modes only; ignored in lite.
1034
1734
  */
1035
1735
  prompt_hint?: string | null;
1736
+ /**
1737
+ * Scanned Pages
1738
+ *
1739
+ * Flash mode: what to do with a page whose text layer produced no words. 'ocr' (default): OCR the page and parse it like any other, at no extra model cost. 'skip': serve it blank and flag it, don't fail the parse. 'fail': raise, naming the page numbers.
1740
+ */
1741
+ scanned_pages?: 'ocr' | 'skip' | 'fail';
1036
1742
  /**
1037
1743
  * Type
1038
1744
  */
1039
1745
  type: 'parse';
1040
1746
  };
1041
1747
  /**
1042
- * ParseResult
1748
+ * PublicSlackAlertNode
1043
1749
  *
1044
- * Parsed markdown for a file.
1750
+ * Terminal alert-sink. ``field_index`` is executor-injected — omitted here.
1045
1751
  */
1046
- type ParseResult = {
1752
+ type PublicSlackAlertNode = {
1047
1753
  /**
1048
- * Blocks
1754
+ * Channel Id
1755
+ */
1756
+ channel_id: string;
1757
+ /**
1758
+ * Channel Name
1759
+ */
1760
+ channel_name: string;
1761
+ /**
1762
+ * Id
1049
1763
  *
1050
- * Structured per-block representation of the parsed document. One entry per `<a id></a>` anchor in document order, with type-specific structured data (`rows` for tables, `image_base64` for pictures) surfaced as first-class fields so consumers don't have to HTML-parse.
1764
+ * Stable identifier for this node within the graph.
1051
1765
  */
1052
- blocks?: Array<Block>;
1766
+ id: string;
1053
1767
  /**
1054
- * Layout Confidence
1768
+ * Message Template
1769
+ */
1770
+ message_template: string;
1771
+ /**
1772
+ * Severity
1773
+ */
1774
+ severity?: 'info' | 'warning' | 'critical';
1775
+ /**
1776
+ * Type
1777
+ */
1778
+ type: 'slack_alert';
1779
+ };
1780
+ /**
1781
+ * PublicValidateNode
1782
+ */
1783
+ type PublicValidateNode = {
1784
+ /**
1785
+ * Id
1055
1786
  *
1056
- * Document-level YOLO layout confidence on a 0-100 scale, char-weighted mean across all blocks. `null` if no annotated sections.
1787
+ * Stable identifier for this node within the graph.
1057
1788
  */
1058
- layout_confidence?: number | null;
1789
+ id: string;
1059
1790
  /**
1060
- * Markdown
1791
+ * Rules
1792
+ */
1793
+ rules: Array<ValidationRule>;
1794
+ /**
1795
+ * Type
1796
+ */
1797
+ type: 'validate';
1798
+ };
1799
+ /**
1800
+ * RangeCheck
1801
+ */
1802
+ type RangeCheck = {
1803
+ /**
1804
+ * Field
1061
1805
  *
1062
- * Document content rendered as structured markdown. Each block is preceded by an empty `<a id="p{page}_b{idx}"></a>` anchor (invisible in any markdown renderer; the id joins to `blocks[].id` and can be used as an in-page link target). Image hydration for picture/figure blocks happens client-side. `null` if parsing failed.
1806
+ * The bounded numeric field. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
1807
+ */
1808
+ field: string;
1809
+ /**
1810
+ * Max
1811
+ */
1812
+ max?: number | null;
1813
+ /**
1814
+ * Min
1815
+ */
1816
+ min?: number | null;
1817
+ /**
1818
+ * Type
1819
+ */
1820
+ type: 'range';
1821
+ };
1822
+ /**
1823
+ * RegexCheck
1824
+ */
1825
+ type RegexCheck = {
1826
+ /**
1827
+ * Field
1828
+ *
1829
+ * The field to match. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
1830
+ */
1831
+ field: string;
1832
+ /**
1833
+ * Pattern
1834
+ *
1835
+ * Evaluated with google-re2 (linear time); never stdlib re.
1836
+ */
1837
+ pattern: string;
1838
+ /**
1839
+ * Type
1840
+ */
1841
+ type: 'regex';
1842
+ };
1843
+ /**
1844
+ * RequiredCheck
1845
+ */
1846
+ type RequiredCheck = {
1847
+ /**
1848
+ * Field
1849
+ *
1850
+ * The field that must be present. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
1851
+ */
1852
+ field: string;
1853
+ /**
1854
+ * Type
1855
+ */
1856
+ type: 'required';
1857
+ };
1858
+ /**
1859
+ * ResultsResponseV3
1860
+ *
1861
+ * v3-scoped results envelope — same shape as ``ResultsResponse`` minus the
1862
+ * legacy ``collection_id`` alias. v3 emits only ``document_packet_id``.
1863
+ */
1864
+ type ResultsResponseV3 = {
1865
+ /**
1866
+ * Classifications
1867
+ *
1868
+ * Per-classifier-node verdicts. Empty when the workflow has no classifier.
1869
+ */
1870
+ classifications?: Array<ClassificationResult>;
1871
+ /**
1872
+ * Document Packet Id
1873
+ *
1874
+ * The document packet's UUID — v3 canonical name for `collection_id`. Same value; both fields are always present.
1875
+ */
1876
+ document_packet_id: string;
1877
+ /**
1878
+ * Edits
1879
+ *
1880
+ * Filled-form output, one entry per file an edit node processed. Empty when the workflow has no edit node.
1881
+ */
1882
+ edits?: Array<Edit>;
1883
+ /**
1884
+ * Extraction
1885
+ *
1886
+ * **Deprecated** — use `extractions` instead. Extracted fields keyed by field name, populated only for linear workflows (single extract node, no splitter). `null` for split workflows; read `extractions[]` instead.
1887
+ *
1888
+ * @deprecated
1889
+ */
1890
+ extraction?: {
1891
+ [key: string]: ExtractedField$1 | Array<{
1892
+ [key: string]: ExtractedField$1;
1893
+ }>;
1894
+ } | null;
1895
+ /**
1896
+ * Extractions
1897
+ *
1898
+ * Flat list of extraction datapoints. Linear workflows produce one entry with `split_name=null` and `partition=null`. Split workflows produce one entry per (split, partition). Empty when no extraction has run yet.
1899
+ */
1900
+ extractions?: Array<Extraction>;
1901
+ /**
1902
+ * Parse-node output (rendered markdown). `null` when the workflow has no parse node. Always present in the response.
1903
+ */
1904
+ parse?: ParseResult | null;
1905
+ /**
1906
+ * Splits
1907
+ *
1908
+ * Splitter output: category-level geometry with optional partitions. Empty when the workflow has no splitter.
1909
+ */
1910
+ splits?: Array<SplitResult>;
1911
+ /**
1912
+ * Verification Url
1913
+ *
1914
+ * Link to the AnyFormat dashboard for human review of this collection's results. `null` if the dashboard URL cannot be constructed (e.g. no files in the collection, or the deployment has no frontend URL configured).
1915
+ */
1916
+ verification_url?: string | null;
1917
+ };
1918
+ /**
1919
+ * RunDetailV3
1920
+ *
1921
+ * Flat single-run read: lifecycle status plus results inline.
1922
+ *
1923
+ * `results` is `null` until the run reaches `processed`, then carries the
1924
+ * same results envelope `GET /v2/workflows/{id}/files/{id}/results/`
1925
+ * returns — no separate results endpoint, no 412 while in flight.
1926
+ */
1927
+ type RunDetailV3 = {
1928
+ /**
1929
+ * Created At
1930
+ *
1931
+ * Timestamp when the run was triggered (ISO 8601).
1932
+ */
1933
+ created_at?: string | null;
1934
+ /**
1935
+ * Document Packet Id
1936
+ *
1937
+ * The document packet the run executed on (hyphenated UUID).
1938
+ */
1939
+ document_packet_id: string;
1940
+ /**
1941
+ * Id
1942
+ *
1943
+ * Unique identifier of the run (hyphenated UUID).
1944
+ */
1945
+ id: string;
1946
+ /**
1947
+ * Extraction results envelope; `null` until `status` is `processed`. Same shape as the v2 results endpoint.
1948
+ */
1949
+ results?: ResultsResponseV3 | null;
1950
+ /**
1951
+ * Execution status. Non-terminal: `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.
1063
1952
  */
1064
- markdown: string | null;
1953
+ status: RunStatus;
1065
1954
  /**
1066
- * Parse Confidence
1955
+ * Updated At
1067
1956
  *
1068
- * Document-level parse confidence on a 0-100 scale, char-weighted mean of per-block LLM logprob scores. `null` when no blocks have logprob-based confidence.
1957
+ * Timestamp of the run's last status change (ISO 8601).
1069
1958
  */
1070
- parse_confidence?: number | null;
1959
+ updated_at?: string | null;
1071
1960
  /**
1072
- * Text
1961
+ * Workflow Id
1073
1962
  *
1074
- * Plain markdown with structural HTML removed — `<DOCUMENT>` framing, block anchors, `<img>` tags, and `<figure-content>` wrappers stripped. Useful when feeding the parsed output into an LLM or a search index that doesn't need the block-level metadata. `null` if `markdown` is null.
1963
+ * The workflow this run executed (hyphenated UUID).
1075
1964
  */
1076
- text?: string | null;
1965
+ workflow_id: string;
1077
1966
  };
1078
1967
  /**
1079
- * ResultsResponse
1968
+ * RunStatus
1080
1969
  *
1081
- * Canonical response shape for the file-collection results endpoint.
1970
+ * Execution lifecycle of a run. Non-terminal: ``queued``,
1971
+ * ``in_progress``. Terminal: ``processed`` (success), ``error``,
1972
+ * ``cancelled``.
1973
+ */
1974
+ type RunStatus = 'queued' | 'in_progress' | 'processed' | 'error' | 'cancelled';
1975
+ /**
1976
+ * RunSummaryV3
1082
1977
  *
1083
- * Returned with HTTP 200 once processing completes. Returns 412 while processing is
1084
- * in progress; poll until 200, or use webhooks.
1978
+ * Slim run projection returned by list pages.
1085
1979
  */
1086
- type ResultsResponse = {
1087
- /**
1088
- * Classifications
1089
- *
1090
- * Per-classifier-node verdicts. Empty when the workflow has no classifier.
1091
- */
1092
- classifications?: Array<ClassificationResult>;
1980
+ type RunSummaryV3 = {
1093
1981
  /**
1094
- * Collection Id
1982
+ * Created At
1095
1983
  *
1096
- * The file collection's UUID. Same value as the `id` returned by `POST /v2/workflows/{wid}/run/`.
1984
+ * Timestamp when the run was triggered (ISO 8601).
1097
1985
  */
1098
- collection_id: string;
1986
+ created_at?: string | null;
1099
1987
  /**
1100
- * Extraction
1988
+ * Document Packet Id
1101
1989
  *
1102
- * **Deprecated** — use `extractions` instead. Extracted fields keyed by field name, populated only for linear workflows (single extract node, no splitter). `null` for split workflows; read `extractions[]` instead.
1103
- *
1104
- * @deprecated
1990
+ * The document packet the run executes on (hyphenated UUID).
1105
1991
  */
1106
- extraction?: {
1107
- [key: string]: ExtractedField | Array<{
1108
- [key: string]: ExtractedField;
1109
- }>;
1110
- } | null;
1992
+ document_packet_id: string;
1111
1993
  /**
1112
- * Extractions
1994
+ * Id
1113
1995
  *
1114
- * Flat list of extraction datapoints. Linear workflows produce one entry with `split_name=null` and `partition=null`. Split workflows produce one entry per (split, partition). Empty when no extraction has run yet.
1115
- */
1116
- extractions?: Array<Extraction>;
1117
- /**
1118
- * Parse-node output (rendered markdown). `null` when the workflow has no parse node. Always present in the response.
1996
+ * Unique identifier of the run (hyphenated UUID).
1119
1997
  */
1120
- parse?: ParseResult | null;
1998
+ id: string;
1121
1999
  /**
1122
- * Splits
1123
- *
1124
- * Splitter output: category-level geometry with optional partitions. Empty when the workflow has no splitter.
2000
+ * Execution status. Non-terminal: `queued`, `in_progress`. Terminal: `processed` (success), `error`, `cancelled`.
1125
2001
  */
1126
- splits?: Array<SplitResult>;
2002
+ status: RunStatus;
1127
2003
  /**
1128
- * Verification Url
2004
+ * Updated At
1129
2005
  *
1130
- * Link to the AnyFormat dashboard for human review of this collection's results. `null` if the dashboard URL cannot be constructed (e.g. no files in the collection, or the deployment has no frontend URL configured).
2006
+ * Timestamp of the run's last status change (ISO 8601).
1131
2007
  */
1132
- verification_url?: string | null;
2008
+ updated_at?: string | null;
1133
2009
  };
1134
2010
  /**
1135
2011
  * SplitPartition
@@ -1140,9 +2016,9 @@ type SplitPartition = {
1140
2016
  /**
1141
2017
  * Confidence
1142
2018
  *
1143
- * 0-100 minimum confidence across the partition's ranges.
2019
+ * 0-100 minimum confidence across the partition's ranges. `null` when the partition holds no page, because nothing was measured.
1144
2020
  */
1145
- confidence: number;
2021
+ confidence: number | null;
1146
2022
  /**
1147
2023
  * Files
1148
2024
  */
@@ -1165,9 +2041,9 @@ type SplitResult = {
1165
2041
  /**
1166
2042
  * Confidence
1167
2043
  *
1168
- * 0-100 aggregate confidence (min across partitions).
2044
+ * 0-100 aggregate confidence (min across partitions). `null` when the category matched no page, because nothing was measured.
1169
2045
  */
1170
- confidence: number;
2046
+ confidence: number | null;
1171
2047
  /**
1172
2048
  * Files
1173
2049
  *
@@ -1222,6 +2098,8 @@ type SplitterRule = {
1222
2098
  name: string;
1223
2099
  /**
1224
2100
  * Partition Key
2101
+ *
2102
+ * Field that further partitions this category into separate sub-documents (e.g. invoice_number): each distinct value becomes its own split, extracted independently. Empty = routing-only, the whole category flows on as one document.
1225
2103
  */
1226
2104
  partition_key?: string;
1227
2105
  };
@@ -1238,61 +2116,176 @@ type StringField = {
1238
2116
  *
1239
2117
  * Free-form description shown to the extraction model.
1240
2118
  */
1241
- description: string;
1242
- /**
1243
- * Lookup
1244
- */
1245
- lookup?: boolean;
2119
+ description?: string;
1246
2120
  /**
1247
2121
  * Name
1248
2122
  *
1249
2123
  * Field name. Used as the key in the extraction response.
1250
2124
  */
1251
2125
  name: string;
2126
+ /**
2127
+ * Persistent Id
2128
+ *
2129
+ * Server-assigned stable field identity (UUID), emitted by GET /definition/. Echo it back on updates — including across renames — to keep quality metrics, ground-truth links and analytics attached to the field. Matching is scoped to the field's nesting level in the immediately-prior version; an id that matches nothing at its level, appears on more than one field, or is sent at workflow creation is rejected with 400. Omit only for genuinely new fields: there is no matching by name, so a field sent without one is always treated as new and minted a fresh id, silently detaching that field's metrics, ground truth and analytics.
2130
+ */
2131
+ persistent_id?: string | null;
2132
+ /**
2133
+ * Source
2134
+ *
2135
+ * How the field gets its value: extraction (from the document), smart_lookup (from the lookup file, always overwrites) or lookup_if_missing (extracted too; the lookup only fills it where extraction left no value).
2136
+ */
2137
+ source?: 'extraction' | 'smart_lookup' | 'lookup_if_missing';
1252
2138
  };
1253
2139
  /**
1254
- * ValidateNode
2140
+ * Validation
2141
+ *
2142
+ * A configured rule verdict or an automatic extraction review warning.
1255
2143
  */
1256
- type ValidateNode = {
2144
+ type Validation = {
1257
2145
  /**
1258
- * Id
2146
+ * Compared Values
1259
2147
  *
1260
- * Stable identifier for this node within the graph.
2148
+ * The field values the rule looked at, keyed by field name. `null` when nothing was compared.
1261
2149
  */
1262
- id: string;
2150
+ compared_values?: {
2151
+ [key: string]: unknown;
2152
+ } | null;
1263
2153
  /**
1264
- * Rules
2154
+ * Description
2155
+ *
2156
+ * The rule's natural-language description; empty for a deterministic rule.
1265
2157
  */
1266
- rules: Array<ValidationRule>;
2158
+ description?: string;
2159
+ /**
2160
+ * Detail
2161
+ *
2162
+ * Human-readable explanation of the verdict.
2163
+ */
2164
+ detail?: string;
2165
+ /**
2166
+ * Rule Id
2167
+ *
2168
+ * The configured rule ID, or an `extract.consolidation:` ID for an automatic review warning.
2169
+ */
2170
+ rule_id: string;
2171
+ /**
2172
+ * Severity
2173
+ *
2174
+ * `error` or `warning`, as declared on the rule.
2175
+ */
2176
+ severity: string;
2177
+ /**
2178
+ * Source Fields
2179
+ *
2180
+ * `persistent_id`s of the rule's inputs. Empty for automatic extraction warnings; field names are in `compared_values`.
2181
+ */
2182
+ source_fields?: Array<string>;
2183
+ /**
2184
+ * Status
2185
+ *
2186
+ * `pass`, `fail`, or `inconclusive` — the last one when the rule could not be evaluated (no data, an unanswerable expression).
2187
+ */
2188
+ status: string;
2189
+ };
2190
+ /**
2191
+ * ValidationCheck
2192
+ *
2193
+ * Routes on the outcome of a named validation rule already run upstream.
2194
+ *
2195
+ * Reads from ``state.validation_results`` (populated by an upstream
2196
+ * ``ValidateNode``), filtered to the current partition (``split_id``) so
2197
+ * per-partition IfElse routing matches per-partition rule outcomes. The
2198
+ * ``status`` values mirror the worker enum
2199
+ * (``anyformat_core.operations.validate_rules`` — ``pass`` / ``fail`` /
2200
+ * ``inconclusive``) verbatim: no translation layer, so template tokens
2201
+ * like ``${validation.<rule_id>.status}`` render the same three strings
2202
+ * the enum uses.
2203
+ *
2204
+ * Unlike every other ``Check`` variant this consumes no extracted fields
2205
+ * (``field_ids`` returns ``[]``); the rule identity is the entire input.
2206
+ * A ``rule_id`` with no matching entry evaluates to ``inconclusive`` — the
2207
+ * rule didn't run for this partition, so the outcome is unknown.
2208
+ */
2209
+ type ValidationCheck = {
2210
+ /**
2211
+ * Rule Id
2212
+ *
2213
+ * Stable id of the upstream ValidationRule to route on.
2214
+ */
2215
+ rule_id: string;
2216
+ /**
2217
+ * Status
2218
+ *
2219
+ * Outcome to match. ``fail`` (default) is the common case for routing to an alert branch.
2220
+ */
2221
+ status?: 'fail' | 'pass' | 'inconclusive';
1267
2222
  /**
1268
2223
  * Type
1269
2224
  */
1270
- type: 'validate';
2225
+ type: 'validation';
1271
2226
  };
1272
2227
  /**
1273
2228
  * ValidationRule
1274
2229
  */
1275
2230
  type ValidationRule = {
2231
+ /**
2232
+ * Check
2233
+ *
2234
+ * Structured deterministic check. Required when kind == 'deterministic'.
2235
+ */
2236
+ check?: ({
2237
+ type: 'range';
2238
+ } & RangeCheck) | ({
2239
+ type: 'date';
2240
+ } & DateCheck) | ({
2241
+ type: 'arithmetic';
2242
+ } & ArithmeticCheck) | ({
2243
+ type: 'comparison';
2244
+ } & ComparisonCheck) | ({
2245
+ type: 'one_of';
2246
+ } & OneOfCheck) | ({
2247
+ type: 'regex';
2248
+ } & RegexCheck) | ({
2249
+ type: 'required';
2250
+ } & RequiredCheck) | ({
2251
+ type: 'confidence';
2252
+ } & ConfidenceCheck) | ({
2253
+ type: 'expression';
2254
+ } & ExpressionCheck) | ({
2255
+ type: 'validation';
2256
+ } & ValidationCheck) | ({
2257
+ type: 'all_of';
2258
+ } & AllOfCheck) | ({
2259
+ type: 'any_of';
2260
+ } & AnyOfCheck) | null;
1276
2261
  /**
1277
2262
  * Description
1278
2263
  *
1279
- * Natural-language description shown to the validation model.
2264
+ * Natural-language description sent to the LLM. Required when kind == 'ai'.
1280
2265
  */
1281
- description: string;
2266
+ description?: string | null;
1282
2267
  /**
1283
2268
  * Id
1284
2269
  *
1285
- * Stable rule id; round-trips through ValidationResult.rule_id.
2270
+ * Stable rule id; round-trips through validation results.
1286
2271
  */
1287
2272
  id: string;
2273
+ /**
2274
+ * Kind
2275
+ *
2276
+ * 'deterministic' = a structured check run in code — instant, free, reproducible; 'ai' = a model judges the rule description against the extraction. Prefer deterministic whenever the condition is exact and testable.
2277
+ */
2278
+ kind?: 'ai' | 'deterministic';
1288
2279
  /**
1289
2280
  * Name
1290
2281
  *
1291
- * Optional human-readable rule name shown on the rule card in the Studio. Stored verbatim on the GraphNode config and surfaced back through the config endpoint so renames round-trip.
2282
+ * Optional human-readable rule name. Round-trips through the config endpoint so renames are preserved.
1292
2283
  */
1293
2284
  name?: string | null;
1294
2285
  /**
1295
2286
  * Severity
2287
+ *
2288
+ * How a failed rule is labelled in results. Display-level only — it never blocks the run.
1296
2289
  */
1297
2290
  severity?: 'error' | 'warning';
1298
2291
  /**
@@ -1305,12 +2298,18 @@ type ValidationRule = {
1305
2298
  /**
1306
2299
  * WorkflowCreateRequest
1307
2300
  *
1308
- * Public-surface workflow create body — typed graph of parse / classify / splitter / extract nodes.
2301
+ * Public-surface workflow create body — typed graph of parse / classify / splitter / extract / validate nodes.
1309
2302
  *
1310
- * Defined as a thin subclass so the FastAPI-generated OpenAPI components
1311
- * entry is named ``WorkflowCreateRequest`` (FastAPI uses the model's
1312
- * ``__name__``). Behaviour is fully inherited from
1313
- * ``WorkflowDefinition`` in ``anyformat.workflow``.
2303
+ * A ``validate`` node carries ``rules``; each rule is either AI-evaluated
2304
+ * (``kind="ai"`` + a natural-language ``description``) or deterministic
2305
+ * (``kind="deterministic"`` + a structured ``check``, evaluated in pure
2306
+ * Python with no model call).
2307
+ *
2308
+ * Uses ``PublicNode`` (public request models with only the fields callers
2309
+ * may set); the domain ``AnyNode`` also carries ``filter`` (worker-only)
2310
+ * and executor-injected / staff-only fields, so the public bodies pin a
2311
+ * stricter node schema. Call :meth:`to_domain` before forwarding to the
2312
+ * backend.
1314
2313
  */
1315
2314
  type WorkflowCreateRequest = {
1316
2315
  /**
@@ -1328,17 +2327,124 @@ type WorkflowCreateRequest = {
1328
2327
  /**
1329
2328
  * Nodes
1330
2329
  */
1331
- nodes: Array<({
1332
- type: 'parse';
1333
- } & ParseNode) | ({
1334
- type: 'classify';
1335
- } & ClassifyNode) | ({
1336
- type: 'splitter';
1337
- } & SplitterNode) | ({
1338
- type: 'extract';
1339
- } & ExtractNode) | ({
1340
- type: 'validate';
1341
- } & ValidateNode)>;
2330
+ nodes: Array<PublicParseNode | ClassifyNode | SplitterNode | PublicExtractNode | PublicValidateNode | PublicIfElseNode | PublicSlackAlertNode | PublicEditNode | KnowledgeNode>;
2331
+ };
2332
+ /**
2333
+ * WorkflowDetailV3
2334
+ *
2335
+ * A workflow with its complete typed graph inline.
2336
+ *
2337
+ * ``{name, description, nodes, edges}`` is the exact shape
2338
+ * ``POST /v3/workflows/`` accepts — mutate it and feed it back to edit.
2339
+ */
2340
+ type WorkflowDetailV3 = {
2341
+ /**
2342
+ * Created At
2343
+ *
2344
+ * Timestamp when the workflow was created (ISO 8601).
2345
+ */
2346
+ created_at?: string | null;
2347
+ /**
2348
+ * Description
2349
+ *
2350
+ * Optional description of what this workflow extracts.
2351
+ */
2352
+ description?: string | null;
2353
+ /**
2354
+ * Edges
2355
+ *
2356
+ * Directed edges between the graph nodes.
2357
+ */
2358
+ edges?: Array<Edge>;
2359
+ /**
2360
+ * Id
2361
+ *
2362
+ * Unique identifier of the workflow (hyphenated UUID).
2363
+ */
2364
+ id: string;
2365
+ /**
2366
+ * Name
2367
+ *
2368
+ * Human-readable name of the workflow.
2369
+ */
2370
+ name: string;
2371
+ /**
2372
+ * Nodes
2373
+ *
2374
+ * Typed graph nodes (parse / classify / splitter / extract / validate / if_else).
2375
+ */
2376
+ nodes: Array<PublicParseNode | ClassifyNode | SplitterNode | PublicExtractNode | PublicValidateNode | PublicIfElseNode | PublicSlackAlertNode | PublicEditNode | KnowledgeNode>;
2377
+ /**
2378
+ * Updated At
2379
+ *
2380
+ * Timestamp when the workflow was last modified (ISO 8601).
2381
+ */
2382
+ updated_at?: string | null;
2383
+ };
2384
+ /**
2385
+ * WorkflowSummaryV3
2386
+ *
2387
+ * Slim workflow projection returned by create and list.
2388
+ */
2389
+ type WorkflowSummaryV3 = {
2390
+ /**
2391
+ * Created At
2392
+ *
2393
+ * Timestamp when the workflow was created (ISO 8601).
2394
+ */
2395
+ created_at?: string | null;
2396
+ /**
2397
+ * Description
2398
+ *
2399
+ * Optional description of what this workflow extracts.
2400
+ */
2401
+ description?: string | null;
2402
+ /**
2403
+ * Id
2404
+ *
2405
+ * Unique identifier of the workflow (hyphenated UUID).
2406
+ */
2407
+ id: string;
2408
+ /**
2409
+ * Name
2410
+ *
2411
+ * Human-readable name of the workflow.
2412
+ */
2413
+ name: string;
2414
+ /**
2415
+ * Updated At
2416
+ *
2417
+ * Timestamp when the workflow was last modified (ISO 8601).
2418
+ */
2419
+ updated_at?: string | null;
2420
+ };
2421
+ /**
2422
+ * _FieldOperand
2423
+ */
2424
+ type FieldOperand = {
2425
+ /**
2426
+ * Field
2427
+ *
2428
+ * The compared field. Either the field's ``persistent_id`` (Studio field-picker path) or its ``sanitized_name`` as it appears in the extraction response (SDK/API/assistant path) — the executor resolves both.
2429
+ */
2430
+ field: string;
2431
+ /**
2432
+ * Source
2433
+ */
2434
+ source: 'field';
2435
+ };
2436
+ /**
2437
+ * _LiteralOperand
2438
+ */
2439
+ type LiteralOperand = {
2440
+ /**
2441
+ * Source
2442
+ */
2443
+ source: 'literal';
2444
+ /**
2445
+ * Value
2446
+ */
2447
+ value: number | string | boolean;
1342
2448
  };
1343
2449
 
1344
2450
  /**
@@ -1368,12 +2474,27 @@ declare class ParseView {
1368
2474
  get layoutConfidence(): number | null;
1369
2475
  }
1370
2476
 
2477
+ /**
2478
+ * One extracted field — generic over the value type so callers get real
2479
+ * types at the access site (`result.field<number>("total").value` is
2480
+ * `number | null`, not `unknown`). Wire shape identical to the codegen type.
2481
+ */
2482
+ type ExtractedField<T = unknown> = Omit<ExtractedField$1, "value" | "value_override"> & {
2483
+ value: T | null;
2484
+ value_override?: T | null;
2485
+ };
2486
+ /**
2487
+ * A list/object-array field (e.g. `line_items`): one entry per row, each row a
2488
+ * record of named `ExtractedField`s. This is the shape `field()` returns for a
2489
+ * non-scalar field.
2490
+ */
2491
+ type ExtractedRows = Array<Record<string, ExtractedField>>;
1371
2492
  /** Typed wrapper over a completed run's results. */
1372
2493
  declare class Result {
1373
- readonly raw: ResultsResponse;
2494
+ readonly raw: ResultsResponseV3;
1374
2495
  private _parse;
1375
- constructor(raw: ResultsResponse);
1376
- get collectionId(): string;
2496
+ constructor(raw: ResultsResponseV3);
2497
+ get documentPacketId(): string;
1377
2498
  get extractions(): Extraction[];
1378
2499
  /**
1379
2500
  * Typed view over the parse node's output, or `null` when the workflow has
@@ -1381,37 +2502,148 @@ declare class Result {
1381
2502
  */
1382
2503
  get parse(): ParseView | null;
1383
2504
  /**
1384
- * Convenience accessor for a top-level scalar field on the first
1385
- * extraction (linear workflows). Returns `undefined` for missing fields
1386
- * or list-valued fields — read `extractions` directly for those.
2505
+ * Convenience accessor for a top-level field on the untagged (linear)
2506
+ * extraction. Returns the scalar `ExtractedField` for a scalar field, or
2507
+ * the array of row records (`ExtractedRows`) for a list/object field such
2508
+ * as `line_items`. `undefined` only when the field is absent.
2509
+ *
2510
+ * Parameterise with the declared schema type to type a scalar's `.value`:
2511
+ * `result.field<number>("total").value` is `number | null`.
1387
2512
  */
1388
- field(name: string): ExtractedField | undefined;
2513
+ field<T = unknown>(name: string): ExtractedField<T> | ExtractedRows | undefined;
1389
2514
  }
1390
2515
 
1391
2516
  interface WaitOptions {
1392
2517
  /** Overall budget before giving up. Default 300 000 ms (300s). */
1393
2518
  timeoutMs?: number;
1394
- /** Delay between result polls. Default 3 000 ms (3s). */
2519
+ /** Delay between status polls. Default 3 000 ms (3s). */
1395
2520
  pollMs?: number;
1396
2521
  }
1397
2522
  /**
1398
- * A submitted run. `wait()` polls for completion. Created eagerly by
1399
- * `Workflow.run()` — the workflow + file submission have already happened
1400
- * by the time you hold a `Run`.
2523
+ * One execution attempt of a workflow against a document packet. Created
2524
+ * eagerly by the run triggers — the extraction is already enqueued by the
2525
+ * time you hold a `Run`. `wait()` polls `GET /v3/runs/{run_id}/` until the
2526
+ * status is terminal and returns the inline results.
1401
2527
  */
1402
2528
  declare class Run {
1403
2529
  private readonly client;
1404
- readonly workflowId: string;
1405
2530
  readonly id: string;
2531
+ readonly workflowId: string;
2532
+ readonly documentPacketId: string;
2533
+ /** Status at trigger time, refreshed on every `wait()` poll. */
2534
+ status: RunStatus;
1406
2535
  /** @internal */
1407
- constructor(client: Client, workflowId: string, id: string);
2536
+ constructor(client: Client, id: string, workflowId: string, documentPacketId: string, status?: RunStatus);
1408
2537
  wait(opts?: WaitOptions): Promise<Result>;
1409
2538
  }
1410
2539
 
2540
+ interface RunTriggerOptions {
2541
+ /**
2542
+ * Caller-supplied key (Stripe convention). Retrying with the same key
2543
+ * returns the original run instead of triggering (and billing) a second
2544
+ * extraction.
2545
+ */
2546
+ idempotencyKey?: string;
2547
+ }
2548
+ /**
2549
+ * Options for the methods that stage an upload (`Workflow.run`,
2550
+ * `Workflow.upload`). Adds the filename-conflict policy on top of the
2551
+ * run-trigger options — it only applies where files are actually uploaded,
2552
+ * which is why the run-only paths (`Upload.run`, `Anyformat.runDocumentPacket`)
2553
+ * take {@link RunTriggerOptions} instead and don't accept it.
2554
+ */
2555
+ interface UploadOptions extends RunTriggerOptions {
2556
+ /**
2557
+ * How the server resolves an uploaded filename that already exists in the
2558
+ * workflow (filenames are unique within a workflow). `"error"` (the server
2559
+ * default) rejects the whole upload with `409`; `"rename"` auto-renames
2560
+ * (`invoice.pdf` → `invoice (1).pdf`). Omit to use the server default.
2561
+ */
2562
+ onConflict?: "error" | "rename";
2563
+ }
2564
+ /**
2565
+ * Options for URL imports. The server derives the filename from each URL, so
2566
+ * there is no idempotency key — only the conflict policy applies.
2567
+ */
2568
+ interface UploadFromUrlsOptions {
2569
+ /** See {@link UploadOptions.onConflict}. Omit to use the server default. */
2570
+ onConflict?: "error" | "rename";
2571
+ }
2572
+ /**
2573
+ * Options for a dataset upload (`Workflow.uploadToDataset`), mirroring the
2574
+ * regular upload's conflict policy.
2575
+ */
2576
+ interface DatasetUploadOptions {
2577
+ /**
2578
+ * The expected document (ground truth) for this document packet, as a plain
2579
+ * object — the SDK JSON-encodes it for the multipart field. Keys are the
2580
+ * workflow schema's field identifiers (advertise `persistent_id`); a scalar
2581
+ * field maps to `string | null`, a table/object field to an array of row
2582
+ * objects. Ground truth attaches to the workflow's current version.
2583
+ */
2584
+ groundTruth?: Record<string, unknown> | null;
2585
+ /**
2586
+ * Caller-supplied key (Stripe convention). Retrying with the same key
2587
+ * replays the original document packet instead of registering a duplicate
2588
+ * document.
2589
+ */
2590
+ idempotencyKey?: string;
2591
+ /**
2592
+ * Filename-collision policy. Omit to use the server default (`error`): a
2593
+ * colliding name fails with `409`. `rename` auto-renames the collision and
2594
+ * the returned file's `original_name` holds the name you sent.
2595
+ */
2596
+ onConflict?: "error" | "rename";
2597
+ }
2598
+ /**
2599
+ * One document for a bulk dataset upload: 1..100 files plus optional
2600
+ * ground truth. Mirrors the arguments of `Workflow.uploadToDataset`.
2601
+ */
2602
+ interface DatasetDocument {
2603
+ /** 1..10 named files forming ONE document (one document packet in the dataset). */
2604
+ files: File | File[];
2605
+ /** See {@link DatasetUploadOptions.groundTruth}. */
2606
+ groundTruth?: Record<string, unknown> | null;
2607
+ /** See {@link DatasetUploadOptions.idempotencyKey}. */
2608
+ idempotencyKey?: string;
2609
+ /** See {@link DatasetUploadOptions.onConflict}. */
2610
+ onConflict?: "error" | "rename";
2611
+ }
2612
+ /**
2613
+ * One document registered into a workflow's dataset as one
2614
+ * document packet. Returned by `Workflow.uploadToDataset()`. `documentPacketId` is the
2615
+ * stable handle for the document; `groundTruthSaved` is `true` only when
2616
+ * ground truth was supplied and stored.
2617
+ */
2618
+ declare class DatasetUpload {
2619
+ readonly workflowId: string;
2620
+ readonly documentPacketId: string;
2621
+ readonly files: DatasetUploadFileV3[];
2622
+ readonly groundTruthSaved: boolean;
2623
+ /** @internal */
2624
+ constructor(workflowId: string, documentPacketId: string, files: DatasetUploadFileV3[], groundTruthSaved: boolean);
2625
+ }
2626
+ /**
2627
+ * A document packet staged in a workflow but not yet run. Returned by
2628
+ * `Workflow.upload()` / `Workflow.uploadFromUrls()`. Call `run()` to start
2629
+ * extraction — uploading alone spends no credits.
2630
+ */
2631
+ declare class Upload {
2632
+ private readonly client;
2633
+ readonly workflowId: string;
2634
+ readonly documentPacketId: string;
2635
+ readonly files: DocumentPacketFileV3[];
2636
+ /** @internal */
2637
+ constructor(client: Client, workflowId: string, documentPacketId: string, files: DocumentPacketFileV3[]);
2638
+ /** Trigger extraction on the staged packet and return a pending `Run`. */
2639
+ run(opts?: RunTriggerOptions): Promise<Run>;
2640
+ }
2641
+
1411
2642
  /**
1412
2643
  * A persisted workflow on the server. Returned by `WorkflowBuilder.create()`.
1413
- * `run(file | text)` submits a document against this workflow's id and returns
1414
- * a `Run` you can `.wait()` on for results.
2644
+ * `run(files)` uploads a document packet and starts extraction, returning a
2645
+ * `Run` you can `.wait()` on. `upload(files)` stages a packet without
2646
+ * running it; call `.run()` on the returned `Upload` to extract.
1415
2647
  */
1416
2648
  declare class Workflow {
1417
2649
  private readonly client;
@@ -1419,10 +2651,33 @@ declare class Workflow {
1419
2651
  readonly name: string;
1420
2652
  /** @internal */
1421
2653
  constructor(client: Client, id: string, name: string);
1422
- /** Submit a document against this workflow and return a pending `Run`. */
1423
- run(file?: File | null, opts?: {
1424
- text?: string;
1425
- }): Promise<Run>;
2654
+ /** Upload 1..100 files as one document packet and run it. Returns a pending `Run`. */
2655
+ run(files?: File | File[] | null, opts?: UploadOptions): Promise<Run>;
2656
+ /**
2657
+ * Stage 1..100 files as one document packet WITHOUT running it (no credits
2658
+ * spent). Returns an `Upload`; call `.run()` on it to start extraction.
2659
+ */
2660
+ upload(files?: File | File[] | null, opts?: UploadOptions): Promise<Upload>;
2661
+ /**
2662
+ * Upload 1..100 files as ONE document (+ optional ground truth) into the
2663
+ * workflow's dataset, as one document packet. Atomic: any rejected file or a
2664
+ * ground-truth failure fails the call and stores nothing. By default a
2665
+ * colliding filename fails with `409`; pass `onConflict: "rename"` to
2666
+ * auto-rename instead.
2667
+ */
2668
+ uploadToDataset(files?: File | File[] | null, opts?: DatasetUploadOptions): Promise<DatasetUpload>;
2669
+ /**
2670
+ * Client-orchestrated bulk dataset upload: one atomic call per document,
2671
+ * in order. There is no batch endpoint — each document is bounded and
2672
+ * independently retryable. On failure the call rejects; documents already
2673
+ * uploaded stay registered.
2674
+ */
2675
+ uploadDocumentsToDataset(documents: DatasetDocument[]): Promise<DatasetUpload[]>;
2676
+ /**
2677
+ * Import 1..10 HTTPS URLs server-side into one document packet, atomically.
2678
+ * Returns an `Upload`; call `.run()` on it to start extraction.
2679
+ */
2680
+ uploadFromUrls(urls: string[], opts?: UploadFromUrlsOptions): Promise<Upload>;
1426
2681
  }
1427
2682
 
1428
2683
  /** Any extraction field — the discriminated union on `data_type`. */
@@ -1432,37 +2687,76 @@ type Field = ExtractionSchema["fields"][number];
1432
2687
  * level of nesting is supported, so objects cannot contain objects.
1433
2688
  */
1434
2689
  type NestedField = ObjectField["nested_fields"][number];
1435
- type LookupOpt = {
1436
- lookup?: boolean;
1437
- };
2690
+ interface FieldOpts {
2691
+ /**
2692
+ * How the field gets its value: `"extraction"` (from the document,
2693
+ * the default), `"smart_lookup"` (from the lookup file, always
2694
+ * overwrites) or `"lookup_if_missing"` (extracted too; the lookup only
2695
+ * fills it where extraction left no value).
2696
+ */
2697
+ source?: "extraction" | "smart_lookup" | "lookup_if_missing";
2698
+ /**
2699
+ * Server-assigned stable field identity from `GET /v3/workflows/{id}/`.
2700
+ * Echo it on updates — including across renames — to keep quality
2701
+ * metrics, ground truth and analytics attached to the field. Omit for
2702
+ * new fields.
2703
+ */
2704
+ persistentId?: string;
2705
+ }
1438
2706
  /**
1439
2707
  * Factory for extraction-schema fields — the TS mirror of the Python
1440
2708
  * `Schema` facade. Each method returns the typed wire model the API
1441
2709
  * validates against; the discriminator (`data_type`) is filled in for you.
1442
2710
  */
1443
2711
  declare const Schema: {
1444
- string: (name: string, description: string, opts?: LookupOpt) => StringField;
1445
- integer: (name: string, description: string, opts?: LookupOpt) => IntegerField;
1446
- float: (name: string, description: string, opts?: LookupOpt) => FloatField;
1447
- boolean: (name: string, description: string, opts?: LookupOpt) => BooleanField;
1448
- date: (name: string, description: string, opts?: LookupOpt) => DateField;
1449
- datetime: (name: string, description: string, opts?: LookupOpt) => DatetimeField;
1450
- enum: (name: string, description: string, options: EnumOption[], opts?: LookupOpt) => EnumField;
1451
- multiSelect: (name: string, description: string, options: EnumOption[], opts?: LookupOpt) => MultiSelectField;
1452
- object: (name: string, description: string, fields: NestedField[], opts?: LookupOpt) => ObjectField;
2712
+ string: (name: string, description: string, opts?: FieldOpts) => StringField;
2713
+ integer: (name: string, description: string, opts?: FieldOpts) => IntegerField;
2714
+ float: (name: string, description: string, opts?: FieldOpts) => FloatField;
2715
+ boolean: (name: string, description: string, opts?: FieldOpts) => BooleanField;
2716
+ date: (name: string, description: string, opts?: FieldOpts) => DateField;
2717
+ datetime: (name: string, description: string, opts?: FieldOpts) => DatetimeField;
2718
+ enum: (name: string, description: string, options: EnumOption[], opts?: FieldOpts) => EnumField;
2719
+ multiSelect: (name: string, description: string, options: EnumOption[], opts?: FieldOpts) => MultiSelectField;
2720
+ object: (name: string, description: string, fields: NestedField[], opts?: FieldOpts) => ObjectField;
1453
2721
  option: (name: string, description: string) => EnumOption;
1454
2722
  };
1455
2723
 
1456
- type ParseMode = "standard" | "agentic";
2724
+ type ExtractMode = "standard" | "agentic" | "lite";
2725
+ type AgenticEffort = "low" | "mid" | "accurate";
2726
+ type ScannedPages = "ocr" | "skip" | "fail";
2727
+ /** How much reasoning a node asks a model for. Taken from the generated wire types, which
2728
+ * follow the Python `ReasoningEffort` alias, so a new level needs no edit here.
2729
+ * The Python gives `ExtractNode.lookup_reasoning_effort`
2730
+ * that same alias, so one of the two fields derives the type for both. */
2731
+ type ReasoningEffort = NonNullable<PublicExtractNode["lookup_reasoning_effort"]>;
1457
2732
  /** Source-port label routing into an extract/validate node. */
1458
2733
  type Branch = string | ClassifyCategory | SplitterRule;
1459
- interface ParseOptions {
1460
- mode?: ParseMode;
1461
- promptHint?: string;
2734
+ /** Knobs shared by every parse mode. */
2735
+ interface ParseOptionsBase {
1462
2736
  figureEnhancement?: boolean;
1463
2737
  cache?: boolean;
1464
2738
  id?: string;
1465
2739
  }
2740
+ /**
2741
+ * Parse options as a `mode`-discriminated union: each mode only accepts its own knobs, so a lite
2742
+ * knob on `{ mode: "standard" }` is a compile-time error rather than a silent no-op. `mode` is
2743
+ * optional only on the standard variant (the default), required on agentic/lite. Lite has no
2744
+ * knobs of its own — one recipe, OCR-only — and never reads `promptHint`.
2745
+ */
2746
+ type ParseOptions = (ParseOptionsBase & {
2747
+ mode?: "standard";
2748
+ promptHint?: string;
2749
+ }) | (ParseOptionsBase & {
2750
+ mode: "agentic";
2751
+ effort?: AgenticEffort;
2752
+ promptHint?: string;
2753
+ }) | (ParseOptionsBase & {
2754
+ mode: "lite";
2755
+ }) | (ParseOptionsBase & {
2756
+ mode: "flash";
2757
+ scannedPages?: ScannedPages;
2758
+ promptHint?: string;
2759
+ });
1466
2760
  /**
1467
2761
  * Fluent assembler for a typed workflow graph — a faithful TS port of the
1468
2762
  * Python `WorkflowBuilder`. `parse`/`classify`/`split` are singletons;
@@ -1495,8 +2789,11 @@ declare class WorkflowBuilder {
1495
2789
  extract(fields: Field[], opts?: {
1496
2790
  branch?: Branch;
1497
2791
  id?: string;
2792
+ mode?: ExtractMode;
1498
2793
  lookupFiles?: string[];
1499
2794
  lookupSuggestion?: string;
2795
+ lookupReasoningEffort?: ReasoningEffort;
2796
+ useImages?: boolean;
1500
2797
  }): this;
1501
2798
  validate(rules: ValidationRule[], opts?: {
1502
2799
  branch?: Branch;
@@ -1506,9 +2803,9 @@ declare class WorkflowBuilder {
1506
2803
  private normalizeExtractBranch;
1507
2804
  /** Assemble the wire request (branch-routed edges). Pure — no network. */
1508
2805
  build(): WorkflowCreateRequest;
1509
- /** Persist the workflow and return a handle you can `.run(file)` on. */
2806
+ /** Persist the workflow and return a handle you can `.run(files)` on. */
1510
2807
  create(): Promise<Workflow>;
1511
- /** Replace an existing workflow's definition and return a handle you can `.run(file)` on. */
2808
+ /** Replace an existing workflow's typed graph and return a handle you can `.run(files)` on. */
1512
2809
  update(workflowId: string): Promise<Workflow>;
1513
2810
  }
1514
2811
 
@@ -1517,43 +2814,155 @@ interface AnyformatOptions {
1517
2814
  /** Override the API base URL (defaults to production). */
1518
2815
  baseUrl?: string;
1519
2816
  }
2817
+ /** One keyset page. Follow `nextCursor` (pass it as `cursor`) until it is `null`. */
2818
+ interface Page<T> {
2819
+ items: T[];
2820
+ nextCursor: string | null;
2821
+ }
2822
+ interface ListOptions {
2823
+ /** Page size, capped at 100 by the API. */
2824
+ limit?: number;
2825
+ /** Opaque token from a previous page's `nextCursor`. */
2826
+ cursor?: string;
2827
+ }
2828
+ interface IterOptions {
2829
+ /** Page size the auto-pager fetches per underlying request, capped at 100 by the API. */
2830
+ limit?: number;
2831
+ }
2832
+ /**
2833
+ * The editable sub-shape of a workflow: exactly what `GET /v3/workflows/{id}/`
2834
+ * returns minus the read-only fields, and exactly what PATCH accepts — so a
2835
+ * fetched `WorkflowDetailV3` can be mutated and sent back as-is.
2836
+ */
2837
+ type WorkflowDefinition = Pick<WorkflowDetailV3, "name" | "description" | "nodes" | "edges">;
1520
2838
  /** Entry point. `new Anyformat({ apiKey }).workflow("name").parse()...` */
1521
2839
  declare class Anyformat {
1522
2840
  /** @internal */
1523
2841
  readonly _client: Client;
1524
2842
  constructor(opts: AnyformatOptions);
1525
2843
  workflow(name: string, description?: string): WorkflowBuilder;
1526
- listWorkflows(opts?: {
1527
- page?: number;
1528
- pageSize?: number;
1529
- status?: string;
1530
- }): Promise<Workflow[]>;
2844
+ listWorkflows(opts?: ListOptions): Promise<Page<Workflow>>;
2845
+ /** Retrieve a workflow with its complete typed graph inline (round-trippable into `updateWorkflow`). */
2846
+ getWorkflow(workflowId: string): Promise<WorkflowDetailV3>;
2847
+ /**
2848
+ * Replace a workflow's typed graph (atomic). Accepts the shape `getWorkflow`
2849
+ * returns — echo each field's `persistent_id` unchanged (including across
2850
+ * renames) to keep the field's identity; omit it for new fields.
2851
+ */
2852
+ updateWorkflow(workflowId: string, definition: WorkflowDefinition): Promise<WorkflowDetailV3>;
1531
2853
  deleteWorkflow(workflowId: string): Promise<string>;
2854
+ /** Stage 1..100 files as one document packet without running it. Returns an `Upload`. */
2855
+ upload(workflowId: string, files: File | File[], opts?: UploadOptions): Promise<Upload>;
2856
+ /** Upload 1..100 files (+ optional ground truth) as one dataset collection. Returns a `DatasetUpload`. */
2857
+ uploadToDataset(workflowId: string, files: File | File[], opts?: DatasetUploadOptions): Promise<DatasetUpload>;
2858
+ /** Bulk-upload documents into a workflow's dataset, one atomic call per document. */
2859
+ uploadDocumentsToDataset(workflowId: string, documents: DatasetDocument[]): Promise<DatasetUpload[]>;
2860
+ getDocumentPacket(documentPacketId: string): Promise<DocumentPacketDetailV3>;
2861
+ /** Delete a document packet and all its files. Irreversible. */
2862
+ deleteDocumentPacket(documentPacketId: string): Promise<string>;
2863
+ /** Run (or re-run) a document packet on the latest version of its workflow. */
2864
+ runDocumentPacket(documentPacketId: string, opts?: RunTriggerOptions): Promise<Run>;
2865
+ listDocumentPackets(workflowId: string, opts?: ListOptions): Promise<Page<DocumentPacketSummaryV3>>;
2866
+ listRuns(workflowId: string, opts?: ListOptions): Promise<Page<RunSummaryV3>>;
2867
+ /**
2868
+ * Every workflow, following `nextCursor` across pages so no rows are silently
2869
+ * truncated. Lazy — each page is fetched on demand as the iterator advances.
2870
+ */
2871
+ iterWorkflows(opts?: IterOptions): AsyncIterableIterator<Workflow>;
2872
+ /** Every document packet of a workflow, following `nextCursor` across pages. Lazy. */
2873
+ iterDocumentPackets(workflowId: string, opts?: IterOptions): AsyncIterableIterator<DocumentPacketSummaryV3>;
2874
+ /** Every run of a workflow, following `nextCursor` across pages. Lazy. */
2875
+ iterRuns(workflowId: string, opts?: IterOptions): AsyncIterableIterator<RunSummaryV3>;
2876
+ /** Retrieve one run: lifecycle status plus results inline once `processed`. */
2877
+ getRun(runId: string): Promise<RunDetailV3>;
2878
+ /**
2879
+ * Parse a document with the platform's atomic parse operation (fast lite
2880
+ * parse). Returns the run id; poll `getParseMarkdown(runId)` for the parsed
2881
+ * markdown.
2882
+ */
2883
+ parse(file: Blob | File): Promise<string>;
2884
+ /**
2885
+ * Poll a parse run. Returns the parsed markdown once the run is `processed`,
2886
+ * or `null` while it is still queued or in progress.
2887
+ */
2888
+ getParseMarkdown(runId: string): Promise<string | null>;
1532
2889
  }
1533
2890
 
1534
2891
  declare class AnyformatError extends Error {
1535
2892
  }
2893
+ /** Any JSON value the envelope's free-shaped `detail` may carry. */
2894
+ type JsonValue = string | number | boolean | null | JsonValue[] | {
2895
+ [key: string]: JsonValue;
2896
+ };
2897
+ /** One field-level failure; the `detail` convention of validation errors. */
2898
+ interface ValidationItem {
2899
+ type: string;
2900
+ loc: (string | number)[];
2901
+ msg: string;
2902
+ }
2903
+ /** A `params` value: a scalar, `null`, or an array of those. */
2904
+ type ScalarOrList = string | number | boolean | null | (string | number | boolean | null)[];
1536
2905
  declare class APIError extends AnyformatError {
1537
2906
  readonly status: number;
1538
2907
  readonly body?: unknown | undefined;
2908
+ /** Stable identifier for programmatic handling, e.g. `PAYMENT_REQUIRED`. */
2909
+ readonly errorCode?: string;
2910
+ /** Developer-facing explanation; not surfaced in `message` (ADR platform/0053 §2). Often a `ValidationItem[]`. */
2911
+ readonly detail?: JsonValue;
2912
+ /** Named substitutions the `error` summary refers to, e.g. `{ required_scope }`. */
2913
+ readonly params?: Record<string, ScalarOrList>;
2914
+ /** Whether the API says retrying the same request can succeed. */
2915
+ readonly retryable?: boolean;
2916
+ /** Correlation id to quote in support requests. */
2917
+ readonly requestId?: string;
1539
2918
  constructor(status: number, message: string, body?: unknown | undefined);
1540
2919
  }
1541
- declare class BadRequest extends APIError {
2920
+ declare class BadRequestError extends APIError {
2921
+ }
2922
+ declare class UnauthorizedError extends APIError {
1542
2923
  }
1543
- declare class Unauthorized extends APIError {
2924
+ declare class PaymentRequiredError extends APIError {
1544
2925
  }
1545
- declare class Forbidden extends APIError {
2926
+ declare class ForbiddenError extends APIError {
1546
2927
  }
1547
- declare class NotFound extends APIError {
2928
+ declare class NotFoundError extends APIError {
1548
2929
  }
1549
- declare class RateLimited extends APIError {
2930
+ declare class RateLimitedError extends APIError {
2931
+ /** Seconds the API asks the caller to wait, from the `Retry-After` header; `undefined` when absent. */
2932
+ readonly retryAfter?: number | undefined;
2933
+ constructor(status: number, message: string, body?: unknown,
2934
+ /** Seconds the API asks the caller to wait, from the `Retry-After` header; `undefined` when absent. */
2935
+ retryAfter?: number | undefined);
1550
2936
  }
1551
2937
  declare class ServerError extends APIError {
1552
2938
  }
1553
- declare class SDKTimeout extends AnyformatError {
2939
+ /** The API key lacks the scope this call needs (`insufficient_api_key_scope`). */
2940
+ declare class InsufficientScopeError extends ForbiddenError {
2941
+ }
2942
+ /** The caller must accept the terms of service first (`terms_acceptance_required`). */
2943
+ declare class TermsAcceptanceRequiredError extends ForbiddenError {
2944
+ }
2945
+ /** A workflow with that name already exists (`WORKFLOW_NAME_CONFLICT`). */
2946
+ declare class WorkflowNameConflictError extends APIError {
2947
+ }
2948
+ declare class SDKTimeoutError extends AnyformatError {
2949
+ }
2950
+ /** Thrown by `Run.wait()` when the run reaches a terminal failure status. */
2951
+ declare class RunFailedError extends AnyformatError {
2952
+ readonly runId: string;
2953
+ readonly status: "error" | "cancelled";
2954
+ constructor(runId: string, status: "error" | "cancelled");
2955
+ }
2956
+ /** The run ended in the terminal `error` status. */
2957
+ declare class ExtractionFailedError extends RunFailedError {
2958
+ constructor(runId: string);
2959
+ }
2960
+ /** The run ended in the terminal `cancelled` status. */
2961
+ declare class ExtractionCancelledError extends RunFailedError {
2962
+ constructor(runId: string);
1554
2963
  }
1555
2964
  /** Raised by the fluent `WorkflowBuilder` for builder-API misuse. */
1556
2965
  declare class WorkflowBuilderError extends AnyformatError {
1557
2966
  }
1558
2967
 
1559
- export { APIError, Anyformat, AnyformatError, type AnyformatOptions, BadRequest, type Block, type BooleanField, type Branch, type ClassifyCategory, type DateField, type DatetimeField, type EnumField, type EnumOption, type ExtractedField, type Extraction, type ExtractionSchema, type Field, type FloatField, Forbidden, type IntegerField, type MultiSelectField, type NestedField, NotFound, type ObjectField, ParseView, RateLimited, Result, type ResultsResponse, Run, SDKTimeout, Schema, ServerError, type SplitterRule, type StringField, Unauthorized, type ValidationRule, type WaitOptions, Workflow, WorkflowBuilder, WorkflowBuilderError, type WorkflowCreateRequest };
2968
+ export { APIError, type AllOfCheck, type AnyOfCheck, Anyformat, AnyformatError, type AnyformatOptions, type ArithmeticCheck, BadRequestError, type Block, type BooleanField, type Branch, type ClassifyCategory, type ComparisonCheck, type DatasetDocument, DatasetUpload, type DatasetUploadFileV3, type DatasetUploadOptions, type DatasetUploadResponseV3, type DateCheck, type DateField, type DatetimeField, type DocumentPacketDetailV3, type DocumentPacketFileV3, type DocumentPacketStatus, type DocumentPacketSummaryV3, type Edge, type EnumField, type EnumOption, type ExpressionCheck, type ExtractedField, type ExtractedRows, type Extraction, ExtractionCancelledError, ExtractionFailedError, type ExtractionSchema, type Field, type FloatField, ForbiddenError, InsufficientScopeError, type IntegerField, type IterOptions, type JsonValue, type ListOptions, type MultiSelectField, type NestedField, NotFoundError, type ObjectField, type OneOfCheck, type Page, type ParseResult, ParseView, PaymentRequiredError, type RangeCheck, RateLimitedError, type RegexCheck, type RequiredCheck, Result, type ResultsResponseV3, Run, type RunDetailV3, RunFailedError, type RunStatus, type RunSummaryV3, type RunTriggerOptions, SDKTimeoutError, type ScalarOrList, Schema, ServerError, type SplitterRule, type StringField, TermsAcceptanceRequiredError, UnauthorizedError, Upload, type UploadFromUrlsOptions, type UploadOptions, type ValidationItem, type ValidationRule, type WaitOptions, Workflow, WorkflowBuilder, WorkflowBuilderError, type WorkflowCreateRequest, type WorkflowDefinition, type WorkflowDetailV3, WorkflowNameConflictError, type WorkflowSummaryV3 };