ReelQuoteAI Survey Tool
Measured conclusion: Deep-tested. L2 outcome: tools_ok.
Filmed moving surveys, itemized inventories, firm quotes and bookings for moving companies.
| Author | com.reelquoteai |
|---|---|
| Access | remote |
| Publisher key required | No |
| Measured state | Deep-tested |
| L1 liveness | alive |
| L1 latency | 150 ms |
| Last measured | 2026-10-24 |
Add to your agent
Copy this into your MCP client config:
{
"mcpServers": {
"ReelQuoteAI Survey Tool": {
"url": "https://widget.reelquoteai.com/mcp",
"transport": "streamable-http"
}
}
}
Measured tools (32)
get_sessionread-onlyResolve the key to its mover (name, branding, config). Scope: quote.
Hints: read-only yes · destructive no · idempotent not declared · open-world no
list_home_profilesread-onlyHome sizes for the ballpark step (2br_apt, 3br_house, …). Scope: quote.
Hints: read-only yes · destructive no · idempotent not declared · open-world no
ballpark_estimateInstant estimate range from home size + addresses. Free; never bookable. Scope: quote.
Parameters:
dwelling(required) — string — A `dwelling` from GET /home-profilesorigin— object — One end of the move, as the customer gives it.move_date— string — Lets date-based pricing apply. Optional but strongly recommended.destination— object — One end of the move, as the customer gives it.distance_miles— number — Only used when no route can be found from the addresses
Hints: read-only no · destructive no · idempotent not declared · open-world no
create_jobStart a job (the survey container). Contact details are NOT accepted here — funnel rule. Send `Idempotency-Key` so a retry cannot create a second job. Scope: jobs:write.
Parameters:
origin— object — One end of the move, as the customer gives it.dwelling— string — What the customer says their home is (any wording; stored beside what the video measures)move_date— string — YYYY-MM-DDquote_kind— string — What the job is for. A firm job becomes bookable once filmed.destination— object — One end of the move, as the customer gives it.idempotency_key— string — Any unique string per intended job (a UUID, your order id). For 24 hours, the same key with the same body returns the ORIGINAL 201 body with `Idempotent-Replayed: true` and creates nothing; the same key with a different body is a 422 `idempotency_key_reused`; the same key while the first request is still running is a 409 `idempotency_in_progress` with `Retry-After: 1`. Scoped to your account and partitioned by the calling key's kind and mode. Omit it and the request is never deduplicated.
Hints: read-only no · destructive no · idempotent not declared · open-world no
list_jobsread-onlyList jobs for the tenant, newest first. Secret key only. Paged: pass `limit` (1–100, default 25), optional `status`, and `cursor` from the previous page's `next_cursor` (null on the last page; a bad cursor is a 400). Scope: jobs:read.
Parameters:
limit— integercursor— string — Opaque; from the previous response's next_cursor.status— string — Funnel order. **created** — The job exists. Nothing uploaded yet. **uploading** — An upload URL was issued; the video is on its way. **uploaded** — A chunked upload was assembled (a single PUT skips this state). **queued** — POST /submit accepted; waiting its turn to be analysed. **processing** — The walkthrough is being analysed. Poll GET /jobs/{id}; typically 1–4 minutes. **complete** — Inventory ready. The firm quote is computed on the first read. **quoted** — A firm, bookable quote exists (set by the first GET after complete). **booked_requested** — The customer asked to book; the mover has not answered yet. **booked** — The mover confirmed the booking. **declined** — The mover turned the request down. `decline_reason` may say why. **error** — Analysis failed. `error` carries a message; upload again or contact the mover.
Hints: read-only yes · destructive no · idempotent not declared · open-world no
get_jobread-onlyFull job state: status, inventory, quote, access, terms, move_date. Scope: jobs:read.
Parameters:
job_id(required) — string — The job's ULID
Hints: read-only yes · destructive no · idempotent not declared · open-world no
set_contactStore customer email + optional name + move date. Sends NOTHING — required before upload-url. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)email(required) — stringconsent(required) — boolean — Must be true. Express consent to email about this quote.name— stringmove_date— ['string', 'null'] — Null clears; absent leaves unchanged.
Hints: read-only no · destructive no · idempotent not declared · open-world no
create_upload_urlPresigned upload for the walkthrough video. Requires stored contact email. Body: { content_type, consent, size }. Send the byte size: at or above 16 MB the response carries `multipart` (an upload_id, a part_size and a presigned PUT per part) instead of `upload`, and each part is retried on its own rather than restarting the whole video. Report each part's ETag to /upload-complete. Below the threshold, or if opening a multipart upload fails, the response is a single `upload`. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)content_type(required) — string — A video/* MIME typeconsent(required) — boolean — Must be true: the customer agrees the video will be analysed and shared with the mover.size— integer — Byte size of the file. Decides single vs multipart.
Hints: read-only no · destructive no · idempotent not declared · open-world no
complete_uploadAssemble a chunked upload. Body: { upload_id, parts: [{ part_number, etag }] }. Only after every part has been PUT; then call /submit. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)upload_id(required) — string — From the multipart ticketparts(required) — array — Every part, in any order
Hints: read-only no · destructive no · idempotent not declared · open-world no
submit_jobQueue the uploaded video for analysis. Poll GET /jobs/{id} for status. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)
Hints: read-only no · destructive no · idempotent not declared · open-world no
hand_off_videoServer-side handoff: give us a public https URL of the walkthrough instead of uploading it from a browser. Secret key only. We fetch it (up to 500 MB, streamed) and the job runs exactly as an upload would — poll GET /jobs/{id}. Needs the stored contact email and consent, like /upload-url. Replaces /upload-url, /upload-complete and /submit for a caller that already holds the file. A job whose fetch failed (`error`) may be handed a new URL. Counts toward the mover's daily analysis cap (429). Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)url(required) — string — Public https URL that serves the video (a signed cloud-storage link is ideal). Private hosts and http are refused.consent(required) — boolean — Must be true: the customer agrees the video will be analysed and shared with the mover.content_type— string — A video/* MIME type when you know it; otherwise the host's Content-Type must be video/*
Hints: read-only no · destructive no · idempotent not declared · open-world no
confirm_accessConfirm floors / elevator / stairs / carry distance for both ends. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)origin— object — What a customer can actually answer about one end. Only these fields are writable; inferred values are kept.move_date— ['string', 'null'] — YYYY-MM-DDdestination— object — What a customer can actually answer about one end. Only these fields are writable; inferred values are kept.
Hints: read-only no · destructive no · idempotent not declared · open-world no
edit_itemsEdit inventory (quantity, exclude, add by item_key). Response carries the re-priced quote. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)items(required) — array — Non-empty. Any edit clears the customer's approval and the e-signature.
Hints: read-only no · destructive no · idempotent not declared · open-world no
approve_inventoryCustomer sign-off on the inventory, plus free-text notes. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)notes— string — Up to 2000 chars; absent leaves unchangedapproved— boolean — Default true. false withdraws the sign-off.
Hints: read-only no · destructive no · idempotent not declared · open-world no
acknowledge_gapsRecord the customer's answer to the capture-gap prompts (inventory.gaps on GET /jobs/{id}). Body: { acknowledged: true } stamps "nothing is missing"; false clears it. The prompts themselves are recomputed from the current inventory on every read, so fixing a gap removes its prompt without this call. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)acknowledged— boolean — Default true
Hints: read-only no · destructive no · idempotent not declared · open-world no
send_resume_linkEmail the customer their resume link. Only on explicit request. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)email(required) — stringconsent(required) — boolean — Must be truename— string
Hints: read-only no · destructive no · idempotent not declared · open-world no
request_bookingRequest the booking. Idempotent per job; requires approve:true (types-name-as-signature approval of the inventory + quote, stored with a quote snapshot) and accept_terms when the mover has terms. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)name(required) — string — The submitted name is the signature on the approval.email(required) — stringapprove(required) — boolean — Must be true: approves the inventory as complete and this quote. Cleared if the inventory is edited afterwards.phone— stringaccept_terms— boolean — Required (true) when the job's `terms.terms` is non-null
Hints: read-only no · destructive no · idempotent not declared · open-world no
report_outcomeReport actuals (hours, final cents, crew). Secret key only. Scope: outcomes.
Parameters:
job_id(required) — string — The job id (ULID)notes— string — Up to 1000 charsactual_crew— integeractual_hours— numberactual_total_cents— integer — What was actually billed, in integer cents. Currency travels beside it — never assume USD.
Hints: read-only no · destructive no · idempotent not declared · open-world no
get_cube_sheet_csvread-onlyItemized cube sheet as CSV (Excel-ready): rooms, volumes, weights, exclusions. Secret key only. Scope: jobs:read.
Parameters:
job_id(required) — string — The job id (ULID)
Hints: read-only yes · destructive no · idempotent not declared · open-world no
get_date_pricesread-onlyThis job's quote priced across a ~2-week window from the mover's date rules. flat=true means every day prices the same. Scope: jobs:read.
Parameters:
job_id(required) — string — The job id (ULID)
Hints: read-only yes · destructive no · idempotent not declared · open-world no
set_move_dateSet or clear the move date; invalidates and recomputes the quote. Refused after a booking is requested. Scope: jobs:write.
Parameters:
job_id(required) — string — The job id (ULID)date— ['string', 'null'] — YYYY-MM-DD, or null to clear.
Hints: read-only no · destructive no · idempotent not declared · open-world no
quote_inventoryDirect pricing for agents: items or total_cuft in, firm quote out. Secret key only. Scope: quote.
Parameters:
items— array — …or this, priced from the catalogorigin— object — One end of the move, as the customer gives it.move_date— string — YYYY-MM-DDtotal_cuft— number — Either this…destination— object — One end of the move, as the customer gives it.rate_card_id— string — A specific card of this mover's; default the active onedistance_miles— numbertotal_weight_lbs— number — Optional with total_cuft; derived from items otherwise
Hints: read-only no · destructive no · idempotent not declared · open-world no
get_availabilityread-onlyWhich days the mover has marked off, before a job exists. Soft: a marked day can still be requested — the mover confirms and calls first — so steer to an open day when the customer has a choice. Scope: quote.
Parameters:
days— integer — Window length; values above 90 are capped.from— string — First day, YYYY-MM-DD. Default tomorrow; earlier dates clamp to tomorrow.
Hints: read-only yes · destructive no · idempotent not declared · open-world no
list_keysread-onlyList the account's API keys — live and test, active and revoked. Never a raw secret. Secret key with the `keys` scope. Scope: keys.
Hints: read-only yes · destructive no · idempotent not declared · open-world no
create_keyMint a key. The raw secret is in THIS response only. A key can never mint one broader than itself; a test key mints only test keys; a live secret key may mint the sandbox pair. Scope: keys.
Parameters:
kind— stringmode— string — Default: the calling key's mode.label— string — Up to 80 chars, e.g. 'CRM sync'scopes— ['array', 'null'] — null (default) = everything the kind allows
Hints: read-only no · destructive no · idempotent not declared · open-world no
rotate_keyReplace a key with its twin (same kind, mode, scopes, label). The old key keeps working until `replaced.expires_at` so a deploy can swap values without a gap. Needs the `keys` scope even to rotate itself — rotate a scoped key with a full key or from the dashboard. A key is rotated once: rotating it again is a 409 `key_already_rotated`, and during its grace the old key cannot mint, rotate, revoke or read deliveries (403 `key_rotated`). A test key cannot rotate a live key (403 `mode_mismatch`). Scope: keys.
Parameters:
id— string — Which key. Default: the key making this call.grace_hours— integer — 0 revokes the old key immediately.
Hints: read-only no · destructive no · idempotent not declared · open-world no
revoke_keyRevoke a key immediately. The only live publishable key is refused (409) — rotate it instead. A test key cannot revoke a live key (403 `mode_mismatch`). Scope: keys.
Parameters:
id(required) — string
Hints: read-only no · destructive no · idempotent not declared · open-world no
list_webhook_deliveriesread-onlyThe delivery log: every webhook POST for 30 days, newest first, with its outcome and the exact body sent. Secret key with the `keys` scope. A key reads the deliveries of its own mode: live keys the live log, test keys the sandbox log. Scope: keys.
Parameters:
limit— integerbefore— string — The previous page's next_beforejob_id— string — Everything sent about one jobwebhook_id— string — One endpoint only
Hints: read-only yes · destructive no · idempotent not declared · open-world no
replay_webhook_deliveryRe-send one delivery to its endpoint: the same body byte for byte (same envelope id, so your dedupe still works) under a fresh signature, with the usual retries. Returns the replay's own delivery record. Deliveries of the other mode are not found (404). Scope: keys.
Parameters:
id(required) — string — A delivery id from the log
Hints: read-only no · destructive no · idempotent not declared · open-world no
search_catalogread-onlySearch the cube-sheet catalog (?q=sofa). Scope: quote.
Parameters:
q(required) — string — Name, synonym or key fragment
Hints: read-only yes · destructive no · idempotent not declared · open-world no
suggest_addressesAddress autocomplete (proxied; send session_token). Scope: quote.
Parameters:
input— string — What the customer has typed so farsession_token— string — Any opaque string, kept for the whole typing session and the resolve call
Hints: read-only no · destructive no · idempotent not declared · open-world no
resolve_addressResolve a suggestion to a full address (same session_token). Scope: quote.
Parameters:
place_id— stringsession_token— string
Hints: read-only no · destructive no · idempotent not declared · open-world no
Measured by MCPYP probing. Untested fields are omitted, never estimated. Listing is always free; MCPYP never proxies calls or stores user tokens.