Leads and Showings
Webhook
The ShowMojo Webhook allows you to receive real-time notifications about lead and showing events via HTTP POST.
Overview
This webhook is triggered whenever a lead or showing is created, updated, or changed. The webhook will POST a JSON payload to the configured endpoint URL in ShowMojo.
Configuration can be found in the Leads Webhook section.
With a webhook and a programmer, you can export data almost anywhere. Even platforms like Zapier or Podio might be enough — no custom code required.
Security
Every request is signed. Two headers carry the signature:
X-ShowMojo-Timestamp: Unix time, in seconds, when ShowMojo sent the requestX-ShowMojo-Signature: lowercase hex HMAC-SHA256 of<timestamp>.<raw request body>, keyed with your webhook's signing secret
Find the signing secret, or generate a new one, in the Leads Webhook section.
To verify a request:
- Read the raw request body before parsing it as JSON.
- Compute HMAC-SHA256 of the
X-ShowMojo-Timestampvalue, a., and the raw body, with the signing secret as the key, and hex-encode it. - Compare the result with
X-ShowMojo-Signatureusing a constant-time comparison. - Reject requests whose timestamp is more than five minutes old.
Ruby (Rails):
def showmojo_request?(request, secret)
timestamp = request.headers['X-ShowMojo-Timestamp'].to_s
expected = OpenSSL::HMAC.hexdigest('SHA256', secret, "#{timestamp}.#{request.raw_post}")
(Time.now.to_i - timestamp.to_i).abs <= 300 &&
ActiveSupport::SecurityUtils.secure_compare(expected, request.headers['X-ShowMojo-Signature'].to_s)
end
Node.js:
const crypto = require('crypto');
function isShowMojoRequest(rawBody, headers, secret) {
const timestamp = headers['x-showmojo-timestamp'] || '';
const signature = headers['x-showmojo-signature'] || '';
const expected = crypto.createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
return Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300 &&
signature.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
Deprecated: HTTPS endpoints configured before request signing was introduced still receive
Authorization: Bearer <API token>. Endpoints configured since then never receive it, and the header will be removed for all endpoints. Verify the signature instead and do not rely on the Bearer token.
Delivery and retries
- ShowMojo sends each event once and waits up to 15 seconds for your response.
- Respond with
200 OK. Any other status, including other2xxcodes, a timeout or a connection error, counts as a failed attempt. - A failed attempt is retried up to 5 times, after 5, 15, 45, 135 and 405 minutes (about 10 hours in total). After the last retry the event is dropped and not sent again.
- If 5 events exhaust their retries within 24 hours, the webhook is disabled and the account owner receives an email. Fix the endpoint, then re-enable the webhook in the Leads Webhook section. Events that occur while it is disabled are not sent.
Replay and duplicates
- Every event has a unique, increasing
event.id. A retry carries the sameevent.id. Its body is rebuilt at send time, so it may reflect a later state of the lead or showing, and the signature headers are computed fresh for each attempt. - Keep the
event.idvalues you have processed and ignore a request whose id you have already seen. - Reject requests whose
X-ShowMojo-Timestampis more than five minutes old, so a captured request cannot be replayed later. - Out-of-order delivery is possible, for example when an earlier event is retried after a later one succeeded. Use
event.idto order events.
Notes
- HTTPS is strongly preferred
- Some fields may be
null(especially timestamps)
Actions Reference
All 169 values of event.action, with the meaning shown in the ShowMojo showing history
event.action | Meaning |
|---|---|
accept | Accepted |
acceptance_reminder | Showtime acceptance reminder sent |
acceptance_reminder_approvers | Showtime acceptance reminder sent to approvers |
acceptance_reminder_owner_agent | Showtime acceptance reminder sent to you |
acceptance_request | Showtime acceptance requested |
accept_for_everyone | Showtime accepted for everyone |
accept_for_me | Showtime accepted |
additional_document_received | Document received |
additional_document_requested | Document manually requested |
additional_document_request_sent | Document requested |
ai_web_conversation_ended | AI web chat conversation |
annual_follow_up_email | Annual follow up email sent |
answer_resent | Answer to prospect question resent |
answer_security_questions | Answer security questions |
answer_security_questions_third_failure | Third failed attempt to answer security questions within 24 hours |
appfolio_user_assignment_failed | User assignment failed in AppFolio due to user permissions |
applicant_transitioned_from_resident | Resident transitioned to applicant |
applicant_transitioned_to_resident | Applicant transitioned to resident |
assign_unclaimed_showing_to_owner | Assign unclaimed showing to account owner |
auto_cancel_no_reply | Auto-canceled due to no reply |
auto_create_by_sms | Showing auto-created by SMS |
blacklisted_asn_passed_anti_fraud_checks | Access code not distributed because the showing was flagged for potential fraudulent activity |
blacklisted_asn_passed_only_location_verification | Access code not distributed because the showing was flagged for potential fraudulent activity |
blacklisted_prospect | Email and phone blacklisted |
call_redirected | Redirected |
call_redirect_ended | Live call |
call_transferred_from_cci | Live call was transferred from Live Answer to Property Manager |
call_transferred_to_cci | Live call was transferred to Live Answer |
call_transferred_to_regular_queue | Live call transferred to regular queue |
call_transferred_to_self_show_escalation_queue | Live call transferred to self-show escalation queue |
cancel | Canceled |
cancel_identity_verification_failed | Canceled because identity verification failed |
cancel_notice | Cancel notice sent |
cancel_phone_or_email_blacklisted | Canceled because phone or email is blacklisted |
cancel_warning | Cancel warning sent |
cci_prospect_asked_question | Prospect question submitted |
cci_screening_criteria_not_met | Screening criteria was not met when scheduled via Live Answer |
claimed | Claimed |
claim_request | Claim requested |
confirm | Confirmed |
confirm_automatically | Automatically confirmed |
confirm_insecured_lockbox | Property NOT secured reported |
confirm_lockbox_outcome_no_show | Prospect did not make showing |
confirm_request | Confirm requested |
confirm_secured_lockbox | Property secured reported |
confirm_secured_lockbox_request | Confirm secured property requested |
create | Showing created |
decline | Showtime rejected |
decline_proposed_times | Proposed showtimes rejected |
document_auto_approved_because_not_reviewed_in_time | Document auto-approved because was not reviewed in time |
document_received | Document for verification sent |
document_rejected | Document rejected |
document_request_resent | Document request resent |
document_verification_request | Document verification request sent |
document_verified | Document verified |
dont_follow_up | Follow up stopped |
do_follow_up | Follow up started |
email_address_updated | Email address changed to |
email_application_criteria_link | Emailed application criteria link |
email_apply_now_link | Emailed application link |
email_delivery_failed | Email delivery failed |
email_link | Emailed a link |
email_on_new_active_listing | New active listing email sent |
email_on_off_market_listing | Listing off market nurturing email sent |
email_on_reannounce_new_listing | New listing reannouncement email sent |
email_on_rent_reduction | Rent reduction email sent |
emergency_reschedule_request | Emergency reschedule requested |
flagged_as_fraudulent | Flagged as fraudulent |
follow_autoreply | Followed auto-reply |
follow_up_reschedule | Follow up reschedule request sent |
fraud_or_scam_report_sent | Sent report about potential fraud activity to agent |
hide | Hidden |
identity_verification_failed | Identity verification failed |
identity_verification_failed_auth_attempts_limit_exceeded | Identity verification failed (exceeded limit of Precise ID Authentication attempted) |
identity_verification_failed_recently_failed | Identity verification failed (recently failed Precise ID) |
identity_verification_passed | Identity verification passed |
identity_verification_requested | Identity verification requested |
identity_verification_skipped_recently_passed | Identity verification skipped (recently passed Precise ID) |
inquired | Inquired |
inquired_about_multi_unit | Inquired about multi unit property |
inquired_about_off_market_listing | Inquired about off market listing |
instant_schedule_call_attempted | AI Instant Schedule call attempt |
instant_schedule_handoff | AI Instant Schedule handed off to an agent |
instant_schedule_initiated | AI Instant Schedule initiated |
last_reminder | Reminder sent |
lead_converted_by_cci | Lead was converted to showing |
lead_created | Lead created |
lead_created_by_off_market_update_process | Lead created by adding an applicant in Required Listing Updates |
lead_showing_denied_custom_question | Showing denied (didn't meet requirements) |
lead_showing_denied_income | Showing denied (didn't meet income requirement) |
lead_showing_denied_move_in_date | Showing denied (didn't meet move-in date requirement) |
lead_showing_denied_pets | Showing denied (didn't meet pet requirements) |
lead_updated | Lead updated |
left_voicemail | Voicemail |
location_verification_auto_triggered | Location verification anti-fraud measure added |
location_verification_based_on_scheduling_anomaly | Location verification added based on scheduling anomaly |
lockbox_code_distributed | Access code was sent to the prospect |
lockbox_code_requested | Access code requested |
lockbox_showing_started | Self-showing started |
notified_showtimes_available | Notified that showtimes are available |
outgoing_call_completed | Outgoing call completed |
outgoing_call_started | Outgoing call started |
pet_screening_sent | Pet screening request sent |
phone_for_lockbox_phone_call_verification_assigned | Phone number for Phone Call Verification assigned |
phone_number_changed | Phone number changed |
phone_verification_call_access_code_distributed | Access code via verification call was sent to the prospect |
phone_verification_call_access_code_distributed_after_no_answer | Access code via verification call distributed after no phone answer |
phone_verification_call_access_denied_during_call | Access denied during verification call |
phone_verification_call_hung_up_before_answer | Verification call hung up before answered |
phone_verification_call_not_answered | Verification call not answered |
pre_screen_completed | Pre-screen completed |
pre_screen_overridden | Pre-screen overridden |
pre_screen_reminder_sent | Pre-screen reminder sent |
pre_screen_request_sent | Pre-screen request sent |
pre_showing_reminder_sent | Pre-showing reminder sent |
proposed_times | Proposed times |
proposed_times_accpt_request_sent | Proposed times acceptance request sent |
prospect_arrived_too_late | Prospect arrived at showing too late |
prospect_question_processed_with_answer | Inquiry reviewed and answered |
prospect_question_processed_with_forwarding | Inquiry forwarded for an answer |
prospect_question_processed_with_no_answer | Inquiry had no question |
question_answered | Prospect question answered |
reply_needed_score_updated | Reply needed score was updated |
report_shared | Report shared |
report_unshared | Stop sharing report |
requested_application_criteria | Requested application criteria |
requested_availability_notification | Requested availability notification |
reschedule_request | Reschedule requested |
reschedule_request_on_answers_not_received | Reschedule requested because answers not received |
reschedule_request_on_document_not_received | Reschedule requested because document not received |
reschedule_request_on_document_not_verified | Reschedule requested because document not verified |
restore | Restored |
screening_requested | Applicant screening requested |
screening_request_automatically | Applicant screening requested automatically |
screening_request_email_sent | Applicant screening request sent |
screening_request_text_sent | Applicant screening request sent |
second_year_follow_up_email | Second year follow up email sent |
send_upcoming_showings | Send upcoming showings link |
sent_access_code_email_fallback | Access code emailed (SMS fallback) |
sent_answers_request | Answers request sent |
sent_autoreply | Auto-reply sent |
sent_autoreply_followup | Sent auto-reply follow-up |
sent_document_and_answers_request | Document and answers request sent |
sent_document_request | Document request sent |
sent_follow_up | Follow up sent |
sent_self_showing_follow_up | Self-showing follow up sent |
set_no_show | Reported as a no show |
showing_denied_custom_question | Showing denied and canceled |
showing_denied_custom_question_reason | Prospect didn't meet requirements |
showing_denied_income | Showing denied and canceled |
showing_denied_income_reason | Prospect didn't meet income requirement |
showing_denied_move_in_date | Showing denied and canceled |
showing_denied_move_in_date_reason | Prospect didn't meet move-in date requirement |
showing_denied_pets | Showing denied and canceled |
showing_denied_pets_reason | Prospect didn't meet pet requirements |
showing_feedback | Feedback was left |
showing_mismatched_custom_question | Scheduling restrictor overridden for pre-scheduled showing (didn't meet requirements) |
showing_mismatched_income | Scheduling restrictor overridden for pre-scheduled showing (didn't meet income requirement) |
showing_mismatched_move_in_date | Scheduling restrictor overridden for pre-scheduled showing (didn't meet move-in date requirement) |
showing_mismatched_pets | Scheduling restrictor overridden for pre-scheduled showing (didn't meet pet requirements) |
showing_with_disabled_location_verification_passed_check | Location verification was not completed because it was disabled on the listing |
text_application_criteria_link | Texted application criteria link |
text_apply_now_link | Texted application link |
text_link | Texted a link |
third_party_applicant_added | Applicant applied outside of ShowMojo |
uncancel | Uncanceled |
unconfirm | Unconfirmed |
undo_no_show | Undone a no show |
update | Showing updated |
Supported Time Zones
Click to expand the full list
American Samoa
International Date Line West
Midway Island
Hawaii
Alaska
Pacific Time (US & Canada)
Tijuana
Arizona
Chihuahua
Mazatlan
Mountain Time (US & Canada)
Central America
Central Time (US & Canada)
Guadalajara
Mexico City
Monterrey
Saskatchewan
Bogota
Eastern Time (US & Canada)
Indiana (East)
Lima
Quito
Atlantic Time (Canada)
Caracas
Georgetown
La Paz
Santiago
Newfoundland
Brasilia
Buenos Aires
Greenland
Mid-Atlantic
Azores
Cape Verde Is.
Casablanca
Dublin
Edinburgh
Lisbon
London
Monrovia
UTC
Amsterdam
Belgrade
Berlin
Bern
Bratislava
Brussels
Budapest
Copenhagen
Ljubljana
Madrid
Paris
Prague
Rome
Sarajevo
Skopje
Stockholm
Vienna
Warsaw
West Central Africa
Zagreb
Athens
Bucharest
Cairo
Harare
Helsinki
Jerusalem
Kyiv
Pretoria
Riga
Sofia
Tallinn
Vilnius
Baghdad
Istanbul
Kuwait
Minsk
Moscow
Nairobi
Riyadh
St. Petersburg
Volgograd
Tehran
Abu Dhabi
Baku
Muscat
Tbilisi
Yerevan
Kabul
Ekaterinburg
Islamabad
Karachi
Tashkent
Chennai
Kolkata
Mumbai
New Delhi
Sri Jayawardenepura
Kathmandu
Almaty
Astana
Dhaka
Urumqi
Rangoon
Bangkok
Hanoi
Jakarta
Krasnoyarsk
Novosibirsk
Beijing
Chongqing
Hong Kong
Irkutsk
Kuala Lumpur
Perth
Singapore
Taipei
Ulaan Bataar
Osaka
Sapporo
Seoul
Tokyo
Yakutsk
Adelaide
Darwin
Brisbane
Canberra
Guam
Hobart
Melbourne
Port Moresby
Sydney
Vladivostok
Magadan
New Caledonia
Solomon Is.
Auckland
Fiji
Kamchatka
Marshall Is.
Wellington
Nuku'alofa
Samoa
Tokelau Is.
Request
Responses
- 200
- 400
- 401
Successfully received
Bad request — malformed payload
Unauthorized — invalid or missing token