@purveyors/sdk 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -115,14 +115,14 @@ interface paths {
115
115
  patch?: never;
116
116
  trace?: never;
117
117
  };
118
- "/v1/catalog/access": {
118
+ "/v1/api-keys": {
119
119
  parameters: {
120
120
  query?: never;
121
121
  header?: never;
122
122
  path?: never;
123
123
  cookie?: never;
124
124
  };
125
- /** Catalog capabilities and visibility for the caller */
125
+ /** List API keys for the authenticated user */
126
126
  get: {
127
127
  parameters: {
128
128
  query?: never;
@@ -132,145 +132,180 @@ interface paths {
132
132
  };
133
133
  requestBody?: never;
134
134
  responses: {
135
- /** @description Resolved catalog access policy for the caller's principal */
135
+ /** @description API keys owned by the authenticated user */
136
136
  200: {
137
137
  headers: {
138
138
  [name: string]: unknown;
139
139
  };
140
140
  content: {
141
- "application/json": components["schemas"]["CatalogAccessResponse"];
141
+ "application/json": components["schemas"]["ApiKeyListResponse"];
142
142
  };
143
143
  };
144
- };
145
- };
146
- put?: never;
147
- post?: never;
148
- delete?: never;
149
- options?: never;
150
- head?: never;
151
- patch?: never;
152
- trace?: never;
153
- };
154
- "/v1/catalog": {
155
- parameters: {
156
- query?: never;
157
- header?: never;
158
- path?: never;
159
- cookie?: never;
160
- };
161
- /**
162
- * List public catalog coffees
163
- * @description Public catalog listing. Excludes wholesale-restricted rows and returns only public fields. API-key callers are capped to their plan's per-call row limit.
164
- */
165
- get: {
166
- parameters: {
167
- query?: {
168
- page?: number;
169
- limit?: number;
170
- stocked?: "true" | "false" | "all";
171
- sort?: string;
172
- order?: "asc" | "desc";
144
+ /** @description Invalid API-key request */
145
+ 400: {
146
+ headers: {
147
+ [name: string]: unknown;
148
+ };
149
+ content: {
150
+ "application/json": components["schemas"]["ErrorResponse"];
151
+ };
173
152
  };
174
- header?: never;
175
- path?: never;
176
- cookie?: never;
177
- };
178
- requestBody?: never;
179
- responses: {
180
- /** @description A page of public catalog rows with pagination + meta */
181
- 200: {
153
+ /** @description Authentication required */
154
+ 401: {
182
155
  headers: {
183
156
  [name: string]: unknown;
184
157
  };
185
158
  content: {
186
- "application/json": components["schemas"]["CatalogListResponse"];
159
+ "application/json": components["schemas"]["ErrorResponse"];
160
+ };
161
+ };
162
+ /** @description Insufficient entitlement (plan or role) */
163
+ 403: {
164
+ headers: {
165
+ [name: string]: unknown;
166
+ };
167
+ content: {
168
+ "application/json": components["schemas"]["ErrorResponse"];
169
+ };
170
+ };
171
+ /** @description API key not found for the authenticated user */
172
+ 404: {
173
+ headers: {
174
+ [name: string]: unknown;
175
+ };
176
+ content: {
177
+ "application/json": components["schemas"]["ErrorResponse"];
178
+ };
179
+ };
180
+ /** @description API key storage is unavailable */
181
+ 503: {
182
+ headers: {
183
+ [name: string]: unknown;
184
+ };
185
+ content: {
186
+ "application/json": components["schemas"]["ErrorResponse"];
187
187
  };
188
188
  };
189
189
  };
190
190
  };
191
191
  put?: never;
192
- post?: never;
193
- delete?: never;
194
- options?: never;
195
- head?: never;
196
- patch?: never;
197
- trace?: never;
198
- };
199
- "/v1/catalog/proof-coverage": {
200
- parameters: {
201
- query?: never;
202
- header?: never;
203
- path?: never;
204
- cookie?: never;
205
- };
206
- /**
207
- * Aggregate proof-coverage over the public catalog
208
- * @description Aggregate-only proof coverage (no row-level evidence) computed over the stocked public catalog.
209
- */
210
- get: {
192
+ /** Create an API key for the authenticated user */
193
+ post: {
211
194
  parameters: {
212
195
  query?: never;
213
196
  header?: never;
214
197
  path?: never;
215
198
  cookie?: never;
216
199
  };
217
- requestBody?: never;
200
+ requestBody: {
201
+ content: {
202
+ "application/json": {
203
+ name: string;
204
+ scopes?: "catalog:read"[];
205
+ };
206
+ };
207
+ };
218
208
  responses: {
219
- /** @description Proof-coverage summary with per-family buckets and gaps */
220
- 200: {
209
+ /** @description API key created. The raw key is returned only once. */
210
+ 201: {
221
211
  headers: {
222
212
  [name: string]: unknown;
223
213
  };
224
214
  content: {
225
- "application/json": components["schemas"]["CatalogProofCoverageResponse"];
215
+ "application/json": components["schemas"]["ApiKeyCreateResponse"];
216
+ };
217
+ };
218
+ /** @description Invalid API-key request */
219
+ 400: {
220
+ headers: {
221
+ [name: string]: unknown;
222
+ };
223
+ content: {
224
+ "application/json": components["schemas"]["ErrorResponse"];
225
+ };
226
+ };
227
+ /** @description Authentication required */
228
+ 401: {
229
+ headers: {
230
+ [name: string]: unknown;
231
+ };
232
+ content: {
233
+ "application/json": components["schemas"]["ErrorResponse"];
234
+ };
235
+ };
236
+ /** @description Insufficient entitlement (plan or role) */
237
+ 403: {
238
+ headers: {
239
+ [name: string]: unknown;
240
+ };
241
+ content: {
242
+ "application/json": components["schemas"]["ErrorResponse"];
243
+ };
244
+ };
245
+ /** @description API key not found for the authenticated user */
246
+ 404: {
247
+ headers: {
248
+ [name: string]: unknown;
249
+ };
250
+ content: {
251
+ "application/json": components["schemas"]["ErrorResponse"];
252
+ };
253
+ };
254
+ /** @description API key storage is unavailable */
255
+ 503: {
256
+ headers: {
257
+ [name: string]: unknown;
258
+ };
259
+ content: {
260
+ "application/json": components["schemas"]["ErrorResponse"];
226
261
  };
227
262
  };
228
263
  };
229
264
  };
230
- put?: never;
231
- post?: never;
232
265
  delete?: never;
233
266
  options?: never;
234
267
  head?: never;
235
268
  patch?: never;
236
269
  trace?: never;
237
270
  };
238
- "/v1/price-index": {
271
+ "/v1/api-keys/{id}": {
239
272
  parameters: {
240
273
  query?: never;
241
274
  header?: never;
242
275
  path?: never;
243
276
  cookie?: never;
244
277
  };
245
- /**
246
- * Parchment Price Index (aggregate snapshots)
247
- * @description Aggregate-only price index over price_index_snapshots. Requires an API key with Parchment Intelligence (ppiAccess).
248
- */
249
- get: {
278
+ get?: never;
279
+ put?: never;
280
+ post?: never;
281
+ /** Revoke an API key owned by the authenticated user */
282
+ delete: {
250
283
  parameters: {
251
- query?: {
252
- page?: number;
253
- limit?: number;
254
- origin?: string;
255
- process?: string;
256
- grade?: string;
257
- from?: string;
258
- to?: string;
259
- wholesale?: "true" | "false";
260
- };
284
+ query?: never;
261
285
  header?: never;
262
- path?: never;
286
+ path: {
287
+ id: string;
288
+ };
263
289
  cookie?: never;
264
290
  };
265
291
  requestBody?: never;
266
292
  responses: {
267
- /** @description A page of aggregate price-index snapshots */
293
+ /** @description API key revoked */
268
294
  200: {
269
295
  headers: {
270
296
  [name: string]: unknown;
271
297
  };
272
298
  content: {
273
- "application/json": components["schemas"]["PriceIndexResponse"];
299
+ "application/json": components["schemas"]["ApiKeyMutationResponse"];
300
+ };
301
+ };
302
+ /** @description Invalid API-key request */
303
+ 400: {
304
+ headers: {
305
+ [name: string]: unknown;
306
+ };
307
+ content: {
308
+ "application/json": components["schemas"]["ErrorResponse"];
274
309
  };
275
310
  };
276
311
  /** @description Authentication required */
@@ -291,35 +326,44 @@ interface paths {
291
326
  "application/json": components["schemas"]["ErrorResponse"];
292
327
  };
293
328
  };
329
+ /** @description API key not found for the authenticated user */
330
+ 404: {
331
+ headers: {
332
+ [name: string]: unknown;
333
+ };
334
+ content: {
335
+ "application/json": components["schemas"]["ErrorResponse"];
336
+ };
337
+ };
338
+ /** @description API key storage is unavailable */
339
+ 503: {
340
+ headers: {
341
+ [name: string]: unknown;
342
+ };
343
+ content: {
344
+ "application/json": components["schemas"]["ErrorResponse"];
345
+ };
346
+ };
294
347
  };
295
348
  };
296
- put?: never;
297
- post?: never;
298
- delete?: never;
299
349
  options?: never;
300
350
  head?: never;
301
351
  patch?: never;
302
352
  trace?: never;
303
353
  };
304
- "/v1/catalog/{id}/similar": {
354
+ "/v1/api-keys/{id}/rotate": {
305
355
  parameters: {
306
356
  query?: never;
307
357
  header?: never;
308
358
  path?: never;
309
359
  cookie?: never;
310
360
  };
311
- /**
312
- * Find catalog coffees similar to a target coffee
313
- * @description Vector-similarity matches for a target catalog coffee, with deterministic identity gating, supplier-diversity re-ranking, and a canonical/similar split. Requires the bean-matching capability (a member session or a paid API plan).
314
- */
315
- get: {
361
+ get?: never;
362
+ put?: never;
363
+ /** Rotate an API key owned by the authenticated user */
364
+ post: {
316
365
  parameters: {
317
- query?: {
318
- threshold?: string;
319
- limit?: number;
320
- stocked_only?: "true" | "false";
321
- mode?: "all" | "likely_same" | "similar_profile";
322
- };
366
+ query?: never;
323
367
  header?: never;
324
368
  path: {
325
369
  id: string;
@@ -328,16 +372,16 @@ interface paths {
328
372
  };
329
373
  requestBody?: never;
330
374
  responses: {
331
- /** @description Target coffee with grouped similarity matches */
332
- 200: {
375
+ /** @description Old API key revoked and replacement created. The raw replacement key is returned only once. */
376
+ 201: {
333
377
  headers: {
334
378
  [name: string]: unknown;
335
379
  };
336
380
  content: {
337
- "application/json": components["schemas"]["CatalogSimilarityResponse"];
381
+ "application/json": components["schemas"]["ApiKeyCreateResponse"];
338
382
  };
339
383
  };
340
- /** @description Invalid path id or query parameter */
384
+ /** @description Invalid API-key request */
341
385
  400: {
342
386
  headers: {
343
387
  [name: string]: unknown;
@@ -364,7 +408,7 @@ interface paths {
364
408
  "application/json": components["schemas"]["ErrorResponse"];
365
409
  };
366
410
  };
367
- /** @description Catalog coffee not found */
411
+ /** @description API key not found for the authenticated user */
368
412
  404: {
369
413
  headers: {
370
414
  [name: string]: unknown;
@@ -373,27 +417,31 @@ interface paths {
373
417
  "application/json": components["schemas"]["ErrorResponse"];
374
418
  };
375
419
  };
420
+ /** @description API key storage is unavailable */
421
+ 503: {
422
+ headers: {
423
+ [name: string]: unknown;
424
+ };
425
+ content: {
426
+ "application/json": components["schemas"]["ErrorResponse"];
427
+ };
428
+ };
376
429
  };
377
430
  };
378
- put?: never;
379
- post?: never;
380
431
  delete?: never;
381
432
  options?: never;
382
433
  head?: never;
383
434
  patch?: never;
384
435
  trace?: never;
385
436
  };
386
- "/v1/procurement/briefs": {
437
+ "/v1/catalog/access": {
387
438
  parameters: {
388
439
  query?: never;
389
440
  header?: never;
390
441
  path?: never;
391
442
  cookie?: never;
392
443
  };
393
- /**
394
- * List saved sourcing briefs
395
- * @description List the authenticated principal's active sourcing briefs. Requires a member session or a paid (member+) API plan; API keys also need the catalog:read scope.
396
- */
444
+ /** Catalog capabilities and visibility for the caller */
397
445
  get: {
398
446
  parameters: {
399
447
  query?: never;
@@ -403,13 +451,13 @@ interface paths {
403
451
  };
404
452
  requestBody?: never;
405
453
  responses: {
406
- /** @description The principal's active sourcing briefs */
454
+ /** @description Resolved catalog access policy for the caller's principal */
407
455
  200: {
408
456
  headers: {
409
457
  [name: string]: unknown;
410
458
  };
411
459
  content: {
412
- "application/json": components["schemas"]["SourcingBriefsListResponse"];
460
+ "application/json": components["schemas"]["CatalogAccessResponse"];
413
461
  };
414
462
  };
415
463
  /** @description Authentication required */
@@ -433,34 +481,173 @@ interface paths {
433
481
  };
434
482
  };
435
483
  put?: never;
484
+ post?: never;
485
+ delete?: never;
486
+ options?: never;
487
+ head?: never;
488
+ patch?: never;
489
+ trace?: never;
490
+ };
491
+ "/v1/catalog": {
492
+ parameters: {
493
+ query?: never;
494
+ header?: never;
495
+ path?: never;
496
+ cookie?: never;
497
+ };
436
498
  /**
437
- * Create a sourcing brief
438
- * @description Create a saved sourcing brief for the authenticated principal. Requires a member session or a paid (member+) API plan; API keys also need the catalog:read scope.
499
+ * List public catalog coffees
500
+ * @description Public catalog listing. Excludes wholesale-restricted rows and returns only public fields. API-key callers are capped to their plan's per-call row limit. Requesting entitlement-gated params (price/score ranges, process facets, advanced sorts) you are not entitled to is handled per PADR-0013 §7: strict callers (API keys, bearer-session JWTs) receive a 401/403; lenient callers (anonymous, first-party web) get the params stripped with a `meta.notices` entry. Send `Prefer: handling=strict` to opt into strict enforcement; `Prefer: handling=lenient` is honored only for callers already lenient-eligible and cannot downgrade a strict caller's enforcement.
439
501
  */
440
- post: {
502
+ get: {
441
503
  parameters: {
442
- query?: never;
443
- header?: never;
504
+ query?: {
505
+ page?: number;
506
+ limit?: number;
507
+ stocked?: "true" | "false" | "all";
508
+ sort?: string;
509
+ order?: "asc" | "desc";
510
+ showWholesale?: "true" | "false";
511
+ wholesaleOnly?: "true" | "false";
512
+ origin?: string;
513
+ continent?: string;
514
+ country?: string | string[];
515
+ region?: string;
516
+ source?: string | string[];
517
+ name?: string;
518
+ processing?: string;
519
+ variety?: string;
520
+ type?: string;
521
+ grade?: string;
522
+ appearance?: string;
523
+ supplier?: string;
524
+ dryingMethod?: string;
525
+ flavorKeywords?: string | string[];
526
+ arrivalDate?: string;
527
+ stockedDate?: string;
528
+ stockedDays?: number;
529
+ coffeeIds?: string;
530
+ scoreValueMin?: number | null;
531
+ scoreValueMax?: number | null;
532
+ pricePerLbMin?: number | null;
533
+ pricePerLbMax?: number | null;
534
+ processing_base_method?: string;
535
+ fermentation_type?: string;
536
+ process_additive?: string;
537
+ has_additives?: "true" | "false";
538
+ processing_disclosure_level?: string;
539
+ processing_confidence_min?: number | null;
540
+ };
541
+ header?: {
542
+ Prefer?: string;
543
+ };
444
544
  path?: never;
445
545
  cookie?: never;
446
546
  };
447
- requestBody?: {
448
- content: {
449
- "application/json": components["schemas"]["SourcingBriefCreateRequest"];
547
+ requestBody?: never;
548
+ responses: {
549
+ /** @description A page of public catalog rows with pagination + meta */
550
+ 200: {
551
+ headers: {
552
+ [name: string]: unknown;
553
+ };
554
+ content: {
555
+ "application/json": components["schemas"]["CatalogListResponse"];
556
+ };
557
+ };
558
+ /** @description Authentication required */
559
+ 401: {
560
+ headers: {
561
+ [name: string]: unknown;
562
+ };
563
+ content: {
564
+ "application/json": components["schemas"]["ErrorResponse"];
565
+ };
566
+ };
567
+ /** @description Insufficient entitlement (plan or role) */
568
+ 403: {
569
+ headers: {
570
+ [name: string]: unknown;
571
+ };
572
+ content: {
573
+ "application/json": components["schemas"]["ErrorResponse"];
574
+ };
575
+ };
576
+ };
577
+ };
578
+ put?: never;
579
+ post?: never;
580
+ delete?: never;
581
+ options?: never;
582
+ head?: never;
583
+ patch?: never;
584
+ trace?: never;
585
+ };
586
+ "/v1/catalog/facets": {
587
+ parameters: {
588
+ query?: never;
589
+ header?: never;
590
+ path?: never;
591
+ cookie?: never;
592
+ };
593
+ /**
594
+ * Catalog filter metadata and counted facets
595
+ * @description Returns access-aware catalog filter metadata. Values are computed after visibility and entitled content filters are applied; premium process metadata is included only for member sessions and paid API tiers. Requesting entitlement-gated filters you are not entitled to is handled per PADR-0013 §7: strict callers (API keys, bearer-session JWTs) receive a 401/403; lenient callers (anonymous, first-party web) get the filters stripped with a `meta.notices` entry. Send `Prefer: handling=strict` to opt into strict enforcement; `Prefer: handling=lenient` is honored only for callers already lenient-eligible and cannot downgrade a strict caller's enforcement.
596
+ */
597
+ get: {
598
+ parameters: {
599
+ query?: {
600
+ stocked?: "true" | "false" | "all";
601
+ showWholesale?: "true" | "false";
602
+ wholesaleOnly?: "true" | "false";
603
+ origin?: string;
604
+ continent?: string;
605
+ country?: string | string[];
606
+ region?: string;
607
+ source?: string | string[];
608
+ name?: string;
609
+ processing?: string;
610
+ variety?: string;
611
+ type?: string;
612
+ grade?: string;
613
+ appearance?: string;
614
+ supplier?: string;
615
+ dryingMethod?: string;
616
+ flavorKeywords?: string | string[];
617
+ arrivalDate?: string;
618
+ stockedDate?: string;
619
+ stockedDays?: number;
620
+ coffeeIds?: string | string[];
621
+ scoreValueMin?: number | null;
622
+ scoreValueMax?: number | null;
623
+ pricePerLbMin?: number | null;
624
+ pricePerLbMax?: number | null;
625
+ processing_base_method?: string;
626
+ fermentation_type?: string;
627
+ process_additive?: string;
628
+ has_additives?: "true" | "false";
629
+ processing_disclosure_level?: string;
630
+ processing_confidence_min?: number | null;
631
+ };
632
+ header?: {
633
+ Prefer?: string;
450
634
  };
635
+ path?: never;
636
+ cookie?: never;
451
637
  };
638
+ requestBody?: never;
452
639
  responses: {
453
- /** @description The created sourcing brief */
454
- 201: {
640
+ /** @description Access-aware catalog filter metadata */
641
+ 200: {
455
642
  headers: {
456
643
  [name: string]: unknown;
457
644
  };
458
645
  content: {
459
- "application/json": components["schemas"]["SourcingBriefResponse"];
646
+ "application/json": components["schemas"]["CatalogFacetsResponse"];
460
647
  };
461
648
  };
462
- /** @description Invalid request body or unsupported criteria */
463
- 400: {
649
+ /** @description Authentication required */
650
+ 401: {
464
651
  headers: {
465
652
  [name: string]: unknown;
466
653
  };
@@ -468,6 +655,57 @@ interface paths {
468
655
  "application/json": components["schemas"]["ErrorResponse"];
469
656
  };
470
657
  };
658
+ /** @description Insufficient entitlement (plan or role) */
659
+ 403: {
660
+ headers: {
661
+ [name: string]: unknown;
662
+ };
663
+ content: {
664
+ "application/json": components["schemas"]["ErrorResponse"];
665
+ };
666
+ };
667
+ };
668
+ };
669
+ put?: never;
670
+ post?: never;
671
+ delete?: never;
672
+ options?: never;
673
+ head?: never;
674
+ patch?: never;
675
+ trace?: never;
676
+ };
677
+ "/v1/catalog/origin-price-stats": {
678
+ parameters: {
679
+ query?: never;
680
+ header?: never;
681
+ path?: never;
682
+ cookie?: never;
683
+ };
684
+ /**
685
+ * Live catalog price context by origin
686
+ * @description Returns per-origin live catalog price percentiles over the caller-visible stocked catalog. Used by first-party surfaces to compare a lot's visible display price against origin peers.
687
+ */
688
+ get: {
689
+ parameters: {
690
+ query?: {
691
+ showWholesale?: "true" | "false";
692
+ wholesaleOnly?: "true" | "false";
693
+ };
694
+ header?: never;
695
+ path?: never;
696
+ cookie?: never;
697
+ };
698
+ requestBody?: never;
699
+ responses: {
700
+ /** @description Per-origin price context for caller-visible catalog rows */
701
+ 200: {
702
+ headers: {
703
+ [name: string]: unknown;
704
+ };
705
+ content: {
706
+ "application/json": components["schemas"]["CatalogOriginPriceStatsResponse"];
707
+ };
708
+ };
471
709
  /** @description Authentication required */
472
710
  401: {
473
711
  headers: {
@@ -488,13 +726,15 @@ interface paths {
488
726
  };
489
727
  };
490
728
  };
729
+ put?: never;
730
+ post?: never;
491
731
  delete?: never;
492
732
  options?: never;
493
733
  head?: never;
494
734
  patch?: never;
495
735
  trace?: never;
496
736
  };
497
- "/v1/procurement/briefs/{id}": {
737
+ "/v1/catalog/proof-coverage": {
498
738
  parameters: {
499
739
  query?: never;
500
740
  header?: never;
@@ -502,27 +742,25 @@ interface paths {
502
742
  cookie?: never;
503
743
  };
504
744
  /**
505
- * Get a sourcing brief
506
- * @description Fetch one of the authenticated principal's sourcing briefs by id. Requires a member session or a paid (member+) API plan; API keys also need the catalog:read scope.
745
+ * Aggregate proof-coverage over the public catalog
746
+ * @description Aggregate-only proof coverage (no row-level evidence) computed over the stocked public catalog.
507
747
  */
508
748
  get: {
509
749
  parameters: {
510
750
  query?: never;
511
751
  header?: never;
512
- path: {
513
- id: string;
514
- };
752
+ path?: never;
515
753
  cookie?: never;
516
754
  };
517
755
  requestBody?: never;
518
756
  responses: {
519
- /** @description The requested sourcing brief */
757
+ /** @description Proof-coverage summary with per-family buckets and gaps */
520
758
  200: {
521
759
  headers: {
522
760
  [name: string]: unknown;
523
761
  };
524
762
  content: {
525
- "application/json": components["schemas"]["SourcingBriefResponse"];
763
+ "application/json": components["schemas"]["CatalogProofCoverageResponse"];
526
764
  };
527
765
  };
528
766
  /** @description Authentication required */
@@ -543,8 +781,65 @@ interface paths {
543
781
  "application/json": components["schemas"]["ErrorResponse"];
544
782
  };
545
783
  };
546
- /** @description No such brief for this principal */
547
- 404: {
784
+ };
785
+ };
786
+ put?: never;
787
+ post?: never;
788
+ delete?: never;
789
+ options?: never;
790
+ head?: never;
791
+ patch?: never;
792
+ trace?: never;
793
+ };
794
+ "/v1/price-index": {
795
+ parameters: {
796
+ query?: never;
797
+ header?: never;
798
+ path?: never;
799
+ cookie?: never;
800
+ };
801
+ /**
802
+ * Parchment Price Index (aggregate snapshots)
803
+ * @description Aggregate-only price index over price_index_snapshots. Requires an API key with Parchment Intelligence (ppiAccess).
804
+ */
805
+ get: {
806
+ parameters: {
807
+ query?: {
808
+ page?: number;
809
+ limit?: number;
810
+ origin?: string;
811
+ process?: string;
812
+ grade?: string;
813
+ from?: string;
814
+ to?: string;
815
+ wholesale?: "true" | "false";
816
+ };
817
+ header?: never;
818
+ path?: never;
819
+ cookie?: never;
820
+ };
821
+ requestBody?: never;
822
+ responses: {
823
+ /** @description A page of aggregate price-index snapshots */
824
+ 200: {
825
+ headers: {
826
+ [name: string]: unknown;
827
+ };
828
+ content: {
829
+ "application/json": components["schemas"]["PriceIndexResponse"];
830
+ };
831
+ };
832
+ /** @description Authentication required */
833
+ 401: {
834
+ headers: {
835
+ [name: string]: unknown;
836
+ };
837
+ content: {
838
+ "application/json": components["schemas"]["ErrorResponse"];
839
+ };
840
+ };
841
+ /** @description Insufficient entitlement (plan or role) */
842
+ 403: {
548
843
  headers: {
549
844
  [name: string]: unknown;
550
845
  };
@@ -562,7 +857,7 @@ interface paths {
562
857
  patch?: never;
563
858
  trace?: never;
564
859
  };
565
- "/v1/procurement/briefs/{id}/matches": {
860
+ "/v1/catalog/{id}/similar": {
566
861
  parameters: {
567
862
  query?: never;
568
863
  header?: never;
@@ -570,14 +865,16 @@ interface paths {
570
865
  cookie?: never;
571
866
  };
572
867
  /**
573
- * Run a sourcing brief against the catalog
574
- * @description Return the catalog coffees that satisfy a saved brief's criteria, each annotated with the deterministic reasons it matched. Requires a member session or a paid (member+) API plan; API keys also need the catalog:read scope.
868
+ * Find catalog coffees similar to a target coffee
869
+ * @description Vector-similarity matches for a target catalog coffee, with deterministic identity gating, supplier-diversity re-ranking, and a canonical/similar split. Requires the bean-matching capability (a member session or a paid API plan).
575
870
  */
576
871
  get: {
577
872
  parameters: {
578
873
  query?: {
579
- page?: number;
874
+ threshold?: string;
580
875
  limit?: number;
876
+ stocked_only?: "true" | "false";
877
+ mode?: "all" | "likely_same" | "similar_profile";
581
878
  };
582
879
  header?: never;
583
880
  path: {
@@ -587,16 +884,16 @@ interface paths {
587
884
  };
588
885
  requestBody?: never;
589
886
  responses: {
590
- /** @description A page of catalog matches for the brief */
887
+ /** @description Target coffee with grouped similarity matches */
591
888
  200: {
592
889
  headers: {
593
890
  [name: string]: unknown;
594
891
  };
595
892
  content: {
596
- "application/json": components["schemas"]["SourcingBriefMatchesResponse"];
893
+ "application/json": components["schemas"]["CatalogSimilarityResponse"];
597
894
  };
598
895
  };
599
- /** @description Invalid pagination parameter */
896
+ /** @description Invalid path id or query parameter */
600
897
  400: {
601
898
  headers: {
602
899
  [name: string]: unknown;
@@ -623,7 +920,7 @@ interface paths {
623
920
  "application/json": components["schemas"]["ErrorResponse"];
624
921
  };
625
922
  };
626
- /** @description No such brief for this principal */
923
+ /** @description Catalog coffee not found */
627
924
  404: {
628
925
  headers: {
629
926
  [name: string]: unknown;
@@ -642,528 +939,349 @@ interface paths {
642
939
  patch?: never;
643
940
  trace?: never;
644
941
  };
645
- }
646
- interface components {
647
- schemas: {
648
- HealthResponse: {
649
- /** @enum {string} */
650
- status: "ok";
651
- /** @enum {string} */
652
- service: "parchment-api";
653
- version: string;
654
- /** Format: date-time */
655
- timestamp: string;
656
- };
657
- DiscoveryResponse: {
658
- /** @enum {string} */
659
- product: "Parchment";
660
- namespace: string;
661
- health: string;
662
- docs: string;
663
- openapi: string;
664
- };
665
- MeResponse: {
666
- authenticated: boolean;
667
- /** @enum {string} */
668
- authKind: "anonymous" | "session" | "api-key";
669
- userId: string | null;
670
- appRoles: string[];
671
- primaryAppRole: string | null;
672
- /** @enum {string|null} */
673
- apiPlan: "viewer" | "member" | "enterprise" | null;
674
- ppiAccess: boolean;
675
- apiScopes: string[];
942
+ "/v1/procurement/briefs": {
943
+ parameters: {
944
+ query?: never;
945
+ header?: never;
946
+ path?: never;
947
+ cookie?: never;
676
948
  };
677
- CatalogAccessResponse: {
678
- visibility: {
679
- isPrivilegedSession: boolean;
680
- publicOnly: boolean;
681
- showWholesale: boolean;
682
- wholesaleOnly: boolean;
949
+ /**
950
+ * List saved sourcing briefs
951
+ * @description List the authenticated principal's active sourcing briefs. Requires a member session or a paid (member+) API plan; API keys also need the catalog:read scope.
952
+ */
953
+ get: {
954
+ parameters: {
955
+ query?: never;
956
+ header?: never;
957
+ path?: never;
958
+ cookie?: never;
683
959
  };
684
- capabilities: {
685
- canViewPublicCatalog: boolean;
686
- canViewFullCatalog: boolean;
687
- canViewWholesale: boolean;
688
- canUseBasicFilters: boolean;
689
- canUseAdvancedFilters: boolean;
690
- canUseProcessFacets: boolean;
691
- canUsePriceScoreRanges: boolean;
692
- canUseAdvancedSorts: boolean;
693
- canViewPremiumFilterMetadata: boolean;
694
- canUseSemanticSearch: boolean;
695
- canUseBeanMatching: boolean;
696
- canUseSavedSearches: boolean;
697
- canExport: boolean;
960
+ requestBody?: never;
961
+ responses: {
962
+ /** @description The principal's active sourcing briefs */
963
+ 200: {
964
+ headers: {
965
+ [name: string]: unknown;
966
+ };
967
+ content: {
968
+ "application/json": components["schemas"]["SourcingBriefsListResponse"];
969
+ };
970
+ };
971
+ /** @description Authentication required */
972
+ 401: {
973
+ headers: {
974
+ [name: string]: unknown;
975
+ };
976
+ content: {
977
+ "application/json": components["schemas"]["ErrorResponse"];
978
+ };
979
+ };
980
+ /** @description Insufficient entitlement (plan or role) */
981
+ 403: {
982
+ headers: {
983
+ [name: string]: unknown;
984
+ };
985
+ content: {
986
+ "application/json": components["schemas"]["ErrorResponse"];
987
+ };
988
+ };
698
989
  };
699
990
  };
700
- CatalogItem: {
701
- id: number;
702
- name?: string | null;
703
- source?: string | null;
704
- continent?: string | null;
705
- country?: string | null;
706
- region?: string | null;
707
- processing?: string | null;
708
- cultivar_detail?: string | null;
709
- type?: string | null;
710
- grade?: string | null;
711
- appearance?: string | null;
712
- score_value?: number | null;
713
- cost_lb?: number | null;
714
- price_per_lb?: number | null;
715
- arrival_date?: string | null;
716
- stocked_date?: string | null;
717
- stocked?: boolean | null;
718
- };
719
- CatalogListResponse: {
720
- data: components["schemas"]["CatalogItem"][];
721
- pagination: {
722
- page: number;
723
- limit: number;
724
- total: number;
725
- totalPages: number;
726
- hasNext: boolean;
727
- hasPrev: boolean;
991
+ put?: never;
992
+ /**
993
+ * Create a sourcing brief
994
+ * @description Create a saved sourcing brief for the authenticated principal. Requires a member session or a paid (member+) API plan; API keys also need the catalog:read scope.
995
+ */
996
+ post: {
997
+ parameters: {
998
+ query?: never;
999
+ header?: never;
1000
+ path?: never;
1001
+ cookie?: never;
728
1002
  };
729
- meta: {
730
- /** @enum {string} */
731
- resource: "catalog";
732
- /** @enum {string} */
733
- namespace: "/v1/catalog";
734
- /** @enum {string} */
735
- version: "v1";
736
- auth: {
737
- /** @enum {string} */
738
- kind: "anonymous" | "session" | "api-key";
739
- /** @enum {string|null} */
740
- role: "viewer" | "member" | "admin" | null;
741
- /** @enum {string|null} */
742
- apiPlan: "viewer" | "member" | "enterprise" | null;
743
- };
744
- access: {
745
- publicOnly: boolean;
746
- rowLimit: number | null;
747
- limited: boolean;
748
- totalAvailable: number;
1003
+ requestBody?: {
1004
+ content: {
1005
+ "application/json": components["schemas"]["SourcingBriefCreateRequest"];
749
1006
  };
750
1007
  };
751
- };
752
- CatalogProofCoverageResponse: {
753
- meta: {
754
- /** @enum {string} */
755
- resource: "catalog-proof-coverage";
756
- /** @enum {string} */
757
- namespace: "/v1/catalog/proof-coverage";
758
- /** @enum {string} */
759
- version: "v1";
760
- auth: {
761
- /** @enum {string} */
762
- kind: "anonymous" | "session" | "api-key";
763
- /** @enum {string|null} */
764
- role: "viewer" | "member" | "admin" | null;
765
- /** @enum {string|null} */
766
- apiPlan: "viewer" | "member" | "enterprise" | null;
1008
+ responses: {
1009
+ /** @description The created sourcing brief */
1010
+ 201: {
1011
+ headers: {
1012
+ [name: string]: unknown;
1013
+ };
1014
+ content: {
1015
+ "application/json": components["schemas"]["SourcingBriefResponse"];
1016
+ };
767
1017
  };
768
- access: {
769
- publicOnly: boolean;
770
- sampled: number;
771
- totalAvailable: number;
1018
+ /** @description Invalid request body or unsupported criteria */
1019
+ 400: {
1020
+ headers: {
1021
+ [name: string]: unknown;
1022
+ };
1023
+ content: {
1024
+ "application/json": components["schemas"]["ErrorResponse"];
1025
+ };
772
1026
  };
773
- };
774
- coverage: {
775
- overall: {
776
- label: string;
777
- count: number;
778
- share: number;
779
- }[];
780
- families: {
781
- [key: string]: {
782
- label: string;
783
- count: number;
784
- share: number;
785
- }[];
1027
+ /** @description Authentication required */
1028
+ 401: {
1029
+ headers: {
1030
+ [name: string]: unknown;
1031
+ };
1032
+ content: {
1033
+ "application/json": components["schemas"]["ErrorResponse"];
1034
+ };
786
1035
  };
787
- signals: {
788
- [key: string]: number;
1036
+ /** @description Insufficient entitlement (plan or role) */
1037
+ 403: {
1038
+ headers: {
1039
+ [name: string]: unknown;
1040
+ };
1041
+ content: {
1042
+ "application/json": components["schemas"]["ErrorResponse"];
1043
+ };
789
1044
  };
790
- top_gaps: {
791
- family: string;
792
- label: string;
793
- count: number;
794
- share: number;
795
- }[];
796
- limitations: string[];
797
1045
  };
798
1046
  };
799
- PriceIndexItem: {
800
- date: string;
801
- origin: string;
802
- process: string | null;
803
- grade: string | null;
804
- wholesale: boolean;
805
- price: {
806
- min: number | null;
807
- max: number | null;
808
- avg: number | null;
809
- median: number | null;
810
- p25: number | null;
811
- p75: number | null;
812
- stdev: number | null;
813
- };
814
- sample: {
815
- suppliers: number;
816
- listings: number;
817
- aggregationTier: number | null;
818
- };
819
- provenance: {
820
- synthetic: boolean;
821
- };
1047
+ delete?: never;
1048
+ options?: never;
1049
+ head?: never;
1050
+ patch?: never;
1051
+ trace?: never;
1052
+ };
1053
+ "/v1/procurement/briefs/{id}": {
1054
+ parameters: {
1055
+ query?: never;
1056
+ header?: never;
1057
+ path?: never;
1058
+ cookie?: never;
822
1059
  };
823
- PriceIndexResponse: {
824
- data: components["schemas"]["PriceIndexItem"][];
825
- pagination: {
826
- page: number;
827
- limit: number;
828
- total: number;
829
- totalPages: number;
830
- hasNext: boolean;
831
- hasPrev: boolean;
1060
+ /**
1061
+ * Get a sourcing brief
1062
+ * @description Fetch one of the authenticated principal's sourcing briefs by id. Requires a member session or a paid (member+) API plan; API keys also need the catalog:read scope.
1063
+ */
1064
+ get: {
1065
+ parameters: {
1066
+ query?: never;
1067
+ header?: never;
1068
+ path: {
1069
+ id: string;
1070
+ };
1071
+ cookie?: never;
832
1072
  };
833
- meta: {
834
- /** @enum {string} */
835
- resource: "price-index";
836
- /** @enum {string} */
837
- namespace: "/v1/price-index";
838
- /** @enum {string} */
839
- version: "v1";
840
- auth: {
841
- /** @enum {string} */
842
- kind: "api-key";
843
- /** @enum {string|null} */
844
- apiPlan: "viewer" | "member" | "enterprise" | null;
845
- /** @enum {boolean} */
846
- ppiAccess: true;
1073
+ requestBody?: never;
1074
+ responses: {
1075
+ /** @description The requested sourcing brief */
1076
+ 200: {
1077
+ headers: {
1078
+ [name: string]: unknown;
1079
+ };
1080
+ content: {
1081
+ "application/json": components["schemas"]["SourcingBriefResponse"];
1082
+ };
847
1083
  };
848
- filters: {
849
- origin: string | null;
850
- process: string | null;
851
- grade: string | null;
852
- from: string | null;
853
- to: string | null;
854
- wholesale: boolean | null;
1084
+ /** @description Authentication required */
1085
+ 401: {
1086
+ headers: {
1087
+ [name: string]: unknown;
1088
+ };
1089
+ content: {
1090
+ "application/json": components["schemas"]["ErrorResponse"];
1091
+ };
855
1092
  };
856
- access: {
857
- rowLimit: number | null;
858
- limited: boolean;
859
- totalAvailable: number;
1093
+ /** @description Insufficient entitlement (plan or role) */
1094
+ 403: {
1095
+ headers: {
1096
+ [name: string]: unknown;
1097
+ };
1098
+ content: {
1099
+ "application/json": components["schemas"]["ErrorResponse"];
1100
+ };
860
1101
  };
861
- source: {
862
- /** @enum {string} */
863
- table: "price_index_snapshots";
864
- /** @enum {boolean} */
865
- aggregateOnly: true;
1102
+ /** @description No such brief for this principal */
1103
+ 404: {
1104
+ headers: {
1105
+ [name: string]: unknown;
1106
+ };
1107
+ content: {
1108
+ "application/json": components["schemas"]["ErrorResponse"];
1109
+ };
866
1110
  };
867
1111
  };
868
1112
  };
869
- ErrorResponse: {
870
- error: {
871
- code: string;
872
- message: string;
873
- };
1113
+ put?: never;
1114
+ post?: never;
1115
+ delete?: never;
1116
+ options?: never;
1117
+ head?: never;
1118
+ patch?: never;
1119
+ trace?: never;
1120
+ };
1121
+ "/v1/procurement/briefs/{id}/matches": {
1122
+ parameters: {
1123
+ query?: never;
1124
+ header?: never;
1125
+ path?: never;
1126
+ cookie?: never;
874
1127
  };
875
- CatalogSimilarityTarget: {
876
- id: number;
877
- name: string;
878
- source: string | null;
879
- origin: string | null;
880
- country: string | null;
881
- continent: string | null;
882
- processing: string | null;
883
- processing_base_method: string | null;
884
- fermentation_type: string | null;
885
- drying_method: string | null;
886
- stocked: boolean | null;
887
- arrival_date: string | null;
888
- stocked_date: string | null;
889
- price_per_lb: number | null;
890
- price_tiers?: unknown;
891
- cost_lb: number | null;
892
- pricing: {
893
- price_per_lb: number | null;
894
- price_tiers?: unknown;
895
- cost_lb: number | null;
896
- /** @enum {number} */
897
- baseline_quantity_lbs: 1;
898
- baseline_price_per_lb: number | null;
899
- /** @enum {string|null} */
900
- baseline_source: "price_per_lb" | "price_tiers" | "cost_lb" | null;
1128
+ /**
1129
+ * Run a sourcing brief against the catalog
1130
+ * @description Return the catalog coffees that satisfy a saved brief's criteria, each annotated with the deterministic reasons it matched. Requires a member session or a paid (member+) API plan; API keys also need the catalog:read scope.
1131
+ */
1132
+ get: {
1133
+ parameters: {
1134
+ query?: {
1135
+ page?: number;
1136
+ limit?: number;
1137
+ };
1138
+ header?: never;
1139
+ path: {
1140
+ id: string;
1141
+ };
1142
+ cookie?: never;
901
1143
  };
902
- proof: {
903
- /** @enum {string} */
904
- version: "proof-summary-v1";
905
- overall: {
906
- /** @enum {string} */
907
- label: "strong" | "partial" | "limited" | "not_available";
908
- families_with_signals: number;
1144
+ requestBody?: never;
1145
+ responses: {
1146
+ /** @description A page of catalog matches for the brief */
1147
+ 200: {
1148
+ headers: {
1149
+ [name: string]: unknown;
1150
+ };
1151
+ content: {
1152
+ "application/json": components["schemas"]["SourcingBriefMatchesResponse"];
1153
+ };
909
1154
  };
910
- families: {
911
- process: {
912
- label: string;
913
- confidence: number | null;
914
- signals: string[];
915
- message: string;
1155
+ /** @description Invalid pagination parameter */
1156
+ 400: {
1157
+ headers: {
1158
+ [name: string]: unknown;
916
1159
  };
917
- provenance: {
918
- label: string;
919
- confidence: number | null;
920
- signals: string[];
921
- message: string;
1160
+ content: {
1161
+ "application/json": components["schemas"]["ErrorResponse"];
922
1162
  };
923
- freshness: {
924
- label: string;
925
- confidence: number | null;
926
- signals: string[];
927
- message: string;
1163
+ };
1164
+ /** @description Authentication required */
1165
+ 401: {
1166
+ headers: {
1167
+ [name: string]: unknown;
928
1168
  };
929
- pricing: {
930
- label: string;
931
- confidence: number | null;
932
- signals: string[];
933
- message: string;
1169
+ content: {
1170
+ "application/json": components["schemas"]["ErrorResponse"];
934
1171
  };
935
1172
  };
936
- limitations: string[];
937
- };
938
- };
939
- CatalogSimilarityMatch: {
940
- coffee: {
941
- id: number;
942
- name: string;
943
- source: string | null;
944
- origin: string | null;
945
- country: string | null;
946
- continent: string | null;
947
- processing: string | null;
948
- processing_base_method: string | null;
949
- fermentation_type: string | null;
950
- drying_method: string | null;
951
- stocked: boolean | null;
952
- arrival_date: string | null;
953
- stocked_date: string | null;
954
- proof: {
955
- /** @enum {string} */
956
- version: "proof-summary-v1";
957
- overall: {
958
- /** @enum {string} */
959
- label: "strong" | "partial" | "limited" | "not_available";
960
- families_with_signals: number;
1173
+ /** @description Insufficient entitlement (plan or role) */
1174
+ 403: {
1175
+ headers: {
1176
+ [name: string]: unknown;
961
1177
  };
962
- families: {
963
- process: {
964
- label: string;
965
- confidence: number | null;
966
- signals: string[];
967
- message: string;
968
- };
969
- provenance: {
970
- label: string;
971
- confidence: number | null;
972
- signals: string[];
973
- message: string;
974
- };
975
- freshness: {
976
- label: string;
977
- confidence: number | null;
978
- signals: string[];
979
- message: string;
980
- };
981
- pricing: {
982
- label: string;
983
- confidence: number | null;
984
- signals: string[];
985
- message: string;
986
- };
1178
+ content: {
1179
+ "application/json": components["schemas"]["ErrorResponse"];
1180
+ };
1181
+ };
1182
+ /** @description No such brief for this principal */
1183
+ 404: {
1184
+ headers: {
1185
+ [name: string]: unknown;
1186
+ };
1187
+ content: {
1188
+ "application/json": components["schemas"]["ErrorResponse"];
987
1189
  };
988
- limitations: string[];
989
1190
  };
990
- };
991
- pricing: {
992
- price_per_lb: number | null;
993
- price_tiers?: unknown;
994
- cost_lb: number | null;
995
- /** @enum {number} */
996
- baseline_quantity_lbs: 1;
997
- baseline_price_per_lb: number | null;
998
- /** @enum {string|null} */
999
- baseline_source: "price_per_lb" | "price_tiers" | "cost_lb" | null;
1000
- };
1001
- price_delta_1lb: {
1002
- amount: number | null;
1003
- percent: number | null;
1004
- /** @enum {string} */
1005
- currency: "USD";
1006
- };
1007
- score: {
1008
- average: number;
1009
- dimensions: {
1010
- origin: number | null;
1011
- processing: number | null;
1012
- tasting: number | null;
1013
- };
1014
- chunk_matches: number;
1015
- };
1016
- match: {
1017
- /** @enum {string} */
1018
- category: "likely_same" | "similar_profile";
1019
- classification: {
1020
- /** @enum {string} */
1021
- kind: "canonical_candidate" | "similar_recommendation";
1022
- /** @enum {string} */
1023
- identity_eligibility: "eligible" | "blocked" | "insufficient_evidence";
1024
- /** @enum {string} */
1025
- confidence: "high_beta" | "medium_beta" | "low_beta";
1026
- blockers: {
1027
- code: string;
1028
- /** @enum {string} */
1029
- severity: "hard" | "soft";
1030
- target_value: string | null;
1031
- candidate_value: string | null;
1032
- }[];
1033
- evidence: string[];
1034
- };
1035
- /** @enum {string} */
1036
- confidence: "high_beta" | "medium_beta" | "low_beta";
1037
- /** @enum {boolean} */
1038
- beta: true;
1039
- language: string;
1040
- same_supplier: boolean;
1041
- };
1042
- explanation: {
1043
- summary: string;
1044
- signals: string[];
1045
- };
1046
- compatibility: {
1047
- cost_lb: number | null;
1048
1191
  };
1049
1192
  };
1050
- CatalogSimilarityResponse: {
1051
- data: {
1052
- target: components["schemas"]["CatalogSimilarityTarget"];
1053
- groups: {
1054
- canonical_candidates: components["schemas"]["CatalogSimilarityMatch"][];
1055
- similar_recommendations: components["schemas"]["CatalogSimilarityMatch"][];
1056
- };
1057
- matches: components["schemas"]["CatalogSimilarityMatch"][];
1058
- };
1059
- meta: {
1060
- /** @enum {string} */
1061
- resource: "catalog-similarity";
1062
- /** @enum {string} */
1063
- namespace: "/v1/catalog/{id}/similar";
1064
- /** @enum {string} */
1065
- version: "v1";
1066
- /** @enum {string} */
1067
- status: "beta";
1068
- auth: {
1069
- /** @enum {string} */
1070
- kind: "session" | "api-key";
1071
- /** @enum {string|null} */
1072
- role: "viewer" | "member" | "admin" | null;
1073
- /** @enum {string|null} */
1074
- apiPlan: "viewer" | "member" | "enterprise" | null;
1075
- };
1076
- access: {
1077
- /** @enum {string} */
1078
- requiredCapability: "canUseBeanMatching";
1079
- /** @enum {boolean} */
1080
- canUseBeanMatching: true;
1081
- };
1082
- query: {
1083
- threshold: number;
1084
- limit: number;
1085
- stockedOnly: boolean;
1086
- /** @enum {string} */
1087
- mode: "all" | "likely_same" | "similar_profile";
1088
- };
1089
- copy: {
1090
- confidence: string;
1091
- };
1092
- /** @enum {string} */
1093
- classification_version: "canonical-match-v1";
1094
- /** @enum {string} */
1095
- query_strategy: "bounded-vector-candidates-v1" | "canonical-vector-aggregated-v2" | "legacy-vector-aggregated-v1";
1096
- };
1193
+ put?: never;
1194
+ post?: never;
1195
+ delete?: never;
1196
+ options?: never;
1197
+ head?: never;
1198
+ patch?: never;
1199
+ trace?: never;
1200
+ };
1201
+ }
1202
+ interface components {
1203
+ schemas: {
1204
+ HealthResponse: {
1205
+ /** @enum {string} */
1206
+ status: "ok";
1207
+ /** @enum {string} */
1208
+ service: "parchment-api";
1209
+ version: string;
1210
+ /** Format: date-time */
1211
+ timestamp: string;
1097
1212
  };
1098
- SourcingBriefCriteria: {
1099
- /** @enum {number} */
1100
- version?: 1;
1101
- country?: string;
1102
- region?: string;
1103
- processing?: string;
1104
- processing_base_method?: string;
1105
- max_price_per_lb?: number;
1106
- stocked_only?: boolean;
1107
- wholesale_only?: boolean;
1108
- stocked_days?: number;
1213
+ DiscoveryResponse: {
1214
+ /** @enum {string} */
1215
+ product: "Parchment";
1216
+ namespace: string;
1217
+ health: string;
1218
+ docs: string;
1219
+ openapi: string;
1109
1220
  };
1110
- SourcingBriefResource: {
1221
+ MeResponse: {
1222
+ authenticated: boolean;
1223
+ /** @enum {string} */
1224
+ authKind: "anonymous" | "session" | "api-key";
1225
+ userId: string | null;
1226
+ appRoles: string[];
1227
+ primaryAppRole: string | null;
1228
+ /** @enum {string|null} */
1229
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1230
+ ppiAccess: boolean;
1231
+ apiScopes: string[];
1232
+ };
1233
+ ApiKeyRecord: {
1234
+ /** Format: uuid */
1111
1235
  id: string;
1112
1236
  name: string;
1113
- criteria: components["schemas"]["SourcingBriefCriteria"] & Record<string, never>;
1114
- /** @enum {string} */
1115
- cadence: "manual";
1237
+ /** Format: date-time */
1238
+ createdAt: string | null;
1239
+ /** Format: date-time */
1240
+ lastUsedAt: string | null;
1116
1241
  isActive: boolean;
1117
- lastRunAt: string | null;
1118
- createdAt: string;
1119
- updatedAt: string;
1242
+ scopes: string[];
1120
1243
  };
1121
- SourcingBriefsListResponse: {
1122
- data: components["schemas"]["SourcingBriefResource"][];
1123
- meta: {
1124
- /** @enum {string} */
1125
- resource: "procurement-briefs";
1126
- /** @enum {string} */
1127
- namespace: "/v1/procurement/briefs";
1128
- /** @enum {string} */
1129
- version: "v1";
1130
- auth: {
1131
- /** @enum {string} */
1132
- kind: "session" | "api-key";
1133
- /** @enum {string|null} */
1134
- role: "admin" | "member" | "viewer" | null;
1135
- /** @enum {string|null} */
1136
- apiPlan: "viewer" | "member" | "enterprise" | null;
1137
- };
1138
- };
1244
+ ApiKeyListResponse: {
1245
+ data: components["schemas"]["ApiKeyRecord"][];
1139
1246
  };
1140
- SourcingBriefResponse: {
1141
- data: components["schemas"]["SourcingBriefResource"];
1142
- meta: {
1143
- /** @enum {string} */
1144
- resource: "procurement-brief";
1145
- /** @enum {string} */
1146
- namespace: "/v1/procurement/briefs" | "/v1/procurement/briefs/:id";
1147
- /** @enum {string} */
1148
- version: "v1";
1149
- auth: {
1150
- /** @enum {string} */
1151
- kind: "session" | "api-key";
1152
- /** @enum {string|null} */
1153
- role: "admin" | "member" | "viewer" | null;
1154
- /** @enum {string|null} */
1155
- apiPlan: "viewer" | "member" | "enterprise" | null;
1156
- };
1247
+ ErrorResponse: {
1248
+ error: {
1249
+ code: string;
1250
+ message: string;
1157
1251
  };
1158
1252
  };
1159
- SourcingBriefCreateRequest: {
1160
- /** @description Human label, 1-120 chars. */
1161
- name: string;
1162
- criteria: components["schemas"]["SourcingBriefCriteria"] & unknown;
1163
- /** @enum {string} */
1164
- cadence?: "manual";
1253
+ ApiKeyCreateResponse: {
1254
+ /** @description Raw API key. Returned only once; store the secret client-side. */
1255
+ apiKey: string;
1256
+ key: components["schemas"]["ApiKeyRecord"];
1165
1257
  };
1166
- SourcingBriefMatch: {
1258
+ ApiKeyMutationResponse: {
1259
+ key: components["schemas"]["ApiKeyRecord"];
1260
+ };
1261
+ CatalogAccessResponse: {
1262
+ visibility: {
1263
+ isPrivilegedSession: boolean;
1264
+ publicOnly: boolean;
1265
+ showWholesale: boolean;
1266
+ wholesaleOnly: boolean;
1267
+ };
1268
+ capabilities: {
1269
+ canViewPublicCatalog: boolean;
1270
+ canViewFullCatalog: boolean;
1271
+ canViewWholesale: boolean;
1272
+ canUseBasicFilters: boolean;
1273
+ canUseAdvancedFilters: boolean;
1274
+ canUseProcessFacets: boolean;
1275
+ canUsePriceScoreRanges: boolean;
1276
+ canUseAdvancedSorts: boolean;
1277
+ canViewPremiumFilterMetadata: boolean;
1278
+ canUseSemanticSearch: boolean;
1279
+ canUseBeanMatching: boolean;
1280
+ canUseSavedSearches: boolean;
1281
+ canExport: boolean;
1282
+ };
1283
+ };
1284
+ CatalogItem: {
1167
1285
  id: number;
1168
1286
  name?: string | null;
1169
1287
  source?: string | null;
@@ -1171,15 +1289,11 @@ interface components {
1171
1289
  country?: string | null;
1172
1290
  region?: string | null;
1173
1291
  processing?: string | null;
1174
- processing_base_method?: string | null;
1175
- fermentation_type?: string | null;
1176
- drying_method?: string | null;
1177
1292
  cultivar_detail?: string | null;
1178
1293
  type?: string | null;
1179
1294
  grade?: string | null;
1180
1295
  appearance?: string | null;
1181
1296
  score_value?: number | null;
1182
- purveyor_score?: number | null;
1183
1297
  cost_lb?: number | null;
1184
1298
  price_per_lb?: number | null;
1185
1299
  price_tiers?: unknown;
@@ -1188,10 +1302,38 @@ interface components {
1188
1302
  stocked?: boolean | null;
1189
1303
  wholesale?: boolean | null;
1190
1304
  public_coffee?: boolean | null;
1191
- matchReasons: string[];
1305
+ purveyor_score?: number | null;
1306
+ purveyor_score_confidence?: number | null;
1307
+ purveyor_score_tier?: string | null;
1308
+ purveyor_score_factors?: unknown;
1309
+ purveyor_score_version?: string | null;
1310
+ purveyor_score_updated_at?: string | null;
1311
+ processing_base_method?: string | null;
1312
+ fermentation_type?: string | null;
1313
+ process_additives?: unknown;
1314
+ process_additive_detail?: string | null;
1315
+ fermentation_duration_hours?: number | null;
1316
+ processing_notes?: string | null;
1317
+ processing_disclosure_level?: string | null;
1318
+ processing_confidence?: number | null;
1319
+ processing_evidence_available?: boolean | null;
1320
+ drying_method?: string | null;
1321
+ farm_notes?: string | null;
1322
+ description_short?: string | null;
1323
+ description_long?: string | null;
1324
+ cupping_notes?: string | null;
1325
+ roast_recs?: string | null;
1326
+ lot_size?: string | null;
1327
+ bag_size?: string | null;
1328
+ packaging?: string | null;
1329
+ link?: string | null;
1330
+ last_updated?: string | null;
1331
+ unstocked_date?: string | null;
1332
+ ai_description?: string | null;
1333
+ ai_tasting_notes?: unknown;
1192
1334
  };
1193
- SourcingBriefMatchesResponse: {
1194
- data: components["schemas"]["SourcingBriefMatch"][];
1335
+ CatalogListResponse: {
1336
+ data: components["schemas"]["CatalogItem"][];
1195
1337
  pagination: {
1196
1338
  page: number;
1197
1339
  limit: number;
@@ -1202,142 +1344,1117 @@ interface components {
1202
1344
  };
1203
1345
  meta: {
1204
1346
  /** @enum {string} */
1205
- resource: "procurement-brief-matches";
1347
+ resource: "catalog";
1206
1348
  /** @enum {string} */
1207
- namespace: "/v1/procurement/briefs/:id/matches";
1349
+ namespace: "/v1/catalog";
1208
1350
  /** @enum {string} */
1209
1351
  version: "v1";
1210
- generatedAt: string;
1211
1352
  auth: {
1212
1353
  /** @enum {string} */
1213
- kind: "session" | "api-key";
1354
+ kind: "anonymous" | "session" | "api-key";
1214
1355
  /** @enum {string|null} */
1215
- role: "admin" | "member" | "viewer" | null;
1356
+ role: "viewer" | "member" | "admin" | null;
1216
1357
  /** @enum {string|null} */
1217
1358
  apiPlan: "viewer" | "member" | "enterprise" | null;
1218
1359
  };
1219
- brief: components["schemas"]["SourcingBriefResource"];
1220
- criteria: components["schemas"]["SourcingBriefCriteria"] & Record<string, never>;
1221
- limitations: string[];
1360
+ access: {
1361
+ publicOnly: boolean;
1362
+ showWholesale: boolean;
1363
+ wholesaleOnly: boolean;
1364
+ rowLimit: number | null;
1365
+ limited: boolean;
1366
+ totalAvailable: number;
1367
+ };
1368
+ /** @description Present only when requested filters/sorts were stripped because the caller lacked the capability. The request still returns 200 with the entitled subset applied. */
1369
+ notices?: {
1370
+ status: 401 | 403;
1371
+ /** @enum {string} */
1372
+ code: "auth_required" | "entitlement_required";
1373
+ message: string;
1374
+ deniedParams: string[];
1375
+ }[];
1222
1376
  };
1223
1377
  };
1224
- };
1225
- responses: never;
1226
- parameters: never;
1227
- requestBodies: never;
1228
- headers: never;
1229
- pathItems: never;
1230
- }
1231
-
1232
- interface ParchmentClientOptions {
1233
- /** Base URL of the Parchment API, e.g. https://api.purveyors.io */
1234
- baseUrl: string;
1235
- /**
1236
- * Optional bearer token (a Supabase JWT or, later, an API key). Sent as
1237
- * `Authorization: Bearer <token>`. Auth is resolved server-side against the
1238
- * unified principal model; the SDK only forwards the credential.
1239
- */
1240
- token?: string;
1241
- /** Override the fetch implementation (useful for tests or custom runtimes). */
1242
- fetch?: ClientOptions["fetch"];
1243
- }
1244
- /** Query parameters for {@link ParchmentClient.catalog.list}. */
1245
- type CatalogListQuery = NonNullable<paths["/v1/catalog"]["get"]["parameters"]["query"]>;
1246
- /** Query parameters for {@link ParchmentClient.catalog.similar}. */
1247
- type CatalogSimilarQuery = NonNullable<paths["/v1/catalog/{id}/similar"]["get"]["parameters"]["query"]>;
1248
- /** Query parameters for {@link ParchmentClient.priceIndex.list}. */
1249
- type PriceIndexQuery = NonNullable<paths["/v1/price-index"]["get"]["parameters"]["query"]>;
1250
- /** Query parameters for {@link ParchmentClient.procurement.briefs.matches}. */
1251
- type BriefMatchesQuery = NonNullable<paths["/v1/procurement/briefs/{id}/matches"]["get"]["parameters"]["query"]>;
1252
- /** Request body for {@link ParchmentClient.procurement.briefs.create}. */
1253
- type SourcingBriefCreateRequest = components["schemas"]["SourcingBriefCreateRequest"];
1254
- /**
1255
- * Create a typed Parchment API client.
1256
- *
1257
- * The generated core (openapi-fetch over the generated `paths` types) is the
1258
- * contract truth; the named helpers below are the hand-maintained ergonomic
1259
- * layer and grow as endpoints land. `raw` always exposes the underlying typed
1260
- * client for direct path access to anything not yet wrapped.
1261
- */
1262
- declare function createParchmentClient(options: ParchmentClientOptions): {
1263
- /** The underlying typed openapi-fetch client for direct path access. */
1264
- raw: openapi_fetch.Client<paths, `${string}/${string}`>;
1265
- /** Liveness and service identity. */
1266
- health: () => Promise<openapi_fetch.FetchResponse<{
1267
- parameters: {
1268
- query?: never;
1269
- header?: never;
1270
- path?: never;
1271
- cookie?: never;
1378
+ CatalogFacetsResponse: {
1379
+ /** @description Compatibility-friendly unique values for dropdown filters. Keys with no values are omitted. */
1380
+ values: {
1381
+ sources?: string[];
1382
+ continents?: string[];
1383
+ countries?: string[];
1384
+ regions?: string[];
1385
+ processing?: string[];
1386
+ cultivar_detail?: string[];
1387
+ type?: string[];
1388
+ grade?: string[];
1389
+ appearance?: string[];
1390
+ arrivalDates?: string[];
1391
+ drying_method?: string[];
1392
+ wholesale?: string[];
1393
+ processing_base_method?: string[];
1394
+ fermentation_type?: string[];
1395
+ process_additives?: string[];
1396
+ processing_disclosure_level?: string[];
1397
+ };
1398
+ /** @description Counted facet values for CLI/agent use. Counts are computed after visibility and entitled query filters are applied. */
1399
+ facets: {
1400
+ sources?: {
1401
+ value: string;
1402
+ count: number;
1403
+ }[];
1404
+ continents?: {
1405
+ value: string;
1406
+ count: number;
1407
+ }[];
1408
+ countries?: {
1409
+ value: string;
1410
+ count: number;
1411
+ }[];
1412
+ regions?: {
1413
+ value: string;
1414
+ count: number;
1415
+ }[];
1416
+ processing?: {
1417
+ value: string;
1418
+ count: number;
1419
+ }[];
1420
+ cultivar_detail?: {
1421
+ value: string;
1422
+ count: number;
1423
+ }[];
1424
+ type?: {
1425
+ value: string;
1426
+ count: number;
1427
+ }[];
1428
+ grade?: {
1429
+ value: string;
1430
+ count: number;
1431
+ }[];
1432
+ appearance?: {
1433
+ value: string;
1434
+ count: number;
1435
+ }[];
1436
+ arrivalDates?: {
1437
+ value: string;
1438
+ count: number;
1439
+ }[];
1440
+ drying_method?: {
1441
+ value: string;
1442
+ count: number;
1443
+ }[];
1444
+ wholesale?: {
1445
+ value: string;
1446
+ count: number;
1447
+ }[];
1448
+ processing_base_method?: {
1449
+ value: string;
1450
+ count: number;
1451
+ }[];
1452
+ fermentation_type?: {
1453
+ value: string;
1454
+ count: number;
1455
+ }[];
1456
+ process_additives?: {
1457
+ value: string;
1458
+ count: number;
1459
+ }[];
1460
+ processing_disclosure_level?: {
1461
+ value: string;
1462
+ count: number;
1463
+ }[];
1464
+ };
1465
+ meta: {
1466
+ /** @enum {string} */
1467
+ resource: "catalog-facets";
1468
+ /** @enum {string} */
1469
+ namespace: "/v1/catalog/facets";
1470
+ /** @enum {string} */
1471
+ version: "v1";
1472
+ auth: {
1473
+ /** @enum {string} */
1474
+ kind: "session" | "api-key";
1475
+ /** @enum {string|null} */
1476
+ role: "viewer" | "member" | "admin" | null;
1477
+ /** @enum {string|null} */
1478
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1479
+ };
1480
+ access: {
1481
+ publicOnly: boolean;
1482
+ showWholesale: boolean;
1483
+ wholesaleOnly: boolean;
1484
+ stocked: boolean | null;
1485
+ premiumMetadata: boolean;
1486
+ };
1487
+ notices?: {
1488
+ status: 401 | 403;
1489
+ /** @enum {string} */
1490
+ code: "auth_required" | "entitlement_required";
1491
+ message: string;
1492
+ deniedParams: string[];
1493
+ }[];
1494
+ };
1272
1495
  };
1273
- requestBody?: never;
1274
- responses: {
1275
- 200: {
1276
- headers: {
1277
- [name: string]: unknown;
1496
+ CatalogOriginPriceStatsResponse: {
1497
+ originPriceStats: {
1498
+ origin: string;
1499
+ median: number;
1500
+ q1: number;
1501
+ q3: number;
1502
+ min: number;
1503
+ max: number;
1504
+ sample_size: number;
1505
+ supplier_count: number;
1506
+ }[];
1507
+ meta: {
1508
+ /** @enum {string} */
1509
+ resource: "catalog-origin-price-stats";
1510
+ /** @enum {string} */
1511
+ namespace: "/v1/catalog/origin-price-stats";
1512
+ /** @enum {string} */
1513
+ version: "v1";
1514
+ auth: {
1515
+ /** @enum {string} */
1516
+ kind: "anonymous" | "session" | "api-key";
1517
+ /** @enum {string|null} */
1518
+ role: "viewer" | "member" | "admin" | null;
1519
+ /** @enum {string|null} */
1520
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1278
1521
  };
1279
- content: {
1280
- "application/json": components["schemas"]["HealthResponse"];
1522
+ access: {
1523
+ publicOnly: boolean;
1524
+ showWholesale: boolean;
1525
+ wholesaleOnly: boolean;
1526
+ /** @enum {string} */
1527
+ scope: "retail" | "wholesale" | "all";
1528
+ totalAvailable: number;
1281
1529
  };
1282
1530
  };
1283
1531
  };
1284
- }, openapi_fetch.FetchOptions<{
1285
- parameters: {
1286
- query?: never;
1287
- header?: never;
1288
- path?: never;
1289
- cookie?: never;
1532
+ CatalogProofCoverageResponse: {
1533
+ meta: {
1534
+ /** @enum {string} */
1535
+ resource: "catalog-proof-coverage";
1536
+ /** @enum {string} */
1537
+ namespace: "/v1/catalog/proof-coverage";
1538
+ /** @enum {string} */
1539
+ version: "v1";
1540
+ auth: {
1541
+ /** @enum {string} */
1542
+ kind: "anonymous" | "session" | "api-key";
1543
+ /** @enum {string|null} */
1544
+ role: "viewer" | "member" | "admin" | null;
1545
+ /** @enum {string|null} */
1546
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1547
+ };
1548
+ access: {
1549
+ publicOnly: boolean;
1550
+ sampled: number;
1551
+ totalAvailable: number;
1552
+ };
1553
+ };
1554
+ coverage: {
1555
+ overall: {
1556
+ label: string;
1557
+ count: number;
1558
+ share: number;
1559
+ }[];
1560
+ families: {
1561
+ [key: string]: {
1562
+ label: string;
1563
+ count: number;
1564
+ share: number;
1565
+ }[];
1566
+ };
1567
+ signals: {
1568
+ [key: string]: number;
1569
+ };
1570
+ top_gaps: {
1571
+ family: string;
1572
+ label: string;
1573
+ count: number;
1574
+ share: number;
1575
+ }[];
1576
+ limitations: string[];
1577
+ };
1290
1578
  };
1291
- requestBody?: never;
1292
- responses: {
1293
- 200: {
1294
- headers: {
1295
- [name: string]: unknown;
1579
+ PriceIndexItem: {
1580
+ date: string;
1581
+ origin: string;
1582
+ process: string | null;
1583
+ grade: string | null;
1584
+ wholesale: boolean;
1585
+ price: {
1586
+ min: number | null;
1587
+ max: number | null;
1588
+ avg: number | null;
1589
+ median: number | null;
1590
+ p25: number | null;
1591
+ p75: number | null;
1592
+ stdev: number | null;
1593
+ };
1594
+ sample: {
1595
+ suppliers: number;
1596
+ listings: number;
1597
+ aggregationTier: number | null;
1598
+ };
1599
+ provenance: {
1600
+ synthetic: boolean;
1601
+ };
1602
+ };
1603
+ PriceIndexResponse: {
1604
+ data: components["schemas"]["PriceIndexItem"][];
1605
+ pagination: {
1606
+ page: number;
1607
+ limit: number;
1608
+ total: number;
1609
+ totalPages: number;
1610
+ hasNext: boolean;
1611
+ hasPrev: boolean;
1612
+ };
1613
+ meta: {
1614
+ /** @enum {string} */
1615
+ resource: "price-index";
1616
+ /** @enum {string} */
1617
+ namespace: "/v1/price-index";
1618
+ /** @enum {string} */
1619
+ version: "v1";
1620
+ auth: {
1621
+ /** @enum {string} */
1622
+ kind: "api-key";
1623
+ /** @enum {string|null} */
1624
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1625
+ /** @enum {boolean} */
1626
+ ppiAccess: true;
1627
+ };
1628
+ filters: {
1629
+ origin: string | null;
1630
+ process: string | null;
1631
+ grade: string | null;
1632
+ from: string | null;
1633
+ to: string | null;
1634
+ wholesale: boolean | null;
1635
+ };
1636
+ access: {
1637
+ rowLimit: number | null;
1638
+ limited: boolean;
1639
+ totalAvailable: number;
1640
+ };
1641
+ source: {
1642
+ /** @enum {string} */
1643
+ table: "price_index_snapshots";
1644
+ /** @enum {boolean} */
1645
+ aggregateOnly: true;
1646
+ };
1647
+ };
1648
+ };
1649
+ CatalogSimilarityTarget: {
1650
+ id: number;
1651
+ name: string;
1652
+ source: string | null;
1653
+ origin: string | null;
1654
+ country: string | null;
1655
+ continent: string | null;
1656
+ processing: string | null;
1657
+ processing_base_method: string | null;
1658
+ fermentation_type: string | null;
1659
+ drying_method: string | null;
1660
+ stocked: boolean | null;
1661
+ arrival_date: string | null;
1662
+ stocked_date: string | null;
1663
+ price_per_lb: number | null;
1664
+ price_tiers?: unknown;
1665
+ cost_lb: number | null;
1666
+ pricing: {
1667
+ price_per_lb: number | null;
1668
+ price_tiers?: unknown;
1669
+ cost_lb: number | null;
1670
+ /** @enum {number} */
1671
+ baseline_quantity_lbs: 1;
1672
+ baseline_price_per_lb: number | null;
1673
+ /** @enum {string|null} */
1674
+ baseline_source: "price_per_lb" | "price_tiers" | "cost_lb" | null;
1675
+ };
1676
+ proof: {
1677
+ /** @enum {string} */
1678
+ version: "proof-summary-v1";
1679
+ overall: {
1680
+ /** @enum {string} */
1681
+ label: "strong" | "partial" | "limited" | "not_available";
1682
+ families_with_signals: number;
1683
+ };
1684
+ families: {
1685
+ process: {
1686
+ label: string;
1687
+ confidence: number | null;
1688
+ signals: string[];
1689
+ message: string;
1690
+ };
1691
+ provenance: {
1692
+ label: string;
1693
+ confidence: number | null;
1694
+ signals: string[];
1695
+ message: string;
1696
+ };
1697
+ freshness: {
1698
+ label: string;
1699
+ confidence: number | null;
1700
+ signals: string[];
1701
+ message: string;
1702
+ };
1703
+ pricing: {
1704
+ label: string;
1705
+ confidence: number | null;
1706
+ signals: string[];
1707
+ message: string;
1708
+ };
1709
+ };
1710
+ limitations: string[];
1711
+ };
1712
+ };
1713
+ CatalogSimilarityMatch: {
1714
+ coffee: {
1715
+ id: number;
1716
+ name: string;
1717
+ source: string | null;
1718
+ origin: string | null;
1719
+ country: string | null;
1720
+ continent: string | null;
1721
+ processing: string | null;
1722
+ processing_base_method: string | null;
1723
+ fermentation_type: string | null;
1724
+ drying_method: string | null;
1725
+ stocked: boolean | null;
1726
+ arrival_date: string | null;
1727
+ stocked_date: string | null;
1728
+ proof: {
1729
+ /** @enum {string} */
1730
+ version: "proof-summary-v1";
1731
+ overall: {
1732
+ /** @enum {string} */
1733
+ label: "strong" | "partial" | "limited" | "not_available";
1734
+ families_with_signals: number;
1735
+ };
1736
+ families: {
1737
+ process: {
1738
+ label: string;
1739
+ confidence: number | null;
1740
+ signals: string[];
1741
+ message: string;
1742
+ };
1743
+ provenance: {
1744
+ label: string;
1745
+ confidence: number | null;
1746
+ signals: string[];
1747
+ message: string;
1748
+ };
1749
+ freshness: {
1750
+ label: string;
1751
+ confidence: number | null;
1752
+ signals: string[];
1753
+ message: string;
1754
+ };
1755
+ pricing: {
1756
+ label: string;
1757
+ confidence: number | null;
1758
+ signals: string[];
1759
+ message: string;
1760
+ };
1761
+ };
1762
+ limitations: string[];
1763
+ };
1764
+ };
1765
+ pricing: {
1766
+ price_per_lb: number | null;
1767
+ price_tiers?: unknown;
1768
+ cost_lb: number | null;
1769
+ /** @enum {number} */
1770
+ baseline_quantity_lbs: 1;
1771
+ baseline_price_per_lb: number | null;
1772
+ /** @enum {string|null} */
1773
+ baseline_source: "price_per_lb" | "price_tiers" | "cost_lb" | null;
1774
+ };
1775
+ price_delta_1lb: {
1776
+ amount: number | null;
1777
+ percent: number | null;
1778
+ /** @enum {string} */
1779
+ currency: "USD";
1780
+ };
1781
+ score: {
1782
+ average: number;
1783
+ dimensions: {
1784
+ origin: number | null;
1785
+ processing: number | null;
1786
+ tasting: number | null;
1787
+ };
1788
+ chunk_matches: number;
1789
+ };
1790
+ match: {
1791
+ /** @enum {string} */
1792
+ category: "likely_same" | "similar_profile";
1793
+ classification: {
1794
+ /** @enum {string} */
1795
+ kind: "canonical_candidate" | "similar_recommendation";
1796
+ /** @enum {string} */
1797
+ identity_eligibility: "eligible" | "blocked" | "insufficient_evidence";
1798
+ /** @enum {string} */
1799
+ confidence: "high_beta" | "medium_beta" | "low_beta";
1800
+ blockers: {
1801
+ code: string;
1802
+ /** @enum {string} */
1803
+ severity: "hard" | "soft";
1804
+ target_value: string | null;
1805
+ candidate_value: string | null;
1806
+ }[];
1807
+ evidence: string[];
1808
+ };
1809
+ /** @enum {string} */
1810
+ confidence: "high_beta" | "medium_beta" | "low_beta";
1811
+ /** @enum {boolean} */
1812
+ beta: true;
1813
+ language: string;
1814
+ same_supplier: boolean;
1815
+ };
1816
+ explanation: {
1817
+ summary: string;
1818
+ signals: string[];
1819
+ };
1820
+ compatibility: {
1821
+ cost_lb: number | null;
1822
+ };
1823
+ };
1824
+ CatalogSimilarityResponse: {
1825
+ data: {
1826
+ target: components["schemas"]["CatalogSimilarityTarget"];
1827
+ groups: {
1828
+ canonical_candidates: components["schemas"]["CatalogSimilarityMatch"][];
1829
+ similar_recommendations: components["schemas"]["CatalogSimilarityMatch"][];
1830
+ };
1831
+ matches: components["schemas"]["CatalogSimilarityMatch"][];
1832
+ };
1833
+ meta: {
1834
+ /** @enum {string} */
1835
+ resource: "catalog-similarity";
1836
+ /** @enum {string} */
1837
+ namespace: "/v1/catalog/{id}/similar";
1838
+ /** @enum {string} */
1839
+ version: "v1";
1840
+ /** @enum {string} */
1841
+ status: "beta";
1842
+ auth: {
1843
+ /** @enum {string} */
1844
+ kind: "session" | "api-key";
1845
+ /** @enum {string|null} */
1846
+ role: "viewer" | "member" | "admin" | null;
1847
+ /** @enum {string|null} */
1848
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1849
+ };
1850
+ access: {
1851
+ /** @enum {string} */
1852
+ requiredCapability: "canUseBeanMatching";
1853
+ /** @enum {boolean} */
1854
+ canUseBeanMatching: true;
1855
+ };
1856
+ query: {
1857
+ threshold: number;
1858
+ limit: number;
1859
+ stockedOnly: boolean;
1860
+ /** @enum {string} */
1861
+ mode: "all" | "likely_same" | "similar_profile";
1862
+ };
1863
+ copy: {
1864
+ confidence: string;
1865
+ };
1866
+ /** @enum {string} */
1867
+ classification_version: "canonical-match-v1";
1868
+ /** @enum {string} */
1869
+ query_strategy: "bounded-vector-candidates-v1" | "canonical-vector-aggregated-v2" | "legacy-vector-aggregated-v1";
1870
+ };
1871
+ };
1872
+ SourcingBriefCriteria: {
1873
+ /** @enum {number} */
1874
+ version?: 1;
1875
+ country?: string;
1876
+ region?: string;
1877
+ processing?: string;
1878
+ processing_base_method?: string;
1879
+ max_price_per_lb?: number;
1880
+ stocked_only?: boolean;
1881
+ wholesale_only?: boolean;
1882
+ stocked_days?: number;
1883
+ };
1884
+ SourcingBriefResource: {
1885
+ id: string;
1886
+ name: string;
1887
+ criteria: components["schemas"]["SourcingBriefCriteria"] & Record<string, never>;
1888
+ /** @enum {string} */
1889
+ cadence: "manual";
1890
+ isActive: boolean;
1891
+ lastRunAt: string | null;
1892
+ createdAt: string;
1893
+ updatedAt: string;
1894
+ };
1895
+ SourcingBriefsListResponse: {
1896
+ data: components["schemas"]["SourcingBriefResource"][];
1897
+ meta: {
1898
+ /** @enum {string} */
1899
+ resource: "procurement-briefs";
1900
+ /** @enum {string} */
1901
+ namespace: "/v1/procurement/briefs";
1902
+ /** @enum {string} */
1903
+ version: "v1";
1904
+ auth: {
1905
+ /** @enum {string} */
1906
+ kind: "session" | "api-key";
1907
+ /** @enum {string|null} */
1908
+ role: "admin" | "member" | "viewer" | null;
1909
+ /** @enum {string|null} */
1910
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1911
+ };
1912
+ };
1913
+ };
1914
+ SourcingBriefResponse: {
1915
+ data: components["schemas"]["SourcingBriefResource"];
1916
+ meta: {
1917
+ /** @enum {string} */
1918
+ resource: "procurement-brief";
1919
+ /** @enum {string} */
1920
+ namespace: "/v1/procurement/briefs" | "/v1/procurement/briefs/:id";
1921
+ /** @enum {string} */
1922
+ version: "v1";
1923
+ auth: {
1924
+ /** @enum {string} */
1925
+ kind: "session" | "api-key";
1926
+ /** @enum {string|null} */
1927
+ role: "admin" | "member" | "viewer" | null;
1928
+ /** @enum {string|null} */
1929
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1930
+ };
1931
+ };
1932
+ };
1933
+ SourcingBriefCreateRequest: {
1934
+ /** @description Human label, 1-120 chars. */
1935
+ name: string;
1936
+ criteria: components["schemas"]["SourcingBriefCriteria"] & unknown;
1937
+ /** @enum {string} */
1938
+ cadence?: "manual";
1939
+ };
1940
+ SourcingBriefMatch: {
1941
+ id: number;
1942
+ name?: string | null;
1943
+ source?: string | null;
1944
+ continent?: string | null;
1945
+ country?: string | null;
1946
+ region?: string | null;
1947
+ processing?: string | null;
1948
+ processing_base_method?: string | null;
1949
+ fermentation_type?: string | null;
1950
+ drying_method?: string | null;
1951
+ cultivar_detail?: string | null;
1952
+ type?: string | null;
1953
+ grade?: string | null;
1954
+ appearance?: string | null;
1955
+ score_value?: number | null;
1956
+ purveyor_score?: number | null;
1957
+ cost_lb?: number | null;
1958
+ price_per_lb?: number | null;
1959
+ price_tiers?: unknown;
1960
+ arrival_date?: string | null;
1961
+ stocked_date?: string | null;
1962
+ stocked?: boolean | null;
1963
+ wholesale?: boolean | null;
1964
+ public_coffee?: boolean | null;
1965
+ matchReasons: string[];
1966
+ };
1967
+ SourcingBriefMatchesResponse: {
1968
+ data: components["schemas"]["SourcingBriefMatch"][];
1969
+ pagination: {
1970
+ page: number;
1971
+ limit: number;
1972
+ total: number;
1973
+ totalPages: number;
1974
+ hasNext: boolean;
1975
+ hasPrev: boolean;
1976
+ };
1977
+ meta: {
1978
+ /** @enum {string} */
1979
+ resource: "procurement-brief-matches";
1980
+ /** @enum {string} */
1981
+ namespace: "/v1/procurement/briefs/:id/matches";
1982
+ /** @enum {string} */
1983
+ version: "v1";
1984
+ generatedAt: string;
1985
+ auth: {
1986
+ /** @enum {string} */
1987
+ kind: "session" | "api-key";
1988
+ /** @enum {string|null} */
1989
+ role: "admin" | "member" | "viewer" | null;
1990
+ /** @enum {string|null} */
1991
+ apiPlan: "viewer" | "member" | "enterprise" | null;
1992
+ };
1993
+ brief: components["schemas"]["SourcingBriefResource"];
1994
+ criteria: components["schemas"]["SourcingBriefCriteria"] & Record<string, never>;
1995
+ limitations: string[];
1996
+ };
1997
+ };
1998
+ };
1999
+ responses: never;
2000
+ parameters: never;
2001
+ requestBodies: never;
2002
+ headers: never;
2003
+ pathItems: never;
2004
+ }
2005
+
2006
+ interface ParchmentClientOptions {
2007
+ /** Base URL of the Parchment API, e.g. https://api.purveyors.io */
2008
+ baseUrl: string;
2009
+ /**
2010
+ * Optional bearer token (a Supabase JWT or, later, an API key). Sent as
2011
+ * `Authorization: Bearer <token>`. Auth is resolved server-side against the
2012
+ * unified principal model; the SDK only forwards the credential.
2013
+ */
2014
+ token?: string;
2015
+ /** Override the fetch implementation (useful for tests or custom runtimes). */
2016
+ fetch?: ClientOptions["fetch"];
2017
+ }
2018
+ /** Query parameters for {@link ParchmentClient.catalog.list}. */
2019
+ type CatalogListQuery = NonNullable<paths["/v1/catalog"]["get"]["parameters"]["query"]>;
2020
+ /** Query parameters for {@link ParchmentClient.catalog.facets}. */
2021
+ type CatalogFacetsQuery = NonNullable<paths["/v1/catalog/facets"]["get"]["parameters"]["query"]>;
2022
+ /**
2023
+ * Optional headers for {@link ParchmentClient.catalog.list}, notably the
2024
+ * RFC 7240 `Prefer: handling=lenient|strict` override (PADR-0013 §7). Sending
2025
+ * `handling=lenient` opts a strict caller (API key or bearer-session JWT) back
2026
+ * into strip-with-notice degradation instead of a 401/403 hard-deny.
2027
+ */
2028
+ type CatalogListHeaders = NonNullable<paths["/v1/catalog"]["get"]["parameters"]["header"]>;
2029
+ /** Optional headers for {@link ParchmentClient.catalog.facets}; see {@link CatalogListHeaders}. */
2030
+ type CatalogFacetsHeaders = NonNullable<paths["/v1/catalog/facets"]["get"]["parameters"]["header"]>;
2031
+ /** Query parameters for {@link ParchmentClient.catalog.originPriceStats}. */
2032
+ type CatalogOriginPriceStatsQuery = NonNullable<paths["/v1/catalog/origin-price-stats"]["get"]["parameters"]["query"]>;
2033
+ /** Query parameters for {@link ParchmentClient.catalog.similar}. */
2034
+ type CatalogSimilarQuery = NonNullable<paths["/v1/catalog/{id}/similar"]["get"]["parameters"]["query"]>;
2035
+ /** Query parameters for {@link ParchmentClient.priceIndex.list}. */
2036
+ type PriceIndexQuery = NonNullable<paths["/v1/price-index"]["get"]["parameters"]["query"]>;
2037
+ /** Query parameters for {@link ParchmentClient.procurement.briefs.matches}. */
2038
+ type BriefMatchesQuery = NonNullable<paths["/v1/procurement/briefs/{id}/matches"]["get"]["parameters"]["query"]>;
2039
+ /** Request body for {@link ParchmentClient.procurement.briefs.create}. */
2040
+ type SourcingBriefCreateRequest = components["schemas"]["SourcingBriefCreateRequest"];
2041
+ /** Request body for {@link ParchmentClient.apiKeys.create}. */
2042
+ type ApiKeyCreateRequest = NonNullable<paths["/v1/api-keys"]["post"]["requestBody"]>["content"]["application/json"];
2043
+ /**
2044
+ * Create a typed Parchment API client.
2045
+ *
2046
+ * The generated core (openapi-fetch over the generated `paths` types) is the
2047
+ * contract truth; the named helpers below are the hand-maintained ergonomic
2048
+ * layer and grow as endpoints land. `raw` always exposes the underlying typed
2049
+ * client for direct path access to anything not yet wrapped.
2050
+ */
2051
+ declare function createParchmentClient(options: ParchmentClientOptions): {
2052
+ /** The underlying typed openapi-fetch client for direct path access. */
2053
+ raw: openapi_fetch.Client<paths, `${string}/${string}`>;
2054
+ /** Liveness and service identity. */
2055
+ health: () => Promise<openapi_fetch.FetchResponse<{
2056
+ parameters: {
2057
+ query?: never;
2058
+ header?: never;
2059
+ path?: never;
2060
+ cookie?: never;
2061
+ };
2062
+ requestBody?: never;
2063
+ responses: {
2064
+ 200: {
2065
+ headers: {
2066
+ [name: string]: unknown;
2067
+ };
2068
+ content: {
2069
+ "application/json": components["schemas"]["HealthResponse"];
2070
+ };
2071
+ };
2072
+ };
2073
+ }, openapi_fetch.FetchOptions<{
2074
+ parameters: {
2075
+ query?: never;
2076
+ header?: never;
2077
+ path?: never;
2078
+ cookie?: never;
2079
+ };
2080
+ requestBody?: never;
2081
+ responses: {
2082
+ 200: {
2083
+ headers: {
2084
+ [name: string]: unknown;
2085
+ };
2086
+ content: {
2087
+ "application/json": components["schemas"]["HealthResponse"];
2088
+ };
2089
+ };
2090
+ };
2091
+ }> | undefined, `${string}/${string}`>>;
2092
+ /** Resolved principal and entitlements for the caller. */
2093
+ me: () => Promise<openapi_fetch.FetchResponse<{
2094
+ parameters: {
2095
+ query?: never;
2096
+ header?: never;
2097
+ path?: never;
2098
+ cookie?: never;
2099
+ };
2100
+ requestBody?: never;
2101
+ responses: {
2102
+ 200: {
2103
+ headers: {
2104
+ [name: string]: unknown;
2105
+ };
2106
+ content: {
2107
+ "application/json": components["schemas"]["MeResponse"];
2108
+ };
2109
+ };
2110
+ };
2111
+ }, openapi_fetch.FetchOptions<{
2112
+ parameters: {
2113
+ query?: never;
2114
+ header?: never;
2115
+ path?: never;
2116
+ cookie?: never;
2117
+ };
2118
+ requestBody?: never;
2119
+ responses: {
2120
+ 200: {
2121
+ headers: {
2122
+ [name: string]: unknown;
2123
+ };
2124
+ content: {
2125
+ "application/json": components["schemas"]["MeResponse"];
2126
+ };
2127
+ };
2128
+ };
2129
+ }> | undefined, `${string}/${string}`>>;
2130
+ apiKeys: {
2131
+ /** List API keys owned by the authenticated session user. */
2132
+ list: () => Promise<openapi_fetch.FetchResponse<{
2133
+ parameters: {
2134
+ query?: never;
2135
+ header?: never;
2136
+ path?: never;
2137
+ cookie?: never;
2138
+ };
2139
+ requestBody?: never;
2140
+ responses: {
2141
+ 200: {
2142
+ headers: {
2143
+ [name: string]: unknown;
2144
+ };
2145
+ content: {
2146
+ "application/json": components["schemas"]["ApiKeyListResponse"];
2147
+ };
2148
+ };
2149
+ 400: {
2150
+ headers: {
2151
+ [name: string]: unknown;
2152
+ };
2153
+ content: {
2154
+ "application/json": components["schemas"]["ErrorResponse"];
2155
+ };
2156
+ };
2157
+ 401: {
2158
+ headers: {
2159
+ [name: string]: unknown;
2160
+ };
2161
+ content: {
2162
+ "application/json": components["schemas"]["ErrorResponse"];
2163
+ };
2164
+ };
2165
+ 403: {
2166
+ headers: {
2167
+ [name: string]: unknown;
2168
+ };
2169
+ content: {
2170
+ "application/json": components["schemas"]["ErrorResponse"];
2171
+ };
2172
+ };
2173
+ 404: {
2174
+ headers: {
2175
+ [name: string]: unknown;
2176
+ };
2177
+ content: {
2178
+ "application/json": components["schemas"]["ErrorResponse"];
2179
+ };
2180
+ };
2181
+ 503: {
2182
+ headers: {
2183
+ [name: string]: unknown;
2184
+ };
2185
+ content: {
2186
+ "application/json": components["schemas"]["ErrorResponse"];
2187
+ };
2188
+ };
2189
+ };
2190
+ }, openapi_fetch.FetchOptions<{
2191
+ parameters: {
2192
+ query?: never;
2193
+ header?: never;
2194
+ path?: never;
2195
+ cookie?: never;
2196
+ };
2197
+ requestBody?: never;
2198
+ responses: {
2199
+ 200: {
2200
+ headers: {
2201
+ [name: string]: unknown;
2202
+ };
2203
+ content: {
2204
+ "application/json": components["schemas"]["ApiKeyListResponse"];
2205
+ };
2206
+ };
2207
+ 400: {
2208
+ headers: {
2209
+ [name: string]: unknown;
2210
+ };
2211
+ content: {
2212
+ "application/json": components["schemas"]["ErrorResponse"];
2213
+ };
2214
+ };
2215
+ 401: {
2216
+ headers: {
2217
+ [name: string]: unknown;
2218
+ };
2219
+ content: {
2220
+ "application/json": components["schemas"]["ErrorResponse"];
2221
+ };
2222
+ };
2223
+ 403: {
2224
+ headers: {
2225
+ [name: string]: unknown;
2226
+ };
2227
+ content: {
2228
+ "application/json": components["schemas"]["ErrorResponse"];
2229
+ };
2230
+ };
2231
+ 404: {
2232
+ headers: {
2233
+ [name: string]: unknown;
2234
+ };
2235
+ content: {
2236
+ "application/json": components["schemas"]["ErrorResponse"];
2237
+ };
2238
+ };
2239
+ 503: {
2240
+ headers: {
2241
+ [name: string]: unknown;
2242
+ };
2243
+ content: {
2244
+ "application/json": components["schemas"]["ErrorResponse"];
2245
+ };
2246
+ };
2247
+ };
2248
+ }> | undefined, `${string}/${string}`>>;
2249
+ /** Create an API key. The raw secret is returned only once. */
2250
+ create: (body: ApiKeyCreateRequest) => Promise<openapi_fetch.FetchResponse<{
2251
+ parameters: {
2252
+ query?: never;
2253
+ header?: never;
2254
+ path?: never;
2255
+ cookie?: never;
2256
+ };
2257
+ requestBody: {
2258
+ content: {
2259
+ "application/json": {
2260
+ name: string;
2261
+ scopes?: "catalog:read"[];
2262
+ };
2263
+ };
2264
+ };
2265
+ responses: {
2266
+ 201: {
2267
+ headers: {
2268
+ [name: string]: unknown;
2269
+ };
2270
+ content: {
2271
+ "application/json": components["schemas"]["ApiKeyCreateResponse"];
2272
+ };
2273
+ };
2274
+ 400: {
2275
+ headers: {
2276
+ [name: string]: unknown;
2277
+ };
2278
+ content: {
2279
+ "application/json": components["schemas"]["ErrorResponse"];
2280
+ };
2281
+ };
2282
+ 401: {
2283
+ headers: {
2284
+ [name: string]: unknown;
2285
+ };
2286
+ content: {
2287
+ "application/json": components["schemas"]["ErrorResponse"];
2288
+ };
2289
+ };
2290
+ 403: {
2291
+ headers: {
2292
+ [name: string]: unknown;
2293
+ };
2294
+ content: {
2295
+ "application/json": components["schemas"]["ErrorResponse"];
2296
+ };
2297
+ };
2298
+ 404: {
2299
+ headers: {
2300
+ [name: string]: unknown;
2301
+ };
2302
+ content: {
2303
+ "application/json": components["schemas"]["ErrorResponse"];
2304
+ };
2305
+ };
2306
+ 503: {
2307
+ headers: {
2308
+ [name: string]: unknown;
2309
+ };
2310
+ content: {
2311
+ "application/json": components["schemas"]["ErrorResponse"];
2312
+ };
2313
+ };
2314
+ };
2315
+ }, {
2316
+ body: {
2317
+ name: string;
2318
+ scopes?: "catalog:read"[];
2319
+ };
2320
+ }, `${string}/${string}`>>;
2321
+ /** Revoke an API key owned by the authenticated session user. */
2322
+ revoke: (id: string) => Promise<openapi_fetch.FetchResponse<{
2323
+ parameters: {
2324
+ query?: never;
2325
+ header?: never;
2326
+ path: {
2327
+ id: string;
2328
+ };
2329
+ cookie?: never;
2330
+ };
2331
+ requestBody?: never;
2332
+ responses: {
2333
+ 200: {
2334
+ headers: {
2335
+ [name: string]: unknown;
2336
+ };
2337
+ content: {
2338
+ "application/json": components["schemas"]["ApiKeyMutationResponse"];
2339
+ };
2340
+ };
2341
+ 400: {
2342
+ headers: {
2343
+ [name: string]: unknown;
2344
+ };
2345
+ content: {
2346
+ "application/json": components["schemas"]["ErrorResponse"];
2347
+ };
2348
+ };
2349
+ 401: {
2350
+ headers: {
2351
+ [name: string]: unknown;
2352
+ };
2353
+ content: {
2354
+ "application/json": components["schemas"]["ErrorResponse"];
2355
+ };
2356
+ };
2357
+ 403: {
2358
+ headers: {
2359
+ [name: string]: unknown;
2360
+ };
2361
+ content: {
2362
+ "application/json": components["schemas"]["ErrorResponse"];
2363
+ };
2364
+ };
2365
+ 404: {
2366
+ headers: {
2367
+ [name: string]: unknown;
2368
+ };
2369
+ content: {
2370
+ "application/json": components["schemas"]["ErrorResponse"];
2371
+ };
2372
+ };
2373
+ 503: {
2374
+ headers: {
2375
+ [name: string]: unknown;
2376
+ };
2377
+ content: {
2378
+ "application/json": components["schemas"]["ErrorResponse"];
2379
+ };
2380
+ };
2381
+ };
2382
+ }, {
2383
+ params: {
2384
+ path: {
2385
+ id: string;
2386
+ };
2387
+ };
2388
+ }, `${string}/${string}`>>;
2389
+ /** Rotate an API key and return the replacement secret once. */
2390
+ rotate: (id: string) => Promise<openapi_fetch.FetchResponse<{
2391
+ parameters: {
2392
+ query?: never;
2393
+ header?: never;
2394
+ path: {
2395
+ id: string;
2396
+ };
2397
+ cookie?: never;
2398
+ };
2399
+ requestBody?: never;
2400
+ responses: {
2401
+ 201: {
2402
+ headers: {
2403
+ [name: string]: unknown;
2404
+ };
2405
+ content: {
2406
+ "application/json": components["schemas"]["ApiKeyCreateResponse"];
2407
+ };
1296
2408
  };
1297
- content: {
1298
- "application/json": components["schemas"]["HealthResponse"];
2409
+ 400: {
2410
+ headers: {
2411
+ [name: string]: unknown;
2412
+ };
2413
+ content: {
2414
+ "application/json": components["schemas"]["ErrorResponse"];
2415
+ };
1299
2416
  };
1300
- };
1301
- };
1302
- }> | undefined, `${string}/${string}`>>;
1303
- /** Resolved principal and entitlements for the caller. */
1304
- me: () => Promise<openapi_fetch.FetchResponse<{
1305
- parameters: {
1306
- query?: never;
1307
- header?: never;
1308
- path?: never;
1309
- cookie?: never;
1310
- };
1311
- requestBody?: never;
1312
- responses: {
1313
- 200: {
1314
- headers: {
1315
- [name: string]: unknown;
2417
+ 401: {
2418
+ headers: {
2419
+ [name: string]: unknown;
2420
+ };
2421
+ content: {
2422
+ "application/json": components["schemas"]["ErrorResponse"];
2423
+ };
1316
2424
  };
1317
- content: {
1318
- "application/json": components["schemas"]["MeResponse"];
2425
+ 403: {
2426
+ headers: {
2427
+ [name: string]: unknown;
2428
+ };
2429
+ content: {
2430
+ "application/json": components["schemas"]["ErrorResponse"];
2431
+ };
1319
2432
  };
1320
- };
1321
- };
1322
- }, openapi_fetch.FetchOptions<{
1323
- parameters: {
1324
- query?: never;
1325
- header?: never;
1326
- path?: never;
1327
- cookie?: never;
1328
- };
1329
- requestBody?: never;
1330
- responses: {
1331
- 200: {
1332
- headers: {
1333
- [name: string]: unknown;
2433
+ 404: {
2434
+ headers: {
2435
+ [name: string]: unknown;
2436
+ };
2437
+ content: {
2438
+ "application/json": components["schemas"]["ErrorResponse"];
2439
+ };
1334
2440
  };
1335
- content: {
1336
- "application/json": components["schemas"]["MeResponse"];
2441
+ 503: {
2442
+ headers: {
2443
+ [name: string]: unknown;
2444
+ };
2445
+ content: {
2446
+ "application/json": components["schemas"]["ErrorResponse"];
2447
+ };
1337
2448
  };
1338
2449
  };
1339
- };
1340
- }> | undefined, `${string}/${string}`>>;
2450
+ }, {
2451
+ params: {
2452
+ path: {
2453
+ id: string;
2454
+ };
2455
+ };
2456
+ }, `${string}/${string}`>>;
2457
+ };
1341
2458
  catalog: {
1342
2459
  /** Catalog capabilities and visibility for the caller. */
1343
2460
  access: () => Promise<openapi_fetch.FetchResponse<{
@@ -1357,6 +2474,22 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
1357
2474
  "application/json": components["schemas"]["CatalogAccessResponse"];
1358
2475
  };
1359
2476
  };
2477
+ 401: {
2478
+ headers: {
2479
+ [name: string]: unknown;
2480
+ };
2481
+ content: {
2482
+ "application/json": components["schemas"]["ErrorResponse"];
2483
+ };
2484
+ };
2485
+ 403: {
2486
+ headers: {
2487
+ [name: string]: unknown;
2488
+ };
2489
+ content: {
2490
+ "application/json": components["schemas"]["ErrorResponse"];
2491
+ };
2492
+ };
1360
2493
  };
1361
2494
  }, openapi_fetch.FetchOptions<{
1362
2495
  parameters: {
@@ -1375,10 +2508,29 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
1375
2508
  "application/json": components["schemas"]["CatalogAccessResponse"];
1376
2509
  };
1377
2510
  };
2511
+ 401: {
2512
+ headers: {
2513
+ [name: string]: unknown;
2514
+ };
2515
+ content: {
2516
+ "application/json": components["schemas"]["ErrorResponse"];
2517
+ };
2518
+ };
2519
+ 403: {
2520
+ headers: {
2521
+ [name: string]: unknown;
2522
+ };
2523
+ content: {
2524
+ "application/json": components["schemas"]["ErrorResponse"];
2525
+ };
2526
+ };
1378
2527
  };
1379
2528
  }> | undefined, `${string}/${string}`>>;
1380
- /** List public catalog coffees (paginated). */
1381
- list: (query?: CatalogListQuery) => Promise<openapi_fetch.FetchResponse<{
2529
+ /**
2530
+ * List public catalog coffees (paginated). Pass `headers` to send the
2531
+ * `Prefer: handling=lenient|strict` override (see {@link CatalogListHeaders}).
2532
+ */
2533
+ list: (query?: CatalogListQuery, headers?: CatalogListHeaders) => Promise<openapi_fetch.FetchResponse<{
1382
2534
  parameters: {
1383
2535
  query?: {
1384
2536
  page?: number;
@@ -1386,8 +2538,40 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
1386
2538
  stocked?: "true" | "false" | "all";
1387
2539
  sort?: string;
1388
2540
  order?: "asc" | "desc";
2541
+ showWholesale?: "true" | "false";
2542
+ wholesaleOnly?: "true" | "false";
2543
+ origin?: string;
2544
+ continent?: string;
2545
+ country?: string | string[];
2546
+ region?: string;
2547
+ source?: string | string[];
2548
+ name?: string;
2549
+ processing?: string;
2550
+ variety?: string;
2551
+ type?: string;
2552
+ grade?: string;
2553
+ appearance?: string;
2554
+ supplier?: string;
2555
+ dryingMethod?: string;
2556
+ flavorKeywords?: string | string[];
2557
+ arrivalDate?: string;
2558
+ stockedDate?: string;
2559
+ stockedDays?: number;
2560
+ coffeeIds?: string;
2561
+ scoreValueMin?: number | null;
2562
+ scoreValueMax?: number | null;
2563
+ pricePerLbMin?: number | null;
2564
+ pricePerLbMax?: number | null;
2565
+ processing_base_method?: string;
2566
+ fermentation_type?: string;
2567
+ process_additive?: string;
2568
+ has_additives?: "true" | "false";
2569
+ processing_disclosure_level?: string;
2570
+ processing_confidence_min?: number | null;
2571
+ };
2572
+ header?: {
2573
+ Prefer?: string;
1389
2574
  };
1390
- header?: never;
1391
2575
  path?: never;
1392
2576
  cookie?: never;
1393
2577
  };
@@ -1401,6 +2585,22 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
1401
2585
  "application/json": components["schemas"]["CatalogListResponse"];
1402
2586
  };
1403
2587
  };
2588
+ 401: {
2589
+ headers: {
2590
+ [name: string]: unknown;
2591
+ };
2592
+ content: {
2593
+ "application/json": components["schemas"]["ErrorResponse"];
2594
+ };
2595
+ };
2596
+ 403: {
2597
+ headers: {
2598
+ [name: string]: unknown;
2599
+ };
2600
+ content: {
2601
+ "application/json": components["schemas"]["ErrorResponse"];
2602
+ };
2603
+ };
1404
2604
  };
1405
2605
  }, {
1406
2606
  params: {
@@ -1410,6 +2610,197 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
1410
2610
  stocked?: "true" | "false" | "all";
1411
2611
  sort?: string;
1412
2612
  order?: "asc" | "desc";
2613
+ showWholesale?: "true" | "false";
2614
+ wholesaleOnly?: "true" | "false";
2615
+ origin?: string;
2616
+ continent?: string;
2617
+ country?: string | string[];
2618
+ region?: string;
2619
+ source?: string | string[];
2620
+ name?: string;
2621
+ processing?: string;
2622
+ variety?: string;
2623
+ type?: string;
2624
+ grade?: string;
2625
+ appearance?: string;
2626
+ supplier?: string;
2627
+ dryingMethod?: string;
2628
+ flavorKeywords?: string | string[];
2629
+ arrivalDate?: string;
2630
+ stockedDate?: string;
2631
+ stockedDays?: number;
2632
+ coffeeIds?: string;
2633
+ scoreValueMin?: number | null;
2634
+ scoreValueMax?: number | null;
2635
+ pricePerLbMin?: number | null;
2636
+ pricePerLbMax?: number | null;
2637
+ processing_base_method?: string;
2638
+ fermentation_type?: string;
2639
+ process_additive?: string;
2640
+ has_additives?: "true" | "false";
2641
+ processing_disclosure_level?: string;
2642
+ processing_confidence_min?: number | null;
2643
+ } | undefined;
2644
+ header: {
2645
+ Prefer?: string;
2646
+ } | undefined;
2647
+ };
2648
+ }, `${string}/${string}`>>;
2649
+ /**
2650
+ * Catalog filter metadata and counted facets. Pass `headers` to send the
2651
+ * `Prefer: handling=lenient|strict` override (see {@link CatalogFacetsHeaders}).
2652
+ */
2653
+ facets: (query?: CatalogFacetsQuery, headers?: CatalogFacetsHeaders) => Promise<openapi_fetch.FetchResponse<{
2654
+ parameters: {
2655
+ query?: {
2656
+ stocked?: "true" | "false" | "all";
2657
+ showWholesale?: "true" | "false";
2658
+ wholesaleOnly?: "true" | "false";
2659
+ origin?: string;
2660
+ continent?: string;
2661
+ country?: string | string[];
2662
+ region?: string;
2663
+ source?: string | string[];
2664
+ name?: string;
2665
+ processing?: string;
2666
+ variety?: string;
2667
+ type?: string;
2668
+ grade?: string;
2669
+ appearance?: string;
2670
+ supplier?: string;
2671
+ dryingMethod?: string;
2672
+ flavorKeywords?: string | string[];
2673
+ arrivalDate?: string;
2674
+ stockedDate?: string;
2675
+ stockedDays?: number;
2676
+ coffeeIds?: string | string[];
2677
+ scoreValueMin?: number | null;
2678
+ scoreValueMax?: number | null;
2679
+ pricePerLbMin?: number | null;
2680
+ pricePerLbMax?: number | null;
2681
+ processing_base_method?: string;
2682
+ fermentation_type?: string;
2683
+ process_additive?: string;
2684
+ has_additives?: "true" | "false";
2685
+ processing_disclosure_level?: string;
2686
+ processing_confidence_min?: number | null;
2687
+ };
2688
+ header?: {
2689
+ Prefer?: string;
2690
+ };
2691
+ path?: never;
2692
+ cookie?: never;
2693
+ };
2694
+ requestBody?: never;
2695
+ responses: {
2696
+ 200: {
2697
+ headers: {
2698
+ [name: string]: unknown;
2699
+ };
2700
+ content: {
2701
+ "application/json": components["schemas"]["CatalogFacetsResponse"];
2702
+ };
2703
+ };
2704
+ 401: {
2705
+ headers: {
2706
+ [name: string]: unknown;
2707
+ };
2708
+ content: {
2709
+ "application/json": components["schemas"]["ErrorResponse"];
2710
+ };
2711
+ };
2712
+ 403: {
2713
+ headers: {
2714
+ [name: string]: unknown;
2715
+ };
2716
+ content: {
2717
+ "application/json": components["schemas"]["ErrorResponse"];
2718
+ };
2719
+ };
2720
+ };
2721
+ }, {
2722
+ params: {
2723
+ query: {
2724
+ stocked?: "true" | "false" | "all";
2725
+ showWholesale?: "true" | "false";
2726
+ wholesaleOnly?: "true" | "false";
2727
+ origin?: string;
2728
+ continent?: string;
2729
+ country?: string | string[];
2730
+ region?: string;
2731
+ source?: string | string[];
2732
+ name?: string;
2733
+ processing?: string;
2734
+ variety?: string;
2735
+ type?: string;
2736
+ grade?: string;
2737
+ appearance?: string;
2738
+ supplier?: string;
2739
+ dryingMethod?: string;
2740
+ flavorKeywords?: string | string[];
2741
+ arrivalDate?: string;
2742
+ stockedDate?: string;
2743
+ stockedDays?: number;
2744
+ coffeeIds?: string | string[];
2745
+ scoreValueMin?: number | null;
2746
+ scoreValueMax?: number | null;
2747
+ pricePerLbMin?: number | null;
2748
+ pricePerLbMax?: number | null;
2749
+ processing_base_method?: string;
2750
+ fermentation_type?: string;
2751
+ process_additive?: string;
2752
+ has_additives?: "true" | "false";
2753
+ processing_disclosure_level?: string;
2754
+ processing_confidence_min?: number | null;
2755
+ } | undefined;
2756
+ header: {
2757
+ Prefer?: string;
2758
+ } | undefined;
2759
+ };
2760
+ }, `${string}/${string}`>>;
2761
+ /** Live catalog price context by origin. */
2762
+ originPriceStats: (query?: CatalogOriginPriceStatsQuery) => Promise<openapi_fetch.FetchResponse<{
2763
+ parameters: {
2764
+ query?: {
2765
+ showWholesale?: "true" | "false";
2766
+ wholesaleOnly?: "true" | "false";
2767
+ };
2768
+ header?: never;
2769
+ path?: never;
2770
+ cookie?: never;
2771
+ };
2772
+ requestBody?: never;
2773
+ responses: {
2774
+ 200: {
2775
+ headers: {
2776
+ [name: string]: unknown;
2777
+ };
2778
+ content: {
2779
+ "application/json": components["schemas"]["CatalogOriginPriceStatsResponse"];
2780
+ };
2781
+ };
2782
+ 401: {
2783
+ headers: {
2784
+ [name: string]: unknown;
2785
+ };
2786
+ content: {
2787
+ "application/json": components["schemas"]["ErrorResponse"];
2788
+ };
2789
+ };
2790
+ 403: {
2791
+ headers: {
2792
+ [name: string]: unknown;
2793
+ };
2794
+ content: {
2795
+ "application/json": components["schemas"]["ErrorResponse"];
2796
+ };
2797
+ };
2798
+ };
2799
+ }, {
2800
+ params: {
2801
+ query: {
2802
+ showWholesale?: "true" | "false";
2803
+ wholesaleOnly?: "true" | "false";
1413
2804
  } | undefined;
1414
2805
  };
1415
2806
  }, `${string}/${string}`>>;
@@ -1431,6 +2822,22 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
1431
2822
  "application/json": components["schemas"]["CatalogProofCoverageResponse"];
1432
2823
  };
1433
2824
  };
2825
+ 401: {
2826
+ headers: {
2827
+ [name: string]: unknown;
2828
+ };
2829
+ content: {
2830
+ "application/json": components["schemas"]["ErrorResponse"];
2831
+ };
2832
+ };
2833
+ 403: {
2834
+ headers: {
2835
+ [name: string]: unknown;
2836
+ };
2837
+ content: {
2838
+ "application/json": components["schemas"]["ErrorResponse"];
2839
+ };
2840
+ };
1434
2841
  };
1435
2842
  }, openapi_fetch.FetchOptions<{
1436
2843
  parameters: {
@@ -1449,6 +2856,22 @@ declare function createParchmentClient(options: ParchmentClientOptions): {
1449
2856
  "application/json": components["schemas"]["CatalogProofCoverageResponse"];
1450
2857
  };
1451
2858
  };
2859
+ 401: {
2860
+ headers: {
2861
+ [name: string]: unknown;
2862
+ };
2863
+ content: {
2864
+ "application/json": components["schemas"]["ErrorResponse"];
2865
+ };
2866
+ };
2867
+ 403: {
2868
+ headers: {
2869
+ [name: string]: unknown;
2870
+ };
2871
+ content: {
2872
+ "application/json": components["schemas"]["ErrorResponse"];
2873
+ };
2874
+ };
1452
2875
  };
1453
2876
  }> | undefined, `${string}/${string}`>>;
1454
2877
  /** Find catalog coffees similar to a target coffee. */