Finance Requests

Finance Requests let you initiate and track financing flows on behalf of your customers without waiting for Slate to issue a pre-approval. You create a request with an amount and customer, receive a trackable object, direct your customer through the application flow, and receive webhook updates at every step.

This is particularly useful for high frequency use cases like early wage access, where multiple small financing requests may be active for the same customer simultaneously.


Overview

CREATED → IN_PROGRESS → SUBMITTED → APPROVED
   |           |             |
   |           |             +→ DECLINED
   |           |
   +→ CANCELED ←─────────────────────────────
   |           |
   +→ EXPIRED ←──── (CREATED and IN_PROGRESS only, after 7 days)
Status Description
CREATED Request created by partner; customer hasn't started yet
IN_PROGRESS Customer has opened the application form
SUBMITTED Customer submitted the application; under review
APPROVED Application approved; financingAgreementId is populated
DECLINED Application was reviewed and declined
CANCELED Partner canceled the request before approval
EXPIRED Request was not completed within 7 days

Terminal states: APPROVED, DECLINED, CANCELED, EXPIRED.


Quickstart

1. Create a Finance Request

POST /finance-requests
{
  "customerId": "123e45...",
  "amount": 50000,
  "currency": "CAD",
  "type": "ewa",
  "externalId": "shift_001",
  "metadata": {
    "shiftDate": "2025-04-04",
    "rate": "67",
    "hours": "3.4"
  }
}

Response

{
  "id": "314ge3...",
  "customerId": "123e45...",
  "status": "CREATED",
  "amount": 50000,
  "currency": "CAD",
  "type": "ewa",
  "externalId": "shift_001",
  "metadata": {
    "shiftDate": "2025-04-04",
    "rate": "67",
    "hours": "3.4"
  },
  "financingAgreementId": null,
  "createdAt": "2024-09-01T10:00:00Z",
  "updatedAt": "2024-09-01T10:00:00Z",
  "expiresAt": "2024-09-08T10:00:00Z"
}

2. Direct the Customer to the Application Form

Pass the finance_request_id to the slate-application-form component. The customer completes identity verification, bank details, and business information — all linked to this specific request.

<slate-application-form finance_request_id="314ge3..." />

Note: finance_request_id is required when using the component for finance requests. There is no "get latest" fallback — each request is independent.

3. Listen for Webhooks

As the customer progresses through the application, Slate fires webhook events. Register your endpoint in the partner dashboard and handle each event in your system.


Cancellation

Partners can cancel a finance request at any point before it reaches a terminal state — as long as the status is CREATED, IN_PROGRESS, or SUBMITTED.

What happens when you cancel

  • The finance request transitions to CANCELED.
  • If the customer has an application in progress (even if already submitted), it is automatically set to CANCELLED — the customer cannot continue working on it.
  • A finance-request.canceled webhook is fired.
  • No financing agreement is created.

When to cancel

Common scenarios where cancellation makes sense:

  • The underlying business event is no longer valid (e.g., a shift was cancelled before the worker completed their early pay application).
  • The customer took too long and the partner wants to close the request before the 7-day expiration.
  • The partner needs to issue a new request with different terms — cancel the existing one and create a fresh finance request.

Once a finance request is APPROVED or DECLINED, it cannot be canceled. Those are terminal states.


Expiration

Finance requests in CREATED or IN_PROGRESS status that have not progressed within 7 days of creation are automatically expired. Expired requests fire the finance-request.expired webhook and move to a terminal state — no further transitions are possible.

Requests in SUBMITTED, APPROVED, DECLINED, CANCELED, or EXPIRED are never expired by the cron job.


Webhooks

Slate fires a webhook event at every status transition. All events share the same payload shape — the full Finance Request object — and follow existing webhook delivery semantics (retries, signatures, etc.).

Event Trigger
finance-request.created Request created via the API
finance-request.in-progress Customer opened the application form
finance-request.submitted Customer submitted the application
finance-request.approved Application approved
finance-request.declined Application declined
finance-request.canceled Partner canceled the request
finance-request.expired Request expired after 7 days

Multiple Concurrent Requests

You can create multiple active finance requests for the same customer simultaneously. Each request is fully independent — it has its own status, application, and webhook stream. This is the intended pattern for use cases like early wage access, where each shift produces its own finance request.

Customer: 123e45...
  ├── fr_shift_001 → APPROVED
  ├── fr_shift_002 → IN_PROGRESS
  └── fr_shift_003 → CREATED

Metadata

The metadata field accepts an arbitrary JSON object and is available throughout the lifecycle of the request. Use it to attach partner-side context that may inform underwriting — for example:

{
  "shiftDate": "2025-04-04",
  "rate": "67",
  "hours": "3.4"
}

Metadata is set at creation and cannot be updated. Cancel and recreate the request if you need to change it.


Coexistence with Pre-Approvals

Finance Requests and Slate-issued pre-approvals are fully independent. Both can exist for the same customer at the same time, and neither blocks or interacts with the other. Your existing pre-approval integrations continue to work without changes.