Overview
A card-issuer integration has two phases — a one-time customer onboarding flow and a continuous transaction stream. The layers below sit between your existing card-issuing platform and the Findity expense engine:POST /cardtransactions call. Transactions are processed asynchronously by default — the endpoint returns 202 Accepted immediately and queues the transaction for processing. The closer to real-time you send them, the better the cardholder experience — expenses appear in the app within seconds of purchase.
Prerequisites
- Have Findity configure your
cardTypevalue. Contact your project manager or Findity support before development begins —cardTypemust match a value the backend recognises, otherwise every transaction returns400. - Complete Authentication and have an admin-scoped access token. The same token is used for onboarding calls (Admin API) and transaction calls (Connect API).
- Decide which
liabilityeach card type you issue carries:PRIVATE,CORPORATE, orDEBET. This is not a per-transaction choice — it’s tied to the card and dictates how Findity treats the resulting expenses. See Key concepts below.
Key concepts
API endpoints
Base URL for all examples in this guide:https://expense.findity.com) only after your integration is verified in stage.
Create customer organization
See the Admin API — Organizations guide for full request and response details.
Create cardholder or administrator
See the Admin API — Users guide for full request and response details.
Submit card transaction
Required headers
Customer onboarding
When a customer signs up to use Findity through your card-issuing platform — typically from a “My Pages” or equivalent surface — your adapter makes three sequential calls to provision the customer in Findity.admin: true on the user object.
See the Organizations and Users guides for the full request and response shape of these calls.
The
organizationId and personId values returned by these onboarding calls are what you’ll pass into every subsequent POST /cardtransactions call. Store them in your adapter, keyed by your own customer and cardholder ids.Add card to user
A user becomes a cardholder when a card is linked to their account. An employee can hold multiple cards (for example, a personal-liability card for travel plus a corporate-liability card for office purchases), but most integrations connect one card per cardholder. The card’sliability setting dictates how Findity treats the expenses generated from it. Pick the right value when the card is provisioned — changing it later requires migration.
Integration steps
After onboarding, your adapter spends most of its time on a single endpoint —POST /api/v1/connect/cardtransactions — with the eventType field driving the behaviour. The four steps below cover the full transaction lifecycle. Steps 1 and 3 fire on every successful transaction; steps 2 and 4 are conditional. Reuse the same transactionId across all events that belong to one purchase so Findity can stitch them together.
Step 1 — Send the authorization
When the card scheme approves a purchase, send anAUTHORIZATION_ACCEPTED event so Findity creates the draft expense and notifies the cardholder via the mobile app. Generate a fresh transactionId here and reuse it on every subsequent event for this purchase.
PRE_AUTHORIZATION first. Findity creates a draft expense that’s hidden from the cardholder. Replay the same transactionId with AUTHORIZATION_ACCEPTED once the final amount is confirmed; the existing draft is updated and the cardholder is notified.
Step 2 — Reverse or reject (if applicable)
If the card scheme cancels the authorization before settlement, or rejects it outright, replay the sametransactionId with the matching eventType.
AUTHORIZATION_REVERSAL and removes the draft expense entirely on AUTHORIZATION_REJECTED. After either event, the lifecycle is closed for this transactionId and no further events (except REFUND after a settled CAPTURE) are accepted.
Step 3 — Capture on settlement
When the transaction settles (the funds actually move from the cardholder’s account), send aCAPTURE event with the same transactionId. For CORPORATE-liability cards, include an invoiceNumber — Findity groups all transactions sharing the same invoiceNumber into a single corporate-card report that the cardholder submits as one batch.
CAPTURE finalises the expense amount. If the cardholder hasn’t yet attached a receipt, they’re prompted to do so at this point. See Invoice matching for the full grouping behaviour.
Step 4 — Process refunds (if applicable)
When a refund clears for a previously captured transaction, send aREFUND event using the same transactionId. Findity records the negative amount on the original expense and preserves the audit trail — the cardholder can see both the original purchase and the refund in their report.
billingAmount — do not negate the value, the negation is implicit from eventType: REFUND.
Generate expenses from card transaction
For each purchase made on a connected card, your adapter sends aPOST /cardtransactions request. Findity creates a draft expense for the cardholder, sends them a push notification through the Findity mobile app, and lets them attach a receipt and submit it for approval. The same endpoint is used for the full transaction lifecycle — initial authorization, optional reversal, settlement (CAPTURE), and refund — by varying the eventType field and reusing the same transactionId.
Request body — required fields
Request body — conditionally required fields
These fields are required depending on your card type and how the cardholder is identified:Cardholder identification: You must provide either
organizationId + personId, or organizationId + employeeId. If the card is already registered in Findity (via a previous transaction), the system can also look up the cardholder by supplierCardId alone.Request body — optional fields
Example request
cURL
Example response
By default, transactions are processed asynchronously. A successful call returns202 Accepted with the request body echoed back, indicating the transaction has been queued for processing.
Async response (default):
?async=false):
For integration testing, you can add ?async=false to process the transaction synchronously. This returns 201 Created with the stored transaction(s), including the Findity-assigned id and expenseRecordId:
Send
AUTHORIZATION_ACCEPTED as close to real time as your card scheme allows — typically within a few seconds of
the authorization clearing. The cardholder’s push notification is generated when Findity processes the event, so any
delay translates directly into a worse user experience.Invoice matching
ForCORPORATE-liability cards, the cardholder cannot submit individual expenses — purchases are invoiced to the employer monthly (or whatever your billing cycle is) and must be grouped to match the invoice. This is what invoiceNumber is for.
The flow:
- During the month, you send
AUTHORIZATION_ACCEPTEDevents for each purchase. Findity creates draft expenses; the cardholder attaches receipts but cannot submit yet. - When your card scheme settles a batch and issues an invoice, you replay each affected transaction with
eventType: CAPTURE, the sametransactionIdas the original authorization, and the newinvoiceNumber. - Findity matches the
CAPTUREevent to the original draft bytransactionId, updates the expense with the final amount, and groups all expenses sharing the sameinvoiceNumberinto one corporate-card report. - The cardholder submits the resulting report. The administrator sees an overview of open corporate-card reports and can send reminders to cardholders who haven’t yet submitted.
Example CAPTURE request
cURL
Transaction lifecycle
Each transaction progresses through a lifecycle of events. TheeventType field indicates the current stage:
Event type behavior
Capture timeout
If aCAPTURE event is not received within a configured timeout period (set per cardType), Findity automatically removes the draft expense. This prevents orphaned expenses from purchases that were never settled.
Airline/travel accumulation
For airline and travel merchants (MCC codes 3005, 3010, 3020, 3030, 3031, 3041, 4511), multipleCAPTURE events with the same transactionId are accumulated onto the existing expense rather than creating duplicates. This handles the common pattern where airlines send multiple settlement records for a single booking.
Error handling
Findity returns a JSON envelope on errors:Validation errors (400)
Authentication errors
Other errors
Transaction order errors
Findity enforces transaction lifecycle order. You cannot send anAUTHORIZATION_ACCEPTED, AUTHORIZATION_REVERSAL, or AUTHORIZATION_REJECTED event after a CAPTURE or REFUND has been recorded for the same transactionId. Attempting to do so returns a 400 error with the message “Transactions received in the wrong order”.

