Skip to main content

Status updates

The post-submission stage of the loan lifecycle. Once the application is lodged and ingested, this is how you learn what the lender decided. Slate reports each lifecycle event with a back-channel message (BCM): a LIXI MessageBatch package POSTed to your callback URL. You can also poll the submission for its current status.

Two different state axes are in play, do not conflate them:

  • Submission status (Received, Processing, Completed, ...): the synchronous ingestion state of your submit call. Completed means the application was built. Returned by the submit response and the poll endpoint.
  • Status Name (ApplicationRegistered, ConditionallyApproved, ...): the application's lender lifecycle, delivered asynchronously as back-channel messages once the application exists.

In short: poll tells you the application was ingested; back-channel messages tell you what the lender decided.

Back-channel messages (webhook)

Slate POSTs a LIXI MessageBatch (http://www.lixi.org.au/schema/cal1.5/MessageBatch) to your callback URL for each event. The application is identified by your X-External-Ref (BrokerAssigned) and Slate's application reference (LenderAssigned); Status Name carries the event.

<?xml version="1.0" encoding="UTF-8"?>
<MessageBatch xmlns="http://www.lixi.org.au/schema/cal1.5/MessageBatch" ProductionData="Yes">
<Identifier UniqueID="evt_01ARZ3NDEKTSV4RRFFQ69G5FAV"/>
<Message>
<Identifier UniqueID="evt_01ARZ3NDEKTSV4RRFFQ69G5FAV"/>
<MessageRelatesTo>
<Application>
<Identifier UniqueID="app_01ARZ3NDEKTSV4RRFFQ69G5FAV" Type="LenderAssigned"/>
<Identifier UniqueID="FIN-SUB-77421" Type="BrokerAssigned"/>
</Application>
</MessageRelatesTo>
<MessageBody Type="Information">
<Status Name="ConditionallyApproved">
<Date>2026-06-25</Date>
<Time>14:02:11</Time>
</Status>
</MessageBody>
</Message>
</MessageBatch>

Lender-lifecycle Status Name values: ApplicationRegistered, Referred, PreApproved, ConditionallyApproved, UnconditionallyApproved, SupportingDocsReceived, Withdrawn, Cancelled, Declined, ApplicationSettled. Treat an unrecognised Status Name as informational and do not hard-fail; new event types may be added over time. Ingestion failures are not a Status Name; they arrive as a DataError back-channel message (see Submission errors).

A few fields carry weight:

  • Identifier UniqueID (on MessageBatch and Message): a single id for this event, stable across redeliveries. This is your deduplication key.
  • ProductionData: No in UAT, Yes in production. Use it to tell test traffic from live.
  • SalesChannel: when your inbound package carried a broker identifier, it is echoed back inside the Application element.

Delivery is at least once: acknowledge each message with an HTTP 2xx, or a non-2xx response or a timeout is retried with backoff. Because retries happen, deduplicate on the Identifier UniqueID so a redelivery is a no-op. Messages may arrive out of order; order by the Status Date and Time, not by arrival order. All Date and Time values are UTC.

Registering your callback

Provide your callback URL to your Slate integration manager during onboarding, one URL per environment (UAT and production). Slate returns a signing secret for each environment, used to verify messages (see below). To rotate the URL or secret, request the change through your integration manager; secrets can be rotated without downtime by accepting both the old and new secret during a short overlap.

Verifying back-channel messages

Every callback is signed so you can confirm it came from Slate. Each request carries two headers:

X-Slate-Signature: sha256=<hex>
X-Slate-Timestamp: 2026-06-25T14:02:11Z

X-Slate-Signature is the lowercase hex HMAC-SHA256 of the exact raw request body bytes, keyed by your environment's signing secret. Recompute it over the body you received and compare for equality; reject the message if it differs. Reject any message whose X-Slate-Timestamp is more than five minutes from your clock to guard against replay. Verify before parsing, and acknowledge a verified message with a 2xx.

Submission errors

When a submission cannot be ingested, no application exists yet, so the message omits the LenderAssigned identifier. Correlate it to your submission by BrokerAssigned and resubmit once corrected.

<?xml version="1.0" encoding="UTF-8"?>
<MessageBatch xmlns="http://www.lixi.org.au/schema/cal1.5/MessageBatch" ProductionData="Yes">
<Identifier UniqueID="evt_01ARZ3NDEKTSV4RRFFQ69G5FAW"/>
<Message>
<Identifier UniqueID="evt_01ARZ3NDEKTSV4RRFFQ69G5FAW"/>
<MessageRelatesTo>
<Application>
<Identifier UniqueID="FIN-SUB-77421" Type="BrokerAssigned"/>
</Application>
</MessageRelatesTo>
<MessageBody Type="DataError">
<Event Name="ErrorOnSubmission">
<Date>2026-06-25</Date>
<Time>14:02:11</Time>
</Event>
</MessageBody>
<MessageBody Type="Information">
<MessageAnnotation Type="Message">DataError</MessageAnnotation>
<MessageAnnotation Type="Message">Applicant date of birth is missing.</MessageAnnotation>
</MessageBody>
</Message>
</MessageBatch>

The classification is the Type attribute on the first MessageBody element (DataError in the example above). The second MessageBody carries human-readable detail in its MessageAnnotation elements.

MessageBody TypeMeaning
DataErrorA required value was missing or invalid.
SystemErrorInternal error blocked ingestion; retry safe.
DuplicateSubmissionA submission with this reference exists.
GatewayOutageTransient gateway failure; retry safe.

See the Error Reference for the synchronous error codes returned by the submit call itself.

Poll

GET https://api.slateos.ai/api/v1/channel-submissions/{submissionUid}
Authorization: Bearer <token>

Returns the submission status (ingestion state) and applicationRef. It does not return the lender lifecycle (Status Name) events, which are delivered only as back-channel messages. Use the poll to confirm ingestion and recover the applicationRef; rely on at-least-once back-channel delivery (and your dedup) for lifecycle events.

Next