Skip to content

Scribe API Reference

This document provides complete API reference for integrating with Scribe’s session management and preference detection system.

Retrieve current session preferences and readiness state.

GET /sessions/scribe-status
{
"ready": true,
"session_age_minutes": 15,
"properties_viewed": 8,
"average_confidence": 72,
"preferences": {
"price": {
"min": 400000,
"max": 600000,
"confidence": 85,
"source": "inferred"
},
"bedrooms": {
"min": 3,
"confidence": 75,
"source": "inferred"
},
"locations": [
{
"value": "Twin Falls",
"confidence": 90,
"source": "inferred"
}
],
"features": [
{
"key": "pool",
"value": "Pool",
"confidence": 65,
"source": "inferred"
}
]
},
"freeform_notes": "Need to be near Lincoln Elementary",
"assigned_agent_id": null
}
CodeMeaning
200Success, status returned
404No session found

Retrieve matched agents for current session preferences.

GET /sessions/suggested-agents
{
"agents": [
{
"id": "agent_123",
"name": "Jane Smith",
"email": "jane@example.com",
"photo_url": "https://...",
"match_score": 87,
"match_label": "Excellent Match",
"best_match": true,
"reasons": [
"Specializes in Twin Falls family homes",
"Expert in $400k-$600k price range"
]
},
{
"id": "agent_456",
"name": "John Doe",
"email": "john@example.com",
"photo_url": "https://...",
"match_score": 68,
"match_label": "Great Match",
"best_match": false,
"reasons": [
"Knows the best neighborhoods with pools"
]
}
]
}
ParameterTypeDescription
limitintegerMaximum agents to return (default: 3, max: 10)
CodeMeaning
200Success, agents returned
400Preferences not ready (insufficient confidence)
404No session found

Assign a selected agent to the visitor’s session.

POST /sessions/assign-agent
Content-Type: application/json
{
"agent_id": "agent_123"
}
{
"success": true,
"agent": {
"id": "agent_123",
"name": "Jane Smith",
"email": "jane@example.com"
}
}
CodeMeaning
200Agent assigned successfully
400Invalid agent_id
404No session or agent not found

Delete all session data for the current visitor.

POST /sessions/clear
{
"success": true,
"message": "All session data cleared"
}
CodeMeaning
200Data cleared successfully
404No session found

Retrieve all session preferences with confidence scores.

GET /sessions/preferences
{
"price": {
"min": 400000,
"max": 600000,
"confidence": 85,
"source": "inferred",
"confirmed": false
},
"bedrooms": {
"min": 3,
"confidence": 100,
"source": "user_added",
"confirmed": true
},
"locations": [
{
"value": "Twin Falls",
"confidence": 90,
"source": "inferred",
"confirmed": false
}
],
"features": [
{
"key": "pool",
"value": "Pool",
"confidence": 65,
"source": "inferred",
"confirmed": false
}
],
"negative": [
{
"type": "property_type",
"value": "condo",
"confidence": 75,
"source": "inferred"
}
]
}

Manually add a preference with 100% confidence.

POST /sessions/preferences
Content-Type: application/json
{
"type": "features",
"key": "home_office",
"value": "Home office space"
}
FieldTypeRequiredDescription
typestringYesprice, bedrooms, bathrooms, locations, features, property_types
keystringSometimesRequired for features and property_types
valuestring/numberYesPreference value
{
"success": true,
"preference": {
"type": "features",
"key": "home_office",
"value": "Home office space",
"confidence": 100,
"source": "user_added"
}
}
CodeMeaning
201Preference created
400Invalid request body
404No session found

Update confidence on an inferred preference.

POST /sessions/preferences/{type}/{key}/confirm
Content-Type: application/json
{
"action": "confirm"
}
ParameterDescriptionExample
typePreference typefeatures, locations, price
keyPreference keypool, twin_falls, budget
FieldTypeValuesEffect
actionstringconfirmSets confidence to 100%
rejectSets confidence to 0% (excluded from matching)
{
"success": true,
"preference": {
"type": "features",
"key": "pool",
"value": "Pool",
"confidence": 100,
"source": "inferred",
"confirmed": true
}
}
CodeMeaning
200Preference updated
400Invalid action
404Preference not found

Remove a manually added preference.

DELETE /sessions/preferences/{type}/{key}
{
"success": true,
"message": "Preference deleted"
}
CodeMeaning
200Preference deleted
403Cannot delete inferred preference
404Preference not found

Store visitor’s freeform preference text.

POST /sessions/preferences/notes
Content-Type: application/json
{
"notes": "Need to be near Lincoln Elementary, home office space required"
}
{
"success": true,
"notes": "Need to be near Lincoln Elementary, home office space required"
}
CodeMeaning
200Notes saved
400Invalid notes (too long)
404No session found

Submit behavioral events for preference inference.

POST /sessions/events
Content-Type: application/json
{
"events": [
{
"type": "property_view",
"listing_id": "12345",
"timestamp": "2024-01-15T10:30:00Z",
"engagement": {
"time_seconds": 180,
"scroll_percent": 85,
"photos_viewed": 8
}
},
{
"type": "photo_engagement",
"listing_id": "12345",
"photo_index": 3,
"dwell_ms": 5200,
"zoomed": true,
"timestamp": "2024-01-15T10:32:00Z"
},
{
"type": "filter_change",
"filter": "price_max",
"value": 600000,
"timestamp": "2024-01-15T10:35:00Z"
}
]
}

Tracks property page visits.

FieldTypeRequiredDescription
typestringYesproperty_view
listing_idstringYesMLS listing ID
timestampISO-8601YesEvent time
engagementobjectNoEngagement metrics
engagement.time_secondsnumberNoTime on page
engagement.scroll_percentnumberNoMax scroll depth (0-100)
engagement.photos_viewednumberNoPhoto carousel views
engagement.used_calculatorbooleanNoUsed mortgage calculator
engagement.downloaded_pdfbooleanNoDownloaded flysheet

Tracks individual photo interactions.

FieldTypeRequiredDescription
typestringYesphoto_engagement
listing_idstringYesMLS listing ID
photo_indexnumberYesPhoto position (0-based)
dwell_msnumberYesMilliseconds viewing photo
zoomedbooleanNoWhether photo was zoomed
timestampISO-8601YesEvent time

Tracks explicit filter applications.

FieldTypeRequiredDescription
typestringYesfilter_change
filterstringYesFilter name (price_min, price_max, beds, baths, etc.)
valueanyYesFilter value
timestampISO-8601YesEvent time

Tracks natural language searches.

FieldTypeRequiredDescription
typestringYessearch_query
querystringYesSearch text
timestampISO-8601YesEvent time

Tracks favorite actions.

FieldTypeRequiredDescription
typestringYesfavorite_added or favorite_removed
listing_idstringYesMLS listing ID
timestampISO-8601YesEvent time
{
"success": true,
"processed": 3,
"updated_preferences": ["price", "features"]
}
CodeMeaning
200Events processed
400Invalid event format
404No session found

Client-side events are batched for efficiency:

SettingValuePurpose
Debounce interval5 secondsWait time before sending batch
Max queue size50 eventsForces immediate flush when exceeded
Delivery methodfetch() with keepalive: trueEnsures delivery even during navigation
Page unloadnavigator.sendBeacon()Reliable delivery when closing tab
class ScribeEventBatcher {
constructor() {
this.queue = [];
this.timer = null;
}
track(event) {
this.queue.push({
...event,
timestamp: new Date().toISOString()
});
// Flush immediately if queue is full
if (this.queue.length >= 50) {
this.flush();
return;
}
// Otherwise debounce
clearTimeout(this.timer);
this.timer = setTimeout(() => this.flush(), 5000);
}
async flush() {
if (this.queue.length === 0) return;
const events = [...this.queue];
this.queue = [];
await fetch('/sessions/events', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ events }),
keepalive: true
});
}
}
// Ensure events are sent on page unload
window.addEventListener('beforeunload', () => {
if (batcher.queue.length > 0) {
navigator.sendBeacon(
'/sessions/events',
JSON.stringify({ events: batcher.queue })
);
}
});

EndpointLimitWindow
/sessions/events100 requests15 minutes
/sessions/preferences50 requests15 minutes
All other endpoints30 requests15 minutes

Rate limit headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705329600