Quick start
- Get your API key from Cedar247. Keep it secret: anyone with the key can place orders on your account.
- Top up your wallet at My account → Wallet. Orders are paid from it automatically.
- Optional: open an order form on the website once and click Save default on your drawing preferences (units, colour style, output format, notes such as "large room labels"). Every API order uses them unless you override a field.
- Place an order:
curl https://cedar247.com/wp-json/cedar247/v1/orders \
-H "Authorization: Bearer $CEDAR247_KEY" \
-H "Content-Type: application/json" \
-d '{
"service": "matterport-floor-plan",
"link": "https://my.matterport.com/show/?m=AbC123xyz",
"notes": "Unit 4B. Please label the den as Office.",
"reference": "listing-2291"
}'That is all a Matterport order needs. Floors, address and project name are read from the Matterport link when you leave them out. The response is the order object with status processing.
Try it
Paste your key and check a price. This box only reads your account and quotes; it never places an order or charges anything. Your key stays in this browser tab.
Authentication
Base URL: https://cedar247.com/wp-json/cedar247/v1
Send your key on every request:
Authorization: Bearer c247_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
The header X-API-Key: <key> works too. Requests and responses are JSON. Limit: 60 requests per minute per key. Lost or leaked key: ask us and we issue a new one (the old key stops at once).
Endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /me | Your account, wallet balance, pay-later status. |
| GET | /services | Services, every field, allowed values, prices and your saved defaults. |
| POST | /quote | Same body as an order. Returns the price and the options that would be used. Nothing is created or charged. |
| POST | /orders | Place and pay an order. |
| GET | /orders | Your orders, newest first. Query: limit (max 50), page, status, reference, source=api. |
| GET | /orders/{id} | One order: status, options, files, messages and download links. |
| POST | /orders/{id}/messages | Send a message or revision request to our team. |
| POST | /files | Upload a file and get a URL to use in an order. |
Machine-readable spec: openapi.json (OpenAPI 3.1).
Services & fields
Values are matched by label, case-insensitive ("metric", "svg", "Style 3" all work). GET /services always has the current list and prices.
matterport-floor-plan · Matterport Floor Plan
| Field | Type | Values |
|---|---|---|
link required | text | Matterport model link. |
floors | choice | 1-6 or ">= 10.000 sq.ft" (send 10000). Auto-detected from the link when omitted. |
address | text | Auto-filled from the Matterport model when omitted. |
unit | choice | Imperial, Metric, Both, None |
language | choice | English, Français, Deutsch, Čeština, Español |
naming | choice | Floor naming style 1-5 (see /services) |
extras | list | 6" Wall Thickness, Add North Arrow, Hide Room Dimensions, Hide area information, Hide room labels, Add Address |
output | list | PDF, JPG, PNG, PNG (Transparent Background), SVG. All formats are included at no extra cost. |
paper | choice | A4(Landscape), A4(Portrait), Letter, Letter(Portrait), 4:3, 3:4 |
style | choice | Colour style 1-12. Previews on the order page. |
siteplan | choice | Site plan style 1-4 |
cadfile | boolean | Add CAD file |
floor3d | boolean | Add a 3D floor plan. Price follows floors: $25, $45, $65, $85, $95, $105, $125 (>= 10.000 sq.ft) |
ceiling | boolean | Add a ceiling plan (+$20) |
delivery | boolean | true = 12 hours rush |
files | list of URLs | Extra reference files. See Files. |
notes | text | Anything our drafters should know. |
floor-plan-redraw · Floor Plan Redraw
Redraw an existing plan (Zillow, builder PDF, hand sketch, photo) in your style. Send the plan in files, or describe it in notes. A link (for example the Zillow listing) is added to the notes for our team.
| Field | Type | Values |
|---|---|---|
files | list of URLs | The reference plan(s). Required unless notes describe it. |
link | text | Optional listing link. |
address | text | Property address. |
style | choice | Colour style 1-12 |
delivery | boolean | true = 12 hours rush |
notes | text | For example "show the total area" or "match the attached sample". |
3d-floor-plan · 3D Floor Plan
A 3D floor plan on its own. Send the Matterport link or source files in files.
| Field | Type | Values |
|---|---|---|
link | text | Matterport link (or send files). |
floors | choice | 1-6 or "> 8000 sq ft" (send 8000). Auto-detected from the link when omitted.Price: 1 floor $25, 2 $45, 3 $65, 4 $85, 5 $95, 6 $105, > 8000 sq ft $125. |
address | text | Auto-filled from the Matterport model when omitted. |
siteplan | boolean | Add site plan (+$20) |
files | list of URLs | Source or reference files. |
notes | text | Anything our team should know. |
scan-to-bim · Scan to Bim
A BIM model from a Matterport scan or point cloud, priced by project size. Send the Matterport link, a file_link or files.
| Field | Type | Values |
|---|---|---|
link | text | Matterport link. Size and address are read from it when you leave them out. |
file_link | text | Download link to your MatterPak, E57 or other files. |
address | text | Property address. |
size required | choice | Square feet (for example 3200) or a label. Above 15,000 sq ft: contact us. |
addons | list | Interior Furniture, MEP, Exterior. Price depends on size (table below). |
unit | choice | Imperial, Metric, Both, None |
language | choice | English, Français, Deutsch, Čeština, Español |
template_link | text | Link to your preferred template. |
files | list of URLs | Source or reference files. |
notes | text | Anything our team should know. |
| Size | Price | Interior Furniture | MEP | Exterior |
|---|---|---|---|---|
| up to 1,000 sq ft | $100 | +$40 | +$40 | +$100 |
| 1,001 - 2,500 | $150 | +$70 | +$100 | +$100 |
| 2,501 - 5,000 | $170 | +$100 | +$150 | +$100 |
| 5,001 - 7,500 | $450 | +$140 | +$170 | +$100 |
| 7,501 - 10,000 | $650 | +$170 | +$220 | +$120 |
| 10,001 - 15,000 | $900 | +$350 | +$700 | +$150 |
iphone-floor-plan · iPhone Floor Plan
A 2D floor plan from an iPhone or iPad LiDAR scan (Scaniverse, Polycam, 3D Scanner App). Send the export in scan_files, or a download link for files over 50 MB.
| Field | Type | Values |
|---|---|---|
scan_files | list of URLs | OBJ (recommended), DAE or XYZ. Max 10. |
link | text | Google Drive / WeTransfer link to the scan. |
address | text | Property address. |
floors required | choice | 1-6. Price: 1 floor $5, +$3 per extra floor (6 floors $20). |
style | choice | Colour style 1-12 (+$1.50, styles 3 and 11 free) |
siteplan | choice | Site plan style 1-4 (+$3) |
dwg | boolean | Add DWG file (+$1) |
files | list of URLs | Logo or supporting files. Max 20. |
notes | text | Anything our drafters should know. |
matterport-video · Matterport Video
A walkthrough video made from your Matterport tour. From $20.
| Field | Type | Values |
|---|---|---|
link required | text | Matterport link. Address is read from it when you leave it out. |
address | text | Property address. |
addons | list | Add Minimap (+$5), Google Fly-in (+$5), GG Fly-in + Lot Line (+$10) |
music | choice | Corporate, Piano, Ambient, Electronic, Upbeat / Energetic (free) |
files | list of URLs | Logo, photos or other files. |
notes | text | Anything our editors should know. |
Order-level fields
| Field | Default | Meaning |
|---|---|---|
service | required | matterport-floor-plan, floor-plan-redraw, 3d-floor-plan, scan-to-bim, iphone-floor-plan or matterport-video |
reference | Your own ID (max 100 chars). Sending the same reference again returns the existing order with "duplicate": true instead of a second charge. Use it on every order. | |
use_defaults | true | Fill missing fields from your saved defaults. |
payment | "wallet" | wallet, pay_link or account. See Payment. |
if_insufficient | "reject" | Wallet too low: reject (nothing created) or pay_link. |
callback_url | HTTPS URL for webhooks about this order. |
Saved defaults
Every field you leave out takes the value you saved on the website order form, exactly like the form does for you there. Saved notes are kept and your request notes are added below them, so a standing instruction such as "draw all room labels large" goes on every order.
Send null (or false / []) to switch a saved option off for one order, for example "style": null for black and white. Send "use_defaults": false to ignore all saved values. Use POST /quote to see the final options and price before ordering.
Payment
wallet(default): the total is taken from your wallet and the order starts right away. Your coupons and top-up bonus credit apply automatically, so the charge can be lower than the quote.- Wallet too low: you get
402 insufficient_balancewith your balance and a top-up link. Nothing is created. With"if_insufficient": "pay_link"the order is created unpaid instead and the response has apay_url. pay_link: the order is created unpaid with apay_url(card). Work starts once it is paid.account: pay later. Work starts right away and your on-account orders of the month are billed on one invoice at the start of the next month. Only when Cedar247 has enabled it for your account, up to your credit limit if one is set.
Check your balance any time with GET /me.
Files
Put public links in files: "files": ["https://photos.zillowstatic.com/.../plan.jpg"]. We download each file and keep our own copy, so links that expire later are fine. Max 20 files per order, 100 MB per link.
For files that are not online, upload them first with POST /files and use the returned url:
# multipart (up to 100 MB)
curl -H "Authorization: Bearer $CEDAR247_KEY" -F "[email protected]" \
https://cedar247.com/wp-json/cedar247/v1/files
# or JSON: {"name": "plan.pdf", "data": "<base64>"} (up to 25 MB)
# or JSON: {"url": "https://..."}
# response
{"name": "plan.pdf", "url": "https://file.cedar247.com/orders/2026/10/aB3dE5fG/plan.pdf", "size": 482113}
Allowed types: jpg, jpeg, png, gif, webp, pdf, svg, tif, tiff, psd, dwg, dxf, obj, dae, e57, xyz, las, laz, rcp, zip, rar, 7z, csv, txt, doc, docx, xls, xlsx.
Order object
{
"id": 5201,
"number": "100712",
"service": "matterport-floor-plan",
"status": "processing",
"stage": "in_progress",
"reference": "listing-2291",
"created_at": "2026-10-03T15:04:11Z",
"paid": true,
"payment": "wallet",
"currency": "USD",
"subtotal": 5.00, "discount": 0, "total": 5.00,
"pay_url": null,
"options": [{"label": "Number of Floors", "value": "2 Floors (+$2.50)"}, ...],
"files": ["https://file.cedar247.com/orders/..."],
"downloads": [],
"messages": [],
"view_url": "https://cedar247.com/my-account/view-order/5201/"
}
| stage | Meaning |
|---|---|
awaiting_payment | Created with a pay link, not paid yet. Not started. |
in_progress | Paid (or on account). Our team is drawing it. |
delivered | Finished. downloads has the files, messages has our note. |
on_hold, cancelled, refunded | As named. Contact us if unexpected. |
number is the order number shown in emails and on the website. Use id in API paths.
Revisions & messages
curl https://cedar247.com/wp-json/cedar247/v1/orders/5201/messages \
-H "Authorization: Bearer $CEDAR247_KEY" -H "Content-Type: application/json" \
-d '{"message": "Please make the room labels larger.", "files": ["https://.../markup.jpg"]}'
The message goes straight to our production board. Replies and redeliveries appear in the order's messages and downloads.
Webhooks
Add callback_url to an order (or ask us to set one for your account) and we POST JSON to it when something happens:
| Event | When |
|---|---|
order.status_changed | Status moves, for example processing → completed. Data has from, to, order. |
order.message | Our team posts a message or delivery. Data has message, links, order. |
{"event": "order.message", "sent_at": "2026-10-03T21:40:02Z",
"data": {"message": "Your order #100712 is ready to be downloaded.", "links": ["https://file.cedar247.com/delivery/.../100712.zip"], "order": {...}}}
Each request has X-Cedar247-Signature: sha256=<hex>, the HMAC-SHA256 of the raw body. The signing secret is the SHA-256 hex digest of your API key.
// Node.js
const crypto = require("crypto");
const secret = crypto.createHash("sha256").update(process.env.CEDAR247_KEY).digest("hex");
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers["x-cedar247-signature"]));
# Python
import hashlib, hmac
secret = hashlib.sha256(KEY.encode()).hexdigest().encode()
ok = hmac.compare_digest("sha256=" + hmac.new(secret, raw_body, hashlib.sha256).hexdigest(), signature)
Webhooks are sent once and not retried. Poll GET /orders/{id} if you miss one.
Errors
{"error": {"code": "invalid_fields", "message": "Some fields need fixing.",
"fields": {"style": "Unknown option \"Style 99\". Allowed: Style 1 | Style 2 | ..."}}}
| HTTP | code | What to do |
|---|---|---|
| 400 | invalid_fields, invalid_service, invalid_file | Fix the fields listed. Allowed values are in the message. |
| 401 | unauthorized | Check the key. |
| 402 | insufficient_balance | Top up (topup_url) or use if_insufficient: "pay_link". |
| 402 | credit_limit, payment_failed | Nothing was charged. Pay open orders or retry. |
| 403 | account_not_enabled | Pay later is not on for your account. Use the wallet. |
| 404 | not_found | Order id is wrong or not yours. |
| 409 | busy | Another order is being placed for your account. Retry after a few seconds. |
| 429 | rate_limited | Slow down (60 requests per minute). |
| 500 | server_error | Retry with the same reference; you will never be charged twice. |
For AI assistants
Paste this into your assistant's instructions (with your key stored as a secret):
You can order floor plans from Cedar247.
API: https://cedar247.com/wp-json/cedar247/v1 (header Authorization: Bearer <CEDAR247_KEY>, JSON)
- GET /services lists services, fields and allowed values. GET /me shows the wallet balance.
- Matterport floor plan: POST /orders {"service":"matterport-floor-plan","link":"<matterport url>","notes":"...","reference":"<unique id>"}.
Floors and address are detected from the link. Add "floors", "style" (1-12), "output" (["PDF","SVG",...]), "delivery": true (12h rush) only if the user asks.
- 3D floor plan: POST /orders {"service":"3d-floor-plan","link":"<matterport url>","notes":"...","reference":"<unique id>"} (add "siteplan": true if asked). Or add "floor3d": true to a matterport-floor-plan order.
- Scan to BIM: POST /orders {"service":"scan-to-bim","link":"<matterport url>","size":<square feet>,"addons":["MEP"],"reference":"<unique id>"}. Size is read from the link when omitted.
- iPhone LiDAR floor plan: POST /orders {"service":"iphone-floor-plan","scan_files":["<obj url>"],"floors":2,"reference":"<unique id>"} (or "link" to a Google Drive / WeTransfer download).
- Matterport video: POST /orders {"service":"matterport-video","link":"<matterport url>","addons":["Add Minimap"],"music":"Piano","reference":"<unique id>"}.
- Redraw a Zillow or other plan: POST /orders {"service":"floor-plan-redraw","files":["<public image or pdf url>"],"link":"<listing url>","notes":"...","reference":"<unique id>"}.
- Always send a unique "reference" per job. Use POST /quote first if the user wants the price.
- Paid from the prepaid wallet. On 402 insufficient_balance tell the user the balance and the top-up link.
- Status: GET /orders/{id}. "stage" is in_progress or delivered; "downloads" has the finished files.
- Revisions: POST /orders/{id}/messages {"message":"..."}.
Full docs: https://cedar247.com/api-docs/