Update a case
To update a case, you must first get the ID of the customer the case belongs to. You will have received this ID when you created the case.
You can then update the case by sending a POST request to the following endpoint:
https://platform.arva.ai/api/v0/customer/update
In the request body, you can provide a patch for the user-provided information, websites and file uploads to update the case. The fields you provide here will depend on which checks you have enabled for the agent. Each time you provide an update, the case will be re-evaluated and an outcome returned.
curl -X POST "https://platform.arva.ai/api/v0/customer/update" \
-H "Authorization: Bearer <API_KEY>" \
-H "Content-Type: multipart/form-data" \
-F "customerId=<CUSTOMER_ID>" \
# The fields you provide here will depend on which checks you have enabled for the agent
-F 'userInfoPatch={
"dba": <string>, # optional
"fkas": <string[]>, # optional
"natureOfBusiness": <string>, # optional
"operatingAddress": <string>, # optional
"tin": <string>, # optional
"addedEntities": Entity[] # optional
"editedEntities": Partial<Entity>[] # optional, must include the ID field
"removedEntityIds": <string[]> # optional, list of entity IDs to remove
# Optional, pass this to run only a subset of the enabled checks e.g. ['INCORPORATION']
# This will skip the overall verdict and RFI but will return the results for those checks
"checks": <CheckType[]>,
}' \
# E.g. Company website, LinkedIn, etc.
-F "websites=<ARRAY_OF_USER_WEBSITE_URLS>" \
# E.g. Certificate of Incorporation, CP-575 letter, etc.
-F "file=@<FILE_1_PATH>" \
-F "file=@<FILE_2_PATH>"
npm i @arva-ai/sdk
import { Arva } from '@arva-ai/sdk'
const client = new Arva(
<string> // Your API key
)
const customer = await client.customers.update({
id: <string>, // The ID of the customer
userInfoPatch: {
// The fields you provide here will depend on which checks you have enabled for the agent
dba: <string> | undefined,
fkas: <string[]> | undefined,
natureOfBusiness: <string> | undefined,
operatingAddress: <string> | undefined,
tin: <string> | undefined,
addedEntities: EntityWithScreeningResults[] | undefined,
editedEntities: Partial<Entity>[] | undefined, // must include the ID field
removedEntityIds: <string[]> | undefined, // list of entity IDs to remove
},
websites: <string[]>,
files: <File[]>,
// Optional, pass this to run only a subset of the enabled checks e.g. ['INCORPORATION']
// This will skip the overall verdict and RFI but will return the results for those checks
checks: <CheckType[]> | undefined
})
import json
import requests
import os
from requests_toolbelt import MultipartEncoder
user_info_patch = {
# The fields you provide here will depend on which checks you have enabled for the agent
'dba': <string> | None,
'fkas': <string[]> | None,
'natureOfBusiness': <string> | None,
'operatingAddress': <string> | None,
'tin': <string> | None,
'addedEntities': Entity[] | None,
'editedEntities': Partial<Entity>[] | None, # must include the ID field
'removedEntityIds': <string[]> | None, # list of entity IDs to remove
}
websites = <string[]>
file_paths = <string[]>
files = [open(fp, 'rb') for fp in file_paths]
file_tuples = [('file', (os.path.basename(f.name), f, 'application/pdf')) for f in files]
# Optional, pass this to run only a subset of the enabled checks, e.g. ['INCORPORATION']
# This will skip the overall verdict and RFI but will return the results for those checks
checks = ['INCORPORATION']
mp_encoder = MultipartEncoder(
fields=[
('customerId', customerId),
('user_info_patch', json.dumps(user_info_patch)),
('websites', json.dumps(websites)),
('checks', json.dumps(checks))
] + file_tuples
)
verdict = requests.post(
'https://platform.arva.ai/api/v0/customer/update',
headers={
'Authorization': 'Bearer ' + apiKey,
'Content-Type': mp_encoder.content_type
},
data=mp_encoder,
)
pip install arva-sdk
from arva import Arva
client = Arva(
api_key=<string>
)
user_info_patch = {
# The fields you provide here will depend on which checks you have enabled for the agent
'dba': <string>,
'fkas': <string[]> | None,
'natureOfBusiness': <string> | None,
'operatingAddress': <string> | None,
'tin': <string> | None,
'addedEntities': Entity[] | None, # optional
'editedEntities': Partial<Entity>[] | None, # optional, must include the ID field
'removedEntityIds': <string[]> | None, # list of entity IDs to remove
}
websites = <string[]>
file_paths = <string[]>
files = [open(fp, 'rb') for fp in file_paths]
# Optional, pass this to run only a subset of the enabled checks, e.g. ['INCORPORATION']
# This will skip the overall verdict and RFI but will return the results for those checks
checks = ['INCORPORATION']
verdict = client.customers.update(
id=<string>
user_info_patch=user_info_patch,
websites=websites,
files=files,
checks=checks
)
If the request is successful, the response from the API will be an object with the following schema:
{
id: string // customer ID
name: string
state: string | undefined
createdAt: Date
verdict: 'ACCEPT' | 'REJECT' | 'REQUEST_INFORMATION' | 'PENDING'
riskLevel: 'HIGH' | 'MEDIUM' | 'LOW' | undefined
periodicReviewYears: number | undefined // undefined unless the verdict is ACCEPT
rfi: string | undefined // undefined unless the verdict is REQUEST_INFORMATION
requiresManualReview: boolean
checks: {
type: string
verdict: 'ACCEPT' | 'REJECT' | 'REQUEST_INFORMATION' | 'PENDING'
riskLevel: 'HIGH' | 'MEDIUM' | 'LOW' | undefined // undefined unless the verdict is ACCEPT
reason: string
periodicReviewYears: number | undefined // undefined unless the verdict is ACCEPT
requiresManualReview: boolean
proofs: Proof[]
// Some checks return additional details e.g. registry results
details: Record<string, unknown> | undefined
}[]
entities: EntityWithScreeningResults[]
}
Where:
type Proof = {
id: string
type: 'DOCUMENT' | 'WEBSITE'
inferredType: string
name: string
url: string
}
type IndividualEntity = {
type: 'individual'
metadata: {
firstName: string
middleNames: string | undefined
lastName: string
dateOfBirth: {
day: number | undefined
month: number | undefined
year: number
} | undefined
address: string | undefined
country: string | undefined
}
}
type CorporateOrTrustEntity = {
type: 'corporate' | 'trust'
metadata: {
name: string
registrationJurisdiction: string | undefined
registrationNumber: string | undefined
address: string | undefined
}
relationships: Relationship[]
}
type Entity = IndividualEntity | CorporateOrTrustEntity
type Relationship = {
type: 'director' | 'officer' | 'psc'
positions: string[]
} | {
type: 'owner'
ownershipPercentage: number
entityId?: string // ID of the owned entity, if not the customer entity
} | {
type: 'additional'
reason: string
}
type EntityWithScreeningResults = Entity & {
screeningHits: ScreeningResult[]
}
type ScreeningResult = {
type: 'adverse_media' | 'sanctions_screening' | 'peps_screening' | 'other_screening'
verdict: 'LOW' | 'MEDIUM' | 'HIGH' | 'REJECT' | 'DISCOUNTED' | 'REVIEW'
reason: string
source: string // e.g. 'webSearch', 'complyAdvantage'
fromMonitoring: boolean
externalIds: {
// varies by provider
}
matchingName: string
// Additional fields vary by type and provider
names: string[] | undefined
url: string | undefined
date: string | undefined
lists: {
name: string
identifier: string
url: string
countryCodes: string[]
dateAdded: string
}[] | undefined
groupId: string | undefined // Adverse media hits that share the same groupId are likely to be the same event
}
Next, see how you can submit a manual review.