- Batch scoping —
collection_idson a batch runs only that collection’s extractor over the bucket. - Dedup protection —
dedup_strategy: "skip"(the default) never re-runs extraction for content a collection has already processed, even if you forget to scope. - Pre-flight pricing —
POST /batches/{id}/estimate-costis a true dry run: it tells you exactly what would run and what it costs before you commit, including analready_extracted_countshowing the work you will NOT be re-billed for.
Everything below operates on content already in a bucket. Buckets hold your
source objects once; collections are independent processing pipelines over
them. That separation is what makes iterating on models cheap.
1. Create a second collection over the same bucket
Your existing collection keeps serving queries untouched. The new understanding gets its own collection pointed at the same bucket:PATCH /v1/namespaces body to run first.)
2. Create a batch scoped to the new collection
Scope the batch withcollection_ids so only the new collection’s pipeline
runs:
3. Price it before you run it
estimate-cost is a dry run — nothing processes, nothing is charged. (For quoting planned ingestion in dollars by modality and feature before you even build the batch, use POST /v1/organizations/billing/estimate — same rating engine that bills you.)
already_extracted_count and prices it at zero — the default
dedup_strategy: "skip" refuses to re-run (and re-bill) extraction whose
inputs haven’t changed. Your existing collection’s GPU spend is protected even
when you forget to scope.
4. Submit, then verify only new work ran
Submit the batch and let it complete. Two checks confirm the cost boundary held:- The new collection has documents; the old collection’s documents show
no changed
updated_at. - The batch record carries its own cost:
batch.cost → {"credits_consumed": 10, "cost_usd": 0.01}—cost_usdis the number that matters (thecredits_consumedfield is the internal ledger unit, 1 credit = 0.01 minimum.
cost_usd of the rollout’s batches —
each batch is its own attribution record.
5. Compare the two understandings side by side
Both collections index the same source objects, so retrieval comparisons need no second corpus copy: run the same query against each collection (or one retriever spanning both) and compare. For systematic comparison, build a small evaluation dataset once and run it against both. When a new version of an extractor ships (versions coexist in the catalog — e.g. v1 and v2 side by side), the same pattern applies: pin the new version in a new collection, roll a scoped batch, compare, and cut over when the numbers say so. For whole-namespace model swaps, use model migration instead.6. Re-run only failures
If some objects fail, you don’t resubmit the batch:GET /v1/buckets/{bucket_id}/batches/{batch_id}/failed-documentslists failures with per-tier detail and what’s retryable.POST /v1/buckets/{bucket_id}/batches/{batch_id}/retryre-runs just those.
Next steps
Feature Extractors
How a single extractor is configured — inputs, outputs, inference cache.
Model Migration
Swap a namespace’s embedding model wholesale with validation and dry-run.
Multi-Tier Extraction
Chain collections into a DAG — transcribe, then embed, then classify.
Custom Extractor Quickstart
Build and test your own extractor end-to-end.

