langchain-velrim
LangChain integration for the Velrim document-extraction API.
Velrim does document extraction against a JSON Schema you supply. Every schema leaf comes back with a per-field state (present / null / missing), a per-field confidence score, and source anchors (page + bounding box). This package ships two pieces:
VelrimLoader, aBaseLoaderthat turns each input document into one LangChainDocumentwhosepage_contentis the extracted object and whose metadata carries the per-field detail.VelrimExtractTool, aBaseToolan agent can call. The model passes a document reference; your resolver turns it into bytes. The model never sees the document bytes.
Requires Python 3.9+, langchain-core>=0.3,<2, and the velrim SDK (installed with it).
Install
pip install langchain-velrim
# or
uv add langchain-velrim
Set VELRIM_API_KEY in the environment, or pass api_key=... / a velrim.Client.
Loader
from pydantic import BaseModel
from langchain_velrim import VelrimLoader
class Invoice(BaseModel):
invoice_number: str
total: float
loader = VelrimLoader(
["invoices/2026-001.pdf", "invoices/2026-002.pdf"],
schema=Invoice, # a Pydantic model class or a JSON Schema dict
doc_class="invoice", # optional hint
confidence_threshold=0.8, # optional; feeds velrim_review
)
for doc in loader.lazy_load(): # load() and aload() also work
print(doc.page_content) # json.dumps(data, indent=2)
print(doc.metadata["velrim_review"])
Each entry in the list is a file path (str or os.PathLike), raw bytes, or a
velrim.Document. Use velrim.Document.from_upload_key(...) for a document staged through the
upload API. One input document produces one output Document.
Pass your own client when you need a custom base URL, timeout, or retry count:
from velrim import Client
client = Client(api_key="...", timeout=120)
loader = VelrimLoader([pdf_bytes], schema=Invoice, client=client)
Metadata
| Key | Type | Meaning |
|---|---|---|
source |
str |
The file path, the upload key, or "bytes" |
velrim_request_id |
str |
Request id for support and log correlation |
velrim_pages |
int |
Pages in the document |
velrim_billed_pages |
int |
Pages billed |
velrim_model |
str |
Model that produced the extraction |
velrim_calibrator_version |
str |
Version of the confidence calibrator |
velrim_doc_class |
str |
Only present when doc_class was set |
velrim_review |
list[str] |
JSON Pointers that need human review (see below) |
velrim_fields |
dict |
The full per-field map, keyed by JSON Pointer |
velrim_review lists every leaf whose state is missing, every leaf where the extraction passes
disagreed (conflict: true), and, when confidence_threshold is set, every leaf whose confidence
is below it. Without a threshold only the first two rules apply.
velrim_fields maps each JSON Pointer ("/total", "/line_items/0/sku") to its state, value,
confidence, anchor (page, bounding box, snippet, page dimensions), conflict flag, and reason.
Flat metadata for vector stores
velrim_fields is a nested object. Vector stores that only accept scalar metadata (many do)
reject it, so turn it off for those and keep the flat keys plus velrim_review:
loader = VelrimLoader(paths, schema=Invoice, include_fields=False)
include_fields defaults to True.
Agent tool
from pathlib import Path
from velrim import Client
from langchain_velrim import VelrimExtractTool
client = Client() # reads VELRIM_API_KEY
def resolve_document(ref: str) -> bytes:
# The model sends a reference; you decide what it means (a path, an S3 key, a row id).
return Path("inbox", ref).read_bytes()
extract = VelrimExtractTool(
client=client,
schema=Invoice,
resolve_document=resolve_document,
confidence_threshold=0.8, # optional
doc_class="invoice", # optional default; the model may override per call
)
# Bind it like any other LangChain tool, for example:
# agent = create_agent(model, tools=[extract])
The tool is named velrim_extract. Its input schema is {document: str, doc_class?: str}.
The resolver returns raw bytes or a velrim.Document (so Document.from_upload_key(...) works
for large documents). The result is a JSON-serializable dict:
{
"data": { "invoice_number": "INV-1001", "total": 4200.0 },
"review": ["/total"],
"request_id": "req_...",
"pages": 1
}
review follows the same rule as velrim_review above.
Errors
Errors from the velrim SDK propagate unchanged, so you can catch the typed classes
(velrim.InsufficientBalanceError, velrim.RateLimitedError, velrim.APIError, ...) around
load() or the tool call. Neither the loader nor the tool swallows them.
License
MIT.
Release files for langchain-velrim 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| langchain_velrim-0.1.0.tar.gz | 6.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| langchain_velrim-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.8 kB
Release files / langchain_velrim-0.1.0.tar.gz
| Download URL | langchain_velrim-0.1.0.tar.gz |
|---|---|
| Size | 6.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a327946205c4712d2603d891f90eb7475a6fc47902ba0f713c013605157fd60b
|
|
BLAKE2b-256 checksum How to use checksums |
910f4053e008ea54a1babf7c321cd4d01ccde21e2daca521205e0ae0a3b71cd4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.12
|
Release files / langchain_velrim-0.1.0-py3-none-any.whl
| Download URL | langchain_velrim-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a73a78812201cdfaae855171dd5661cbd1d78dc8cdd2f0a3863f6309d21f3fff
|
|
BLAKE2b-256 checksum How to use checksums |
0ce364a175b1ef3b42f6fc6240c3b9e62243e0289fde0c706b215d42e868bf8d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.12
|