Report Delivery

When a report is ready, Geocerta delivers it automatically according to your account's delivery settings.

Methods

email

The report PDF is sent as an email attachment. Configure via PATCH /accounts/me.

Field Description
delivery.method "email"
delivery.email Address to send the report to

xml

Geocerta POSTs the report as an XML document to your endpoint, with the PDF embedded as a base64-encoded attachment. Configure via PATCH /accounts/me.

Field Description
delivery.method "xml"
delivery.endpoint Your endpoint URL
delivery.key Authentication key included in the XML payload

webhook

Geocerta POSTs a JSON payload to your endpoint when the report is ready. Configure via PATCH /accounts/me.

Field Description
delivery.method "webhook"
delivery.endpoint Your HTTPS endpoint URL
delivery.key Secret sent in the authorization header (min 6 characters)

Payload

Field Type Description
_id string Order ID
reference string Order reference
products[].id string Product ID
products[].reference string Product reference
products[].code string Product code (e.g. resi_pro)
products[].title string Product display name
products[].document_url string API URL to retrieve the document — call this to get the pre-signed download URL

Downloading a report

Call document_url with your API key to get the document metadata, including a download field with a pre-signed URL. See GET /orders/:id/documents/:doc_id.

Retries

If your endpoint does not return a 2xx response, Geocerta retries with exponential backoff:

Attempt Delay
2nd 5 min
3rd 20 min
4th 40 min
5th 60 min

After five failed attempts the delivery is marked as failed.

Verifying requests

Validate incoming webhooks by checking that the authorization header matches your configured delivery.key.

Example receiver

const WEBHOOK_KEY = process.env.GEOCERTA_WEBHOOK_KEY!;
const GEOCERTA_API_KEY = process.env.GEOCERTA_API_KEY!;
const REPORTS_DIR = './reports';

router.post('/geocerta/webhook', async (req: Request, res: Response) => {
  if (req.headers['authorization'] !== WEBHOOK_KEY) {
    res.status(401).json({ message: 'Unauthorized' });
    return;
  }

  res.sendStatus(200);

  const { _id, reference, products } = req.body;

  for (const product of products) {
    try {
      const metaRes = await fetch(product.document_url, {
        headers: { 'api-key': GEOCERTA_API_KEY },
      });

      if (!metaRes.ok) throw new Error(`Failed to fetch document metadata: ${metaRes.status}`);

      const { download, filename } = await metaRes.json();

      const fileRes = await fetch(download);
      if (!fileRes.ok) throw new Error(`Failed to download file: ${fileRes.status}`);

      fs.writeFileSync(`${REPORTS_DIR}/${filename}`, Buffer.from(await fileRes.arrayBuffer()));

      console.log(`Saved ${filename} for order ${reference} (${_id})`);
    } catch (err) {
      console.error(`Failed to download ${product.reference}:`, err);
    }
  }
});