public-api-docs

Data Exports Guide

Overview

Wunder Mobility Data Exports allow you to receive scheduled bulk data from your fleet management platform as CSV files. When an export is ready, you are notified via email, webhook, or both, with a link to download the file.

Exports are configured by your Customer Success Manager (CSM), who sets up predefined reports tailored to your data needs (e.g., trip history, vehicle utilization, active users). This is distinct from the synchronous JSON export endpoints available in the Operations API (such as /customers/export and /rentals/export), which are designed for on-demand programmatic access.

Who This Guide Is For: Developers and technical teams integrating with Wunder Mobility’s scheduled data export system, particularly those building automated pipelines to ingest webhook-delivered CSV reports.

Related Documentation: Wunder Operations API API Basics

How Exports Work

  1. Your CSM configures a query – a predefined SQL report tailored to your data needs
  2. Exports run automatically – either as a one-time export or on a recurring schedule (e.g., daily, weekly)
  3. You get notified – once the export file is ready, you receive an email and/or a webhook notification with a download link
  4. You download the CSV – click the link in the email or use the URL from the webhook payload

Export Types

Type Description
One-time export Runs once at a scheduled time and delivers a single CSV file
Recurring export Runs on a repeating schedule (e.g., every day at midnight) and delivers a new CSV file each time

File Format

Export files are delivered as CSV (comma-separated values) with:


Receiving Exports via Email

When an export completes, you receive an email containing a download link.

Email Details

Property Details
Subject {Your Organization} {Report Name} - {Date and Time}
Body A short message with a clickable download link
From Wunder Mobility system email address

Click the “Export results” link in the email. This link redirects you to a temporary download URL for the CSV file.

Important: Download links are valid for 7 days after you receive the notification. After that, the link will no longer work.


Receiving Exports via Webhook

If you have a webhook endpoint configured, Wunder Mobility sends an HTTP POST request to your URL each time an export completes successfully.

Not to be confused with Platform Webhooks: The platform webhooks deliver real-time event notifications (e.g., rental started, invoice created) and use a different payload format, different headers (x-webhook-*), and HMAC-SHA1 signing. Data export webhooks described here follow the Standard Webhooks specification, use webhook-* headers, and sign with HMAC-SHA256.

Webhook Payload

POST https://your-endpoint.example.com/webhook
Content-Type: application/json
{
  "id": 42,
  "queryId": 7,
  "queryName": "Active Vehicles Report",
  "exportUrl": "https://export.gourban.services/.../download?uuid=abc-123-def",
  "expirationDate": "2026-03-01T14:30:00+01:00"
}
Field Type Description
id Number Unique identifier of this export run
queryId Number Identifier of the report query
queryName String Human-readable name of the report
exportUrl String URL to download the CSV file (see Downloading the File)
expirationDate String ISO 8601 timestamp after which the file is no longer available

Downloading the File

The exportUrl in the webhook payload points to the download endpoint. When you make a GET request to this URL, you receive an HTTP 303 redirect to a temporary pre-signed download URL.

GET https://export.gourban.services/.../download?uuid=abc-123-def

303 See Other
Location: https://s3.amazonaws.com/...?X-Amz-Signature=...

Most HTTP clients follow redirects automatically, so a simple GET request will download the CSV file directly.

Two expiration levels apply:

Webhook Headers

Every webhook request includes the following HTTP headers:

Header Example Description
Content-Type application/json Payload format
webhook-id a1b2c3d4-e5f6-... Unique identifier for this export. Stays the same across retries – use this to deduplicate deliveries
x-webhook-dispatch-attempt-count 1 Which delivery attempt this is (starts at 1)

Authentication Headers

If authentication is enabled for your organization, additional headers are included:

Header Example Description
x-api-key f8e7d6c5-b4a3-... Your organization’s API key. Use this to verify the request is coming from Wunder Mobility
webhook-timestamp 1709042400 Unix timestamp (seconds) of when the webhook was sent. Used for signature verification
webhook-signature v1,K7gNU3sdo+OL... HMAC-SHA256 signature of the payload. Used to verify message integrity

Your CSM can provide you with your API key and signing key if you need them.


Verifying Webhook Signatures

If your organization has a signing key configured, you can verify that webhook payloads are authentic and have not been tampered with.

The signature follows the Standard Webhooks specification.

How to Verify

  1. Extract the webhook-id, webhook-timestamp, and webhook-signature headers from the request
  2. Construct the signing content by concatenating:
    {webhook-id}.{webhook-timestamp}.{request-body}
    

    Where {request-body} is the raw JSON body of the request

  3. Compute an HMAC-SHA256 using your Base64-decoded signing key over the signing content
  4. Compare your computed signature with the value after v1, in the webhook-signature header

Example: Python

import hmac
import hashlib
import base64

def verify_webhook(headers, body, signing_key):
    webhook_id = headers["webhook-id"]
    timestamp = headers["webhook-timestamp"]
    signature = headers["webhook-signature"]

    # Construct signing content
    signing_content = f"{webhook_id}.{timestamp}.{body}"

    # Compute expected signature
    key_bytes = base64.b64decode(signing_key)
    expected = hmac.new(
        key_bytes,
        signing_content.encode("utf-8"),
        hashlib.sha256
    ).digest()
    expected_b64 = base64.b64encode(expected).decode("utf-8")

    # Compare with received signature (strip "v1," prefix)
    received_b64 = signature[3:] if signature.startswith("v1,") else signature
    return hmac.compare_digest(expected_b64, received_b64)

Example: Node.js

const crypto = require("crypto");

function verifyWebhook(headers, body, signingKey) {
  const webhookId = headers["webhook-id"];
  const timestamp = headers["webhook-timestamp"];
  const signature = headers["webhook-signature"];

  // Construct signing content
  const signingContent = `${webhookId}.${timestamp}.${body}`;

  // Compute expected signature
  const keyBytes = Buffer.from(signingKey, "base64");
  const expected = crypto
    .createHmac("sha256", keyBytes)
    .update(signingContent)
    .digest("base64");

  // Compare with received signature (strip "v1," prefix)
  const received = signature.replace("v1,", "");
  const expectedBuf = Buffer.from(expected);
  const receivedBuf = Buffer.from(received);
  if (expectedBuf.length !== receivedBuf.length) {
    return false;
  }
  return crypto.timingSafeEqual(expectedBuf, receivedBuf);
}

Retry Behavior

If your endpoint is unreachable (network error or timeout), delivery is retried up to 3 times with increasing delays:

Attempt Delay
1st (initial) Immediate
2nd (retry) ~10 seconds
3rd (retry) ~20 seconds
4th (retry) ~40 seconds

The webhook-id header stays the same across all retry attempts, so you can use it to detect and ignore duplicate deliveries.

Note: If your endpoint returns an error response (e.g., HTTP 4xx or 5xx), the delivery is marked as failed and is not retried. Make sure your endpoint returns a 2xx status code to acknowledge successful receipt.


Webhook Endpoint Requirements

Your webhook endpoint should:


File Expiration

Export files are available for a limited time after generation. The retention period depends on how your export is configured:

Retention Period Duration
1 day 24 hours
1 week 7 days
2 weeks 14 days
1 month 30 days
Default 31 days

After the retention period, the file is permanently deleted and the exportUrl will no longer work. The expirationDate field in the webhook payload tells you exactly when this happens.

Note: Each time you call the exportUrl, it generates a pre-signed download URL that is valid for 7 days. If a pre-signed URL expires, you can simply call the exportUrl again to get a new one — as long as the file has not yet reached its expirationDate.


Notifications Summary

  Email Webhook
Triggered on Export completed successfully Export completed successfully
Contains Download link JSON payload with download URL, report name, and expiration date
Authentication N/A Optional API key and HMAC signature
Retries Up to 4 total attempts Up to 4 total attempts
Failure notification Not sent if export fails Not sent if export fails

Getting Started

To configure data exports for your organization:

  1. Contact your CSM to discuss which reports you need and how often
  2. Provide your notification preferences – email addresses and/or a webhook URL
  3. If using webhooks, share your endpoint URL and request your API key and signing key for secure verification
  4. Test the integration – your CSM can trigger a test export to verify everything works end-to-end

For questions or changes to your export configuration, reach out to your Customer Success Manager.


Reference