Status: Stub — architecture is finalized, REST endpoint not yet live. Pre-launch reference for partner conversations. ETA for the endpoint: ~1 week from 2026-06-02.
Showingly is the showing-coordination layer underneath real estate. We handle the messy multi-party orchestration of getting a buyer in front of a listing — slot picking, listing-agent confirmation, lockbox code delivery, feedback collection — so you don't have to.
If your product touches real estate buyers and you want to offer showing scheduling without building a showings team, this is for you.
The one-line summary
Your service POSTs to one endpoint. We give you back a URL. You point your user at it. We handle the rest.
That's the entire integration model. No SDK, no JavaScript snippet, no platform-specific work. Just an HTTP POST and a redirect.
Who this is for
- Discovery layers — agent-matching apps, brokerage portals, "find an agent" services. When a buyer matches with an agent in your product, hand the showing-coordination off to us.
- Video providers — when a viewer hits "Schedule a Showing" inside your player, send them to us. The viewer metadata (watch %, replays) flows through as a warmth signal.
- Search apps — IDX-powered websites, mobile listing apps, AI-driven property search. Add a showing-scheduling CTA without owning the calendar logic.
- AI-agent builders — if your AI books showings for users, talk to us about MCP. See MCP integration below.
- CRMs and brokerage platforms — embed showing actions inside your existing agent workflow.
The flow
┌──────────────────────┐ ┌──────────────────────┐
│ Your service │ │ Showingly │
│ (discovers a buyer │ │ │
│ wants a showing) │ │ │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
│ 1. POST /api/v1/showing-intents │
│ { listing_id, buyer, ... } │
│ ─────────────────────────────────────▶ │
│ │
│ 2. { intent_id, resume_url, │
│ sms_number, expires_at } │
│ ◀───────────────────────────────────── │
│ │
│ 3. Redirect buyer → resume_url │
│ (or hand them sms_number) │
│ │
│ │ ◀─── Buyer interacts:
│ │ picks slot, etc.
│ │
│ 4. We webhook your callback_url │
│ on state changes │
│ ◀───────────────────────────────────── │
│ │
│ (state machine drives │
│ listing-agent approval, │
│ lockbox delivery, │
│ feedback collection) │
│ │
│ 5. Final webhook: │
│ { state: 'complete' } │
│ ◀───────────────────────────────────── │
Create a showing intent
POST https://www.showingly.com/api/v1/showing-intents
Authorization: Bearer pk_partner_<your-key>
Content-Type: application/json
{
"listing_id": "lst_abc123",
"buyer": {
"name": "Sarah Park",
"phone": "+13035551234",
"email": "sarah@example.com"
},
"buyer_agent_id": "agt_xyz789",
"requested_window": {
"earliest": "2026-06-08T18:00:00Z",
"latest": "2026-06-09T02:00:00Z"
},
"source_metadata": {
"match_id": "tch_match_42"
},
"callback_url": "https://your-domain.com/webhooks/showings"
}
Required
listing_id— Showingly's listing ID, or{ "mls_id": "<id>", "mls": "<mls-name>" }if you only have MLS data
Strongly preferred
buyer.phone— verified phone is the strongest identity anchor. Without it, we'll capture it on the resume URL or via SMS first-touch.buyer_agent_id— if your product already knows which agent is representing the buyer
Optional
buyer.name,buyer.emailrequested_window— if your user picked a rough time window. Without it, we ask the buyer.source_metadata— partner-specific context (video watch %, match ID, anything). Indexed for analytics; surfaces to the listing agent as a warmth signal.callback_url— your webhook for state changes. Without it you'd need to poll the GET endpoint.
Response
{
"intent_id": "si_01HXVZ...",
"state": "pending_slot_selection",
"resume_url": "https://www.showingly.com/i/si_01HXVZ...",
"sms_number": "+17204440000",
"expires_at": "2026-06-03T18:00:00Z"
}
Three things you can do with the buyer:
- Redirect to
resume_url— they'll see our scheduling UI with the intent loaded and their context preserved - Tell them to text
sms_number— for mobile contexts or if you'd rather not redirect them - Wait for state-change webhooks on
callback_urlif you registered one
State machine
Every intent passes through one of these states. We webhook your callback_url on every transition.
| State | Meaning |
|---|---|
pending_buyer_info | We don't have enough info to proceed (no phone or no name) |
pending_slot_selection | Slots have been offered; awaiting buyer pick |
pending_listing_agent_approval | Slot picked; awaiting listing-agent confirm (often auto-confirmed) |
confirmed | Locked in. Calendars updated. |
in_progress | Within the showing window. Lockbox code delivered. |
complete | Showing happened. Feedback collected. |
cancelled | Explicitly cancelled by buyer or listing agent |
expired | Auto-cancelled — no activity for N hours |
Webhooks
We POST to your callback_url on every state change. Signed with HMAC-SHA256 in the X-Showingly-Signature header.
POST https://your-domain.com/webhooks/showings
X-Showingly-Signature: t=1717372800,v1=abc123...
Content-Type: application/json
{
"event": "showing-intent.state-changed",
"intent_id": "si_01HXVZ...",
"from_state": "pending_slot_selection",
"to_state": "pending_listing_agent_approval",
"at": "2026-06-08T18:42:31Z",
"intent": { /* full ShowingIntent object */ }
}
Retry with exponential backoff on non-2xx responses. Idempotency keys per event so you can safely accept retries.
Concrete examples
Discovery layer (Tochigami-style)
You match a buyer with an agent. You want Showingly to handle every showing the buyer schedules with that agent from this point on.
// When buyer matches with agent
const intent = await fetch('https://www.showingly.com/api/v1/showing-intents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${SHOWINGLY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
listing_id: matchedListing.id,
buyer: { name: buyer.name, phone: buyer.phone, email: buyer.email },
buyer_agent_id: agent.showingly_id,
source_metadata: { match_id: match.id, platform: 'tochigami' },
callback_url: 'https://tochigami.com/webhooks/showings',
}),
}).then(r => r.json());
// Hand off to Showingly
window.location.href = intent.resume_url;
// or, if you prefer mobile:
// alert(`Text ${intent.sms_number} to schedule`);
Video player (WellcomeMat-style)
Viewer clicks "Schedule a Showing" inside your player. You want them to schedule without leaving the video page.
player.on('schedule-click', async (event) => {
const intent = await fetch('https://www.showingly.com/api/v1/showing-intents', {
method: 'POST',
headers: { 'Authorization': `Bearer ${SHOWINGLY_API_KEY}` },
body: JSON.stringify({
listing_id: event.listing_id,
source_metadata: {
watch_percentage: player.completionRatio,
replay_count: player.replayCount,
time_on_kitchen_segment: player.segmentDwell('kitchen'),
},
callback_url: 'https://your-video-platform.com/webhooks/showings',
}),
}).then(r => r.json());
// Open an iframe modal on top of your player
showInlineModal(intent.resume_url);
});
The source_metadata payload is high-signal — a viewer who watched 92% and rewound the kitchen twice is a warmer lead than a click from a still photo. We surface that to the listing agent as part of the showing request.
Generic search app
Same pattern. Add a "Schedule a Showing" button. On click, POST and redirect.
MCP integration
If you're building an AI agent that books showings on behalf of users, don't use the REST API. Use our MCP server.
Install:
npx showingly-mcp configure
Adds a server entry to claude_desktop_config.json (or your equivalent). Your agent gets these tools:
search_listings(query)get_availability(listing_id, date_range)request_showing(listing_id, buyer, window)— creates an intentget_showing_status(intent_id)cancel_showing(intent_id)
The MCP tools are thin wrappers around the same REST endpoints. The benefit is your agent doesn't need to know about HTTP — it speaks MCP natively.
Get an API key
We're in private beta. Request access and tell us:
- What you're building
- What audience you serve (agents, buyers, AI builders)
- Rough integration volume estimate
We'll respond and walk you through onboarding. Keys come in two flavors:
- Partner key (
pk_partner_*) — full REST access, webhook-eligible, can create intents on behalf of buyers - MCP key (
mcp_*) — scoped to MCP tools, for AI-agent builders
Questions
Direct: partners@showingly.com