Skip to content

Bulk job completion callback

Geobridge can notify you when a bulk job finishes processing. Every delivery includes authentication headers so you can verify authenticity and defend against replays before acknowledging the request.

HeaderPurpose
X-Geobridge-SignatureBase64-encoded HMAC SHA-256 signature.
X-Geobridge-TimestampUnix epoch seconds. Reject payloads with a stale timestamp.

The signature is generated with the shared secret you supplied when creating the job. Geobridge signs the canonical string "<timestamp>." + body.

  1. Parse the JSON body as bytes (do not mutate or prettify it).
  2. Confirm the timestamp is within your allowed replay window (5 minutes is a good default).
  3. Recompute HMAC_SHA256(secret, canonicalString) and Base64-encode the digest.
  4. Compare the signature with a constant-time function. Reject mismatches with a non-2xx status to trigger retries.
import crypto from 'node:crypto';
export function verifyWebhook({ signature, timestamp, rawBody, secret }) {
const ts = Number(timestamp);
if (!Number.isFinite(ts)) throw new Error('Invalid webhook timestamp');
const age = Math.abs(Date.now() / 1000 - ts);
if (age > 300) throw new Error('Webhook timestamp outside allowable window');
const canonical = `${timestamp}.${rawBody}`;
const expected = crypto
.createHmac('sha256', secret)
.update(canonical)
.digest('base64');
const actualBuf = Buffer.from(signature, 'utf8');
const expectedBuf = Buffer.from(expected, 'utf8');
if (actualBuf.length !== expectedBuf.length) {
throw new Error('Invalid webhook signature length');
}
if (!crypto.timingSafeEqual(actualBuf, expectedBuf)) {
throw new Error('Invalid webhook signature');
}
}
  • Geobridge retries with exponential backoff using the policy you set on the job (max_attempts, strategy, initial_delay_seconds).
  • Return an HTTP 2xx status once the payload is persisted. Non-2xx responses consume a retry.
  • If retries exhaust, the job status remains failed and the error is captured in the job metadata for later inspection.