Enriching is one of the steps a listing goes through before being published. Most enrichers come in the form of webhooks.

With webhooks your server will receive a HTTP POST request from ILSA with vehicle information and you can return additional information to be attached to the vehicle.

Webhooks can’t be configured in the Backoffice yet, so let us know and we’ll configure it for you. We’ll need to know a couple of things:

  • The endpoint (which URL should we call?)
  • Which fields you want to receive. These should include all the information your webhook needs, but nothing more. ILSA will cache your responses based on the hash of the input, so by including fields you don’t use the effectiveness of the cache is reduced.
  • Fields you plan on returning (yoursite.final_term, yoursite.monthly_amount_24 and yoursite.monthly_amount_36 in the example below). You can choose your own names, but we do prefer you use a prefix indicating those fields are custom for you, to keep things clear. You can create more complex structures if needed. These fields will then be available in the backoffice for you to add as searchable fields (filters), use in ordering or add to fieldsets.
  • The number of parallel requests we’re allowed to make, if more than 1.
  • Optionally, a shared secret for signing the webhook requests

You can’t use the enricher webhooks as a notification system about new vehicles. They might (seemingly arbitrarily) get reenriched and new vehicles might not call the webhook at all if they hit the cache. This is strictly for appending more information to the vehicle record.

Here’s an example request:

POST /ilsa-enricher HTTP/1.1
Host: www.yoursite.com
User-Agent: ILSA enricher v1.0 (info@ilsa.cloud)
Content-Type: application/json

{
    "sales_conditions": {
        "pricing": {
            "asking": {
                "business": {
                    "in_eur": {
                        "excl_vat": {
                            "amount": 24426
                        },
                        "incl_vat": {
                            "amount": 28450
                        }
                    }
                }
            }
        },
        "margin_scheme": "vat"
    }
}

and an example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
    "yoursite": {
  	    "final_term": 3500
        "monthly_amount_24": 399,
        "monthly_amount_36": 299
    }
}

Any errors from your webhook are retried a few minutes later and are not advertiser visible.

If you want to return an error to the advertiser, you can respond like this:

HTTP/1.1 422 Unprocessable Content
Content-Type: text/plain

The vehicle could not be found in the manufacturer datebase.

TIP

If you’re rejecting listings based on specific fields, prefer doing so with our Static Filters Enricher. This allows DV to give a nicely translated error message to the advertiser.

As mentioned above, we cache webhook requests based on their inputs. Your webhook should give the same result when given the same input.

Sometimes the world changes however. Maybe you’ve changed your interest rate and all vehicles need to be enriched again. In the Backoffice you can Purge an enricher. That will purge the cache and send all vehicles through enrichment again.

You can also purge an enricher for a single vehicle:

POST https://api.hexon.nl/ilsa/api/v1/rest/enrichers/987654321/purge
Content-Type: application/json
Authorization: Bearer <token>

{
	"object_id": 12345
}

Contact us to get to get credentials for the Hexon API.

Optionally, a shared secret can be entered which ILSA will use to sign the requests. This allows you to confirm the request is originating from the ILSA servers and the payload has not been tampered with. ILSA uses HMAC SHA256 and adds the signature in the header X-Signature-SHA256.

Golang example
import (
	"crypto/hmac"
	"encoding/base64"
)

const ilsaSharedSecret = "secret-to-be-configured"

func VerifiedBody(r *http.Request) ([]byte, error) {
	expected, err := base64.StdEncoding.DecodeString(r.Header.Get("X-Signature-SHA256"))
	if err != nil {
		return nil, errors.New("bad signature")
	}
	body, err := io.ReadAll(r.Body)
	if err != nil {
		return nil, err
	}
	mac := hmac.New(sha256.New, []byte(ilsaSharedSecret))
	mac.Write(body)
	if !hmac.Equal(expected, mac.Sum(nil)) {
		return nil, errors.New("bad signature")
	}
	return body, nil
}
PHP example
$body = file_get_contents('php://input');
if(!hash_equals(hash_hmac('sha256', $body, 'secret-to-be-configured'), $_SERVER['HTTP_X_SIGNATURE_SHA256'])) {
	http_response_code(403);
	exit();
}