Wunderprop API Documentation

Integrate Wunderprop's powerful real estate platform into your applications. Manage partners, submit property leads, and automate your real estate workflows.

Always Test in Sandbox First!

Before using the production API, always test your integration in our sandbox environment. The sandbox mirrors the production API but does NOT persist any data, allowing you to safely validate requests, test error handling, and debug your integration. Switch to the production endpoint only after all problems have been resolved.

  • Fast & ReliableBuilt on modern REST principles with comprehensive rate limiting
  • Secure by DefaultAPI key authentication with fine-grained access control
  • Easy IntegrationSimple REST API with JSON responses and comprehensive examples

Getting Started

Introduction

The Wunderprop API enables developers to integrate real estate partner management and property lead submission into their applications. The API uses REST principles with JSON request and response bodies.

Base URLs

Sandbox (recommended):
https://wunderprop.io/api/sandbox/v1
Production:
https://wunderprop.io/api/public/v1
Local Dev (Sandbox):
http://localhost:5000/api/sandbox/v1
Local Dev (Prod):
http://localhost:5000/api/public/v1

What You Can Build

  • Automated partner invitation systems
  • Property lead submission from external websites
  • CRM integrations for real estate workflows
  • Custom dashboards and reporting tools
  • Mobile applications for property management

Rate Limiting

API requests are subject to internal email and request rate limits. Contact support if you need higher rate limits for your application.

Note: Excessive requests may result in temporary API key suspension.

Sandbox

Sandbox Environment

The sandbox environment is a safe testing ground that mirrors the production API but does NOT persist any data to the database. Use it to develop and debug your integration without affecting live data.

✓ What Sandbox Does

  • Validates all request payloads and schemas
  • Returns realistic mock responses
  • Tests authentication and error handling
  • Logs requests for debugging (visible in console)
  • Accepts test API keys (starting with wp_sandbox_ or wp_test_)

✗ What Sandbox Does NOT Do

  • Does NOT save data to the database
  • Does NOT send actual emails (e.g., partner invitations)
  • Does NOT create real partner or lead records
  • Does NOT affect production data or workflows

Sandbox API Endpoint

https://wunderprop.io/api/sandbox/v1

Sandbox Authentication

The sandbox accepts any API key that starts with wp_sandbox_ or wp_test_. You don't need a real API key to test in sandbox.

Example Sandbox API Keys (all valid)
wp_sandbox_test123
wp_sandbox_myapp_dev
wp_test_integration
wp_test_local

Tip: Use descriptive sandbox API keys to identify different test scenarios (e.g., wp_sandbox_local_dev, wp_test_ci_pipeline)

Quick Start: Testing in Sandbox

  1. Test Health Endpoint

    curl https://wunderprop.io/api/sandbox/v1/health
  2. Test Authenticated Endpoint

    curl https://wunderprop.io/api/sandbox/v1/industry-types \
      -H "X-API-Key: wp_sandbox_test123"
  3. Test Lead Creation

    curl -X POST https://wunderprop.io/api/sandbox/v1/leads \
      -H "Content-Type: application/json" \
      -H "X-API-Key: wp_sandbox_test123" \
      -d '{
        "sellerName": "Test Seller",
        "propertyType": "haus",
        "propertyAddress": "Test St 1, Hamburg"
      }'

    Expected: Success response with sandbox: true flag

  4. Verify All Features Work

    Test all endpoints you plan to use, verify error handling, and ensure your integration works correctly.

  5. Switch to Production

    Once everything works in sandbox, change the base URL to https://wunderprop.io/api/public/v1 and use your real API key.

Sandbox Response Format

Sandbox responses include additional fields to help you identify test data:

Sandbox Lead Creation Response
{
  "id": 12345,
  "sandbox": true,
  "message": "Lead validated successfully. In production, this would be saved to the database.",
  "lead": {
    "sellerName": "Test Seller",
    "propertyType": "haus",
    "propertyAddress": "Test St 1, Hamburg",
    "id": 12345,
    "status": "neu",
    "source": "public_api_sandbox",
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}
Production Lead Creation Response (for comparison)
{
  "id": 789
}

Notice the sandbox: true flag and additional debugging information in sandbox responses.

Authentication

API Key Authentication

All API requests require authentication using an API key. Include your API key in the X-API-Key header of each request.

Obtaining Your API Key

  1. Log in to your Wunderprop admin account
  2. Navigate to Settings → Integrations
  3. Click "Generate API Key" in the Public API section
  4. Copy and securely store your API key (starts with wp_)
Example Request Header
curl https://wunderprop.io/api/public/v1/industry-types \
  -H "X-API-Key: wp_your_api_key_here"

Security: Never share your API key or commit it to version control. Store it securely in environment variables.

Managing API Keys

Rotating Your Key

You can rotate your API key at any time through the admin dashboard. The old key will be immediately invalidated.

Checking API Key Status

GET /api/admin/public-api/key
// Response
{
  "apiKeyMasked": "wp_***...***abc",
  "isEnabled": true
}

Public API

Health Check

Verify API availability

GET/health

✓ No authentication required

Check if the API is operational. This endpoint is public and does not require an API key.

Response 200
{
  "ok": true
}

Get Industry Types

Retrieve available industry/service types

GET/industry-types

🔒 Requires authentication

Response 200
[
  {
    "id": 1,
    "name": "Immobilienmakler"
  },
  {
    "id": 2,
    "name": "Fotograf"
  },
  {
    "id": 3,
    "name": "Gutachter"
  }
]

Invite Partner

Send a magic-link invitation to a partner

POST/partners/invite

🔒 Requires authentication

Sends a magic-link invitation email to a partner. Creates a curated partner record with status "invited" if not already existing.

Request Body
{
  "email": "partner@example.com",
  "companyName": "Muster GmbH",
  "firstName": "Max",
  "lastName": "Mustermann",
  "service": "Immobilienmakler",
  "phone": "+49 123 456789",
  "city": "Hamburg"
}
Response 200
{
  "success": true
}

Required Fields

  • email - Valid email address
  • companyName - Company name

Optional Fields

  • firstName - Contact first name
  • lastName - Contact last name
  • service - Industry type/service
  • phone - Contact phone number
  • city - Location city

Submit Lead

Create a property tip (lead)

POST/leads

🔒 Requires authentication

Create a property tip (lead) associated with your account. Leads are immediately available in your dashboard.

Request Body
{
  "sellerName": "Erika Musterfrau",
  "sellerPhone": "+49 987 654321",
  "sellerEmail": "erika@example.com",
  "propertyType": "haus",
  "propertyAddress": "Beispielstraße 1, 20095 Hamburg",
  "estimatedPrice": 350000,
  "description": "Renovierungsbedürftig",
  "marketingType": "verkauf"
}
Response 201
{
  "id": 42
}

Required Fields

  • sellerName - Property seller name
  • propertyType - Type (e.g., "haus", "wohnung") - uses German terms
  • propertyAddress - Full address

Optional Fields

  • sellerPhone - Seller phone number
  • sellerEmail - Seller email
  • estimatedPrice - Estimated price in EUR
  • description - Additional notes
  • marketingType - "verkauf" (sale) or "vermietung" (rental)

Note: Property types and marketing types use German terms as this is a German real estate platform. Common types: "haus" (house), "wohnung" (apartment), "grundstück" (land).

Makler API

Makler API Overview

APIs for real estate agents (Makler) to manage properties, partners, and leads

The Makler API provides endpoints for real estate agents to manage their business operations, including property searches, partner relationships, property tips (leads), and integrations.

🔒 All Makler endpoints require user authentication with makler role

Properties

Search and manage properties from ImmoScout24

GET/api/properties

Get list of properties matching your search criteria. Supports pagination and filtering.

Example Response
[
  {
    "id": 123,
    "title": "Schöne 3-Zimmer Wohnung",
    "address": "Hamburg, Eimsbüttel",
    "price": 450000,
    "rooms": 3,
    "livingSpace": 85,
    "propertyType": "wohnung"
  }
]

GET/api/properties/:id

Get detailed information about a specific property.

PATCH/api/properties/:id/prospect

Mark a property as a prospect for follow-up.

Search Criteria

Manage automated property search criteria

GET/api/search-criteria

List all saved search criteria.

POST/api/search-criteria

Create a new search criteria for automated property matching.

Request Body
{
  "name": "Hamburg Apartments",
  "city": "Hamburg",
  "minPrice": 200000,
  "maxPrice": 500000,
  "propertyType": "wohnung",
  "minRooms": 2,
  "isActive": true
}

PATCH/api/search-criteria/:id

Update an existing search criteria.

DELETE/api/search-criteria/:id

Delete a search criteria.

Favorites

Manage favorite properties

GET/api/favorites

Get all favorited properties.

POST/api/favorites/:propertyId

Add a property to favorites.

DELETE/api/favorites/:propertyId

Remove a property from favorites.

Partner Management

Access and invite curated partners

GET/api/makler/curated-partners

Browse available partner companies. Supports filtering by city, industry type, and status.

Query Parameters
?city=Hamburg&industryType=Fotograf&status=active

GET/api/makler/curated-partners/cities

Get list of cities where partners are available.

POST/api/makler/curated-partners/:id/invite

Send invitation email to a curated partner.

Property Tips (Leads)

Manage property leads and tips

GET/api/makler/property-tips

Get all property tips/leads submitted to you.

POST/api/makler/property-tips

Create a new property tip/lead.

Request Body
{
  "sellerName": "Max Mustermann",
  "sellerEmail": "max@example.com",
  "sellerPhone": "+49 123 456789",
  "propertyType": "haus",
  "propertyAddress": "Hauptstraße 1, 20095 Hamburg",
  "description": "Family house for sale"
}

PATCH/api/makler/property-tips/:tipId

Update status or add notes to a property tip.

GET/api/makler/property-tips/:tipId/history

Get history of changes for a specific property tip.

Integrations & Export

Connect with external systems like Propstack

POST/api/propstack/export

Export properties to Propstack CRM system.

Request Body
{
  "propertyIds": [123, 456, 789],
  "pipeline": "sales"
}

GET/api/exports

Get history of exports to external systems.

Partner API

Partner API Overview

APIs for service partners (photographers, appraisers, etc.)

The Partner API enables service partners to manage their profile, property tips, commissions, marketplace listings, and communication with real estate agents.

🔒 All Partner endpoints require user authentication with partner role

Partner Profile

Manage partner company profile and information

GET/api/partner/current

Get current partner company information.

Example Response
{
  "id": 42,
  "companyName": "Foto Plus GmbH",
  "industryType": "Fotograf",
  "city": "Hamburg",
  "contactPerson": "Max Mustermann",
  "email": "max@fotoplus.de",
  "phone": "+49 123 456789",
  "website": "https://fotoplus.de",
  "status": "active"
}

GET/api/partner/profile

Get detailed partner profile.

PUT/api/partner/profile

Update partner profile information.

Request Body
{
  "contactPerson": "Max Mustermann",
  "phone": "+49 123 456789",
  "website": "https://fotoplus.de",
  "description": "Professional real estate photography"
}

GET/api/partner/stats

Get partner statistics (tips received, commissions earned, etc.).

Property Tips (Partner View)

Manage property tips received from agents

GET/api/partner/property-tips

Get all property tips assigned to this partner.

POST/api/partner/property-tips

Submit a new property tip to the pool.

PATCH/api/partner/property-tips/:tipId

Update a property tip (add notes, change status).

Request Body
{
  "status": "in_bearbeitung",
  "partnerNotes": "Contacted seller, scheduled visit"
}

GET/api/partner/property-tips/:tipId/history

View history of changes for a property tip.

Commissions

Track commission payments and earnings

GET/api/partner/commissions

Get all commission records for completed deals.

Example Response
[
  {
    "id": 1,
    "tipId": 123,
    "amount": 1500.00,
    "currency": "EUR",
    "status": "paid",
    "paidAt": "2024-01-15T10:00:00Z",
    "propertyAddress": "Hauptstraße 1, Hamburg"
  }
]

Marketplace Listings

Manage service offerings in the marketplace

GET/api/marketplace/partner/listings

Get all marketplace listings for this partner.

POST/api/marketplace/partner/listings

Create a new marketplace listing.

Request Body
{
  "serviceId": 5,
  "title": "Professional Property Photography",
  "description": "High-quality photos for real estate listings",
  "basePrice": 299.00,
  "currency": "EUR",
  "turnaroundDays": 2
}

PUT/api/marketplace/partner/listings/:id

Update an existing marketplace listing.

DELETE/api/marketplace/partner/listings/:id

Delete a marketplace listing.

GET/api/marketplace/partner/orders

Get all orders received from agents.

PATCH/api/marketplace/partner/orders/:itemId/status

Update order status (e.g., mark as completed).

Request Body
{
  "status": "completed",
  "notes": "Photos delivered via email"
}

Messages

Communicate with real estate agents

GET/api/partner/messages

Get all messages from agents.

POST/api/partner/messages

Send a message to an agent.

Request Body
{
  "recipientUserId": 42,
  "subject": "Property tip follow-up",
  "message": "I have completed the property visit..."
}

Search Criteria

Set up automated property notifications

GET/api/partner-criteria

Get all saved search criteria for property notifications.

POST/api/partner-criteria

Create a new search criteria for property notifications.

Request Body
{
  "name": "Hamburg properties",
  "cities": ["Hamburg"],
  "propertyTypes": ["haus", "wohnung"],
  "isActive": true
}

PUT/api/partner-criteria/:id

Update a search criteria.

DELETE/api/partner-criteria/:id

Delete a search criteria.

Examples

Development Workflow: Sandbox to Production

// Step 1: Start with sandbox for development and testing
const SANDBOX_BASE = 'https://wunderprop.io/api/sandbox/v1';
const SANDBOX_KEY = 'wp_sandbox_test123'; // Any key starting with wp_sandbox_ or wp_test_

// Step 2: Test your integration in sandbox
async function testInSandbox() {
  const response = await fetch(`${SANDBOX_BASE}/leads`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': SANDBOX_KEY
    },
    body: JSON.stringify({
      sellerName: 'Test Seller',
      propertyType: 'haus',
      propertyAddress: 'Test Street 1, Hamburg'
    })
  });
  
  const result = await response.json();
  console.log('Sandbox test:', result);
  // Output includes: { sandbox: true, message: "...", ... }
}

// Step 3: Once testing is complete, switch to production
const PROD_BASE = 'https://wunderprop.io/api/public/v1';
const PROD_KEY = process.env.WUNDERPROP_API_KEY; // Real API key from admin dashboard

async function createLead(leadData) {
  const response = await fetch(`${PROD_BASE}/leads`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': PROD_KEY
    },
    body: JSON.stringify(leadData)
  });
  
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`API Error: ${error.error}`);
  }
  
  return await response.json();
}

JavaScript / Node.js Example

// Using fetch API with environment-based configuration
const IS_PRODUCTION = process.env.NODE_ENV === 'production';
const API_BASE = IS_PRODUCTION 
  ? 'https://wunderprop.io/api/public/v1'
  : 'https://wunderprop.io/api/sandbox/v1';
const API_KEY = IS_PRODUCTION
  ? process.env.WUNDERPROP_API_KEY
  : 'wp_sandbox_local_dev';

async function invitePartner(partnerData) {
  const response = await fetch(`${API_BASE}/partners/invite`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': API_KEY
    },
    body: JSON.stringify(partnerData)
  });
  
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`API Error: ${error.error}`);
  }
  
  return await response.json();
}

// Usage
const partner = {
  email: 'max@example.com',
  companyName: 'Max Immobilien GmbH',
  firstName: 'Max',
  lastName: 'Mustermann',
  service: 'Immobilienmakler',
  phone: '+49 123 456789',
  city: 'Hamburg'
};

try {
  const result = await invitePartner(partner);
  if (result.sandbox) {
    console.log('✓ Sandbox test successful:', result.message);
  } else {
    console.log('Partner invited successfully');
  }
} catch (error) {
  console.error('Error:', error.message);
}

Python Example

import os
import requests

# Use sandbox for testing, production for live
IS_PRODUCTION = os.environ.get('ENV') == 'production'
API_BASE = (
    'https://wunderprop.io/api/public/v1' if IS_PRODUCTION 
    else 'https://wunderprop.io/api/sandbox/v1'
)
API_KEY = (
    os.environ.get('WUNDERPROP_API_KEY') if IS_PRODUCTION
    else 'wp_sandbox_python_test'
)

def submit_lead(lead_data):
    """Submit a property lead"""
    headers = {
        'Content-Type': 'application/json',
        'X-API-Key': API_KEY
    }
    
    response = requests.post(
        f'{API_BASE}/leads',
        json=lead_data,
        headers=headers
    )
    
    response.raise_for_status()
    result = response.json()
    
    if result.get('sandbox'):
        print(f"✓ Sandbox test: {result.get('message')}")
    
    return result

# Usage
lead = {
    'sellerName': 'Erika Musterfrau',
    'sellerPhone': '+49 987 654321',
    'sellerEmail': 'erika@example.com',
    'propertyType': 'haus',
    'propertyAddress': 'Beispielstraße 1, 20095 Hamburg',
    'estimatedPrice': 350000,
    'description': 'Renovierungsbedürftig'
}

try:
    result = submit_lead(lead)
    print(f"Lead created with ID: {result['id']}")
except requests.exceptions.RequestException as e:
    print(f"Error: {e}")

Use Case: Automated Property Monitoring System

Build a system that monitors new properties and alerts users

// Authenticated Makler API - Build automated property monitoring
const API_BASE = 'https://wunderprop.io/api';
const authToken = 'your-session-token'; // From login

// Complete workflow: Monitor properties and manage favorites
async function automatedPropertyMonitoring() {
  // Step 1: Create search criteria
  const criteria = await fetch(`${API_BASE}/search-criteria`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Cookie': `session=${authToken}`
    },
    body: JSON.stringify({
      name: "Hamburg Waterfront Properties",
      city: "Hamburg",
      minPrice: 500000,
      maxPrice: 1500000,
      propertyType: "wohnung",
      minRooms: 3,
      isActive: true
    })
  }).then(r => r.json());
  
  // Step 2: Get matching properties
  const properties = await fetch(`${API_BASE}/properties`, {
    headers: { 'Cookie': `session=${authToken}` }
  }).then(r => r.json());
  
  // Step 3: Process each property
  for (const property of properties) {
    if (property.price < 800000 && property.rooms >= 3) {
      // Add to favorites
      await fetch(`${API_BASE}/favorites/${property.id}`, {
        method: 'POST',
        headers: { 'Cookie': `session=${authToken}` }
      });
      
      // Mark as prospect
      await fetch(`${API_BASE}/properties/${property.id}/prospect`, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
          'Cookie': `session=${authToken}`
        },
        body: JSON.stringify({ isProspect: true })
      });
    }
  }
}

Use Case: Partner Service Management Platform

Build a partner dashboard to manage services and orders

// Partner API - Complete service management workflow
const API_BASE = 'https://wunderprop.io/api';
const sessionToken = 'partner-session-token';

async function managePartnerBusiness() {
  // Get dashboard overview
  const [profile, stats, tips, orders] = await Promise.all([
    fetch(`${API_BASE}/partner/current`, {
      headers: { 'Cookie': `session=${sessionToken}` }
    }).then(r => r.json()),
    fetch(`${API_BASE}/partner/stats`, {
      headers: { 'Cookie': `session=${sessionToken}` }
    }).then(r => r.json()),
    fetch(`${API_BASE}/partner/property-tips`, {
      headers: { 'Cookie': `session=${sessionToken}` }
    }).then(r => r.json()),
    fetch(`${API_BASE}/marketplace/partner/orders`, {
      headers: { 'Cookie': `session=${sessionToken}` }
    }).then(r => r.json())
  ]);
  
  console.log(`Partner: ${profile.companyName}`);
  console.log(`Open tips: ${tips.length}`);
  console.log(`Pending orders: ${orders.filter(o => o.status === 'pending').length}`);
  
  // Create marketplace listing
  const listing = await fetch(`${API_BASE}/marketplace/partner/listings`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Cookie': `session=${sessionToken}`
    },
    body: JSON.stringify({
      serviceId: 3,
      title: "Premium Photography Package",
      description: "Professional photos + 3D tour",
      basePrice: 499.00,
      currency: "EUR",
      turnaroundDays: 3
    })
  }).then(r => r.json());
  
  // Process orders
  for (const order of orders.filter(o => o.status === 'pending')) {
    await fetch(`${API_BASE}/marketplace/partner/orders/${order.id}/status`, {
      method: 'PATCH',
      headers: {
        'Content-Type': 'application/json',
        'Cookie': `session=${sessionToken}`
      },
      body: JSON.stringify({
        status: 'in_progress',
        notes: 'Started working on order'
      })
    });
  }
}

cURL Examples

Health Check (Sandbox)

curl https://wunderprop.io/api/sandbox/v1/health

Invite Partner (Sandbox)

curl -X POST https://wunderprop.io/api/sandbox/v1/partners/invite \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wp_sandbox_test123" \
  -d '{
    "email": "partner@example.com",
    "companyName": "Muster GmbH",
    "firstName": "Max",
    "service": "Immobilienmakler"
  }'

Submit Lead (Sandbox)

curl -X POST https://wunderprop.io/api/sandbox/v1/leads \
  -H "Content-Type: application/json" \
  -H "X-API-Key: wp_sandbox_test123" \
  -d '{
    "sellerName": "Erika Musterfrau",
    "propertyType": "haus",
    "propertyAddress": "Beispielstraße 1, 20095 Hamburg",
    "estimatedPrice": 350000
  }'

Switching to Production

Once your sandbox tests pass, simply change:

  • /api/sandbox/v1 → /api/public/v1
  • wp_sandbox_* → Your real API key from admin dashboard

Errors

Error Responses

The API uses standard HTTP status codes to indicate success or failure. Error responses include a JSON body with details.

400Bad Request

Invalid or missing request parameters.

{
  "error": "Invalid payload",
  "details": {
    "email": ["Invalid email address"],
    "companyName": ["Required field"]
  }
}

401Unauthorized

Missing or invalid API key.

{
  "error": "Missing API key"
}

// or

{
  "error": "Invalid API key"
}

429Too Many Requests

Rate limit exceeded. Retry after a brief delay.

{
  "error": "Rate limit exceeded"
}

500Internal Server Error

An unexpected error occurred. Contact support if this persists.

{
  "error": "Internal server error"
}

Best Practices

  • Always test in sandbox first before using the production API to avoid data corruption and ensure your integration works correctly
  • Always handle errors gracefully and implement retry logic with exponential backoff
  • Store API keys securely in environment variables, never in code
  • Use different API keys for sandbox testing and production environments
  • Validate input data before sending to the API to reduce errors
  • Monitor your API usage and set up alerts for failures
  • Use HTTPS for all requests in production environments
  • Check for the sandbox: true flag in responses to distinguish test data

Ready to Get Started?

Create your account and start building with the Wunderprop API today.

Get Your API Key