If you run software where people ask businesses for financials (a deal room, a lending portal, an advisory tool), you can put FinShare behind a button in your own product. Your server creates the request, your user's customer goes through FinShare's review page and Intuit, and comes back to you. Reports arrive at your server by webhook.
Vetting Vault is one example of an app that works this way.
The flow
How a request moves
From request to tied-out files
Nothing is read from QuickBooks until step four.
01 · You
Send a request
Reports, periods, basis and how long you need access.
02 · Owner
Reviews the list
Sees who is asking and exactly what for.
03 · Owner
Connects QuickBooks
Signs in to Intuit and picks the company.
04 · Owner
Approves
Can shorten the access window first.
05 · FinShare
Pulls and checks
Reads each report and ties it out.
06 · You
Download
Excel, CSV or JSON, plus a timeline of who did what.
Show as a list
| Step | Who | What happens |
|---|---|---|
| 1 | You | Send a request. Reports, periods, basis and how long you need access. |
| 2 | Owner | Reviews the list. Sees who is asking and exactly what for. |
| 3 | Owner | Connects QuickBooks. Signs in to Intuit and picks the company. |
| 4 | Owner | Approves. Can shorten the access window first. |
| 5 | FinShare | Pulls and checks. Reads each report and ties it out. |
| 6 | You | Download. Excel, CSV or JSON, plus a timeline of who did what. |
- Register your return origin. In Settings › Organization › Return URLs, add the origin owners should come back to, for example
https://app.yourproduct.com. One per line, https only. - Create the request from your server. Call
POST /v1/requestswith the reports, your own id inexternal_ref, and areturn_urlon that origin. - Send the owner to
consent_url. Redirect them, or open it in a new tab. FinShare's pages can't be shown inside an iframe. - The owner reviews, connects and approves on FinShare's page. Intuit sends them back to FinShare, not to you, because Intuit's sign-in is tied to FinShare.
- They return to you. After approving or declining, the owner sees a Return to <your account name> button that opens your
return_url. - Reports arrive by webhook. Handle
report.ready(orround.delivered), download each file with your API key, and attach it to the record named byexternal_ref.
Create the request
curl https://app.finshare.io/v1/requests \
-H "Authorization: Bearer fl_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: filereq-8812" \
-d '{
"items": [
{ "report_type": "profit_and_loss", "period": { "kind": "fiscal_years", "years": 3 }, "options": { "summarize_by": "year" } },
{ "report_type": "balance_sheet", "period": { "kind": "as_of" } }
],
"access_days": 30,
"requester": { "name": "Dana Reyes", "email": "dana@harborpartners.example", "org": "Harbor Partners" },
"owner": { "email": "sam@ortizplumbing.example" },
"message": "Requested in the Ortiz Plumbing data room.",
"external_ref": "filereq-8812",
"return_url": "https://app.yourproduct.com/deals/4471/requests/8812?finshare=done"
}'send_owner_email defaults to false over the API, so FinShare won't email the owner unless you ask it to. If you're redirecting your own user to consent_url, leave it off.
What the owner sees
The review page is the same one every owner sees. Two fields matter when you're a platform:
requester.orgis who the page says is asking: "Harbor Partners is asking for reports from your QuickBooks." Set it to your user's firm.- Your account name is shown as the channel when it differs: "Requested by Dana Reyes (dana@harborpartners.example) through <your account name>." The return button uses it too.
The return URL
- It must be
httpsand on an origin registered for your account. Anything else is rejected when you create the request, so FinShare can't be used as an open redirect. - FinShare opens it exactly as you gave it and doesn't add parameters. Put whatever you need to route the user (your record id, a "done" flag) in the URL yourself.
- The button appears after the owner approves or declines, and again if they revisit a link for a request that's already been answered.
- Don't treat the return as proof of approval. Anyone can open a URL. Check
GET /v1/requests/:idor wait forrequest.approved.
Buttons and links
The consent_url from create is shown once. If your UI has a "Connect QuickBooks" button that people may click more than once, call POST /v1/requests/:id/consent_link on each click and redirect to the new link. Earlier unused links stop working, so an old link sitting in someone's inbox can't be used.
Status in your UI
Map FinShare's status to yours from webhooks:
| Event | Typical badge |
|---|---|
request.viewed | Owner opened |
request.approved | Approved, pulling |
report.ready | File received |
round.delivered with status: "delivered" | Complete |
round.delivered with partially_delivered or failed | Needs attention |
request.declined | Declined |
grant.revoked, grant.expired | Access ended |
connection.needs_reconnect | Owner needs to reconnect |
When to use connector mode instead
The flow above sends a separate request, and a separate owner approval, for each set of reports. If your product asks the same business for reports many times over a deal, and you'd rather the owner connect once and click to send each time, see Connector mode. It's enabled per account.