Media Bridge API - Quickstart

The REcolorado Media Bridge api allows you to prepare a collection of photos and virtual tours that a listing owner may review and publish to their listing.
Already have a handle on the basics? Visit our Swagger page for an overview of all operations.

1. Authenticate

The Media Bridge API supports Bearer Token authentication, where your API key is provided with each request.
Your API key can be generated by logging in to Media Bridge and visiting the My Account page.

A natural first call is to get a list of all your media packages:

Example code:

# 1. Authenticate
session = requests.Session()
session.headers.update({'Authorization': f'Bearer <API_KEY>'})

r = session.get(url='https://test.mediabridge.recolorado.com/api/v1/MediaPackages')
print(r.json())
# 1. Authenticate
AUTH="Authorization: Bearer <API_KEY>"
API="https://test.mediabridge.recolorado.com"

curl -X GET -H "$AUTH" "$API/api/v1/MediaPackages"
// 1. Authenticate        
using (var client = new HttpClient(handler))
{
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<API_KEY>");

    var response = await client.GetAsync("https://test.mediabridge.recolorado.com/api/v1/MediaPackages");
    var result = await response.Content.ReadAsStringAsync();
    Console.WriteLine(result);
// 1. Authenticate
const headers = {
    'Authorization': 'Bearer <API_KEY>',
    'Content-Type': 'application/json'
}

fetch('https://test.mediabridge.recolorado.com/api/v1/MediaPackages', {
    method: 'GET',
    headers: headers
}).then(res => console.log(res.json()));

2. Create a Package

When creating a media package you must identify the agent responsible for publishing the photos to a listing.
The simplest way to do this is by providing ListingId, which will ultimately grant access of the package to the agents who manage the listing.

If the listing does not yet exist, you may instead provide MemberMlsId and ListingAddressHint. In this case, the agent will be responsible for assigning the package to their listing within Media Bridge.

Example code:

# 2. Create a Package
package_id = session.post(
    url='https://test.mediabridge.recolorado.com/api/v1/MediaPackages', 
    data={ 'ListingId': '123456' }
).json()['MediaPackageId']
# 2. Create a Package
RESP=$(curl -X POST  -H "$AUTH" "$API/api/v1/MediaPackages" \
     -d '{"ListingId": "123456"}')
PKGID=$(echo "$RESP" | jq -r '.MediaPackageId')
PKGID="474"
// 2. Create a Package
var packageData = new Dictionary<string, string> { 
    { "ListingId", "123456" }
};

response = await client.PostAsync("https://test.mediabridge.recolorado.com/api/v1/MediaPackages", new FormUrlEncodedContent(packageData));
result = await response.Content.ReadAsStringAsync();
var package_id = JObject.Parse(result)["MediaPackageId"].ToString();
// 2. Create a Package
let packageId;

fetch('https://test.mediabridge.recolorado.com/api/v1/MediaPackages', {
    method: 'POST',
    headers: headers,
    body: JSON.stringify({
        'ListingId': '123456'
    })
}).then(res => res.json())
  .then(json => { packageId = json.MediaPackageId; });

...and an example response:

{
  "MediaPackageId": "8675309",
  "MediaStatus": "Draft",
  "MediaStatusLong": "Draft",
  "PhotoCount": 0,
  "TourCount": 0,
  "MemberMlsId": "ALISUB",
  "MemberFullName": "Allison Broker",
  "MemberEmail": "alison.broker@example.com",
  "ListingAddressHint": null,
  "ListingId": "123456",
  "Listing": {
    "ListingId": "123456",
    "StreetAddress": "330 Carmella Views",
    "CityStateZip": "Denver, CO 80122",
    "FullAddress": "330 Carmella Views Denver, CO 80122",
    "ListOfficeMlsId": "OFFICE1",
    "ListOfficeName": "Example Office One",
    "ListAgentMlsId": "ALISUB",
    "ListAgentFullName": "Allison Broker",
    "ListAgentEmail": "alison.broker@example.com",
    "CoListAgentMlsId": null,
    "CoListAgentFullName": null,
    "CoListAgentEmail": null
  },
  "DisplayStreetAddress": "330 Carmella Views",
  "DisplayCityStateZip": "Denver, CO 80122",
  "IsTerminal": false,
  "IsRetryingPublishAfterError": false,
  "ListingIsLocked": false,
  "CreationTimestamp": "2024-05-17T03:12:20.5273279Z",
  "CreatedByMemberID": "PROVIDER1",
  "CreatorEmail": "provider1@example.com",
  "CreatorName": "ProviderOne",
  "ModificationTimestamp": "2024-05-17T03:12:20.5273279Z",
  "ChangedByMemberID": "PROVIDER1",
  "ChangedByMemberFullName": "ProviderOne",
  "ProposedTimestamp": null,
  "PublishedTimestamp": null,
  "FirstPublishFail": null,
  "LastPublishFail": null,
  "ListingLockedInMatrix": false,
  "CancelPublishTrigger": false,
  "IsUnavailable": false,
  "UnavailableTimestamp": null,
  "UnavailableReason": null,
  "PublishAttemptCount": null,
  "MediaURL": null,
  "DownloadPhotosUrl": null,
  "Tours": null,
  "Photos": null,
  "Warnings": []
}

Top

3. Add Tours

When adding a MediaTour you may provide MediaURL, and optionally specify the Order of the tour. Up to three tours may be published.

Example code:

# 3. Add Tours
session.put(
    url=f'https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/Tours',
    data={ 
        'MediaURL': 'https://www.example.com/tour1', 
        'Order': 0
    }
)
# 3. Add Tours
curl -X PUT -H "$AUTH" "$API/api/v1/MediaPackages($PKGID)/Tours" \
     -d '{"MediaURL": "https://www.example.com/tour1", "Order": 0}'
// 3. Add Tours
var tourData = new Dictionary<string, string>
{
    { "MediaURL", "https://www.example.com/tour1" },
    { "Order", "0" }
};
response = await client.PutAsync($"https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/Tours", new FormUrlEncodedContent(tourData));
// 3. Add Tours
fetch(`https://test.mediabridge.recolorado.com/api/v1/MediaPackages(${packageId})/Tours`, {
    method: 'PUT',
    headers: headers,
    body: JSON.stringify({
        'MediaURL': 'https://www.example.com/tour1',
        'Order': 0
    })
});

...and an example response:

{
  "MediaKey": "4",
  "MediaPackageId": 8675309,
  "MediaURL": "https://www.example.com/tour1",
  "Order": 0,
  "CreationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
  "CreatedByMemberID": "PROVIDER1",
  "ModificationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
  "ChangedByMemberID": "PROVIDER1"
}

Top

4. Add Photos

When adding a MediaPhoto you may provide LongDescription, and optionally specify the Order of the photo.

Note that ultimately photos must be provided in a contiguous sequence, so Order may be adjusted during submissions.
Up to 50 photos may be published, but you may provide up to 80 for the agent to select from.
Providing photos at the MLS maximum resolution of 1600x1200 is recommended.

Example code:

# 4. Add Photos
photo_dir = './example_photos'
for i, photo_file in enumerate(os.listdir(photo_dir)):
    session.put(
        url=f'https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/Photos(Order={i})',
        data={ "LongDescription": f'{photo_file} submitted at {start_time}' },
        files={ "Content": open(os.path.join(photo_dir, photo_file), 'rb') }
    )
# 4. Add Photos
for f in ./example_photos/*; do
  curl -X POST -H "$AUTH" "$API/api/v1/MediaPackages($PKGID)/Photos" \
       -d '{"LongDescription": "'"$f"' submitted at '"$(date +%Y-%m-%d\ %H:%M:%S)"'"}' \
       -F "Content=@$f"
done
// 4. Add Photos
var photoFiles = Directory.GetFiles("./example_photos");
for (var i = 0; i < photoFiles.Length; ++i)
{
    var photoFile = photoFiles[i];
    var photoData = new Dictionary<string, string>
    {
        { "LongDescription", $"{Path.GetFileName(photoFile)} submitted at {DateTime.Now}" }
    };

    var photoContent = new ByteArrayContent(File.ReadAllBytes(photo_file));
    response = await client.PutAsync($"https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/Photos(Order={i})", 
        new MultipartFormDataContent { 
            { photoContent, "metadata" },
            { photoContent, "Content", Path.GetFileName(photoFile) } 
        }
    );
}
// 4. Add Photos
const photoDir = './example_photos';
fs.readdir(photoDir, (err, files) => {
    files.forEach((file, i) => {
        fetch(`https://test.mediabridge.recolorado.com/api/v1/MediaPackages(${packageId})/Photos(Order=${i})`, {
            method: 'PUT',
            headers: headers,
            body: JSON.stringify({
                'LongDescription': `${file} submitted at ${start_time}`
            }),
            files: {
                'Content': fs.createReadStream(`${photoDir}/${file}`)
            }
        });
    });
});

...and an example response:

{
  "MediaKey": "1977",
  "MediaPackageId": 8675309,
  "Order": 0,
  "MediaURL": "./api/images(0)/fullsize",
  "MediaThumbURL": "./api/images(0)/fullsize",
  "LongDescription": "Sample description for 'example_photo_1.jpg'",
  "ImageWidth": 1600,
  "ImageHeight": 1200,
  "ImageSizeDescription": "X-Large",
  "IsPublished": false,
  "MarkedForDeletion": false,
  "MarkedForRotation": 0,
  "MediaType": "jpeg",
  "FileName": "example_photo_1.jpg",
  "CreationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
  "CreatedByMemberID": "PROVIDER1",
  "ModificationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
  "ChangedByMemberID": "PROVIDER1",
  "Warnings": []
}

Top

5. Review the Package

When all media has been added, you can review the package for correctness. Use expansions ($expand=Tours,Photos) to include the full collection of MediaTour and MediaPhoto objects inline in the package.

Example code:

# 5. Review the Package
r = session.get(url=f'https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})?$expand=Photos,Tours')
print(r.json())
# 5. Review the Package
curl -X GET -H "$AUTH" "$API/api/v1/MediaPackages($PKGID)?$expand=Photos,Tours"
// 5. Review the Package
response = await client.GetAsync($"https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})?$expand=Photos,Tours");
result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
// 5. Review the Package
fetch(`https://test.mediabridge.recolorado.com/api/v1/MediaPackages(${packageId})?$expand=Photos,Tours`, {
    method: 'GET',
    headers: headers
}).then(res => console.log(res.json()));

...and an example response:

{
  "MediaPackageId": "8675309",
  "MediaStatus": "Ready",
  "MediaStatusLong": "Ready to Publish",
  "PhotoCount": 3,
  "TourCount": 1,
  "MemberMlsId": "ALISUB",
  "MemberFullName": "Allison Broker",
  "MemberEmail": "alison.broker@example.com",
  "ListingAddressHint": null,
  "ListingId": "123456",
  "Listing": {
    "ListingId": "123456",
    "StreetAddress": "330 Carmella Views",
    "CityStateZip": "Denver, CO 80122",
    "FullAddress": "330 Carmella Views Denver, CO 80122",
    "ListOfficeMlsId": "OFFICE1",
    "ListOfficeName": "Example Office One",
    "ListAgentMlsId": "ALISUB",
    "ListAgentFullName": "Allison Broker",
    "ListAgentEmail": "alison.broker@example.com",
    "CoListAgentMlsId": null,
    "CoListAgentFullName": null,
    "CoListAgentEmail": null
  },
  "DisplayStreetAddress": "330 Carmella Views",
  "DisplayCityStateZip": "Denver, CO 80122",
  "IsTerminal": false,
  "IsRetryingPublishAfterError": false,
  "ListingIsLocked": false,
  "CreationTimestamp": "2024-05-17T03:12:20.5273279Z",
  "CreatedByMemberID": "PROVIDER1",
  "CreatorEmail": "provider1@example.com",
  "CreatorName": "ProviderOne",
  "ModificationTimestamp": "2024-05-17T03:12:20.6054524Z",
  "ChangedByMemberID": "PROVIDER1",
  "ChangedByMemberFullName": "ProviderOne",
  "ProposedTimestamp": "2024-05-17T03:12:20.6054524Z",
  "PublishedTimestamp": null,
  "FirstPublishFail": null,
  "LastPublishFail": null,
  "ListingLockedInMatrix": false,
  "CancelPublishTrigger": false,
  "IsUnavailable": false,
  "UnavailableTimestamp": null,
  "UnavailableReason": null,
  "PublishAttemptCount": null,
  "MediaURL": null,
  "DownloadPhotosUrl": null,
  "Tours": [
    {
      "MediaKey": "4",
      "MediaPackageId": 8675309,
      "MediaURL": "https://www.example.com/tour1",
      "Order": 0,
      "CreationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
      "CreatedByMemberID": "PROVIDER1",
      "ModificationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
      "ChangedByMemberID": "PROVIDER1"
    }
  ],
  "Photos": [
    {
      "MediaKey": "1977",
      "MediaPackageId": 8675309,
      "Order": 0,
      "MediaURL": "./api/images(0)/fullsize",
      "MediaThumbURL": "./api/images(0)/fullsize",
      "LongDescription": "Sample description for 'example_photo_1.jpg'",
      "ImageWidth": 1600,
      "ImageHeight": 1200,
      "ImageSizeDescription": "X-Large",
      "IsPublished": false,
      "MarkedForDeletion": false,
      "MarkedForRotation": 0,
      "MediaType": "jpeg",
      "FileName": "example_photo_1.jpg",
      "CreationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
      "CreatedByMemberID": "PROVIDER1",
      "ModificationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
      "ChangedByMemberID": "PROVIDER1",
      "Warnings": []
    },
    {
      "MediaKey": "1978",
      "MediaPackageId": 8675309,
      "Order": 1,
      "MediaURL": "./api/images(0)/fullsize",
      "MediaThumbURL": "./api/images(0)/fullsize",
      "LongDescription": "Sample description for 'example_photo_2.jpg'",
      "ImageWidth": 1600,
      "ImageHeight": 1200,
      "ImageSizeDescription": "X-Large",
      "IsPublished": false,
      "MarkedForDeletion": false,
      "MarkedForRotation": 0,
      "MediaType": "jpeg",
      "FileName": "example_photo_2.jpg",
      "CreationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
      "CreatedByMemberID": "PROVIDER1",
      "ModificationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
      "ChangedByMemberID": "PROVIDER1",
      "Warnings": []
    },
    {
      "MediaKey": "1979",
      "MediaPackageId": 8675309,
      "Order": 2,
      "MediaURL": "./api/images(0)/fullsize",
      "MediaThumbURL": "./api/images(0)/fullsize",
      "LongDescription": "Sample description for 'example_photo_3.jpg'",
      "ImageWidth": 1600,
      "ImageHeight": 1200,
      "ImageSizeDescription": "X-Large",
      "IsPublished": false,
      "MarkedForDeletion": false,
      "MarkedForRotation": 0,
      "MediaType": "jpeg",
      "FileName": "example_photo_3.jpg",
      "CreationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
      "CreatedByMemberID": "PROVIDER1",
      "ModificationTimestamp": "2024-05-16T21:12:20.5898303-06:00",
      "ChangedByMemberID": "PROVIDER1",
      "Warnings": []
    }
  ],
  "Warnings": []
}

Top

6. Mark as Ready

When all media has been added, you can mark the package as ready. Notably, this changes the MediaStatus of the package to Ready. This will also notify the agents who manage the listing that the package is available for them to publish.

During testing, consider using previewOnly=1 to have the notification email sent only to you, removing the parameter when you're ready to broadcast to the listing agents.

Example code:

# 6. Mark as Ready
session.post(url=f'https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/MarkReady?previewOnly=1')
# 6. Mark as Ready
curl -X POST -H "$AUTH" "$API/api/v1/MediaPackages($PKGID)/MarkReady?previewOnly=1"
// 6. Mark as Ready
response = await client.PostAsync($"https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/MarkReady?previewOnly=1", null);
// 6. Mark as Ready
fetch(`https://test.mediabridge.recolorado.com/api/v1/MediaPackages(${packageId})/MarkReady?previewOnly=1`, { method: 'POST', headers: headers });

...and an example response:

{
  "MediaPackageId": "8675309",
  "MediaStatus": "Ready",
  "MediaStatusLong": "Ready to Publish",
  "PhotoCount": 3,
  "TourCount": 1,
  "MemberMlsId": "ALISUB",
  "MemberFullName": "Allison Broker",
  "MemberEmail": "alison.broker@example.com",
  "ListingAddressHint": null,
  "ListingId": "123456",
  "Listing": {
    "ListingId": "123456",
    "StreetAddress": "330 Carmella Views",
    "CityStateZip": "Denver, CO 80122",
    "FullAddress": "330 Carmella Views Denver, CO 80122",
    "ListOfficeMlsId": "OFFICE1",
    "ListOfficeName": "Example Office One",
    "ListAgentMlsId": "ALISUB",
    "ListAgentFullName": "Allison Broker",
    "ListAgentEmail": "alison.broker@example.com",
    "CoListAgentMlsId": null,
    "CoListAgentFullName": null,
    "CoListAgentEmail": null
  },
  "DisplayStreetAddress": "330 Carmella Views",
  "DisplayCityStateZip": "Denver, CO 80122",
  "IsTerminal": false,
  "IsRetryingPublishAfterError": false,
  "ListingIsLocked": false,
  "CreationTimestamp": "2024-05-17T03:12:20.5273279Z",
  "CreatedByMemberID": "PROVIDER1",
  "CreatorEmail": "provider1@example.com",
  "CreatorName": "ProviderOne",
  "ModificationTimestamp": "2024-05-17T03:12:20.6054524Z",
  "ChangedByMemberID": "PROVIDER1",
  "ChangedByMemberFullName": "ProviderOne",
  "ProposedTimestamp": "2024-05-17T03:12:20.6054524Z",
  "PublishedTimestamp": null,
  "FirstPublishFail": null,
  "LastPublishFail": null,
  "ListingLockedInMatrix": false,
  "CancelPublishTrigger": false,
  "IsUnavailable": false,
  "UnavailableTimestamp": null,
  "UnavailableReason": null,
  "PublishAttemptCount": null,
  "MediaURL": null,
  "DownloadPhotosUrl": null,
  "Tours": null,
  "Photos": null,
  "Warnings": []
}

Top

Complete Example

Putting all the pieces together, here are some top-to-bottom examples. Proper response and error handling are omitted to keep the examples brief.

Example code:

import os
import requests

# 1. Authenticate
session = requests.Session()
session.headers.update({'Authorization': f'Bearer <API_KEY>'})

r = session.get(url='https://test.mediabridge.recolorado.com/api/v1/MediaPackages')
print(r.json())

# 2. Create a Package
package_id = session.post(
    url='https://test.mediabridge.recolorado.com/api/v1/MediaPackages', 
    data={ 'ListingId': '123456' }
).json()['MediaPackageId']

# 3. Add Tours
session.put(
    url=f'https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/Tours',
    data={ 
        'MediaURL': 'https://www.example.com/tour1', 
        'Order': 0
    }
)

# 4. Add Photos
photo_dir = './example_photos'
for i, photo_file in enumerate(os.listdir(photo_dir)):
    session.put(
        url=f'https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/Photos(Order={i})',
        data={ "LongDescription": f'{photo_file} submitted at {start_time}' },
        files={ "Content": open(os.path.join(photo_dir, photo_file), 'rb') }
    )

# 5. Review the Package
r = session.get(url=f'https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})?$expand=Photos,Tours')
print(r.json())

# 6. Mark as Ready
session.post(url=f'https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/MarkReady?previewOnly=1')
#!/bin/bash

# 1. Authenticate
AUTH="Authorization: Bearer <API_KEY>"
API="https://test.mediabridge.recolorado.com"

curl -X GET -H "$AUTH" "$API/api/v1/MediaPackages"

# 2. Create a Package
RESP=$(curl -X POST  -H "$AUTH" "$API/api/v1/MediaPackages" \
     -d '{"ListingId": "123456"}')
PKGID=$(echo "$RESP" | jq -r '.MediaPackageId')
PKGID="474"
# 3. Add Tours
curl -X PUT -H "$AUTH" "$API/api/v1/MediaPackages($PKGID)/Tours" \
     -d '{"MediaURL": "https://www.example.com/tour1", "Order": 0}'

# 4. Add Photos
for f in ./example_photos/*; do
  curl -X POST -H "$AUTH" "$API/api/v1/MediaPackages($PKGID)/Photos" \
       -d '{"LongDescription": "'"$f"' submitted at '"$(date +%Y-%m-%d\ %H:%M:%S)"'"}' \
       -F "Content=@$f"
done

# 5. Review the Package
curl -X GET -H "$AUTH" "$API/api/v1/MediaPackages($PKGID)?$expand=Photos,Tours"

# 6. Mark as Ready
curl -X POST -H "$AUTH" "$API/api/v1/MediaPackages($PKGID)/MarkReady?previewOnly=1"
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        // 1. Authenticate        
        using (var client = new HttpClient(handler))
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<API_KEY>");

            var response = await client.GetAsync("https://test.mediabridge.recolorado.com/api/v1/MediaPackages");
            var result = await response.Content.ReadAsStringAsync();
            Console.WriteLine(result);

            // 2. Create a Package
            var packageData = new Dictionary<string, string> { 
                { "ListingId", "123456" }
            };

            response = await client.PostAsync("https://test.mediabridge.recolorado.com/api/v1/MediaPackages", new FormUrlEncodedContent(packageData));
            result = await response.Content.ReadAsStringAsync();
            var package_id = JObject.Parse(result)["MediaPackageId"].ToString();

            // 3. Add Tours
            var tourData = new Dictionary<string, string>
            {
                { "MediaURL", "https://www.example.com/tour1" },
                { "Order", "0" }
            };
            response = await client.PutAsync($"https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/Tours", new FormUrlEncodedContent(tourData));

            // 4. Add Photos
            var photoFiles = Directory.GetFiles("./example_photos");
            for (var i = 0; i < photoFiles.Length; ++i)
            {
                var photoFile = photoFiles[i];
                var photoData = new Dictionary<string, string>
                {
                    { "LongDescription", $"{Path.GetFileName(photoFile)} submitted at {DateTime.Now}" }
                };

                var photoContent = new ByteArrayContent(File.ReadAllBytes(photo_file));
                response = await client.PutAsync($"https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/Photos(Order={i})", 
                    new MultipartFormDataContent { 
                        { photoContent, "metadata" },
                        { photoContent, "Content", Path.GetFileName(photoFile) } 
                    }
                );
            }

            // 5. Review the Package
            response = await client.GetAsync($"https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})?$expand=Photos,Tours");
            result = await response.Content.ReadAsStringAsync();
            Console.WriteLine(result);

            // 6. Mark as Ready
            response = await client.PostAsync($"https://test.mediabridge.recolorado.com/api/v1/MediaPackages({package_id})/MarkReady?previewOnly=1", null);
        }
    }
}
const fetch = require('node-fetch');
const fs = require('fs');

// 1. Authenticate
const headers = {
    'Authorization': 'Bearer <API_KEY>',
    'Content-Type': 'application/json'
}

fetch('https://test.mediabridge.recolorado.com/api/v1/MediaPackages', {
    method: 'GET',
    headers: headers
}).then(res => console.log(res.json()));

// 2. Create a Package
let packageId;

fetch('https://test.mediabridge.recolorado.com/api/v1/MediaPackages', {
    method: 'POST',
    headers: headers,
    body: JSON.stringify({
        'ListingId': '123456'
    })
}).then(res => res.json())
  .then(json => { packageId = json.MediaPackageId; });

// 3. Add Tours
fetch(`https://test.mediabridge.recolorado.com/api/v1/MediaPackages(${packageId})/Tours`, {
    method: 'PUT',
    headers: headers,
    body: JSON.stringify({
        'MediaURL': 'https://www.example.com/tour1',
        'Order': 0
    })
});

// 4. Add Photos
const photoDir = './example_photos';
fs.readdir(photoDir, (err, files) => {
    files.forEach((file, i) => {
        fetch(`https://test.mediabridge.recolorado.com/api/v1/MediaPackages(${packageId})/Photos(Order=${i})`, {
            method: 'PUT',
            headers: headers,
            body: JSON.stringify({
                'LongDescription': `${file} submitted at ${start_time}`
            }),
            files: {
                'Content': fs.createReadStream(`${photoDir}/${file}`)
            }
        });
    });
});

// 5. Review the Package
fetch(`https://test.mediabridge.recolorado.com/api/v1/MediaPackages(${packageId})?$expand=Photos,Tours`, {
    method: 'GET',
    headers: headers
}).then(res => console.log(res.json()));

// 6. Mark as Ready
fetch(`https://test.mediabridge.recolorado.com/api/v1/MediaPackages(${packageId})/MarkReady?previewOnly=1`, { method: 'POST', headers: headers });

Top

Media Bridge Objects

Below are summaries of individual fields within the MediaPackage, MediaListing, MediaPhoto, and MediaTour objects:

A collection of photos and tours that are presented to an agent for publication to a listing.
Field Type Editable Description
MediaStatus String The status of the package. Options: Draft, Ready, Publishing..., Published, Expired, Deleted, Closed, Publishing.
MediaStatusLong String An expanded MediaStatus option. Displayed in desktop views for the package.
PhotoCount Int32 The total number of photos on the package, including photos above the Publish limit.
TourCount Int32 The total number of tours on the package, between 0 and 3.
MemberMlsId String The MemberMlsId of the agent who will be responsible for publishing the package to a listing. Typically the listing agent.
MemberFullName String The first and last name of the agent responsible for publishing the package, as designated by MemberMlsId.
MemberEmail String The email of the agent responsible for publishing the package, as designated by MemberMlsId.
ListingAddressHint String The property address, if the listing is not known at the time of package creation.
ListingId String The MLS# of the listing receiving media.
Listing MediaListing A subset of listing agent and address fields.
DisplayStreetAddress String The displayed street address. Sourced from the listing if ListingId is provided, otherwise this will display the ListingAddressHint.
DisplayCityStateZip String The displayed city, state and postal code of the listing, if ListingId is provided.
IsTerminal Boolean
IsRetryingPublishAfterError Boolean
ListingIsLocked Boolean When true, users can no longer change the listing id
CreationTimestamp DateTime The timestamp when the media package was created.
CreatedByMemberID String The MemberMlsId of the user who created the media package, typically a photo provider.
CreatorEmail String The email of the user who created the media package, as designated by CreatedByMemberID.
CreatorName String Desctriptive name for the creator of the package
ModificationTimestamp DateTime? The timestamp when the media package was last changed.
ChangedByMemberID String The MemberMlsId of the user who last changed the media package.
ChangedByMemberFullName String The MemberFullName of the user who last changed the media package.
ProposedTimestamp DateTime? The timestamp when the media package was last proposed to the agent for review.
PublishedTimestamp DateTime? Timestamp when the media package was last published.
FirstPublishFail DateTime?
LastPublishFail DateTime?
ListingLockedInMatrix Boolean
CancelPublishTrigger Boolean
IsUnavailable Boolean The media package is no longer available for editing. MediaStatus will be Closed, Expired, or Deleted. UnavailableReason may contain a reason for the status.
UnavailableTimestamp DateTime? Timestamp when the package expired, for example: when the associated listing was no longer on the market.
UnavailableReason String The reason a package is marked as IsUnavailable
PublishAttemptCount Int32? The number of unsuccessful attempts made by the system to publish the media package.
MediaURL String Direct link to the media package. Used in emails.
DownloadPhotosUrl String A link to download the original photos.
Tours ICollection`1 The package's MediaTour collection.
Photos ICollection`1 The package's MediaPhoto collection.
Warnings String[] A list of warnings for the current package.

A local collection of fields identifying the listing that the package will be published to.
Field Type Editable Description
ListingId String The listing identifier, often called the MLS#.
StreetAddress String The street address of the listing, in the form "{StreetNumber} {StreetDir} {StreetName} {StreetSuffix} {UnitNumber}".
CityStateZip String The city, state, and zip of the listing, in the form "{PostalCity}, {StateOrProvince} {PostalCode}".
FullAddress String The full address of the listing, in the form "{StreetAddress} {CityStateZip}".
ListOfficeMlsId String The MemberMlsId of the office that owns the listing.
ListOfficeName String The name of the office that owns the listing.
ListAgentMlsId String The MemberMlsId of the primary listing agent.
ListAgentFullName String The name of the primary listing agent.
ListAgentEmail String The email of the primary listing agent.
CoListAgentMlsId String The MemberMlsId of the co-listing agent.
CoListAgentFullName String The name of the co-listing agent.
CoListAgentEmail String The email of the co-listing agent.

A photo prepared for submission to the MLS. Photos are resized to maximum MLS quality on upload.
Field Type Editable Description
MediaKey String The unique identifier for an uploaded photo.
MediaPackageId Int32 The id of the media package the photo is associated with.
Order Int32? The 0-based order of the photo in the sequence.
MediaURL String The url of the photo within Media Bridge.
MediaThumbURL String The thumbnail url of the photo within Media Bridge.
LongDescription String The description of the photo. Visible in the MLS.
ImageWidth Int32 The width of the photo in pixels.
ImageHeight Int32 The height of the photo in pixels.
ImageSizeDescription String Set to the maximum size the MLS can display. Will always be "X-Large".
IsPublished Boolean Indicates that the photo is already published to the MLS.
MarkedForDeletion Boolean Flags an IsPublished photo for deletion, to take place at time of Publish.
MarkedForRotation Int32 Deprecated. Flags an IsPublished photo for rotation by X degrees, to take place at time of Publish.
MediaType String All photos are converted to JPEG format on upload, thus this value will always be "jpeg".
FileName String The original filename of the uploaded photo. If a filename is not provided, one will be assigned using the current date and time.
CreationTimestamp DateTime The date the photo was added to Media Bridge.
CreatedByMemberID String The MemberMlsId of the user who added the photo to Media Bridge.
ModificationTimestamp DateTime The timestamp when the photo was last changed in Media Bridge.
ChangedByMemberID String The MemberMlsId of the user who last changed the photo in Media Bridge.
Warnings String[] A list of warnings about the photo. e.g.: if a photo is below the minimum recommended resolution.

A link to externally-hosted listing content. Typically a virtual tour.
Field Type Editable Description
MediaKey String The unique identifier for a tour url.
MediaPackageId Int32 The id of the media package the tour is associated with.
MediaURL String Required. A publicly shared url linking to additional listing content. Typically a virtual tour, which may be Branded or Unbranded.
Order Int32? The 0-based order of the tour in the sequence.
CreationTimestamp DateTime The timestamp when the tour was added to Media Bridge.
CreatedByMemberID String The MemberMlsId of the user who added the tour to Media Bridge.
ModificationTimestamp DateTime The timestamp when the tour was last changed in Media Bridge.
ChangedByMemberID String The MemberMlsId of the user who last changed the tour in Media Bridge.


Questions, comments, or feedback? Email us at support@recolorado.com.