RapidEye API

Reference

Home setup

Set a home's checklist, Matterport tour and baseline photos.

Setting up a home

Once a property is in the roster you can prepare it for inspections: give it the checklist the cleaner works through, a Matterport tour, and baseline photos of the home in good condition. All three are optional, and an inspection works without any of them; each one makes the report sharper.

Every call here addresses a home by your property_id, the one you sent in the roster, and takes workspace_id as a query parameter. Any roster state may be set up, inactive and unconfirmed included, so you can prepare a home before it goes live. An id that is not in that workspace's roster answers 404 property_not_found, and so does an id that belongs to a different workspace. The id is matched literally and must survive as one path segment, so percent-encode anything reserved.

Request bodies on these endpoints are limited to 376,224 bytes; a larger body answers 413 payload_too_large before it is read. That is a guard against a mistaken bulk upload, separate from the field limits below. It sits well above any realistic body at those limits, and both rules apply.

Progress for every home shows in the setup block on GET /v1/properties:

JSON
"setup": {
  "checklist": { "items": 12 },
  "matterport": { "state": "imported", "url": "https://my.matterport.com/show/?m=SxQL3iGyoDo" },
  "baseline_photos": { "count": 18, "state": "imported" }
}
Field Meaning
checklist.items How many items the home's own housekeeping checklist has (the list a cleaner is served on a turnover). 0 means it has none of its own. The inspection and maintenance lists are not counted here; read them with GET .../checklist?type=.
matterport.state none, importing, imported or failed, for the tour the home currently names. url is omitted when no tour is set.
baseline_photos.count Every photo in the home's baseline, whatever added it: your imports, and photos the home's managers or we added (uploads, a Google Drive folder, their Airbnb listing, Breezeway listing photos).
baseline_photos.state importing while a photo import is running, yours or one the home's managers started. Otherwise imported when the home has any baseline photos, failed when it has none and its most recent import in the last 30 days failed, and none otherwise. Read the import itself for which photos were refused.

PUT/v1/properties/{property_id}/checklist?workspace_id=...#

Replace the home's checklist with the list you send. The cleaner sees the items in your order. It is a full replace, not a merge, and it is idempotent: sending the same list twice leaves the same checklist. It is safe after the home has been recorded; items a cleaner already checked off stay on the reports that recorded them.

Field Required Notes
items yes Array of 1 to 50 items. To remove the checklist, use DELETE; an empty array is refused.
items[].name yes The step as the cleaner reads it on their phone, one step at a time. 1 to 120 characters; under 55 reads best. Name the area, then the visible results: Kitchen: counters clear, sink empty, floor swept. A dash used as punctuation (an em dash, or an en dash with a space beside it) is refused; use a colon.
items[].notes no A short label shown under the step on one truncated line, such as the floor or room. Not a place for instructions. Up to 500 characters.

Unknown fields, at the top level or on an item, are rejected with 400 invalid_request, and detail names the field and the item index.

A home has three checklists, and ?type= picks which one you are writing. The values are housekeeping (the default when you omit it), inspection and maintenance. Each is a separate list: writing one never disturbs the other two, and clearing one leaves the others alone. Anything outside those three is 400 invalid_request with detail.parameter set to type.

Housekeeping is the list a cleaner is served during a turnover, so it is the one to use unless you have a reason not to. The response echoes type back even when you left it out, so a stored response always says which list it describes.

Every item comes back with an id, which is ours and is how per-item results are reported (see What we send back to you). One thing to know about it: a replace retires the old items and creates new ones, so an id is stable between writes and not across them. That is deliberate, because a result should point at the version of the item that was actually checked. Read the ids back after each PUT rather than caching them across an edit.

Shell
curl -sS -X PUT "https://api.rapideyeinspections.com/v1/properties/unit_42/checklist?workspace_id=ws_123" \
  -H "Authorization: Bearer rapideye_pk_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "name": "Bedrooms: beds made, linens fresh, floors clear", "notes": "Upstairs" },
      { "name": "Hot tub: cover on and latched" }
    ]
  }'
JSON
{
  "workspace_id": "ws_123",
  "property_id": "unit_42",
  "type": "housekeeping",
  "items": [
    { "id": "c1f0a2e4-...", "name": "Bedrooms: beds made, linens fresh, floors clear", "notes": "Upstairs" },
    { "id": "9b73d5a1-...", "name": "Hot tub: cover on and latched" }
  ],
  "updated_at": "2026-09-19T14:02:11Z"
}

GET/v1/properties/{property_id}/checklist?workspace_id=...#

The home's own checklist, in order. items is an empty array when the home has none of its own, and updated_at is then omitted; a company-wide checklist set up with us may still apply to that home.

?type= reads one of the three lists, same values and same default as the PUT. Read the item ids back from here after any edit: they are what per-item results are keyed on, and a replace issues new ones.

Shell
curl -sS "https://api.rapideyeinspections.com/v1/properties/unit_42/checklist?workspace_id=ws_123&type=maintenance" \
  -H "Authorization: Bearer rapideye_pk_REPLACE_ME"
JSON
{
  "workspace_id": "ws_123",
  "property_id": "unit_42",
  "type": "maintenance",
  "items": [
    { "id": "c1f0a2e4-...", "name": "Bedrooms: beds made, linens fresh, floors clear", "notes": "Upstairs" }
  ],
  "updated_at": "2026-09-19T14:02:11Z"
}

DELETE/v1/properties/{property_id}/checklist?workspace_id=...#

Remove one of the home's own checklists. Idempotent: removing a checklist that is not there is a 200. If the customer has a company-wide checklist of that type on our side, the home goes back to using it. ?type= picks which list to clear and leaves the other two alone.

Shell
curl -sS -X DELETE "https://api.rapideyeinspections.com/v1/properties/unit_42/checklist?workspace_id=ws_123" \
  -H "Authorization: Bearer rapideye_pk_REPLACE_ME"
JSON
{ "workspace_id": "ws_123", "property_id": "unit_42", "type": "housekeeping", "items": [] }

PUT/v1/properties/{property_id}/matterport?workspace_id=...#

Set the home's Matterport tour and import it as baseline imagery. Answers 202 with state: "importing"; watch setup.matterport.state on GET /v1/properties for imported or failed.

Field Required Notes
url yes A https://my.matterport.com/show/?m=<model id> share link (other query parameters are fine) or a https://discover.matterport.com/space/<model id> link. We store it as https://my.matterport.com/show/?m=<model id>.

Sending a tour again is safe. The same tour that is already imported answers 200 with state: "imported" and imports nothing; the same tour that is still importing answers 202 with the import already running. A different tour while one is importing is 409 matterport_import_in_progress, and detail.importing names the tour that is running; wait for the first to finish. A tour whose import failed is imported again. A different tour while one is already imported replaces it: the home keeps using the imported tour until the new one finishes importing, and if the new import fails the old tour stays in use and state reads failed for the tour you sent.

Shell
curl -sS -X PUT "https://api.rapideyeinspections.com/v1/properties/unit_42/matterport?workspace_id=ws_123" \
  -H "Authorization: Bearer rapideye_pk_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://my.matterport.com/show/?m=SxQL3iGyoDo&play=1" }'
JSON
{
  "workspace_id": "ws_123",
  "property_id": "unit_42",
  "matterport": { "url": "https://my.matterport.com/show/?m=SxQL3iGyoDo", "state": "importing" }
}

DELETE/v1/properties/{property_id}/matterport?workspace_id=...#

Remove the home's tour. Idempotent. Its imported imagery is deleted and stops being used from the next inspection, and an import that is running is stopped. Nothing else in the home's baseline (photos, the baseline video) is affected.

Shell
curl -sS -X DELETE "https://api.rapideyeinspections.com/v1/properties/unit_42/matterport?workspace_id=ws_123" \
  -H "Authorization: Bearer rapideye_pk_REPLACE_ME"
JSON
{ "workspace_id": "ws_123", "property_id": "unit_42", "matterport": { "state": "none" } }

POST/v1/properties/{property_id}/baseline-photos?workspace_id=...#

Import baseline photos of the home, in good condition, from URLs. Answers 202 with an import_id; the photos are fetched in the background. Photos add to the home's baseline, they never replace it, and sending a photo we already hold adds nothing, whatever URL it arrives from. One import runs per home at a time: a second batch while one is importing is 409 baseline_import_in_progress. Baseline imports (photos and tours, from every workspace) also queue behind each other on our side, so at a busy moment an import can stay importing for some minutes before its first photo is fetched. Poll the import; do not time it out and send it again.

Field Required Notes
photos yes Array of 1 to 25 objects. A repeated photo counts toward the 25 and is fetched, is stored once, and is reported in the import's duplicates count.
photos[].url yes An https URL on the default port, up to 2,048 characters, with no credentials in it.

What we fetch, and what we refuse per photo rather than for the whole batch:

  • Public hosts only. A host that resolves to a private, loopback, link-local or otherwise non-public address is refused, and so is a redirect to one. We follow at most three redirects, each checked the same way.
  • JPEG, PNG or WebP, up to 15 MB. The Content-Type must say so and the bytes must match it.
  • 20 seconds per photo. A slower server fails that photo.
  • Nothing of yours or ours is sent. No cookies and no authorization header, so the URL has to be fetchable on its own; a signed URL that lives for a few minutes is fine.
Shell
curl -sS -X POST "https://api.rapideyeinspections.com/v1/properties/unit_42/baseline-photos?workspace_id=ws_123" \
  -H "Authorization: Bearer rapideye_pk_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{
    "photos": [
      { "url": "https://photos.example.com/unit_42/living-room.jpg" },
      { "url": "https://photos.example.com/unit_42/kitchen.jpg" }
    ]
  }'
JSON
{
  "workspace_id": "ws_123",
  "property_id": "unit_42",
  "import_id": "5d0c7a4e-3b1f-4f7e-9c2a-8e6b1d4f0a37",
  "state": "importing",
  "accepted": 2
}

GET/v1/properties/{property_id}/baseline-photos/imports/{import_id}?workspace_id=...#

One photo import: its state (importing, imported or failed), how many photos were stored, how many were duplicates (a photo the home already holds, from this request or from anywhere else, or one removed from the home while the import ran), and every photo we refused, with its position in your request, its URL and a reason. stored, duplicates and the refused photos add up to the number you sent. The import is failed when every photo was refused, or when it failed before it could report on any photo. The first carries no error: every refused photo is already in failed with its own reason. The second carries a short error, and sending the same photos again is safe.

reason Meaning
invalid_url The URL, or a redirect it sent us to, is not one we fetch.
dns_failed The host did not resolve.
private_address The host resolves to a non-public address.
connect_failed We could not connect or the connection broke.
too_many_redirects More than three redirects.
http_status The server answered something other than 200.
unsupported_content_type Not JPEG, PNG or WebP.
content_mismatch The bytes are not a usable image of the type the server declared: another type, truncated or corrupt, or over 100 megapixels.
too_large Over 15 MB.
timeout The photo took longer than 20 seconds.
upload_failed We fetched it and could not store it. Sending it again is safe.
fetch_failed Something unexpected went wrong on our side with this photo. Sending it again is safe.

An import_id from another home or workspace answers 404 not_found, identical to one that does not exist.

Shell
curl -sS "https://api.rapideyeinspections.com/v1/properties/unit_42/baseline-photos/imports/5d0c7a4e-3b1f-4f7e-9c2a-8e6b1d4f0a37?workspace_id=ws_123" \
  -H "Authorization: Bearer rapideye_pk_REPLACE_ME"
JSON
{
  "workspace_id": "ws_123",
  "property_id": "unit_42",
  "import_id": "5d0c7a4e-3b1f-4f7e-9c2a-8e6b1d4f0a37",
  "state": "imported",
  "stored": 1,
  "duplicates": 0,
  "failed": [
    { "index": 1, "url": "https://photos.example.com/unit_42/kitchen.jpg", "reason": "http_status" }
  ]
}