> ## Documentation Index
> Fetch the complete documentation index at: https://docs.imprint.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Application event notifications

> Receive the authoritative result of an Imprint application server-side, and reconcile it with the client-side SDK result

## Overview

When a customer completes an Imprint application, you learn the outcome in **two
complementary ways**:

1. **The SDK result** — returned client-side, in the browser or mobile app, the
   moment the customer exits the Imprint application experience (see
   [Step 3 of Apply for a loan or credit card](https://docs.imprint.co/creating-an-application#step-3-handle-the-application-result)).
2. **The application event notification** — a signed, server-to-server webhook
   Imprint `POST`s to your configured endpoint when a credit decision is reached.

Both report on the same application, but they are designed for different jobs.
Use the **SDK result** to update the customer's experience immediately. Use the
**webhook** as the source of truth for your backend systems.

<Info>
  New to event notifications? Start with
  [Subscribe to event notifications](https://docs.imprint.co/guide-event-notifications)
  for setup, signature verification, and retry/idempotency handling.
</Info>

## SDK result vs. event notification

|                        | **SDK result** (client-side)                                       | **Application event notification** (server-side)     |
| ---------------------- | ------------------------------------------------------------------ | ---------------------------------------------------- |
| **How you receive it** | Returned synchronously in the browser/app when the SDK exits       | Asynchronous `POST` to your registered endpoint      |
| **When it fires**      | Every time the SDK exits — including abandonment and launch errors | Only when Imprint reaches a terminal credit decision |
| **Possible values**    | `OFFER_ACCEPTED`, `REJECTED`, `IN_PROGRESS`, `ERROR`               | `OFFER_ACCEPTED`, `REJECTED`                         |
| **Authority**          | Client-reported; best-effort                                       | Authoritative; the system of record                  |
| **Reliability**        | Fires once; lost if the customer closes the tab first              | Retried with exponential back-off until acknowledged |
| **Security**           | In your client context                                             | HMAC SHA-256 signed (`X-IMPRINT-HMAC-SIGNATURE`)     |
| **Customer mapping**   | Available in the client session                                    | Carries `customer_id` and `partner_customer_id`      |

### Why the status sets differ

The two channels answer **different questions**:

* The **SDK result** answers *"What happened in this browser/app session?"* — including
  the customer walking away or launching with a bad token.
* The **webhook** answers *"What did Imprint decide about this application?"* — and a
  decision only exists once the application reaches a terminal state.

Abandoning the flow (`IN_PROGRESS`) and a bad launch (`ERROR`) are session outcomes, not
credit decisions — so they exist **only** on the SDK side and **never** produce a webhook.
`OFFER_ACCEPTED` and `REJECTED` are the two terminal decisions, so they appear in both
channels.

Use this mapping to decide what to expect:

| SDK result       | What it means                                | Webhook sent?                                            |
| ---------------- | -------------------------------------------- | -------------------------------------------------------- |
| `OFFER_ACCEPTED` | Approved and offer accepted — new cardholder | **Yes** — `status: OFFER_ACCEPTED`                       |
| `REJECTED`       | Rejected by Imprint                          | **Yes** — `status: REJECTED` <sup>(see note below)</sup> |
| `IN_PROGRESS`    | Customer exited before finishing             | **No** — not a decision                                  |
| `ERROR`          | Invalid launch parameters (e.g. bad token)   | **No** — not a decision                                  |

<Warning>
  **`OFFER_ACCEPTED` and `REJECTED` are the same strings in both channels — but they
  are not interchangeable.** The SDK result is client-reported and best-effort; the
  webhook is authoritative. Two consequences:

  * **Don't treat the client-side `OFFER_ACCEPTED` as final** for fulfillment, accounting,
    or provisioning. Confirm it against the webhook (or the [API](https://docs.imprint.co/api-reference/payment-methods/retrieve-a-payment-method)).
  * **Don't wait for a webhook on an abandoned or errored session** — there will never be
    one. Handle `IN_PROGRESS` and `ERROR` entirely client-side.

  A customer can also close their browser *between* accepting the offer and the SDK
  returning, so you may receive the **webhook with no client-side result at all**. Always
  treat the webhook as the source of truth.
</Warning>

## When the webhook fires

Imprint sends an `APPLICATION` event notification when an application reaches a
terminal state:

| `status`         | Meaning                                                                                              | Terminal? |
| ---------------- | ---------------------------------------------------------------------------------------------------- | --------- |
| `OFFER_ACCEPTED` | The application was approved and the customer accepted the credit offer — they are now a cardholder. | Yes       |
| `REJECTED`       | The application was rejected by Imprint.                                                             | Yes       |

There are no `IN_PROGRESS` or intermediate-state webhooks. An application emits at
most one terminal notification.

<Note>
  A `REJECTED` notification is only delivered when Imprint can give you enough
  context to act on it — i.e. the application carries a `partner_customer_id`
  and/or maps to a known customer. If neither is available, the rejection is not
  sent, because it would not be actionable on your side.
</Note>

## Payload

See also the
[Application Event reference](https://docs.imprint.co/api-reference/event_notifications#application-event).

| Property              | Required | Type      | Description                                                                                                                                             |
| --------------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`              | TRUE     | String    | `OFFER_ACCEPTED` or `REJECTED`                                                                                                                          |
| `created_at`          | TRUE     | Timestamp | RFC-3339 time the application was created.                                                                                                              |
| `updated_at`          | TRUE     | Timestamp | RFC-3339 time of this decision.                                                                                                                         |
| `customer_id`         | FALSE    | String    | Imprint's unique identifier for the customer. Present once a customer profile exists; on a `REJECTED` event it may be absent if no profile was created. |
| `partner_customer_id` | FALSE    | String    | Your identifier for the customer, as supplied when the session was created. Present only if you provided one.                                           |

```json theme={null}
{
  "object": "APPLICATION",
  "data": {
    "customer_id": "2EE24580-B97B-4949-A65C-929CCB9B9B8D",
    "partner_customer_id": "PARTNER_USER_456",
    "status": "OFFER_ACCEPTED",
    "created_at": "2025-02-13T19:08:07.000Z",
    "updated_at": "2025-02-13T19:08:07.000Z"
  }
}
```

## Recommended handling

<Steps>
  <Step title="Update the UI from the SDK result">
    On SDK exit, react to the client-side result immediately — for
    `OFFER_ACCEPTED`, show a success banner or route the customer to a page to
    learn more about the credit card rewards. Treat this as provisional.
  </Step>

  <Step title="Confirm and persist from the webhook">
    When the `APPLICATION` webhook arrives, verify the signature, then record the
    decision against the `customer_id` / `partner_customer_id` as the source of
    truth for fulfillment, accounting, and downstream systems.
  </Step>

  <Step title="Deduplicate">
    Use `object`, `customer_id`, and `updated_at` to ignore duplicate deliveries
    (Imprint retries until you acknowledge with a `2XX`).
  </Step>

  <Step title="Don't block on a webhook for non-decisions">
    `IN_PROGRESS` and `ERROR` SDK results never produce a webhook. Handle them
    entirely client-side.
  </Step>
</Steps>
