Classify a Document
This guide walks through a complete classification request — from token to result — in production-ready code.
Step 1: Get an access token
If you don't have a cached token, fetch one. See Obtaining Access Tokens for the helper functions.
Step 2: Choose a file source
- Inline (base64)
- S3 URL
- External URL
Simplest for files under 3 MB. No extra setup.
Files already in an OSIGU-managed bucket. Bucket name provided at onboarding.
DVS will fetch from your HTTPS endpoint. Must be publicly reachable and pass DVS's SSRF guard (no private IP ranges).
Step 3: Call the endpoint
- curl
- Python
- Node.js
curl -X POST https://dvs-ingestion-api.sandbox.osigu.com/v1/classification-requests \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: req-$(uuidgen)" \
-d "{
\"mode\": \"async\",
\"file\": {
\"content_base64\": \"$BASE64\",
\"mime_type\": \"application/pdf\"
},
\"country_code\": \"BR\",
\"external_ref_id\": \"ORDER-12345\",
\"auto_validate\": true
}"
import httpx, uuid
def classify_document(access_token: str, base64_content: str, external_ref_id: str):
response = httpx.post(
"https://dvs-ingestion-api.sandbox.osigu.com/v1/classification-requests",
headers={
"Authorization": f"Bearer {access_token}",
"Idempotency-Key": f"req-{uuid.uuid4()}",
},
json={
"mode": "async",
"file": {"content_base64": base64_content, "mime_type": "application/pdf"},
"country_code": "BR",
"external_ref_id": external_ref_id,
"auto_validate": True,
},
timeout=30,
)
response.raise_for_status()
return response.json()
import crypto from "node:crypto";
async function classifyDocument(accessToken, base64Content, externalRefId) {
const response = await fetch(
"https://dvs-ingestion-api.sandbox.osigu.com/v1/classification-requests",
{
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
"Idempotency-Key": `req-${crypto.randomUUID()}`,
},
body: JSON.stringify({
mode: "async",
file: { content_base64: base64Content, mime_type: "application/pdf" },
country_code: "BR",
external_ref_id: externalRefId,
auto_validate: true,
}),
},
);
if (!response.ok) {
throw new Error(`Classification failed: ${response.status}`);
}
return await response.json();
}
Step 4: Handle the response
Sync mode (200 OK)
{
"classification_request_id": "550e8400-...",
"type": "SADT",
"status": "COMPLETED",
"duration_ms": 3187,
"validation_request_id": null
}
Async mode (202 Accepted)
{
"classification_request_id": "550e8400-...",
"status": "RECEIVED",
"mode": "async"
}
Wait for the classification.completed webhook (or poll via GET /v1/classification-requests/{id}).
Step 5: (Optional) Process the chained validation
If you passed auto_validate: true and the result type is not UNKNOWN, DVS automatically triggers validation. You'll receive a second webhook — validation.completed — sharing the same correlation_id.
Common patterns
When to use sync vs async
Sync: interactive UI where the user is waiting (file upload screen, document review). Caps file at 3 MB. Use when latency matters.
Async: batch processing, background workflows, files >3 MB. No UX latency constraint.
Always set external_ref_id
Use your internal ID (order, claim, file id). DVS persists and returns it on every event. Lets you correlate without exposing your internal IDs in URLs.
Always set Idempotency-Key
Use a UUID generated client-side. If the same request is retried due to network failure, DVS deduplicates and returns the original result without re-processing.
Handle UNKNOWN gracefully
When type=UNKNOWN, DVS could not classify with confidence. Don't treat as an error — surface to the operator for manual review or fall back to your own heuristics.