DataVisuals Decision Governance
Home Quickstart API Reference datavisuals.com
Quickstart

Get started in five minutes

Sign in, find a decision, work it through the lifecycle. All responses elide non-essential fields with ...; the API reference documents complete shapes.

1. Persist the session cookie

Every authenticated call carries a session HttpOnly cookie set by POST /auth/login (or POST /auth/signup). Your client needs to persist it across requests:

2. Sign in

curl -c cookies.txt -b cookies.txt \
  https://dg.datavisuals.com/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"[email protected]","password":"..."}'
{
  "id": "5d4f...",
  "username": "[email protected]",
  "name": "Jordan Reyes",
  "tenant_id": "bayside",
  "tenant_name": "Bayside Community Bank",
  "role": "member",
  "has_apex": false,
  "is_sandbox": false,
  "entitled_workflows": ["01-regulatory-compliance", "02-bsa-fraud"]
}

No account yet? POST /auth/signup accepts the same shape plus name, institution_name, eula_accepted: true, and the current eula_version (fetch from GET /legal/eula-version). The response is the same SessionUser and the cookie is set the same way.

3. See what you can do

curl -b cookies.txt https://dg.datavisuals.com/api/auth/me

Returns the same SessionUser payload as login. Use entitled_workflows to know which workflow surfaces this user can access.

4. Find a decision to work

curl -b cookies.txt \
  'https://dg.datavisuals.com/api/decisions?scope=all_entitled&density=active&limit=5'
{
  "items": [
    {
      "id": "8c2a...",
      "decision_number": "DG-2026-05-1042",
      "workflow_id": "02-bsa-fraud",
      "decision_type": "sar_filing_decision",
      "title": "Structuring pattern, $43,200 aggregate",
      "status": "open",
      "priority": "high",
      "severity": "high",
      "sla_deadline": "2026-05-08T17:00:00Z",
      "signal_summary": "Eight cash deposits below $10K reporting threshold across three days, one customer.",
      "...": "..."
    }
  ],
  "total": 17,
  "limit": 5,
  "offset": 0
}

Default sort is severity DESC, SLA deadline ASC nulls-last, created_at DESC tiebreak — the same order the Inbox UI shows. Filter further with workflow_id, stage, or scope=assigned (only decisions you own).

5. Claim it

curl -X POST -b cookies.txt \
  https://dg.datavisuals.com/api/decisions/8c2a.../claim

Returns the updated Decision with status: "in_progress", owner_id set to the caller, owner_authority_level snapshotted, and escalation_path computed from user_supervisors. Subsequent edits are gated on this snapshot — your authority at claim time is what governs your finalize options.

6. Finalize

curl -X POST -b cookies.txt \
  https://dg.datavisuals.com/api/decisions/8c2a.../finalize \
  -H 'Content-Type: application/json' \
  -d '{
    "selected_option": "file_sar",
    "rationale": "Pattern matches structuring typology in BSA examination manual §VII.A. Customer has no commercial cash-handling activity that explains sub-threshold pacing.",
    "evidence_refs": [
      {"type": "transaction_log", "ref": "TXN-2026-04-29-3318"},
      {"type": "kyc_record", "ref": "MEM-78214"}
    ]
  }'

Response is the updated Decision with status: "decided", decided_at set, and the rationale + evidence captured. A decision_event row is appended; you can fetch it via GET /decisions/8c2a.../events.

7. Close the loop with an outcome

Most workflows expect outcome capture within 90 days post-decision.

curl -X POST -b cookies.txt \
  https://dg.datavisuals.com/api/decisions/8c2a.../outcome \
  -H 'Content-Type: application/json' \
  -d '{
    "outcome_text": "SAR filed with FinCEN 2026-05-12 (BSA-ID 31000099812). Account placed under enhanced monitoring; no further structuring detected over 60-day review window.",
    "outcome_impact": "low_loss",
    "outcome_metrics": {"days_to_file": 4, "monitoring_window_days": 60}
  }'

Response is the Decision with status: "closed", outcome_recorded_at set. The decision contributes to the next nightly DGI computation — see GET /dgi/current for the tenant's score.

Same flow in Python

import requests

BASE = "https://dg.datavisuals.com/api"
s = requests.Session()  # carries the session cookie automatically

# 1. Sign in
me = s.post(f"{BASE}/auth/login", json={
    "username": "[email protected]",
    "password": "...",
}).json()
print(f"Logged in as {me['name']} ({me['tenant_name']})")

# 2. Find a decision
listing = s.get(f"{BASE}/decisions", params={
    "scope": "all_entitled", "density": "active", "limit": 5,
}).json()
decision_id = listing["items"][0]["id"]

# 3. Claim and finalize
s.post(f"{BASE}/decisions/{decision_id}/claim").raise_for_status()
s.post(f"{BASE}/decisions/{decision_id}/finalize", json={
    "selected_option": "file_sar",
    "rationale": "Pattern matches structuring typology...",
    "evidence_refs": [
        {"type": "transaction_log", "ref": "TXN-2026-04-29-3318"},
    ],
}).raise_for_status()

Same flow in JavaScript

const BASE = "https://dg.datavisuals.com/api";
// credentials: 'include' tells fetch to send + receive the session cookie.
// In a browser this also requires the page to be served from
// dg.datavisuals.com (or CORS configured on the server).
const opts = (extra = {}) => ({
  credentials: "include",
  headers: { "Content-Type": "application/json" },
  ...extra,
});

// 1. Sign in
const me = await fetch(`${BASE}/auth/login`, opts({
  method: "POST",
  body: JSON.stringify({
    username: "[email protected]",
    password: "...",
  }),
})).then(r => r.json());

// 2. Find a decision
const listing = await fetch(
  `${BASE}/decisions?scope=all_entitled&density=active&limit=5`,
  opts(),
).then(r => r.json());
const decisionId = listing.items[0].id;

// 3. Claim and finalize
await fetch(`${BASE}/decisions/${decisionId}/claim`, opts({ method: "POST" }));
await fetch(`${BASE}/decisions/${decisionId}/finalize`, opts({
  method: "POST",
  body: JSON.stringify({
    selected_option: "file_sar",
    rationale: "Pattern matches structuring typology...",
    evidence_refs: [
      { type: "transaction_log", ref: "TXN-2026-04-29-3318" },
    ],
  }),
}));

Where to go from here

Open the full API reference →