Reapit · AsyncAPI Specification
Reapit Foundations Webhooks
Version
View Spec
View on GitHub
Real EstateUnited KingdomPropTechCRMEstate AgentsProperty ListingsProperty ManagementRentalsConveyancingAustraliaAsyncAPIWebhooksEvents
AsyncAPI Specification
generated: '2026-07-26'
method: searched
source: https://foundations-documentation.reapit.cloud/api/webhooks
spec_type: null
spec_status: >-
No AsyncAPI, CloudEvents or event-catalog document is published anywhere on
the Reapit estate — the GitHub org (reapit/foundations, reapit/foundations-
documentation, reapit/ts-cdk-constructs) carries none, and no /asyncapi.yaml
or /asyncapi.json exists on any host. This file is the webhook catalog
captured from the documentation, not a fabricated AsyncAPI.
description: >-
Reapit Foundations Webhooks is a genuinely complete outbound event system for
a CRM vendor: 55 published topics across 17 entity domains, per-customer
subscription (including the SBOX sandbox), JSON-Schema event filters,
Ed25519 asymmetric payload signing, documented exponential-backoff retry, and
published static source IPs for allowlisting. Events fire on data changes from
ANY application touching the customer's CRM — AgencyCloud, Property Cloud or
another AppMarket app — which is what makes it the practical integration
substrate for the UK agency market. Payload bodies reuse the same schemas as
the corresponding REST endpoints.
transport: HTTPS POST
content_type: application/json
management:
ui: https://developers.reapit.cloud/webhooks/new
manage_ui: https://developers.reapit.cloud/webhooks/manage
api: https://platform.reapit.cloud/webhooks
api_note: webhooks can be created and managed programmatically through the REST API
subscription_scope: per customer (per Reapit tenant), including SBOX
filters: >-
Optional per-webhook event filters expressed as JSON Schema; a filter is
tied to a single topic and the event is only delivered when the payload
validates. Example use is targeting a specific appointment typeId (e.g. VL
for valuation) on appointments.created / appointments.modified.
payload_data: optional inclusion of semi-structured payload data
security:
signing:
algorithm: Ed25519
header: X-Signature
format: 's:keyId:timestamp:signature'
key_scope: key pair is generated per APP, not per webhook
public_key_endpoint: https://platform.reapit.cloud/webhooks/signing/{id}
public_key_endpoint_auth: bearer token required; an app can only fetch its own keys
public_key_format: JWK set with crv Ed25519 and base64url-encoded x
verification: >-
Concatenate the timestamp (segment 3) with the RAW request body (no
delimiter) and verify segment 4 against the app's public key using Ed25519.
legacy: >-
A legacy symmetric signing method exists and is documented as obsolescent;
asymmetric signing should be used.
source_ips:
- 18.133.192.77
- 18.133.96.95
- 18.132.113.124
source_ip_note: >-
Static Elastic IPs used for webhook egress in eu-west-2 across multiple AZs.
Reapit commits to documenting future changes here in advance where possible.
endpoint_requirements:
- publicly reachable URI using the https scheme
- accepts POST
- accepts an application/json request body
- 'AWS API Gateway execute-api DNS namespace is NOT supported — use a custom domain'
delivery:
retry_policy: exponential backoff
max_attempts: 6
schedule:
- attempt: 2
delay: at least 60s after attempt 1
- attempt: 3
delay: at least 120s after attempt 2
- attempt: 4
delay: at least 300s after attempt 3
- attempt: 5
delay: at least 600s after attempt 4
- attempt: 6
delay: at least 900s after attempt 5; no further attempts
no_retry_when:
- the event is associated with Sandbox data
- the receiving endpoint returned a 4xx response (treated as misconfiguration)
ordering: not guaranteed — use eventTime to order
duplicates: 'at-least-once: a single event may produce more than one notification'
recommended_handling: respond fast (202 Accepted) and process asynchronously
billing: webhook-originated requests count toward developer analytics and billing
testing:
ping: >-
The developer portal Ping function sends an example payload to the
configured URL for the selected topic.
ping_customer_id: webhook-test
ping_entity_id: 9e7e4181-6210-49ea-abf5-d5ce16d23647
recommendation: register webhooks inactive, Ping first, then test against SBOX
envelope:
SendAttempts: number of attempts it took to deliver the message
eventId: unique identifier for the event
entityId: identifier of the entity — unique per customer database, NOT globally unique
customerId: the Reapit customer the event belongs to
eventTime: UTC timestamp the event was emitted
topicId: the topic (see topics below)
new: new version of the entity; null when the entity was deleted or archived
old: previous version; null on .created events
diff: field-level diff; only populated on .modified events
schema_note: >-
new/old/diff use the same schema as the corresponding REST endpoint, e.g.
contacts.modified carries the GET /contacts shape. Types are published as
@reapit/foundations-ts-definitions.
metadata_note: app-specific metadata is NOT currently included in webhook payloads
topic_count: 55
topics:
- topic: application.install
scope: none
description: A customer installs the application in the AppMarket.
note: payload carries applicationId (auth client id) and internalAppId (portal app id)
- topic: application.uninstall
scope: none
description: A customer uninstalls the application in the AppMarket.
- topic: applicants.created
scope: applicants.read
description: A new applicant is created.
- topic: applicants.modified
scope: applicants.read
description: An applicant, or any of its associated contacts, is modified.
- topic: appointments.cancelled
scope: appointments.read
description: An appointment is created as cancelled or an existing one is cancelled.
- topic: appointments.confirmed
scope: appointments.read
description: All required parties have confirmed attendance.
- topic: appointments.created
scope: appointments.read
description: A new appointment is created.
- topic: appointments.modified
scope: appointments.read
description: An existing appointment is modified.
- topic: companies.created
scope: companies.read
description: A new company is created.
- topic: companies.modified
scope: companies.read
description: An existing company is modified.
- topic: contacts.created
scope: contacts.read
description: A new contact is created.
- topic: contacts.landlorddetails.updated
scope: contacts.read
description: An agent updates a landlord's Making Tax Digital consent status.
- topic: contacts.modified
scope: contacts.read
description: An existing contact is modified.
- topic: contacts.optedout
scope: contacts.read
description: Marketing consent is set to or changed to deny.
- topic: conveyancing.modified
scope: conveyancing.read
description: A conveyancing (sales progression) entity is modified.
- topic: documents.created
scope: documents.read
description: A new document is created.
- topic: documents.modified
scope: documents.read
description: An existing document is modified.
- topic: enquiries.accepted
scope: enquiries.read
description: An enquiry status changes to added.
- topic: enquiries.created
scope: enquiries.read
description: A new enquiry is created.
- topic: enquiries.modified
scope: enquiries.read
description: An existing enquiry is modified.
- topic: enquiries.rejected
scope: enquiries.read
description: An enquiry status changes to rejected.
- topic: identitychecks.created
scope: identitychecks.read
description: A new identity check is created against an existing contact.
- topic: identitychecks.modified
scope: identitychecks.read
description: An existing identity check is modified.
- topic: landlords.created
scope: landlords.read
description: A new landlord is created.
- topic: landlords.modified
scope: landlords.read
description: A landlord, or any of its associated contacts, is modified.
- topic: offers.accepted
scope: offers.read
description: An offer is created accepted or an existing offer becomes accepted.
- topic: offers.created
scope: offers.read
description: A new offer is created.
- topic: offers.modified
scope: offers.read
description: An existing offer is modified.
- topic: offers.rejected
scope: offers.read
description: An offer is created rejected or an existing offer becomes rejected.
- topic: offers.withdrawn
scope: offers.read
description: An offer is created withdrawn or an existing offer becomes withdrawn.
- topic: offices.created
scope: offices.read
description: A new office is created.
- topic: offices.modified
scope: offices.read
description: An existing office is modified.
- topic: properties.created
scope: properties.read
description: A new property is created.
- topic: properties.modified
scope: properties.read
description: An existing property is modified.
- topic: properties.selling.askingpricechanged
scope: properties.read
description: The asking price of a sales property is changed.
- topic: properties.selling.completed
scope: properties.read
description: A sales property reaches completed status.
- topic: properties.selling.exchanged
scope: properties.read
description: A sales property reaches exchanged status.
- topic: properties.selling.withdrawn
scope: properties.read
description: A sales property is withdrawn.
- topic: properties.selling.instructed
scope: properties.read
description: A sales property reaches forSale or forSaleUnavailable status.
- topic: properties.selling.lostinstruction
scope: properties.read
description: A sales property enters a lost-instruction state.
- topic: properties.selling.underoffer
scope: properties.read
description: A sales property reaches underOffer or underOfferUnavailable status.
- topic: propertyimages.created
scope: properties.read
description: A new property image is created.
- topic: propertyimages.modified
scope: properties.read
description: An existing property image is modified.
- topic: referrals.created
scope: referrals.read
description: A new referral is created.
- topic: referrals.modified
scope: referrals.read
description: An existing referral is modified.
- topic: tenancies.created
scope: tenancies.read
description: A new tenancy is created.
- topic: tenancies.modified
scope: tenancies.write
description: An existing tenancy is modified.
note: documented as requiring tenancies.write, unlike every other .modified topic
- topic: vendors.created
scope: vendors.read
description: Vendor information is associated with a sales property for the first time.
- topic: vendors.modified
scope: vendors.read
description: Vendor information, or an associated vendor contact, is modified.
- topic: worksorders.cancelled
scope: worksorders.read
description: A works order is created cancelled or becomes cancelled.
- topic: worksorders.complete
scope: worksorders.read
description: A works order is created complete or becomes complete.
- topic: worksorders.modified
scope: worksorders.read
description: An existing works order is modified.
- topic: worksorders.raised
scope: worksorders.read
description: A works order is created raised or becomes raised.
domains:
- applicants
- appointments
- companies
- contacts
- conveyancing
- documents
- enquiries
- identity checks
- landlords
- offers
- offices
- properties
- property images
- referrals
- tenancies
- vendors
- works orders
- appmarket application lifecycle
inbound_events:
name: Foundations Notifications API
direction: inbound (third party -> Reapit products)
endpoint: POST https://platform.reapit.cloud/notifications
scope: negotiators.read
targets: '{ "targets": { "negotiatorId": [...] } } — multiple ids fan out'
docs: https://foundations-documentation.reapit.cloud/api/notifications
note: >-
The counterpart of webhooks — pushes an app's real-time events INTO the CRM
for display to named negotiators. Sandbox testing needs an active Developer
Edition subscription and a dedicated negotiator id; display inside a live
customer CRM must be enabled by Reapit support at the customer's request.