# $RESULT is the saved JSON body from POST /v3/wallet-screening/
curl -X POST 'https://verification.didit.me/v3/wallet-screening/pdf/' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d "$RESULT" \
-o wallet_screening_report.pdfimport requests
# `result` is the dict returned by POST /v3/wallet-screening/, unmodified
response = requests.post(
'https://verification.didit.me/v3/wallet-screening/pdf/',
headers={'x-api-key': 'YOUR_API_KEY'},
json=result,
timeout=30,
)
response.raise_for_status()
with open('wallet_screening_report.pdf', 'wb') as fh:
fh.write(response.content)// `result` is the object returned by POST /v3/wallet-screening/, unmodified
const response = await fetch('https://verification.didit.me/v3/wallet-screening/pdf/', {
method: 'POST',
headers: {
'x-api-key': process.env.DIDIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(result),
});
if (!response.ok) throw new Error(`PDF generation failed: HTTP ${response.status}`);
const pdfBuffer = Buffer.from(await response.arrayBuffer());<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/wallet-screening/pdf/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'provider' => '<string>',
'screening_type' => 'WALLET_SCREENING',
'risk_score' => 123,
'summary' => '<string>',
'wallet_address' => '<string>',
'blockchain' => '<string>',
'source_of_funds' => [
[
'category' => '<string>',
'percentage' => 123,
'amount_usd' => 123,
'entity_name' => '<string>',
'entity_type' => '<string>',
'entity_subtype' => '<string>',
'hops' => 123,
'description' => '<string>',
'is_direct' => true,
'provider_entity_id' => '<string>',
'provider_entity_type_id' => '<string>',
'provider_entity_subtype_id' => '<string>',
'country' => '<string>',
'raw_amount' => 123,
'raw_currency' => '<string>'
]
],
'destination_of_funds' => [
[
'category' => '<string>',
'percentage' => 123,
'amount_usd' => 123,
'entity_name' => '<string>',
'entity_type' => '<string>',
'entity_subtype' => '<string>',
'hops' => 123,
'description' => '<string>',
'is_direct' => true,
'provider_entity_id' => '<string>',
'provider_entity_type_id' => '<string>',
'provider_entity_subtype_id' => '<string>',
'country' => '<string>',
'raw_amount' => 123,
'raw_currency' => '<string>'
]
],
'counterparty_connections' => [
[
'entity_name' => '<string>',
'entity_type' => '<string>',
'entity_subtype' => '<string>',
'risk_level' => '<string>',
'categories' => [
'<string>'
],
'received_usd' => 123,
'sent_usd' => 123,
'received_hops' => 123,
'sent_hops' => 123,
'percentage' => 123,
'is_direct' => true,
'country' => '<string>',
'provider_entity_id' => '<string>'
]
],
'sanctions_hit' => true,
'dominant_risk_category' => '<string>',
'report_signature' => '<string>',
'transaction_hash' => '<string>',
'block_timestamp' => '<string>',
'total_value_usd' => 123,
'fee_usd' => 123,
'sender_rows' => [
[
]
],
'receiver_rows' => [
[
]
],
'transaction_flows' => [
[
]
],
'transaction_flows_status' => '<string>',
'transaction_flows_error' => '<string>',
'network_nodes' => [
[
]
],
'network_edges' => [
[
]
],
'pep_counterparty' => true,
'risk_factors' => [
[
'category' => '<string>',
'label' => '<string>',
'entity_name' => '<string>',
'amount_usd' => 123,
'percentage' => 123,
'is_high_risk' => true,
'description' => '<string>'
]
],
'raw_response' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://verification.didit.me/v3/wallet-screening/pdf/"
payload := strings.NewReader("{\n \"provider\": \"<string>\",\n \"screening_type\": \"WALLET_SCREENING\",\n \"risk_score\": 123,\n \"summary\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"blockchain\": \"<string>\",\n \"source_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"destination_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"counterparty_connections\": [\n {\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"risk_level\": \"<string>\",\n \"categories\": [\n \"<string>\"\n ],\n \"received_usd\": 123,\n \"sent_usd\": 123,\n \"received_hops\": 123,\n \"sent_hops\": 123,\n \"percentage\": 123,\n \"is_direct\": true,\n \"country\": \"<string>\",\n \"provider_entity_id\": \"<string>\"\n }\n ],\n \"sanctions_hit\": true,\n \"dominant_risk_category\": \"<string>\",\n \"report_signature\": \"<string>\",\n \"transaction_hash\": \"<string>\",\n \"block_timestamp\": \"<string>\",\n \"total_value_usd\": 123,\n \"fee_usd\": 123,\n \"sender_rows\": [\n {}\n ],\n \"receiver_rows\": [\n {}\n ],\n \"transaction_flows\": [\n {}\n ],\n \"transaction_flows_status\": \"<string>\",\n \"transaction_flows_error\": \"<string>\",\n \"network_nodes\": [\n {}\n ],\n \"network_edges\": [\n {}\n ],\n \"pep_counterparty\": true,\n \"risk_factors\": [\n {\n \"category\": \"<string>\",\n \"label\": \"<string>\",\n \"entity_name\": \"<string>\",\n \"amount_usd\": 123,\n \"percentage\": 123,\n \"is_high_risk\": true,\n \"description\": \"<string>\"\n }\n ],\n \"raw_response\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://verification.didit.me/v3/wallet-screening/pdf/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"provider\": \"<string>\",\n \"screening_type\": \"WALLET_SCREENING\",\n \"risk_score\": 123,\n \"summary\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"blockchain\": \"<string>\",\n \"source_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"destination_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"counterparty_connections\": [\n {\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"risk_level\": \"<string>\",\n \"categories\": [\n \"<string>\"\n ],\n \"received_usd\": 123,\n \"sent_usd\": 123,\n \"received_hops\": 123,\n \"sent_hops\": 123,\n \"percentage\": 123,\n \"is_direct\": true,\n \"country\": \"<string>\",\n \"provider_entity_id\": \"<string>\"\n }\n ],\n \"sanctions_hit\": true,\n \"dominant_risk_category\": \"<string>\",\n \"report_signature\": \"<string>\",\n \"transaction_hash\": \"<string>\",\n \"block_timestamp\": \"<string>\",\n \"total_value_usd\": 123,\n \"fee_usd\": 123,\n \"sender_rows\": [\n {}\n ],\n \"receiver_rows\": [\n {}\n ],\n \"transaction_flows\": [\n {}\n ],\n \"transaction_flows_status\": \"<string>\",\n \"transaction_flows_error\": \"<string>\",\n \"network_nodes\": [\n {}\n ],\n \"network_edges\": [\n {}\n ],\n \"pep_counterparty\": true,\n \"risk_factors\": [\n {\n \"category\": \"<string>\",\n \"label\": \"<string>\",\n \"entity_name\": \"<string>\",\n \"amount_usd\": 123,\n \"percentage\": 123,\n \"is_high_risk\": true,\n \"description\": \"<string>\"\n }\n ],\n \"raw_response\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/wallet-screening/pdf/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"provider\": \"<string>\",\n \"screening_type\": \"WALLET_SCREENING\",\n \"risk_score\": 123,\n \"summary\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"blockchain\": \"<string>\",\n \"source_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"destination_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"counterparty_connections\": [\n {\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"risk_level\": \"<string>\",\n \"categories\": [\n \"<string>\"\n ],\n \"received_usd\": 123,\n \"sent_usd\": 123,\n \"received_hops\": 123,\n \"sent_hops\": 123,\n \"percentage\": 123,\n \"is_direct\": true,\n \"country\": \"<string>\",\n \"provider_entity_id\": \"<string>\"\n }\n ],\n \"sanctions_hit\": true,\n \"dominant_risk_category\": \"<string>\",\n \"report_signature\": \"<string>\",\n \"transaction_hash\": \"<string>\",\n \"block_timestamp\": \"<string>\",\n \"total_value_usd\": 123,\n \"fee_usd\": 123,\n \"sender_rows\": [\n {}\n ],\n \"receiver_rows\": [\n {}\n ],\n \"transaction_flows\": [\n {}\n ],\n \"transaction_flows_status\": \"<string>\",\n \"transaction_flows_error\": \"<string>\",\n \"network_nodes\": [\n {}\n ],\n \"network_edges\": [\n {}\n ],\n \"pep_counterparty\": true,\n \"risk_factors\": [\n {\n \"category\": \"<string>\",\n \"label\": \"<string>\",\n \"entity_name\": \"<string>\",\n \"amount_usd\": 123,\n \"percentage\": 123,\n \"is_high_risk\": true,\n \"description\": \"<string>\"\n }\n ],\n \"raw_response\": {}\n}"
response = http.request(request)
puts response.read_bodyScreen Wallet PDF
Stateless companion to POST /v3/wallet-screening/: repost the exact JSON body that endpoint returned — including the report_signature it added — and get back a Didit-branded PDF of the same result. No provider is called and nothing is billed or persisted; this only re-renders a result Didit already produced. The signature ties the PDF to an unmodified result: editing risk_score, severity, sanctions_hit, or any other signed field before reposting fails with 400.
# $RESULT is the saved JSON body from POST /v3/wallet-screening/
curl -X POST 'https://verification.didit.me/v3/wallet-screening/pdf/' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d "$RESULT" \
-o wallet_screening_report.pdfimport requests
# `result` is the dict returned by POST /v3/wallet-screening/, unmodified
response = requests.post(
'https://verification.didit.me/v3/wallet-screening/pdf/',
headers={'x-api-key': 'YOUR_API_KEY'},
json=result,
timeout=30,
)
response.raise_for_status()
with open('wallet_screening_report.pdf', 'wb') as fh:
fh.write(response.content)// `result` is the object returned by POST /v3/wallet-screening/, unmodified
const response = await fetch('https://verification.didit.me/v3/wallet-screening/pdf/', {
method: 'POST',
headers: {
'x-api-key': process.env.DIDIT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(result),
});
if (!response.ok) throw new Error(`PDF generation failed: HTTP ${response.status}`);
const pdfBuffer = Buffer.from(await response.arrayBuffer());<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://verification.didit.me/v3/wallet-screening/pdf/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'provider' => '<string>',
'screening_type' => 'WALLET_SCREENING',
'risk_score' => 123,
'summary' => '<string>',
'wallet_address' => '<string>',
'blockchain' => '<string>',
'source_of_funds' => [
[
'category' => '<string>',
'percentage' => 123,
'amount_usd' => 123,
'entity_name' => '<string>',
'entity_type' => '<string>',
'entity_subtype' => '<string>',
'hops' => 123,
'description' => '<string>',
'is_direct' => true,
'provider_entity_id' => '<string>',
'provider_entity_type_id' => '<string>',
'provider_entity_subtype_id' => '<string>',
'country' => '<string>',
'raw_amount' => 123,
'raw_currency' => '<string>'
]
],
'destination_of_funds' => [
[
'category' => '<string>',
'percentage' => 123,
'amount_usd' => 123,
'entity_name' => '<string>',
'entity_type' => '<string>',
'entity_subtype' => '<string>',
'hops' => 123,
'description' => '<string>',
'is_direct' => true,
'provider_entity_id' => '<string>',
'provider_entity_type_id' => '<string>',
'provider_entity_subtype_id' => '<string>',
'country' => '<string>',
'raw_amount' => 123,
'raw_currency' => '<string>'
]
],
'counterparty_connections' => [
[
'entity_name' => '<string>',
'entity_type' => '<string>',
'entity_subtype' => '<string>',
'risk_level' => '<string>',
'categories' => [
'<string>'
],
'received_usd' => 123,
'sent_usd' => 123,
'received_hops' => 123,
'sent_hops' => 123,
'percentage' => 123,
'is_direct' => true,
'country' => '<string>',
'provider_entity_id' => '<string>'
]
],
'sanctions_hit' => true,
'dominant_risk_category' => '<string>',
'report_signature' => '<string>',
'transaction_hash' => '<string>',
'block_timestamp' => '<string>',
'total_value_usd' => 123,
'fee_usd' => 123,
'sender_rows' => [
[
]
],
'receiver_rows' => [
[
]
],
'transaction_flows' => [
[
]
],
'transaction_flows_status' => '<string>',
'transaction_flows_error' => '<string>',
'network_nodes' => [
[
]
],
'network_edges' => [
[
]
],
'pep_counterparty' => true,
'risk_factors' => [
[
'category' => '<string>',
'label' => '<string>',
'entity_name' => '<string>',
'amount_usd' => 123,
'percentage' => 123,
'is_high_risk' => true,
'description' => '<string>'
]
],
'raw_response' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://verification.didit.me/v3/wallet-screening/pdf/"
payload := strings.NewReader("{\n \"provider\": \"<string>\",\n \"screening_type\": \"WALLET_SCREENING\",\n \"risk_score\": 123,\n \"summary\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"blockchain\": \"<string>\",\n \"source_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"destination_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"counterparty_connections\": [\n {\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"risk_level\": \"<string>\",\n \"categories\": [\n \"<string>\"\n ],\n \"received_usd\": 123,\n \"sent_usd\": 123,\n \"received_hops\": 123,\n \"sent_hops\": 123,\n \"percentage\": 123,\n \"is_direct\": true,\n \"country\": \"<string>\",\n \"provider_entity_id\": \"<string>\"\n }\n ],\n \"sanctions_hit\": true,\n \"dominant_risk_category\": \"<string>\",\n \"report_signature\": \"<string>\",\n \"transaction_hash\": \"<string>\",\n \"block_timestamp\": \"<string>\",\n \"total_value_usd\": 123,\n \"fee_usd\": 123,\n \"sender_rows\": [\n {}\n ],\n \"receiver_rows\": [\n {}\n ],\n \"transaction_flows\": [\n {}\n ],\n \"transaction_flows_status\": \"<string>\",\n \"transaction_flows_error\": \"<string>\",\n \"network_nodes\": [\n {}\n ],\n \"network_edges\": [\n {}\n ],\n \"pep_counterparty\": true,\n \"risk_factors\": [\n {\n \"category\": \"<string>\",\n \"label\": \"<string>\",\n \"entity_name\": \"<string>\",\n \"amount_usd\": 123,\n \"percentage\": 123,\n \"is_high_risk\": true,\n \"description\": \"<string>\"\n }\n ],\n \"raw_response\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://verification.didit.me/v3/wallet-screening/pdf/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"provider\": \"<string>\",\n \"screening_type\": \"WALLET_SCREENING\",\n \"risk_score\": 123,\n \"summary\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"blockchain\": \"<string>\",\n \"source_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"destination_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"counterparty_connections\": [\n {\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"risk_level\": \"<string>\",\n \"categories\": [\n \"<string>\"\n ],\n \"received_usd\": 123,\n \"sent_usd\": 123,\n \"received_hops\": 123,\n \"sent_hops\": 123,\n \"percentage\": 123,\n \"is_direct\": true,\n \"country\": \"<string>\",\n \"provider_entity_id\": \"<string>\"\n }\n ],\n \"sanctions_hit\": true,\n \"dominant_risk_category\": \"<string>\",\n \"report_signature\": \"<string>\",\n \"transaction_hash\": \"<string>\",\n \"block_timestamp\": \"<string>\",\n \"total_value_usd\": 123,\n \"fee_usd\": 123,\n \"sender_rows\": [\n {}\n ],\n \"receiver_rows\": [\n {}\n ],\n \"transaction_flows\": [\n {}\n ],\n \"transaction_flows_status\": \"<string>\",\n \"transaction_flows_error\": \"<string>\",\n \"network_nodes\": [\n {}\n ],\n \"network_edges\": [\n {}\n ],\n \"pep_counterparty\": true,\n \"risk_factors\": [\n {\n \"category\": \"<string>\",\n \"label\": \"<string>\",\n \"entity_name\": \"<string>\",\n \"amount_usd\": 123,\n \"percentage\": 123,\n \"is_high_risk\": true,\n \"description\": \"<string>\"\n }\n ],\n \"raw_response\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://verification.didit.me/v3/wallet-screening/pdf/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"provider\": \"<string>\",\n \"screening_type\": \"WALLET_SCREENING\",\n \"risk_score\": 123,\n \"summary\": \"<string>\",\n \"wallet_address\": \"<string>\",\n \"blockchain\": \"<string>\",\n \"source_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"destination_of_funds\": [\n {\n \"category\": \"<string>\",\n \"percentage\": 123,\n \"amount_usd\": 123,\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"hops\": 123,\n \"description\": \"<string>\",\n \"is_direct\": true,\n \"provider_entity_id\": \"<string>\",\n \"provider_entity_type_id\": \"<string>\",\n \"provider_entity_subtype_id\": \"<string>\",\n \"country\": \"<string>\",\n \"raw_amount\": 123,\n \"raw_currency\": \"<string>\"\n }\n ],\n \"counterparty_connections\": [\n {\n \"entity_name\": \"<string>\",\n \"entity_type\": \"<string>\",\n \"entity_subtype\": \"<string>\",\n \"risk_level\": \"<string>\",\n \"categories\": [\n \"<string>\"\n ],\n \"received_usd\": 123,\n \"sent_usd\": 123,\n \"received_hops\": 123,\n \"sent_hops\": 123,\n \"percentage\": 123,\n \"is_direct\": true,\n \"country\": \"<string>\",\n \"provider_entity_id\": \"<string>\"\n }\n ],\n \"sanctions_hit\": true,\n \"dominant_risk_category\": \"<string>\",\n \"report_signature\": \"<string>\",\n \"transaction_hash\": \"<string>\",\n \"block_timestamp\": \"<string>\",\n \"total_value_usd\": 123,\n \"fee_usd\": 123,\n \"sender_rows\": [\n {}\n ],\n \"receiver_rows\": [\n {}\n ],\n \"transaction_flows\": [\n {}\n ],\n \"transaction_flows_status\": \"<string>\",\n \"transaction_flows_error\": \"<string>\",\n \"network_nodes\": [\n {}\n ],\n \"network_edges\": [\n {}\n ],\n \"pep_counterparty\": true,\n \"risk_factors\": [\n {\n \"category\": \"<string>\",\n \"label\": \"<string>\",\n \"entity_name\": \"<string>\",\n \"amount_usd\": 123,\n \"percentage\": 123,\n \"is_high_risk\": true,\n \"description\": \"<string>\"\n }\n ],\n \"raw_response\": {}\n}"
response = http.request(request)
puts response.read_bodyWhy it’s stateless
Standalone wallet screening writes nothing to the transactions table, so there is no stored record for this endpoint to render from. Instead, you repost the exact JSON thatPOST /v3/wallet-screening/ already gave you, and Didit renders that payload into a PDF without calling a provider again.
The report_signature field
Every POST /v3/wallet-screening/ response now includes a report_signature field — an opaque signature scoped to your application. This endpoint verifies it before rendering, so a caller can’t edit risk_score, severity, sanctions_hit, or any other field and get a clean-looking Didit-branded PDF for a result Didit never produced.
Always repost the full response body unmodified, including report_signature. Reordering keys is fine; changing any signed value is not.
# 1. Run the screening and save the full response
RESULT=$(curl -s -X POST https://verification.didit.me/v3/wallet-screening/ \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"wallet_address": "0x28c6c06298d514db089934071355e5743bf21d60", "blockchain": "ETH"}')
# 2. Repost it verbatim to render the PDF
curl -X POST https://verification.didit.me/v3/wallet-screening/pdf/ \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "$RESULT" \
-o wallet_screening_report.pdf
Billing
No provider call is made and nothing is billed — this only re-renders a result you already paid for when you calledPOST /v3/wallet-screening/.
Errors
| Status | Meaning |
|---|---|
400 | Body is not a JSON object matching the wallet-screening result shape, or report_signature is missing or does not match the reposted fields. |
401 | Missing or invalid x-api-key. |
Next steps
Screen Wallet
On-demand wallet screening
Authorizations
Your application's API key, from Developers -> API keys in the Business Console. The primary key has full access. A named key can be scoped: none, read or write per resource, limited to some workflows or to approved sessions, to a list of IP addresses, and to an expiry date. 401 means the key is missing, wrong, revoked or expired; 403 means the key has no access to this resource or action, or the request came from an address outside its IP list; 404 on a session route means the session is outside the key's workflows or statuses. A key without media access receives image, video and PDF URLs as null, and a key without sessions write receives session links and tokens as null. See https://docs.didit.me/console/api-keys.
Body
The unmodified JSON object returned by POST /v3/wallet-screening/, including report_signature.
Same shape as the POST /v3/wallet-screening/ response — pass that response body back verbatim, including report_signature.
Provider that performed the screening (e.g. merklescience, crystal).
Always WALLET_SCREENING for this endpoint.
WALLET_SCREENING Normalised 0-100 risk score. Higher means greater exposure to risky entities. Merkle Science grades an address 0-5, which maps to 0, 15, 35, 55, 75 or 95.
Risk bucket derived from risk_score: 0-9 UNKNOWN, 10-39 LOW, 40-69 MEDIUM, 70-89 HIGH, 90-100 CRITICAL. UNKNOWN is the lowest band, not a separate no-data state: risk_score 0 (the common clean-address case) means no adverse assessment, while a non-zero score in the 1-9 range is a real but sub-LOW signal - read the risk_score, not just the band. Never treat UNKNOWN as an affirmative low-risk or clear rating; do not display it as a pass.
UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL Screening outcome status.
SCREENED, PENDING, ERROR Human-readable summary of the screening result.
The screened address, echoed back.
The blockchain that was screened.
Where the address received funds from, attributed by entity. Each entry is an exposure breakdown.
Show child attributes
Show child attributes
Where the address sent funds to, attributed by entity. Same item shape as source_of_funds with exposure_direction = outgoing.
Show child attributes
Show child attributes
Entities the provider attributes the screened address to. For Merkle Science these come from the address's own owner and user tags, so the same entity can appear twice, and they carry no fund flows: received_usd, sent_usd, received_hops and sent_hops are null and percentage is 0. Do not route on risk_level or is_direct here: use sanctions_hit, dominant_risk_category and risk_factors[].is_high_risk for the verdict, and exposure_type in source_of_funds/destination_of_funds for directness.
Show child attributes
Show child attributes
True if the address has direct or indirect sanctions exposure.
Highest-weighted high-risk category, or null when none is dominant (e.g. sanctioned, mixer, stolen_funds).
Opaque HMAC-SHA256 signature over this exact result, scoped to your application. Not meaningful on its own — repost the full response body, unmodified and including this field, to POST /v3/wallet-screening/pdf/ to render it as a PDF. The PDF endpoint rejects the request with 400 if report_signature is missing or if any signed field (e.g. risk_score, severity, sanctions_hit) was edited before repost.
Transaction screening field, shared with the result shape. Always null on a wallet screening result.
Transaction screening field, shared with the result shape. Always null on a wallet screening result.
Transaction screening field, shared with the result shape. Always null on a wallet screening result.
Transaction screening field, shared with the result shape. Always null on a wallet screening result.
Transaction screening field, shared with the result shape. Always empty on a wallet screening result.
Transaction screening field, shared with the result shape. Always empty on a wallet screening result.
Transaction screening field, shared with the result shape. Always empty on a wallet screening result.
Transaction screening field, shared with the result shape. Always null on a wallet screening result.
Transaction screening field, shared with the result shape. Always null on a wallet screening result.
Exposure graph nodes for transaction screening. Empty on a wallet screening result.
Exposure graph edges for transaction screening. Empty on a wallet screening result.
Politically exposed person exposure. null when no PEP finding is available, which is every result today because no provider reports one; false only for an explicit negative screening result. Do not read null as a completed PEP check.
Ranked explanation of risk_score: what produced this verdict. Providers grade an address on their own model and return only a verdict (Merkle Science returns an integer 0-5), so the score alone is not actionable. Ordered high-risk first, then by the value that moved through each driver, capped at the five strongest; source_of_funds and destination_of_funds always carry the complete breakdown. A high risk_score with no is_high_risk entry means the provider reported no sanctions or attributed-entity match and graded the address purely on its own exposure model - summary states this explicitly.
Show child attributes
Show child attributes
The provider's own payload. Its shape is provider-specific and can change without notice: read the normalised fields instead of parsing it.
Response
The rendered PDF document, returned directly as binary application/pdf — there is no JSON wrapper.
The response is of type file.