Skip to navigation
AI Team MembersCORA

CORA events

The events CORA consumes

Every event uses the event envelope and is signed as described in Webhooks.

EventWhen Fortress sends it
application.signedThe last adult applicant signs the application. The bundle serves the current definition version for each document type.
requirement.upload_receivedA document is uploaded to a requirement. The document starts at NOT_YET_REVIEWED.
requirement.upload_removedA Fortress user removes a document from a requirement.
compliance_review.openedStaff open a manual compliance review, which blocks the whole application; documentIds lists the documents under review (empty means application-wide). The cancel route and the Results API answer 409 COMPLIANCE_REVIEW_OPEN until it closes.
compliance_review.closedStaff close the manual compliance review, with the same sessionId and documentIds, a decision and the decidedDocumentIds it set: APPROVED / DENIED set every covered document to APPROVED / REJECTED (statusSetBy: fortress_user), NONE changes none. The cancel route and the Results API accept writes again.
application.completedThe application reaches a final status (APPROVED, CANCELED, DENIED, ABANDONED or WAITLIST), including after a cancellation CORA requested.
agent.state_changedStaff enable or disable an agent (cora or leslie) for a property in Fortress’ agent configuration. Sent for every agent, so ignore events whose agentKey is not cora. Sent with scope: PROPERTY (organizationId and propertyId set, householdId null) to that property’s active subscriptions that list the event. GLOBAL and HOUSEHOLD may also be sent; CORA handles every scope from the payload. Also sent when staff change the CORA cadence policy: CORA re-reads the state route and applies the new cadencePolicy from its next touchpoint.
message.receivedAn inbound message from the applicant is received, for example a reply to a touchpoint.

Testing your receiver

You do not have to wait for the real flow to test your receiver. Call POST /v1/webhooks/trigger with the event you want and the organization and property to test, for example { "eventType": "application.signed", "organizationId": "1a2b3c4d-5e6f-4a1b-8c2d-3e4f5a6b7c8d", "propertyId": "3a1e2b4c-5d6f-4a7b-8c9d-0e1f2a3b4c5d" }. Fortress sends that event’s documented example payload only to the active cora subscriptions of that property that list that event type in their eventTypes, never to other subscriptions, properties or organizations:

  • The delivery uses the normal event envelope and X-Fortress-* headers, with a fresh eventId and occurredAt, and is signed with the subscription’s signing secret. Verify it exactly as you will verify real deliveries.
  • Fortress makes one attempt and does not retry. The 200 response lists each subscription with the HTTP status your receiver answered, or failed when no response was received or Fortress could not sign the delivery. The call returns once every delivery has finished; deliveries run in parallel within the gateway’s limit of about 29 seconds.
  • Any of the events above except message.received can be sent. message.received is delivered for real as soon as the applicant replies to a message CORA sent with Send message, so you can test it end to end with a real conversation instead of an example. A missing or invalid field, another eventType, or an event Fortress has no example payload for yet returns 400. An organization or property your API key does not own returns 404 with code: NOT_FOUND, and a property none of whose active cora subscriptions lists the event type returns 404 with code: NO_SUBSCRIPTION.
  • Your API key needs the webhooks permission with create. An all-organizations key works, as long as the property belongs to the organization you pass.

The payloads are examples, not real data. Their ids do not point to records in your organization, so do not act on them. This includes data.organizationId and data.propertyId: they are the documented example values, not the ones in your request. If your receiver checks the organization, verify the signature first and do not reject a test delivery on that check.