Overview
The Push API notifies you the moment something changes in your Taboola account - instead of polling for updates, your endpoint receives a notification per change.
The concept is simple:
- In the Realize UI, create a subscription: the entity to watch, and your endpoint.
- When a tracked entity changes, Taboola sends a signed
POSTrequest to your endpoint. - Your endpoint validates the signature and responds with a
2xxstatus code.
Each event carries the fields that changed, their previous values, and the entity itself - in full when Fetch Entity is enabled on the subscription.
Creating a subscription
In the Realize UI, click Admin (the gear icon at the bottom of the left navigation sidebar) and select API Integrations.

Click New and select Subscription.
Name the subscription and select an API key, then set the entity to watch, your endpoint, the policy, and any field-level filters.
New subscriptions start in
Pendingstatus. Events begin flowing once the subscription is approved by Taboola.
Your endpoint
Taboola delivers events as POST requests to the endpoint you configure. Your endpoint must:
- Be publicly accessible over HTTPS.
- Accept
Content-Type: application/json. - Validate the
Taboola-Signatureheader. - Respond with a
2xxstatus code within 500 ms.
Respond within 500 msA slower response is treated as a failed delivery, and events can be delayed or dropped. Acknowledge the event first, then process it.
Events are not orderedFailed deliveries are retried according to Taboola's retry policy, so events are not guaranteed to arrive in the order the changes occurred. Sequence them by
change_time_in_utc.
Security
Every event carries a Taboola-Signature header - an HMAC-SHA256 of the request body, keyed with the client_secret of the API key selected on the subscription.
Validate it on every request. An endpoint that skips this check will accept a forged event from anyone who knows its URL.
Validating the signature
To confirm that an event came from Taboola:
- Read the raw request body as bytes, before any JSON parsing.
- Compute an HMAC-SHA256 over those bytes, using that
client_secretas the key. - Hex-encode the result in lowercase, and compare it to the
Taboola-Signatureheader.
If the values don't match, reject the request.
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
public final class TaboolaSignatureVerifier {
private static final String HMAC_SHA256 = "HmacSHA256";
/**
* @param rawBody the request body exactly as received - read it as bytes
* BEFORE any JSON parsing. A framework that parses and
* re-serializes the body produces a different hash.
* @param secret the client_secret of the API key on the subscription
* @param signature the value of the Taboola-Signature header
*/
public static boolean isValid(byte[] rawBody, String secret, String signature)
throws Exception {
Mac mac = Mac.getInstance(HMAC_SHA256);
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), HMAC_SHA256));
String expected = Hex.encodeHexString(mac.doFinal(rawBody));
// Constant-time comparison, so a rejected request reveals nothing
// about the expected value.
return MessageDigest.isEqual(
expected.getBytes(StandardCharsets.UTF_8),
signature.getBytes(StandardCharsets.UTF_8));
}
}Hex.encodeHexString (Apache Commons Codec) returns lowercase hex, which is what the header contains. Any equivalent hex encoder works, as long as the output is lowercase.
Troubleshooting
| Issue | Possible cause | Resolution |
|---|---|---|
| No events arriving | The subscription is still Pending. | Wait for approval, or contact [email protected]. |
| Events late or missing | Your endpoint is slow or failing. | Return a 2xx status code within 500 ms. |
| Signature validation fails | Check you are keying with the client_secret of the subscription's API key, and hashing the body exactly as received. | Recheck your logic against Validating the signature. |
What's next
Push API events covers the event payload structure and the request headers.
