@printhive/api 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/CHANGELOG.md +23 -0
- package/README.md +209 -6
- package/dist/chunk-GOUMDFJR.js +27615 -0
- package/dist/{errors-TJFN2M7S.js → errors-4M56UUFV.js} +1 -1
- package/dist/index.cjs +19245 -5418
- package/dist/index.d.cts +3012 -140
- package/dist/index.d.ts +3012 -140
- package/dist/index.js +194 -22
- package/package.json +1 -1
- package/dist/chunk-7UULMDS5.js +0 -13947
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
- Add typed `printers.search` and `filaments.search`, with bounded integer pagination and catalog `filamentId` values.
|
|
6
|
+
- Reuse the web palette printer matcher and the filament picker ranking through narrow partner routes.
|
|
7
|
+
- Add `acceptedByCreate` using the same catalog lookup and admission predicate as print-job creation. Global, unsynced, and invalid-color rows remain searchable with the flag false.
|
|
8
|
+
- Require Read scope on the existing `/v1/search` and `/v1/materials/command-search` API-key routes. Empty-scope keys receive 403.
|
|
9
|
+
|
|
10
|
+
## 0.3.2
|
|
11
|
+
|
|
12
|
+
- Add `printJobs.get` for live job polling after creation, including the API's waiting-reason snapshot.
|
|
13
|
+
|
|
14
|
+
## 0.3.1
|
|
15
|
+
|
|
16
|
+
- Add `cause` to generated filament waiting reasons and export `FilamentWaitingReason`. Reasons include only unmet source slots at creation and claim recheck.
|
|
17
|
+
|
|
18
|
+
## 0.3.0
|
|
19
|
+
|
|
20
|
+
- Add partner catalog upsert, filtered list and read methods; `preparation_disabled` is not retried as a transient 503.
|
|
21
|
+
- Generate preparation contracts and validators from the current API routes.
|
|
22
|
+
- Add typed preparation creation, reads, total-deadline polling and signed-download metadata.
|
|
23
|
+
- Preserve idempotency keys, immutable retry bodies and typed target refusal reasons.
|
|
24
|
+
- Migrate the Printie simulator from its local preparation wrapper to the SDK.
|
|
25
|
+
|
|
3
26
|
## 0.2.0
|
|
4
27
|
|
|
5
28
|
- Add `printJobs.create` for multipart project preparation and existing JSON artifact creation.
|
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ A TypeScript client for Print Hive's REST API. Version 0.2.0 has zero runtime de
|
|
|
4
4
|
|
|
5
5
|
Version 0.2.0 adds public single-plate print creation and creation-request polling alongside customer printer reads, partner source uploads, and model reads.
|
|
6
6
|
|
|
7
|
+
Preparation support in this source tree is unreleased. See the [changelog](CHANGELOG.md) for released capabilities and the [release procedure](#release) for publishing. Order methods (#4631) remain outside this client.
|
|
8
|
+
|
|
7
9
|
Partner API keys belong on your server. Never bundle a key into a browser, mobile app, or other distributed client. Printie's browser calls Printie's backend; that backend calls Print Hive.
|
|
8
10
|
|
|
9
11
|
## Create a print job
|
|
@@ -26,11 +28,31 @@ const created = await hive.printJobs.waitUntilCreated(request.requestId);
|
|
|
26
28
|
console.log(created.job);
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
`printJobs.create` sends multipart to `/v1/print-jobs/create` for a file path or `Uint8Array` plus `filename`. `plate` and typed `filaments` are required; `targetSlot` is optional. Other inputs include `printer_id`, `name`, `externalId`, `release`, `on_filament_mismatch`, and existing `print_options`. This method reads file paths into memory, copies byte inputs, and can retry the multipart body safely. It returns the server's `202` request fields plus `idempotencyKey`. Persist your own key before calling when retries must survive process restarts. Changed metadata or bytes with the same key conflict.
|
|
31
|
+
`printJobs.create` sends multipart to `/v1/print-jobs/create` for a file path or `Uint8Array` plus `filename`. `plate` and typed `filaments` are required; `targetSlot` is optional. Other inputs include `printer_id`, `name`, `externalId`, `release`, `acceptEngineSettingUpdates`, `on_filament_mismatch`, and existing `print_options`. This method reads file paths into memory, copies byte inputs, and can retry the multipart body safely. It returns the server's `202` request fields plus `idempotencyKey`. Persist your own key before calling when retries must survive process restarts. Changed metadata or bytes with the same key conflict.
|
|
30
32
|
|
|
31
33
|
For an existing artifact, `printJobs.create({ name, model_file_id, ... })` sends JSON and returns the existing `201` response with `job` and eligibility fields plus `idempotencyKey`. The client generates an idempotency key once per call if omitted.
|
|
32
34
|
|
|
33
|
-
`printJobs.getCreateRequest(requestId)` reads the current receipt. `waitUntilCreated(requestId, { intervalMs?, timeoutMs?, signal? })` polls while `preparing`, defaults to a 120-second total deadline, and returns when `created`, including a retained receipt with `job: null` after the job was deleted. `PrintJobCreateStoppedError.request` exposes a `held`, `failed`, or `cancelled` receipt, including its required actions or failure reasons. It does not authorize a held request automatically.
|
|
35
|
+
`printJobs.getCreateRequest(requestId)` reads the current receipt. `waitUntilCreated(requestId, { intervalMs?, timeoutMs?, signal? })` polls while `preparing`, defaults to a 120-second total deadline, and returns when `created`, including a retained receipt with `job: null` after the job was deleted. `PrintJobCreateStoppedError.request` exposes a `held`, `failed`, or `cancelled` receipt, including its required actions or failure reasons. It does not authorize a held request automatically.
|
|
36
|
+
|
|
37
|
+
## Source preparation opt-ins
|
|
38
|
+
|
|
39
|
+
The opt-ins grant separate permissions. `acceptEngineSettingUpdates` permits eligible stock-setting updates; it does not permit an unqualified printer conversion. The separate `allowUnqualifiedConversion` control is being added in [#5083](https://github.com/PrintHive/hive/pull/5083) and is unavailable until that PR merges. Its conversion consent does not approve customised engine-setting changes. When both controls are available, a request can enable both; each still applies its own checks.
|
|
40
|
+
|
|
41
|
+
`acceptEngineSettingUpdates` has OpenAPI `default: false` for JSON and multipart creates. For source preparation, `true` accepts engine changes only to settings absent from the source's `different_settings_to_system` customisation list and backed by nonempty `inherits_group` entries for their presets. Missing diff metadata, a missing diff entry, or missing or empty preset inheritance makes the setting customised and it holds. An empty diff entry counts as stock only with inheritance evidence. Empty source setting values do not exempt customised settings. Accepted changes appear in the prepared plate's `lineage.acceptedEngineSettingChanges`.
|
|
42
|
+
|
|
43
|
+
An engine review hold includes `changes`, `sourceRelease`, and `engineRelease`, alongside the existing `detail`. Each change has `key`, `sourceValue`, `engineValue`, and `slots`. Array values identify changed slots using one-based source slot numbers. Scalar settings have an empty `slots` array. A setting removed by the engine has `engineValue: null`.
|
|
44
|
+
|
|
45
|
+
Call `printJobs.approveReview(requestId, { changes, sourceRelease, engineRelease })` with the reported values to re-slice. This requires `control` scope. It returns `{ approved: true }` with HTTP 202. Repeating the same approval returns 202 while that submitted review still covers the current pending or ready slice, without starting another slice. This includes Cloud Slice retries that change the slice ID while retaining the plate's approval. A stale or mismatched review returns HTTP 409 `review_conflict`. Approval accepts those changes for those releases, including customised settings. The create-time stock opt-in continues to accept eligible stock changes after approval. Other changes hold again. Poll the receipt again after approval.
|
|
46
|
+
|
|
47
|
+
For `release: "manual"` requests held by an engine review or another preparation reason, `/release` now returns HTTP 409 `manual_release_not_available` instead of 202. It keeps the holds and does not authorize manual release. Resolve the preparation holds first, then call `/release` when the only hold is `manual_release_required`.
|
|
48
|
+
|
|
49
|
+
Use the HTTP release/cancel operations described in the [integration reference](../../docs/integrations/printie/planned-production.md) when needed.
|
|
50
|
+
|
|
51
|
+
## Observe created jobs
|
|
52
|
+
|
|
53
|
+
`printJobs.get(jobId, signal?)` reads `GET /v1/print-jobs/{id}` and returns the inner job snapshot. It requires a positive safe-integer ID. After a create receipt reaches `created` with a non-null job, read that job separately to observe its current status and `print_options.filament_waiting_reasons`. A created job may still wait for materials or printer readiness. Keep polling the live job rather than treating its creation receipt as a current material assessment. A deleted or inaccessible job returns the API's error; the retained create receipt does not recreate it.
|
|
54
|
+
|
|
55
|
+
The sample and simulator upgrade audit is [SDK upgrade from npm 0.2.0](../../tools/printie-simulator/SDK-UPGRADE.md). The local 0.3.2 build includes the live job read and the merged #4945 waiting-reason types. It is not an npm release. Reasons list only unmet filaments; the optional `cause` remains advisory because a material-type mismatch can still report `color_distance`.
|
|
34
56
|
|
|
35
57
|
## Upload a Printie design
|
|
36
58
|
|
|
@@ -79,19 +101,67 @@ for await (const source of hive.models.listSourceFiles(model.modelId)) {
|
|
|
79
101
|
}
|
|
80
102
|
```
|
|
81
103
|
|
|
104
|
+
## Prepare selected plates
|
|
105
|
+
|
|
106
|
+
Preparation requires `production:upload` for creation and `production:read` for reads and downloads, plus the organization's preparation feature flag.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const preparation = await hive.preparations.create({
|
|
110
|
+
idempotencyKey: "printie:order-1234",
|
|
111
|
+
items: [
|
|
112
|
+
{
|
|
113
|
+
sourceVersionId: source.sourceVersionId,
|
|
114
|
+
plates: [2],
|
|
115
|
+
quantity: 3,
|
|
116
|
+
materialMappings: [{ sourceSlot: 1, material: "PETG", color: "#1F6FEB" }],
|
|
117
|
+
target: { printerId: "<qualified printer UUID>" },
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
});
|
|
121
|
+
const outcome = await hive.preparations.waitUntilSettled(
|
|
122
|
+
preparation.preparationId,
|
|
123
|
+
{
|
|
124
|
+
timeoutMs: 120_000,
|
|
125
|
+
intervalMs: 1000,
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
for (const item of outcome.items) {
|
|
129
|
+
for (const plate of item.preparedPlates) {
|
|
130
|
+
if (plate.status === "ready") {
|
|
131
|
+
const info = await hive.preparations.downloadInfo(
|
|
132
|
+
outcome.preparationId,
|
|
133
|
+
plate.plateId
|
|
134
|
+
);
|
|
135
|
+
// info contains url, expiresAt, filename, bytes and sha256.
|
|
136
|
+
// Fetch the signed URL without sending the Hive API key.
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Creation accepts at most 20 items. Generated request validation rejects larger arrays locally with `TypeError` before sending HTTP. The API continues to return `422 request_too_large` with limit metadata for oversized raw HTTP requests.
|
|
143
|
+
|
|
144
|
+
Each item names either `sourceVersionId` or `externalId`. Creation returns the preparation plus the supplied or generated `idempotencyKey`, just like upload. Persist a caller-supplied key before sending when recovery must survive process restarts. A replay returns the original preparation identity. Request JSON is snapshotted before sending and stays unchanged across retries.
|
|
145
|
+
|
|
146
|
+
`preparations.get(id, signal?)` returns the full preparation. `waitUntilSettled` resolves on `ready`, `held`, or `failed`. Holds and failures remain in the returned items and plates. Its total deadline aborts active reads, retry delays, and poll delays. A timeout leaves the creation outcome intact; resume reads using the preparation ID instead of creating replacement work. `downloadInfo(id, plateId, signal?)` retains all signed-download metadata without fetching the artifact.
|
|
147
|
+
|
|
148
|
+
`materialMappings[].sourceSlot` is one-based. Ambiguous palettes require explicit source-version or SHA-bound bindings; color order alone cannot establish source slots. Pin `sourceVersionId` after validating a binding. `target.printerId` names the exact qualified target. Preparation creates no print job and never authorizes printer motion.
|
|
149
|
+
|
|
150
|
+
Public preparation types, including `PartnerPreparationItemInput`, `PartnerMaterialMapping`, `PartnerPreparedPlate`, `PartnerPreparationDownload`, and `PartnerPreparationTargetReason`, derive from the current API export.
|
|
151
|
+
|
|
82
152
|
## Handle failures and retries
|
|
83
153
|
|
|
84
|
-
`PrintHiveApiError` exposes HTTP `status`, the response's `error` as `code`, optional `limit` with `name`, `max`, and `observed`, `retryAfterMs`, and `requestId`. Its optional `body` exposes the validated error envelope, preserving additional fields as JSON values for callers to narrow. Invalid envelopes leave `body` undefined. Error messages omit response bodies and credentials. `PrintHiveNetworkError.reason` distinguishes `network`, `timeout`, and `aborted` failures.
|
|
154
|
+
`PrintHiveApiError` exposes HTTP `status`, the response's `error` as `code`, optional `limit` with `name`, `max`, and `observed`, `retryAfterMs`, and `requestId`. For `target_not_qualified`, `reasons` exposes validated, typed printer qualification reasons. Its optional `body` exposes the validated error envelope, preserving additional fields as JSON values for callers to narrow. Invalid envelopes leave `body` undefined. Error messages omit response bodies and credentials. `PrintHiveNetworkError.reason` distinguishes `network`, `timeout`, and `aborted` failures.
|
|
85
155
|
|
|
86
156
|
The API can answer `411 content_length_required`, `413 upload_too_large`, `429 upload_capacity_reached`, `409 external_id_conflict`, or `409 idempotency_conflict`. Inspection failures resolve through the source's `failed` status and include their own error and optional restriction limit.
|
|
87
157
|
|
|
88
|
-
Only 429, 503, and network failures retry. GET requests are idempotent.
|
|
158
|
+
Only 429, 503, and network failures retry. Permanent `preparation_disabled` never retries, including HTTP 503. GET requests are idempotent. Preparation JSON and upload retries retain their idempotency key and require replayable bytes or a path. One-shot streams never retry. Timeouts and caller aborts never retry. Retries use exponential backoff with jitter and wait at least `Retry-After`, supporting both seconds and HTTP dates. If `Retry-After` exceeds 60 seconds, the client throws the API error with `retryAfterMs` so the caller can schedule the retry. It never retries before that delay. `maxRetries: 0` disables retries. Request timeouts apply per attempt; polling also has a total deadline.
|
|
89
159
|
|
|
90
160
|
## Coverage and contract maintenance
|
|
91
161
|
|
|
92
|
-
|
|
162
|
+
The current source covers creation and request polling under `/v1/print-jobs/create`, partner printer and filament search at `/v1/printers/search` and `/v1/filaments/search`, customer printer list and detail reads at `/v1/printers` and `/v1/printers/{id}`, plus preparation creation, reads, polling and download metadata, uploads, source reads and polling, external-id model lookup, and source-file listing under `/v1/partner-production/`. It offers no generic request method for other routes.
|
|
93
163
|
|
|
94
|
-
`apps/api/scripts/export-openapi.ts` builds a schema-only Fastify app from the real printer, file-compatibility, print-job, and partner route plugins, without listening, worker startup, database calls, or queue startup. It uses stub environment values. This intentionally exports authenticated partner routes directly. The Swagger UI's public-operation filter would remove them, and generic error enrichment would lose partner restriction details.
|
|
164
|
+
`apps/api/scripts/export-openapi.ts` builds a schema-only Fastify app from the real partner search, printer, file-compatibility, print-job, and partner route plugins, without listening, worker startup, database calls, or queue startup. It uses stub environment values. This intentionally exports authenticated partner routes directly. The Swagger UI's public-operation filter would remove them, and generic error enrichment would lose partner restriction details.
|
|
95
165
|
|
|
96
166
|
`bun run generate` filters that export by the prefix list in `scripts/contracts.mjs`, commits `openapi.json`, and generates TypeScript types and standalone response validators. AJV compiles the validators during development; the build bundles their small runtime helpers. `openapi-typescript` is a development dependency because it generates OpenAPI 3 union types without adding runtime dependencies. `bun run check:drift` reexports and compares the snapshot. Types and standalone validators regenerate in ignored `.temp` build output on every check. `bun run test` builds the distribution and runs its HTTP tests against `dist`, including in the release workflow. `api-client-check.yml` also runs when API or client sources change, so drift checks do not depend on Turbo selecting the client as affected.
|
|
97
167
|
|
|
@@ -132,3 +202,136 @@ never contact a printer.
|
|
|
132
202
|
|
|
133
203
|
`readiness.ready` reports the stored ready flag. `readiness.bedClear` reports
|
|
134
204
|
the flag only when its source is `bed_occupancy_verified`; otherwise it is null.
|
|
205
|
+
|
|
206
|
+
## Sync your filament catalog
|
|
207
|
+
|
|
208
|
+
Use a Control API key to sync each partner record. Repeating an external id
|
|
209
|
+
updates the same organization-owned material, including concurrent retries.
|
|
210
|
+
The external id namespace belongs to the organization, so coordinate ids across
|
|
211
|
+
integrations. Reads require Read scope. Hive trims surrounding whitespace from `externalId`
|
|
212
|
+
and `sku` on writes and list filters; neither field can be blank.
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
const filament = await hive.filamentCatalog.upsert({
|
|
216
|
+
externalId: "printie-pla-blue",
|
|
217
|
+
brand: "Printie",
|
|
218
|
+
material: "PLA",
|
|
219
|
+
colorName: "Blue",
|
|
220
|
+
colorHex: "#0000FF",
|
|
221
|
+
sku: "PLA-BLUE",
|
|
222
|
+
replacementFilamentId: null,
|
|
223
|
+
});
|
|
224
|
+
console.log(filament.id, filament.sku);
|
|
225
|
+
const page = await hive.filamentCatalog.list({ sku: "PLA-BLUE", limit: 100 });
|
|
226
|
+
const saved = await hive.filamentCatalog.get(filament.id);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
`POST /v1/filament-catalog` accepts the fields above and returns 200 with the
|
|
230
|
+
material row. `hex` is an alias for `colorHex`; both must agree when supplied.
|
|
231
|
+
`replacementFilamentId` is retained as partner metadata, not resolved as a Hive id.
|
|
232
|
+
`GET /v1/filament-catalog` filters by exact `externalId` and `sku`, with `limit`
|
|
233
|
+
(1–200, default 100) and `offset` (default 0). Results are ordered by Hive id.
|
|
234
|
+
It returns `{ materials, total }`. `GET /v1/filament-catalog/:id` returns one row.
|
|
235
|
+
All operations enforce organization ownership. Returned rows include `id`, `sku`,
|
|
236
|
+
`material_type`, `color`, and partner metadata.
|
|
237
|
+
|
|
238
|
+
Errors include 400 `invalid_catalog_input`, 400 `conflicting_color_hex`, 403 `API_KEY_SCOPE_REQUIRED`,
|
|
239
|
+
404 `catalog_filament_not_found`, 409 `catalog_conflict` for uniqueness conflicts,
|
|
240
|
+
and 500 `catalog_store_failed`. Invalid bodies return the API validation error.
|
|
241
|
+
Pass the returned `id` as `filaments[].filamentId` in JSON or multipart print-job
|
|
242
|
+
creation. A slot can contain only `{ sourceSlot, filamentId }`, plus an optional
|
|
243
|
+
`targetSlot`. Hive derives material and color from that organization catalog row.
|
|
244
|
+
Explicit `material` and `color` must agree with the row. Material comparisons
|
|
245
|
+
ignore case, and colors accept a leading `#` and either case.
|
|
246
|
+
|
|
247
|
+
A contradiction returns 422 `filament_catalog_conflict` with the `sourceSlot` in
|
|
248
|
+
`filaments[]`. An unknown or foreign catalog ID returns 422
|
|
249
|
+
`catalog_filament_not_found` with the slot. Catalog rows without a material or a
|
|
250
|
+
six-digit hex color return 422 `invalid_catalog_filament`.
|
|
251
|
+
|
|
252
|
+
Stored requirements, waiting reasons, and load-step requirements retain
|
|
253
|
+
`filamentId`, `brand`, `name`, `colorName`, `material`, and `colorHex`. Catalog
|
|
254
|
+
identity is a snapshot. Multipart retries reuse the first saved catalog snapshot,
|
|
255
|
+
even if the catalog changes. Matching still uses material and color proximity.
|
|
256
|
+
Requests and stored jobs without `filamentId` keep their existing shape.
|
|
257
|
+
|
|
258
|
+
Catalog validation errors in JSON or multipart creation do not reserve a new
|
|
259
|
+
idempotency key or `externalId`. For JSON requests that include `filamentId`,
|
|
260
|
+
the same applies to every other validation error that Hive returns
|
|
261
|
+
before it accepts the request. Correct the request, or add the missing catalog
|
|
262
|
+
entry, and retry with the same identity. Existing created or failed receipts
|
|
263
|
+
replay before a new catalog lookup. Once Hive accepts the request, changes to
|
|
264
|
+
its submitted fields or uploaded bytes return 409. Requests without `filamentId`
|
|
265
|
+
keep their existing receipt behavior.
|
|
266
|
+
Filament search returns catalog IDs and `acceptedByCreate`. A result with
|
|
267
|
+
`acceptedByCreate: true` satisfies the current catalog admission checks for
|
|
268
|
+
print-job filament requirements. Other create admission checks still apply.
|
|
269
|
+
|
|
270
|
+
## Search printers and filaments
|
|
271
|
+
|
|
272
|
+
Both methods require an organization API key with the `read` tier or higher.
|
|
273
|
+
The API derives organization ownership from the authenticated key.
|
|
274
|
+
|
|
275
|
+
The existing `GET /v1/search` and `GET /v1/materials/command-search` routes
|
|
276
|
+
also require the `read` tier or higher for API keys. Empty-scope API keys now
|
|
277
|
+
receive 403 on those routes. JWT authentication keeps its existing membership
|
|
278
|
+
checks.
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
const printerPage = await hive.printers.search({ query: "Boo P1S", limit: 10 });
|
|
282
|
+
const filamentPage = await hive.filaments.search({
|
|
283
|
+
query: "black PETG",
|
|
284
|
+
limit: 20,
|
|
285
|
+
});
|
|
286
|
+
const redFilaments = await hive.filaments.search({ query: "bambu red" });
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
| Method | Return type | API route |
|
|
290
|
+
| ------------------------------------------------------- | ----------------------------- | -------------------------------- |
|
|
291
|
+
| `printers.search({ query, limit?, offset?, signal? })` | `Promise<PrinterSearchPage>` | `GET /v1/printers/search?q=...` |
|
|
292
|
+
| `filaments.search({ query, limit?, offset?, signal? })` | `Promise<FilamentSearchPage>` | `GET /v1/filaments/search?q=...` |
|
|
293
|
+
|
|
294
|
+
`SearchOptions` contains the string `query`, optional integer `limit` and
|
|
295
|
+
`offset`, and an optional `AbortSignal`. Both methods return one page and use
|
|
296
|
+
the client's normal GET retry policy. Invalid response shapes throw `TypeError`.
|
|
297
|
+
Missing authentication returns 401. Insufficient API-key scope returns 403.
|
|
298
|
+
Fractional or out-of-range pagination returns 400. `limit` accepts 1–50, with
|
|
299
|
+
default 20. `offset` accepts 0–10,000, with default 0.
|
|
300
|
+
|
|
301
|
+
`PrinterSearchPage` contains `printers`, `total`, and `query`. Each
|
|
302
|
+
`PrinterSearchResult` includes `id`, name, model, serial, status, location,
|
|
303
|
+
`score`, and `match`. The API reads organization-scoped stored observations
|
|
304
|
+
and uses the same shared candidate builder and ranking code as the web
|
|
305
|
+
palette. Queries contain 1–256 characters. Ranking happens before pagination.
|
|
306
|
+
Each request reads every organization printer in batches of up to 1,000 before
|
|
307
|
+
ranking and pagination. These reads have no per-organization cache. Large
|
|
308
|
+
fleets and frequent queries therefore increase database read work. The SDK
|
|
309
|
+
does not debounce or cache requests.
|
|
310
|
+
|
|
311
|
+
No printer search index is involved, and no printer is contacted. Printer `id`
|
|
312
|
+
is the identity for explicit printer placement. Search does not guarantee
|
|
313
|
+
readiness; `printers.get(id)` returns stored printer details.
|
|
314
|
+
|
|
315
|
+
`FilamentSearchPage` contains `filaments`, `total`, `hasMore`, `matchMode`, and
|
|
316
|
+
`originalQuery`. Each `FilamentSearchResult` includes `id`, `filamentId`, name,
|
|
317
|
+
brand, material type, color, diameter, category, organization, and optional SKU.
|
|
318
|
+
`filamentId` equals the catalog material row's `id`. It is not an inventory item
|
|
319
|
+
ID. `acceptedByCreate` reports whether the row satisfies the current partner
|
|
320
|
+
catalog identity and material checks. It does not promise that a print job
|
|
321
|
+
passes file, plate, target, or dispatch admission.
|
|
322
|
+
|
|
323
|
+
Filament search reuses the web Material Command Search picker, including its
|
|
324
|
+
ranked database query and the organization's global-filament setting. It can
|
|
325
|
+
return organization filaments and enabled global catalog filaments. Global
|
|
326
|
+
rows have `organization_id: "global"`. Results also include unsynced organization
|
|
327
|
+
rows and rows without a color. These rows do not satisfy the current partner
|
|
328
|
+
catalog contract for `filaments[].filamentId` on `POST /v1/print-jobs/create`.
|
|
329
|
+
These rows have `acceptedByCreate: false`. The contract requires an organization-owned partner catalog row, a material
|
|
330
|
+
family, and a six-digit hex color. Search does not filter out other rows.
|
|
331
|
+
|
|
332
|
+
Queries contain at most 100 characters. An empty query browses the catalog.
|
|
333
|
+
Set the next offset to the previous offset plus the returned filament count
|
|
334
|
+
while `hasMore` is true. When no strict filament match exists, the picker
|
|
335
|
+
returns a broader catalog page with `matchMode: "broadened"` and retains the
|
|
336
|
+
sanitized `originalQuery`. Callers can display that distinction and ask users
|
|
337
|
+
to choose a filament. Neither search method selects a result or creates a job.
|