Score a case
curl --request POST \
--url https://app.sahlfinancial.com/api/v1/cases/{case_id}/score \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.sahlfinancial.com/api/v1/cases/{case_id}/score', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.sahlfinancial.com/api/v1/cases/{case_id}/score"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"case_id": "7e3b9a14-2d6c-4c85-b1f0-6a8d4e2c9b37",
"score": 742,
"risk_level": "low",
"eligible_amount": 350000,
"breakdown": {
"income_stability": 0.82,
"debt_ratio": 0.74
},
"ai_insight": "Stable salaried income, moderate debt ratio."
}{
"detail": "Case 7e3b9a14-2d6c-4c85-b1f0-6a8d4e2c9b37 not found"
}{
"detail": "Invalid or expired token"
}{
"detail": "Insufficient permissions"
}{
"detail": "Case not found"
}{
"detail": [
{
"type": "missing",
"loc": [
"body",
"bank_code"
],
"msg": "Field required",
"input": {}
}
]
}{
"code": "rate_limit_exceeded",
"message": "Too many requests. Please slow down."
}Score a case
Who can call it: tenant_admin, tenant_reviewer or platform_admin.
Runs the scoring engine with the workspace’s active scoring policy, then decides the case from the policy thresholds when the score is conclusive. Fires the case.scored webhook. 400 with the engine’s message when the case cannot be scored.
Auth: dashboard session (Authorization: Bearer <access token>). Not available with a partner API key.
Score a case
curl --request POST \
--url https://app.sahlfinancial.com/api/v1/cases/{case_id}/score \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.sahlfinancial.com/api/v1/cases/{case_id}/score', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.sahlfinancial.com/api/v1/cases/{case_id}/score"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"case_id": "7e3b9a14-2d6c-4c85-b1f0-6a8d4e2c9b37",
"score": 742,
"risk_level": "low",
"eligible_amount": 350000,
"breakdown": {
"income_stability": 0.82,
"debt_ratio": 0.74
},
"ai_insight": "Stable salaried income, moderate debt ratio."
}{
"detail": "Case 7e3b9a14-2d6c-4c85-b1f0-6a8d4e2c9b37 not found"
}{
"detail": "Invalid or expired token"
}{
"detail": "Insufficient permissions"
}{
"detail": "Case not found"
}{
"detail": [
{
"type": "missing",
"loc": [
"body",
"bank_code"
],
"msg": "Field required",
"input": {}
}
]
}{
"code": "rate_limit_exceeded",
"message": "Too many requests. Please slow down."
}Authorizations
The access token (JWT) of a signed-in console user, from POST /v1/auth/login. It lasts 30 minutes. It is not an API key: a partner API key is refused here. There is no cookie.