4. HTTP API
The bounce-classifier service provides HTTP(S) endpoints for classifying bounce reasons using a machine learning model. It supports batching, caching, and can run with or without TLS.
4.1. Endpoints
POST
/v1/bnac/single
— Classify a single message, returns class onlyPOST
/v2/bnac/single
— Classify a single message, returns class and probabilityPOST
/v1/bnac
— Classify a batch or single, returns class only, uses server-side cache if enabledPOST
/v2/bnac
— Classify a batch or single, returns class and probability, uses server-side cache if enabledGET
/v1/cache/stats
— Get cache statisticsGET
/v1/cache/info
— Get cache configuration info
4.1.1. Version 1 (/v1
)
Classification Only: Endpoints under
/v1
will solely return the model’s classification prediction.
Response (v1
):
{"class":"GRAYLISTING"}
4.1.2. Version 2 (/v2
)
- Classification with Probability: Endpoints under
/v2
provide both: The classification prediction, and
An associated probability value for informational purposes.
- Classification with Probability: Endpoints under
Probability Usage: The provided probability is meant to supplement the classification. It’s recommended not to rely solely on this value for automated decision-making processes.
Response (v2
):
{"class":"GRAYLISTING","probability":0.95663047}
4.2. HTTPS
To run the service with HTTPS you can set the environment varibales:
You can also configure the port and the host as defined in configuration:
4.3. Authentication
You can use the X-API-Key
header for authentication.
The X-API-Key
header is optional and can be used to restrict access to the API. If not provided, the API will still function but without authentication.
To configure the API key, look in the configuration section: API_KEY
, once that is set then that key can be used in the requests:
curl -X 'POST' 'https://127.0.0.1:8443/v1/bnac/single' \
-H 'X-API-Key: <YOUR_API_KEY_HERE>' -H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"message": "smtp;451 4.7.1 <[email protected]>: Recipient address rejected: Greylisting in effect, please come back later"}'
The API key is independent of HTTPS, it can be used with HTTP as well:
curl -X 'POST' 'http://127.0.0.1:8080/v1/bnac' \
-H 'X-API-Key: <YOUR_API_KEY_HERE>' -H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"message": "smtp;451 4.7.1 <[email protected]>: Recipient address rejected: Greylisting in effect, please come back later"}'
4.4. Single Message Example
curl -X 'POST' 'http://127.0.0.1:8080/v1/bnac/single' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{"message": "smtp;451 4.7.1 <[email protected]>: Recipient address rejected: Greylisting in effect, please come back later"}'
Response (v1):
{"class":"GRAYLISTING"}
Response (v2):
{"class":"GRAYLISTING","probability":0.95663047}
4.5. Batch Message Example
Sending multiple messages at the same time is supported and will be faster than sending them one by one.
curl -X 'POST' 'http://127.0.0.1:8080/v2/bnac' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"messages": [
"smtp;451 4.7.1 <[email protected]>: Recipient address rejected: Greylisting in effect, please come back later",
"smtp;450 4.0.0 <[email protected]>... User unknown..."
]
}'
Response (v2):
[ {"class":"GRAYLISTING","probability":0.95663047}, {"class":"RECIPIENT_NOT_FOUND","probability":0.70459944}]
4.6. Cache
4.6.1. Cache Endpoints
curl -X 'GET' 'http://127.0.0.1:8080/v1/cache/stats' -H 'accept: application/json'
curl -X 'GET' 'http://127.0.0.1:8080/v1/cache/info' -H 'accept: application/json'
4.6.1.1. Cache statistics
curl -X 'GET' 'http://127.0.0.1:8080/v1/cache/stats' -H 'accept: application/json'
Returns:
{
"cache_enabled": true,
"stats_enabled": false,
"timer_enabled": false,
"hit_requests": 0,
"miss_requests": 0,
"size_in_bytes": 12288,
"number_of_elements": 0,
"avg_get_time_ms": 0,
"avg_set_time_ms": 0
}
4.6.1.2. Cache info
Cache info endpoint returns the current cache configuration,
including whether it is enabled (see HALON_BNAC_CACHE
), the folder where it is stored (see HALON_BNAC_CACHE_FOLDER
), and the maximum size in bytes (see HALON_BNAC_CACHE_SIZE
).
{
"cache_enabled": true,
"folder": "/var/lib/halon/bounce-classifier",
"max_size": "104857600"
}
4.7. Results
An object with a class property is returned. The possible classifications are:
Classification |
Suggested Action |
Severity |
Scope |
---|---|---|---|
|
Recipient MTA is blocking, with third-party (e.g. Spamhaus,..) information |
5 |
|
|
Recipient MTA is blocking, no third-party information |
3 |
|
|
Fix DKIM |
3 |
|
|
Fix DMARC |
3 |
|
|
Fix reverse DNS |
3 |
|
|
Slow down from this sending domain |
4 |
|
|
Slow down to this recipient domain, you are at risk of being blocked |
3 |
|
|
Slow down from this sending IP |
4 |
|
|
Suspend campaign and review what is sent |
3 |
|
|
Verify your DNS resolution of this recipient domain |
3 |
|
|
Verify the MTA configuration and protocols |
1 |
|
|
Slow down to this recipient domain |
3 |
|
|
Slow down, possible poor list quality, reduce frequency to this address |
2 |
|
|
Remove the address |
1 |
recipient address |
|
Fix SPF |
3 |
|
|
Slow down sending to this recipient domain |
1 |
|
|
Check your TLS negotiation with this recipient domain |
3 |
|
|
Suspend campaign and review what is sent |
6 |
|
4.7.1. Severity
6 = Most severe impact on sender reputation
1 = Lowest impact on sender reputation
4.8. Example HSL script
This example script can be run from the terminal directly with hsh.
It is equivalent to the curl
example above, passing in a message and receiving a response.
$guru = "http://127.0.0.1:8000/v1/bnac"; $options = ["headers" => ["Content-Type: application/json", "Accept: application/json"], "extended_result" => true]; $data = "451 4.7.1 <[email protected]>: Recipient address rejected: Greylisting in effect, please come back later"; $payload = json_encode(["message" => $data]); $res = http($guru, $options, [], $payload); if ($res["content"]) { $content = json_decode($res["content"]); $class = $content["class"]; echo $class; }
For best performance in calls from script hooks, use the http-background plugin instead of the foreground http function.