Installations
An installation is your app connected to one company or syndicate. It is what routes that company's webhook events to your endpoints, what a founder sees under Settings → Installed apps, and, since September 2026, what your integration's credential for that company comes from: each install mints a company-owned token that reads exactly that company, with exactly the install's scopes, for as long as the install exists.
Three ways to get installed. All produce the same installation and the same kind of token.
1. Programmatically, by someone who can edit the company
This is the flow for a firm that already works inside its clients' Wefunder dashboards: founders grant you access by adding your staff to the company team with the Editor toggle, and your staff install your app from there.
- Connect one of your users to your app with Authorization Code + PKCE, requesting
read:installations write:installations(plus whatever the app itself reads). GET /installations/eligiblelists the companies that user can edit and the syndicates they manage, with the tier an install would be granted at and any current install.POST /installationswithtarget_type: "company"and the company'sco_…id installs your app there and returns the company-owned token once. Store it against that company.
curl -X POST https://api.wefunder.com/installations \
-H "Authorization: Bearer $USER_TOKEN" -H "Content-Type: application/json" \
-d '{"target_type":"company","target_id":"co_aB3xQ9k2","scopes":["read:investments","read:investors:pii"]}'
{
"data": { "id": "inst_7Hk2…", "type": "installation",
"attributes": { "target": { "type": "company", "id": "co_aB3xQ9k2", "name": "Acme Robotics" },
"tier": "editor", "scopes": ["read:investments", "read:investors:pii"],
"status": "active", "installed_at": "2026-09-21T20:14:09Z", "installed_by": "M. Springer", "revoked_at": null } },
"token": { "access_token": "at_live_…", "token_type": "Bearer", "scope": "read:investments read:investors:pii", "installation": "inst_7Hk2…" }
}
2. From the portal, on your own company or syndicate
In the developer portal, pick the app in the sidebar and open its Installations page. It lists
the companies you edit and the syndicates you manage; Install next to one opens the consent page
for exactly that company or syndicate, with the app's permissions spelled out. After consent you are
back on the page, the new install is listed with its tier and scopes, and Mint token shows the
company-owned token once, with a curl you can paste. That is the whole path when you are the
founder syncing your own company: no link to copy and no OAuth flow against yourself.
The same section has a You row. Mint token there records your own install of the app (the
same User installation an OAuth consent would create) and shows a personal token once: it acts as
you, with the app's declared scopes, and is revoked from Settings → Connected apps like any other
connected app. Use it to try user endpoints such as GET /users/me before wiring up OAuth.
3. By the founder, through your install link
Copy the link from the same Installations page (pick who it is for: a company, a syndicate, or
a person) and send it to the founder. They sign in, pick their company, and consent. A person's link
is your app's OAuth authorize URL; they authorize and land at your redirect URI with a code, and the
install is recorded when your app exchanges it. If your app has a setup URL, Wefunder then redirects them to it with the
new installation_id. Portal-created apps cannot set a setup URL yet, so the consent page is where
the founder's part ends. The new install then appears on the app's Installations page with its
tier and scopes and the same Mint token action. From a server, the same mint is
GET /installations with one of your own user tokens, then POST /installations/{id}/tokens; the
credential is token.access_token in that response.
What an install may carry
- Who can install: anyone who can edit the company (founder, admin, or a team member with the Editor toggle), or a syndicate manager. Until your app is approved, the installer must also manage your developer organization; approval removes that second condition, so any editor of a company can install an approved app on it.
- Scopes are intersected, not validated. The install carries the requested scopes that your
app holds; a requested scope the app does not hold is dropped and the request still succeeds.
Read
data.attributes.scopesin the response rather than assuming what you asked for. - Tier: the installer's own tier —
founder,adminoreditorfor a company — or lower. An admin cannot grant founder tier; an editor grants editor tier. - Editor installs are read-only. An editor-tier install may carry no
write:scope. Installing never widens what the editor could already see. - Only company editors can grant write access. A founder or admin listed on the company without
edit access installs read-only, at any tier they hold:
POST /installationsdrops thewrite:scopes, and a request for write scopes alone is422 no_grantable_scopes. - Scopes ⊆ your app's declared scopes.
read:investors:piiis granted per install: the install carries it when the installer manages your organization, or when Wefunder has approved your app for investor PII (the third-party case). OtherwisePOST /installationssucceeds without it and the response'sscopessay so; the founder's consent screen likewise omits it. The grant is frozen at install time, so re-install where you need it after an approval. See Scopes.
Using the token
A company-owned token acts as the company, not as the person who installed you:
GET /investmentsreturns that company's records only, with PII only if the install grants it. There is no "own investments" leg.- Company endpoints (
/companies/{id}/…) accept it for that company alone. - Endpoints that act as a person (
/users/me, installing, webhook management) refuse it. - It has no expiry and no refresh token. Revoking the install revokes every token minted for it,
and a request with a token from a revoked install gets
401regardless.
Revoking
DELETE /installations/{id} (your side), or the founder from Settings → Installed apps (theirs).
Either way your tokens for that company stop working immediately, and your app-wide webhook
endpoints subscribed to it receive installation.revoked
naming the installation and who revoked it (founder, partner, wefunder, …). Every new install,
from any path, arrives as installation.created. Your organization's owners and admins also get an
email naming the company or syndicate (the person who removed you is described by role, not by
name), and the company's founders and admins are emailed when you install your app on their
company and when you remove it.