Skip to main content
POST
/
api
/
v1
/
enterprise
/
eudr
/
clearance
/
webhook
Python
import agribackup
from agribackup.rest import ApiException

# Initialize Client
configuration = agribackup.Configuration(host="https://live.agribackup.com/api/v1")
configuration.api_key['ApiKeyAuth'] = 'sk_live_YOUR_API_KEY'

with agribackup.ApiClient(configuration) as api_client:
    try:
        api_instance = agribackup.EnterpriseClearanceWebhooksApi(api_client)
        response = api_instance.handle_clearance_webhook()
        print(response)
    except ApiException as e:
        print("Exception when calling API: %s\n" % e)
import { AgriBackupClient } from '@agribackup/sdk';

// Initialize Client
const client = new AgriBackupClient({
apiKey: 'sk_live_YOUR_API_KEY',
baseUrl: 'https://live.agribackup.com/api/v1'
});

async function execute() {
try {
const response = await client.webhooks.handleClearanceWebhook();
console.log(response);
} catch (error) {
console.error(error);
}
}
import com.agribackup.client.*;
import com.agribackup.client.api.*;
import com.agribackup.client.model.*;

public class Example {
public static void main(String[] args) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setBasePath("https://live.agribackup.com/api/v1");
defaultClient.setApiKey("sk_live_YOUR_API_KEY");

EnterpriseClearanceWebhooksApi apiInstance = new EnterpriseClearanceWebhooksApi(defaultClient);
try {
Object result = apiInstance.handleClearanceWebhook();
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling API: " + e.getResponseBody());
}
}
}
using System;
using System.Threading.Tasks;
using AgriBackup.SDK.Api;
using AgriBackup.SDK.Client;
using AgriBackup.SDK.Model;

class Program {
static async Task Main() {
Configuration config = new Configuration();
config.BasePath = "https://live.agribackup.com/api/v1";
config.AddApiKey("ApiKeyAuth", "sk_live_YOUR_API_KEY");

var apiInstance = new EnterpriseClearanceWebhooksApi(config);
try {
var result = await apiInstance.HandleClearanceWebhookAsync();
Console.WriteLine(result);
} catch (ApiException e) {
Console.WriteLine("Exception when calling API: " + e.Message);
}
}
}
curl --request POST \
--url https://live.agribackup.com/api/v1/enterprise/eudr/clearance/webhook \
--header 'Content-Type: application/json' \
--data '
{
"tracesReferenceNumber": "<string>",
"status": "<string>",
"timestamp": "<string>"
}
'
const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({tracesReferenceNumber: '<string>', status: '<string>', timestamp: '<string>'})
};

fetch('https://live.agribackup.com/api/v1/enterprise/eudr/clearance/webhook', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://live.agribackup.com/api/v1/enterprise/eudr/clearance/webhook",
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([
'tracesReferenceNumber' => '<string>',
'status' => '<string>',
'timestamp' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);

$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://live.agribackup.com/api/v1/enterprise/eudr/clearance/webhook"

payload := strings.NewReader("{\n \"tracesReferenceNumber\": \"<string>\",\n \"status\": \"<string>\",\n \"timestamp\": \"<string>\"\n}")

req, _ := http.NewRequest("POST", url, payload)

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))

}
require 'uri'
require 'net/http'

url = URI("https://live.agribackup.com/api/v1/enterprise/eudr/clearance/webhook")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"tracesReferenceNumber\": \"<string>\",\n \"status\": \"<string>\",\n \"timestamp\": \"<string>\"\n}"

response = http.request(request)
puts response.read_body
{}
This endpoint describes an inbound webhook event that AgriBackup delivers to your registered callback URL when the TRACES NT system posts a clearance status update for a Due Diligence Statement (DDS) you submitted. You do not call this endpoint directly — AgriBackup calls your server. When TRACES NT issues a clearance decision (e.g., VALIDATED, REJECTED, or PENDING), AgriBackup wraps the status update in a signed payload and delivers it to the URL you registered via Register Webhook Endpoint. The payload is signed with HMAC-SHA256 and included in the X-AgriBackup-Signature header — verify the signature before processing.

Payload Shape

{
  "tracesReferenceNumber": "TRACES-2026-EU-000123",
  "status": "VALIDATED",
  "timestamp": "2026-06-12T14:30:00Z"
}
FieldTypeRequiredDescription
tracesReferenceNumberstringThe official TRACES NT reference number for the DDS
statusstringClearance decision from TRACES NT — e.g., VALIDATED, REJECTED, PENDING
timestampstringISO-8601 timestamp of the clearance decision

Handling the Event

Your endpoint must return HTTP 200 OK to acknowledge receipt. A non-2xx response is treated as a delivery failure and triggers AgriBackup’s standard retry policy. If retries are exhausted, the message is moved to the Dead-Letter Queue and can be retrieved via Retrieve Permanently Failed Webhook Payloads.
import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
SIGNING_SECRET = "whsec_YOUR_SIGNING_SECRET"

@app.route("/agribackup-webhooks", methods=["POST"])
def receive_clearance_webhook():
    raw_body = request.get_data()
    header_sig = request.headers.get("X-AgriBackup-Signature", "")

    computed = hmac.new(
        SIGNING_SECRET.encode("utf-8"),
        raw_body,
        hashlib.sha256,
    ).hexdigest()

    if not hmac.compare_digest(computed, header_sig):
        abort(401)

    payload = request.get_json()
    traces_ref = payload["tracesReferenceNumber"]
    status = payload["status"]

    # Update DDS record in your ERP
    print(f"DDS {traces_ref} is now {status}")
    return "", 200
const crypto = require("crypto");
const express = require("express");

const app = express();
const SIGNING_SECRET = "whsec_YOUR_SIGNING_SECRET";

app.post(
  "/agribackup-webhooks",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const headerSig = req.headers["x-agribackup-signature"] || "";
    const computed = crypto
      .createHmac("sha256", SIGNING_SECRET)
      .update(req.body)
      .digest("hex");

    if (!crypto.timingSafeEqual(Buffer.from(computed), Buffer.from(headerSig))) {
      return res.status(401).send("Invalid signature");
    }

    const payload = JSON.parse(req.body);
    const { tracesReferenceNumber, status } = payload;

    // Update DDS record in your ERP
    console.log(`DDS ${tracesReferenceNumber} is now ${status}`);
    res.sendStatus(200);
  }
);

Body

application/json
tracesReferenceNumber
string
required
status
string
required
timestamp
string

Response

200 - */*

OK

{key}
string