Visuals Ready Event Scenarios

Overview


The VISUALS_READY event is triggered when materials (visuals, documents, or other deliverables) are ready for download. The exact trigger logic depends on the product kind and workflow scenario. For a full description of the event and its payload, see Webhook System Documentation.

Visuals Ready Event Flow

Scenario Table

ScenarioVisuals TakingEditingNo SelectionVisual SelectionTriggerDescription
AYes/NoYesNoNoThe edited visuals are uploaded and available for the client.The event is sent when the edited visuals are ready. The edited visuals don't need a selection.
BYes/NoYes/NoYes/NoYesThe visual selection is done and confirmed.The event is sent when the final visual selection is done.

Product Kinds by Scenario

Scenario A (After Editing)ConditionsScenario B (After Selection)Conditions
Self-edited photosTo be implementedGround PhotoMore visuals and client has to choose them.
Visual exportTo be implementedGround Photo PrestigeMore visuals and client has to choose them.
Ground PhotoLess or exact amount of visuals.Drone PhotoMore visuals and client has to choose them.
Ground Photo PrestigeLess or exact amount of visuals.Mast PhotoMore visuals and client has to choose them.
Drone PhotoLess or exact amount of visuals.Photo (Standard Editing)More visuals and client has to choose them.
Mast PhotoLess or exact amount of visuals.
Photo (Standard Editing)Less or exact amount of visuals.
Standard Ground VideoVIDEOS
Standard Drone Video
Standard Ground And Drone Video
Prestige Ground And Drone Video
Reel Video
Teaser Video
Slideshow
Matterport Floorplan With VisitFLOORPLANS
Floorplan Editing 2D
Floorplan Editing 3D
Mobile Application Floorplan
Floorplan Rendering 3D
Matterport SD (Virtual Visit)MATTERPORT
Matterport HD (Virtual Visit)
Matterport Photo
On-site Area Report
Residential StagingSTAGING
Commercial Staging

Documents and Special Cases

Product KindSpecial Trigger Condition
Authorities DocumentsOn DocEstate delivery to BKBN VISUALS_READY is triggered without client acceptance (instant)
Energy CertificateOn FINAL delivery (i.e. NOT PREVIEW or PENDING APPROVAL) after the client has accepted in the gallery, VISUALS_READY is triggered (couple mins delay)
Floorplan CertificationAfter client accepts the document in the gallery, VISUALS_READY is triggered (instant)
AI Photo EditingAfter client accepts the visuals in the gallery, VISUALS_READY is triggered (Instant)
AI Text GeneratorNot yet implemented for VISUALS_READY
Upsell in galleryAs soon as a visual is bought as an upsell in the gallery, VISUALS_READY is triggered.

For the full event payload, integration examples, and error handling, see Webhook System Documentation.

Materials API Documentation

Overview

The Materials API allows clients to request and retrieve materials (media files, documents, or result URLs) that have been delivered for specific orders and assignments. This endpoint is typically called after receiving a VISUALS_READY webhook event, which indicates that materials are available for download.

API Endpoint

Request Materials

GET /materials/{orderId}/{assignmentId}

Requests materials for a specific order and assignment combination.

Path Parameters

ParameterTypeRequiredDescriptionExample
orderIdstringYesUnique identifier of the order12345
assignmentIdstringYesUnique identifier of the assignment within the order12345-A

Query Parameters

ParameterTypeRequiredDescriptionExample
productRequestProductKindYesType of output/deliverable to requestGROUND_PHOTO
visualTypeRequestResourceTypeNoType of visual/resource to request (defaults to POST)POST

Authentication

All requests require JWT authentication. Include your token in the Authorization header:

Authorization: Bearer <your-jwt-token>

Example Request

GET /materials/12345/12345-A?product=GROUND_PHOTO&visualType=POST
Authorization: Bearer <your-jwt-token>

Response

Success (200 OK):

{
  "orderId": "12345",
  "assignmentId": "12345-A",
  "orderType": "PHOTO",
  "mediaFiles": [
    {
      "mediaType": "PHOTO",
      "downloadUrl": "https://storage.example.com/photos/photo1.jpg",
      "originalFileName": "property_front_view.jpg"
    },
    {
      "mediaType": "PHOTO", 
      "downloadUrl": "https://storage.example.com/photos/photo2.jpg",
      "originalFileName": "property_back_view.jpg"
    }
  ],
  "resultUrls": []
}

Error Responses:

  • 400 Bad Request: Invalid request parameters (e.g., incompatible visualType for product)
  • 401 Unauthorized: Authentication required
  • 403 Forbidden: Access denied to this resource
  • 404 Not Found: Order, assignment, or materials not found

Product Types (RequestProductKind)

The product parameter specifies what type of output/deliverable you want to retrieve:

Photography & Media

  • GROUND_PHOTO - Standard ground-level photographs
  • GROUND_PHOTO_PRESTIGE - Premium ground-level photographs with enhanced processing
  • DRONE_PHOTO - Aerial photographs taken by drones
  • DRONE_VIDEO - Aerial video content captured by drones

Virtual Experiences

  • PHOTO360 - 360-degree panoramic photographs
  • MATTERPORT - Professional 3D virtual tour files

Staging & Rendering

  • RESIDENTIAL_STAGING - Virtually staged residential property images
  • COMMERCIAL_STAGING - Virtually staged commercial property images
  • RESIDENTIAL_RENDERING - 3D rendered residential property visualizations
  • COMMERCIAL_RENDERING - 3D rendered commercial property visualizations

Documentation Services

  • MEASUREMENT_ON_SITE - On-site measurement reports and documentation
  • FLOOR_PLAN - Technical floor plan drawings and documents
  • FLOOR_PLAN_CERTIFICATION - Certified and official floor plan documents
  • ENERGY_CERTIFICATE - Energy efficiency certification documents
  • AUTHORITIES_DOCUMENTS - Official documents from local authorities

Visual Types (RequestResourceType)

The visualType parameter specifies the type of visual/resource to request:

ValueDescriptionUsage
POSTStandard post-processing visualsDefault for most products
POST_WEBWeb-optimized post-processing visualsFor web display
DOCUMENTDocument filesRequired for document-based products
RAWRaw, unprocessed filesFor original, unedited content

Note: For document-based products (FLOOR_PLAN, ENERGY_CERTIFICATE, etc.), visualType should be set to DOCUMENT or omitted.

Response Structure

MaterialsDeliveryDTO

FieldTypeDescription
orderIdstringThe order identifier
assignmentIdstringThe assignment identifier
orderTypeOrderTypeThe type of order (mapped from product)
mediaFilesMediaFileResultDTO[]Array of downloadable media files
resultUrlsLinkResultDTO[]Array of result URLs (for virtual tours, etc.)

MediaFileResultDTO

FieldTypeDescription
mediaTypeMediaFileTypeType of media (PHOTO, VIDEO, DOCUMENT)
downloadUrlstringDirect download URL for the file
originalFileNamestringOriginal filename of the media

LinkResultDTO

FieldTypeDescription
titlestringTitle/name of the result
linkUrlstringURL to access the result

MediaFileType

  • PHOTO - Image files (JPG, PNG, etc.)
  • VIDEO - Video files (MP4, MOV, etc.)
  • DOCUMENT - Document files (PDF, etc.)

Usage Workflow

1. Receive Webhook Notification

When materials are ready, you'll receive a VISUALS_READY webhook event:

{
  "event": "VISUALS_READY",
  "timestamp": "2023-01-15T12:45:00Z",
  "orderId": "12345",
  "assignmentId": "12345-A",
  "visualType": "POST",
  "product": "GROUND_PHOTO",
  "realEstatePropertyId": "RE-123"
}

2. Request Materials

Use the webhook payload to request the materials:

GET /materials/12345/12345-A?product=GROUND_PHOTO&visualType=POST

3. Process the Response

Download the media files or access the result URLs as needed for your application.

Integration Examples

JavaScript/Node.js

async function handleVisualsReadyWebhook(webhookPayload) {
  const { orderId, assignmentId, product, visualType } = webhookPayload;
  
  // Request materials
  const response = await fetch(
    `/materials/${orderId}/${assignmentId}?product=${product}&visualType=${visualType || 'POST'}`,
    {
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      }
    }
  );
  
  if (response.ok) {
    const materials = await response.json();
    
    // Process media files
    for (const mediaFile of materials.mediaFiles) {
      console.log(`Downloading: ${mediaFile.originalFileName}`);
      // Download and process the file
    }
    
    // Process result URLs
    for (const resultUrl of materials.resultUrls) {
      console.log(`Accessing: ${resultUrl.title} at ${resultUrl.linkUrl}`);
    }
  }
}

Python

import requests

def handle_visuals_ready_webhook(webhook_payload):
    order_id = webhook_payload['orderId']
    assignment_id = webhook_payload['assignmentId']
    product = webhook_payload['product']
    visual_type = webhook_payload.get('visualType', 'POST')
    
    # Request materials
    response = requests.get(
        f'/materials/{order_id}/{assignment_id}',
        params={
            'product': product,
            'visualType': visual_type
        },
        headers={
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }
    )
    
    if response.status_code == 200:
        materials = response.json()
        
        # Process media files
        for media_file in materials['mediaFiles']:
            print(f"Downloading: {media_file['originalFileName']}")
            # Download and process the file
            
        # Process result URLs
        for result_url in materials['resultUrls']:
            print(f"Accessing: {result_url['title']} at {result_url['linkUrl']}")

PHP

<?php
function handleVisualsReadyWebhook($webhookPayload) {
    $orderId = $webhookPayload['orderId'];
    $assignmentId = $webhookPayload['assignmentId'];
    $product = $webhookPayload['product'];
    $visualType = $webhookPayload['visualType'] ?? 'POST';
    
    // Request materials
    $url = "/materials/{$orderId}/{$assignmentId}?product={$product}&visualType={$visualType}";
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Authorization: Bearer {$token}",
        "Content-Type: application/json"
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode === 200) {
        $materials = json_decode($response, true);
        
        // Process media files
        foreach ($materials['mediaFiles'] as $mediaFile) {
            echo "Downloading: " . $mediaFile['originalFileName'] . "\n";
            // Download and process the file
        }
        
        // Process result URLs
        foreach ($materials['resultUrls'] as $resultUrl) {
            echo "Accessing: " . $resultUrl['title'] . " at " . $resultUrl['linkUrl'] . "\n";
        }
    }
}
?>

Error Handling

Common Error Scenarios

  1. 404 Not Found

    • Order or assignment doesn't exist
    • Materials haven't been delivered yet
    • Check if you received the VISUALS_READY webhook first
  2. 400 Bad Request

    • Invalid product type
    • Incompatible visualType for the product
    • Missing required parameters
  3. 401 Unauthorized

    • Invalid or expired JWT token
    • Missing Authorization header
  4. 403 Forbidden

    • No access to the specified order/assignment
    • Check your permissions

Retry Strategy

  • 404 errors: Don't retry immediately - wait for the VISUALS_READY webhook
  • 400 errors: Don't retry - fix the request parameters
  • 401/403 errors: Refresh your authentication token
  • 5xx errors: Retry with exponential backoff

Security Considerations

  1. Authentication: Always use JWT tokens for authentication
  2. HTTPS: Use HTTPS for all API calls in production
  3. Token Management: Store and rotate JWT tokens securely
  4. URL Validation: Validate download URLs before accessing them
  5. File Downloads: Implement proper file download security measures

Rate Limiting

The API implements rate limiting to ensure fair usage. If you exceed the rate limits, you'll receive a 429 Too Many Requests response. Implement exponential backoff for retries.

Testing

You can test the materials API using:

  1. Postman/Insomnia: Import the API specification
  2. cURL: Use command-line examples
  3. Integration Testing: Set up test orders and assignments

Support

For issues with the Materials API:

  1. Check the webhook trigger history for delivery status
  2. Verify your authentication and permissions
  3. Review the error response details
  4. Contact support with order/assignment IDs and error details