Skip to main content

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.

  1. Connect one of your users to your app with Authorization Code + PKCE, requesting read:installations write:installations (plus whatever the app itself reads).
  2. GET /installations/eligible lists the companies that user can edit and the syndicates they manage, with the tier an install would be granted at and any current install.
  3. POST /installations with target_type: "company" and the company's co_… 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.

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.scopes in the response rather than assuming what you asked for.
  • Tier: the installer's own tier — founder, admin or editor for 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 /installations drops the write: scopes, and a request for write scopes alone is 422 no_grantable_scopes.
  • Scopes ⊆ your app's declared scopes. read:investors:pii is 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). Otherwise POST /installations succeeds without it and the response's scopes say 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 /investments returns 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 401 regardless.

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.

Was this page helpful?