Quickstart
This guide walks you through the minimum path to get a classification result back from DVS. Validation works the same way — replace the endpoint in step 3 and the result event in step 5.
Prerequisites
You should already have:
- Sandbox credentials (
client_idandclient_secret) issued by OSIGU. All examples in this guide point to sandbox — when you go live, swap to the production hosts (https://dvs-ingestion-api.osigu.comfor the API andhttps://api.osigu.com/v1/oauth/tokenfor OAuth) and use your production credentials. - Network access from your servers to
https://dvs-ingestion-api.sandbox.osigu.com(DVS) andhttps://sandbox.osigu.com(OAuth). - A test document (PDF or image) you want to classify.
1. Get an access token
OAuth2 client credentials grant. Send your client_id:client_secret as HTTP Basic auth and grant_type as a query string parameter:
- curl
- Python
- Node.js
curl --location --request POST \
"https://sandbox.osigu.com/v1/oauth/token?grant_type=client_credentials" \
--header "Authorization: Basic $(echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64)"
import httpx, base64
basic = base64.b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode()
token_response = httpx.post(
"https://sandbox.osigu.com/v1/oauth/token",
params={"grant_type": "client_credentials"},
headers={"Authorization": f"Basic {basic}"},
)
data = token_response.json()
access_token = data["access_token"]
# data["extensions"] carries tenant metadata, e.g. {"provider_slug": "br-gamma"}
const basic = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64");
const tokenResponse = await fetch(
"https://sandbox.osigu.com/v1/oauth/token?grant_type=client_credentials",
{
method: "POST",
headers: { Authorization: `Basic ${basic}` },
},
);
const data = await tokenResponse.json();
const accessToken = data.access_token;
// data.extensions carries tenant metadata, e.g. { provider_slug: "br-gamma" }
Response:
{
"access_token": "7dd4f350-676e-4257-9d7b-f3c5ac4dfi14",
"token_type": "bearer",
"expires_in": 86399,
"scope": "read write",
"extensions": { "provider_slug": "br-gamma" }
}
The access_token is an opaque string (not a JWT) valid for ~24 hours by default. The extensions map carries metadata about your tenant (e.g., provider_slug) — useful for logging and debugging.
Cache the token in memory and reuse it until close to expiry. Don't hit the OAuth endpoint on every API call.
See Obtaining Access Tokens for the full reference.
2. Prepare your document
You can send the document in one of three ways:
- Inline (base64)
- S3 URL
- External URL
Best for files under 3 MB. No setup required.
BASE64=$(base64 -i document.pdf)
If your document already lives in an OSIGU-managed S3 bucket. OSIGU will tell you the bucket name during onboarding.
s3://osigu-dvs-documents-prod/incoming/your-key.pdf
DVS will fetch the document from your HTTPS endpoint. Must be publicly reachable.
https://your-storage.example.com/secure/doc.pdf
3. Classify the document
- 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\": \"sync\",
\"file\": {
\"content_base64\": \"$BASE64\",
\"mime_type\": \"application/pdf\"
},
\"country_code\": \"BR\",
\"external_ref_id\": \"my-internal-id-12345\"
}"
import httpx, uuid
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": "sync",
"file": {"content_base64": base64_str, "mime_type": "application/pdf"},
"country_code": "BR",
"external_ref_id": "my-internal-id-12345",
},
timeout=30,
)
result = response.json()
print(result["type"]) # e.g., "SADT"
import crypto from "node:crypto";
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: "sync",
file: { content_base64: base64Str, mime_type: "application/pdf" },
country_code: "BR",
external_ref_id: "my-internal-id-12345",
}),
},
);
const result = await response.json();
console.log(result.type); // e.g., "SADT"
4. Read the response
On success you get a 200 OK (sync) or 202 Accepted (async). The sync response looks like this:
{
"classification_request_id": "550e8400-e29b-41d4-a716-446655440000",
"type": "SADT",
"status": "COMPLETED",
"classifier_slug": "br-default-v1",
"mode": "sync",
"auto_validate": false,
"validation_request_id": null,
"external_ref_id": "my-internal-id-12345",
"timestamp": "2026-06-03T17:42:18.224Z",
"duration_ms": 3187
}
The type is one of 17 Brazilian document types — see Document Types for the full catalog.
5. (Async only) Receive the webhook
If you chose mode=async, the response is 202 Accepted with the classification_request_id. DVS sends a signed webhook to your registered endpoint when processing completes.
Implementing the receiver takes under 30 lines of code in any language. Jump to Implement Webhook Receiver for the full recipe with HMAC verification.
What's next
Run the full extraction + validation pipeline with the same auth.
Production-ready receiver with HMAC verification, idempotency, retry handling.
Full endpoint reference with request/response schemas and "Try it" panels.
Error codes, retry policy, idempotency.