wefunder 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +35 -13
- data/lib/wefunder/client.rb +127 -12
- data/lib/wefunder/version.rb +1 -1
- data/lib/wefunder/webhooks.rb +5 -2
- data/lib/wefunder_generated/api/activity_api.rb +0 -92
- data/lib/wefunder_generated/api/explore_api.rb +24 -6
- data/lib/wefunder_generated/api/intents_api.rb +2 -2
- data/lib/wefunder_generated/api/investment_delta_api.rb +4 -4
- data/lib/wefunder_generated/api/investments_api.rb +2 -2
- data/lib/wefunder_generated/api/member_links_api.rb +287 -0
- data/lib/wefunder_generated/api/partner_invites_sessions_api.rb +374 -0
- data/lib/wefunder_generated/api/portfolio_api.rb +2 -2
- data/lib/wefunder_generated/api/referral_codes_api.rb +374 -0
- data/lib/wefunder_generated/api/syndicate_deals_api.rb +2 -140
- data/lib/wefunder_generated/api/syndicate_members_api.rb +216 -0
- data/lib/wefunder_generated/api/syndicate_statistics_api.rb +2 -2
- data/lib/wefunder_generated/api/users_api.rb +4 -4
- data/lib/wefunder_generated/models/audit_event_attributes.rb +1 -0
- data/lib/wefunder_generated/models/campaign.rb +1 -1
- data/lib/wefunder_generated/models/company_attributes.rb +88 -1
- data/lib/wefunder_generated/models/company_disclosures_attributes_ratios.rb +13 -2
- data/lib/wefunder_generated/models/create_intent_request.rb +2 -2
- data/lib/wefunder_generated/models/{webhook_subscription_with_secret2_envelope.rb → create_offering_investment_session_request.rb} +17 -10
- data/lib/wefunder_generated/models/{attribution_stats_envelope.rb → create_offering_member_link_request.rb} +10 -10
- data/lib/wefunder_generated/models/{create_partner_invite_request.rb → create_referral_code_request.rb} +58 -63
- data/lib/wefunder_generated/models/{attribution_stats_period.rb → create_syndicate_join_session_request.rb} +17 -19
- data/lib/wefunder_generated/models/{anonymized_attribution.rb → create_syndicate_join_session_request_join_session.rb} +81 -53
- data/lib/wefunder_generated/models/create_webhook_endpoint_request.rb +11 -1
- data/lib/wefunder_generated/models/fiscal_year_financials.rb +25 -1
- data/lib/wefunder_generated/models/intent_attributes.rb +1 -0
- data/lib/wefunder_generated/models/investment_delta_record.rb +4 -4
- data/lib/wefunder_generated/models/investment_session_attributes.rb +1 -0
- data/lib/wefunder_generated/models/investment_session_create_input.rb +13 -2
- data/lib/wefunder_generated/models/investment_session_envelope.rb +1 -1
- data/lib/wefunder_generated/models/invite_link_attributes.rb +47 -4
- data/lib/wefunder_generated/models/invite_link_attributes_events_inner.rb +12 -1
- data/lib/wefunder_generated/models/invite_link_envelope.rb +1 -1
- data/lib/wefunder_generated/models/{full_attribution_status.rb → member_link.rb} +34 -24
- data/lib/wefunder_generated/models/{marketing_partner.rb → member_link_attributes.rb} +60 -44
- data/lib/wefunder_generated/models/{attribution_me_envelope.rb → member_link_create_input.rb} +40 -10
- data/lib/wefunder_generated/models/{spv_with_meta_envelope.rb → member_link_envelope.rb} +5 -5
- data/lib/wefunder_generated/models/{spv_list_envelope.rb → member_link_list_envelope.rb} +5 -5
- data/lib/wefunder_generated/models/{full_attribution_investor.rb → member_link_list_envelope_meta.rb} +28 -29
- data/lib/wefunder_generated/models/offering_attributes.rb +34 -1
- data/lib/wefunder_generated/models/offering_list_envelope_meta.rb +57 -3
- data/lib/wefunder_generated/models/portfolio_company_ref.rb +16 -5
- data/lib/wefunder_generated/models/portfolio_position_attributes.rb +13 -2
- data/lib/wefunder_generated/models/portfolio_security_terms.rb +15 -2
- data/lib/wefunder_generated/models/{spv_status.rb → referral_code.rb} +4 -4
- data/lib/wefunder_generated/models/{webhook_subscription.rb → referral_code_attributes.rb} +51 -63
- data/lib/wefunder_generated/models/{anonymized_attribution_status.rb → referral_code_attributes_target.rb} +36 -27
- data/lib/wefunder_generated/models/{spv_status_envelope.rb → referral_code_envelope.rb} +5 -5
- data/lib/wefunder_generated/models/{spv_with_meta_envelope_meta.rb → referral_code_envelope_meta.rb} +3 -3
- data/lib/wefunder_generated/models/{partner_investor_list_envelope.rb → referral_code_list_envelope.rb} +5 -5
- data/lib/wefunder_generated/models/{attribution_campaign_summary.rb → referral_code_list_envelope_meta.rb} +36 -35
- data/lib/wefunder_generated/models/{spv_status_attributes.rb → referral_code_stats_company.rb} +70 -47
- data/lib/wefunder_generated/models/referral_code_stats_envelope.rb +223 -0
- data/lib/wefunder_generated/models/{partner_investor.rb → referral_code_stats_envelope_data.rb} +4 -5
- data/lib/wefunder_generated/models/{syndicate_deal_finalize_intent_envelope_meta.rb → referral_code_stats_envelope_data_attributes.rb} +56 -10
- data/lib/wefunder_generated/models/{webhook_endpoint_envelope_meta.rb → referral_code_stats_envelope_meta.rb} +32 -4
- data/lib/wefunder_generated/models/{full_attribution.rb → referral_code_utm.rb} +130 -56
- data/lib/wefunder_generated/models/{attribution_me.rb → referral_code_visits.rb} +23 -25
- data/lib/wefunder_generated/models/{attribution_campaign_access.rb → referral_cohort.rb} +29 -28
- data/lib/wefunder_generated/models/referral_cohort_investors.rb +224 -0
- data/lib/wefunder_generated/models/syndicate_attributes.rb +11 -1
- data/lib/wefunder_generated/models/{syndicate_deal_close_intent_envelope.rb → syndicate_deal_created_envelope.rb} +5 -5
- data/lib/wefunder_generated/models/{attribution_campaign_summary_list_envelope.rb → syndicate_deal_created_envelope_meta.rb} +11 -12
- data/lib/wefunder_generated/models/{attribution_user.rb → syndicate_deal_created_envelope_meta_target_company.rb} +5 -14
- data/lib/wefunder_generated/models/{marketing_partner_envelope.rb → syndicate_deal_readiness_envelope.rb} +4 -4
- data/lib/wefunder_generated/models/syndicate_deal_readiness_envelope_data.rb +267 -0
- data/lib/wefunder_generated/models/{attribution_partner.rb → syndicate_deal_readiness_envelope_data_attributes.rb} +27 -33
- data/lib/wefunder_generated/models/{webhook_delivery.rb → syndicate_deal_readiness_item.rb} +55 -61
- data/lib/wefunder_generated/models/syndicate_statistics_attributes.rb +2 -2
- data/lib/wefunder_generated/models/test_webhook_endpoint_request.rb +2 -2
- data/lib/wefunder_generated/models/{webhook_test_result_envelope.rb → update_referral_code_request.rb} +47 -10
- data/lib/wefunder_generated/models/user_attributes.rb +1 -0
- data/lib/wefunder_generated/models/webhook_endpoint_attributes.rb +23 -1
- data/lib/wefunder_generated/models/webhook_endpoint_envelope.rb +1 -1
- data/lib/wefunder_generated/models/webhook_endpoint_test_result_envelope.rb +1 -1
- data/lib/wefunder_generated.rb +38 -63
- metadata +40 -65
- data/lib/wefunder_generated/api/attribution_api.rb +0 -182
- data/lib/wefunder_generated/api/attribution_partners_api.rb +0 -392
- data/lib/wefunder_generated/api/attribution_webhooks_api.rb +0 -504
- data/lib/wefunder_generated/models/anonymized_attribution_attribution.rb +0 -330
- data/lib/wefunder_generated/models/attributed_investment_list_envelope.rb +0 -226
- data/lib/wefunder_generated/models/attributed_investment_list_envelope_data_inner.rb +0 -105
- data/lib/wefunder_generated/models/attributed_investment_list_envelope_meta.rb +0 -295
- data/lib/wefunder_generated/models/attribution_stats.rb +0 -266
- data/lib/wefunder_generated/models/attribution_stats_by_campaign_inner.rb +0 -232
- data/lib/wefunder_generated/models/attribution_stats_by_source_inner.rb +0 -232
- data/lib/wefunder_generated/models/attribution_stats_quality_breakdown.rb +0 -236
- data/lib/wefunder_generated/models/attribution_stats_totals.rb +0 -245
- data/lib/wefunder_generated/models/create_webhook_subscription_request.rb +0 -263
- data/lib/wefunder_generated/models/full_attribution_attribution.rb +0 -326
- data/lib/wefunder_generated/models/partner_investment_list_envelope.rb +0 -225
- data/lib/wefunder_generated/models/partner_investor_attributes.rb +0 -264
- data/lib/wefunder_generated/models/partner_invite.rb +0 -360
- data/lib/wefunder_generated/models/partner_invite_envelope.rb +0 -214
- data/lib/wefunder_generated/models/partner_invite_list_envelope.rb +0 -216
- data/lib/wefunder_generated/models/register_as_partner_request.rb +0 -232
- data/lib/wefunder_generated/models/syndicate_deal_close_intent_envelope_meta.rb +0 -214
- data/lib/wefunder_generated/models/syndicate_deal_finalize_intent_envelope.rb +0 -224
- data/lib/wefunder_generated/models/webhook_subscription_envelope.rb +0 -214
- data/lib/wefunder_generated/models/webhook_subscription_list_envelope.rb +0 -225
- data/lib/wefunder_generated/models/webhook_subscription_list_envelope_meta.rb +0 -225
- data/lib/wefunder_generated/models/webhook_subscription_with_recent_deliveries_envelope.rb +0 -214
- data/lib/wefunder_generated/models/webhook_subscription_with_recent_deliveries_envelope_data.rb +0 -322
- data/lib/wefunder_generated/models/webhook_subscription_with_secret2_envelope_data.rb +0 -320
- data/lib/wefunder_generated/models/webhook_subscription_with_secret_envelope.rb +0 -214
- data/lib/wefunder_generated/models/webhook_subscription_with_secret_envelope_data.rb +0 -320
- data/lib/wefunder_generated/models/webhook_test_result.rb +0 -233
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc048e16fefefd8990b541796babbd387abc54f4e02f64af2c742ae31e45b375
|
|
4
|
+
data.tar.gz: e4595cd74e1b0fc03d20cb0b564d68d28deaedf56b600cc4e0cdcc07978edb5e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab861d9306c4247e365fa1eef24f50d90efdb80375a22a33ad6b1f6f89c0091566c2059bea111400ca9377bff1dcd5fc01d53427f28a4e1cfb82641aea16b343
|
|
7
|
+
data.tar.gz: '08489fc8cb90890feebdb951227e008693d97b498ab5b5791312fbf27a4cd09237cb215cce8ed7523eec6f0c7d3e73ccc4d8b54b63a0efa768e4fc555c1c6eca'
|
data/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# wefunder
|
|
2
2
|
|
|
3
|
-
Official Ruby SDK for the [Wefunder API](https://docs.wefunder.com).
|
|
4
|
-
and `0.x` releases may include breaking changes.
|
|
3
|
+
Official Ruby SDK for the [Wefunder API](https://docs.wefunder.com).
|
|
5
4
|
|
|
6
5
|
- A `Wefunder::Client` on [Faraday](https://lostisland.github.io/faraday/) with a generated, typed
|
|
7
6
|
layer for every public operation
|
|
@@ -94,6 +93,15 @@ Concurrent requests that hit a 401 at the same time share one refresh (the clien
|
|
|
94
93
|
If several application instances can use the same OAuth connection, serialize refreshes for that
|
|
95
94
|
connection yourself.
|
|
96
95
|
|
|
96
|
+
## API version
|
|
97
|
+
|
|
98
|
+
The SDK sends `Wefunder-Version: 2026-10-15` on every request (`DEFAULT_API_VERSION`); pass
|
|
99
|
+
`api_version:` to pin an older one. 1.1.0 moved the default from the pre-launch `2025-01-15` alias:
|
|
100
|
+
`GET /activity` and the syndicate deal `close` / `finalize` operations (and the
|
|
101
|
+
`syndicates.close_deal` / `finalize_deal` intent actions) are not part of 2026-10-15, so their
|
|
102
|
+
generated methods are gone; the legacy Attribution and attribution-webhook operations, removed
|
|
103
|
+
from the API on 2026-10-14, left with them (`wf.attribution` is gone; use `wf.referral_codes`).
|
|
104
|
+
|
|
97
105
|
## Calling the API
|
|
98
106
|
|
|
99
107
|
```ruby
|
|
@@ -103,13 +111,22 @@ portfolio = wf.portfolio.get
|
|
|
103
111
|
```
|
|
104
112
|
|
|
105
113
|
Namespaces: `users`, `offerings`, `investments`, `portfolio`, `campaigns`, `syndicates`, `intents`,
|
|
106
|
-
`
|
|
114
|
+
`installations`, `member_links`, `referral_codes`, `join_sessions`, `investment_sessions`, and
|
|
115
|
+
`webhook_endpoints`. Query parameters are keyword arguments;
|
|
107
116
|
enum-typed ones take plain strings, and `Time` / `DateTime` / `Date` values are sent as ISO 8601.
|
|
108
117
|
|
|
109
118
|
`wf.installations` lets your app act as a company or syndicate: `eligible_targets`, `create`,
|
|
110
119
|
`mint_token`, `list`, `get`, `revoke`, and `install_or_mint_token`, which handles the API's 409
|
|
111
120
|
`already_installed` answer by minting a token for the existing install with the same scopes.
|
|
112
121
|
|
|
122
|
+
`wf.member_links` mints your app's per-person links to one deal page and reports what each member did
|
|
123
|
+
(`list`, `all`, `create`, `get`, `cancel`; needs a company- or syndicate-owned token). `wf.referral_codes`
|
|
124
|
+
(beta) creates codes with your server key and reads per-company stats (`list`, `all`, `get`, `create`,
|
|
125
|
+
`update`, `stats`). `wf.join_sessions` (beta) mints hosted syndicate join sessions (`list`, `all`, `get`,
|
|
126
|
+
`create`; the API publishes no schema for these yet, so they come back as string-keyed Hashes), and
|
|
127
|
+
`wf.investment_sessions` (beta) puts a known investor straight into checkout for one offering (`list`,
|
|
128
|
+
`all`, `list_for_offering`, `all_for_offering`, `get`, `create`, `cancel`).
|
|
129
|
+
|
|
113
130
|
`wf.investments` is the Investment Delta API. `list` without a cursor bootstraps; pass `updated_since:`
|
|
114
131
|
or the `meta.next_cursor` you saved from your last page to receive only records that changed since then.
|
|
115
132
|
`next_cursor` is always present, even on the final page, so persist it after every sync.
|
|
@@ -138,16 +155,20 @@ API failures raise `Wefunder::Error`:
|
|
|
138
155
|
|
|
139
156
|
```ruby
|
|
140
157
|
begin
|
|
141
|
-
wf.syndicates.get("
|
|
158
|
+
wf.syndicates.get("syn_aB3xQ9k2vF8mNp1zT5wY7Qc4")
|
|
142
159
|
rescue Wefunder::Error => e
|
|
143
160
|
puts e.status, e.type, e.message, e.request_id, e.remediation
|
|
144
161
|
end
|
|
145
162
|
```
|
|
146
163
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
164
|
+
Retries are bounded (`retry_options:` `max_retries`, default 2) and differ by failure: a `429` is
|
|
165
|
+
retried for any method after waiting out `X-RateLimit-Reset`; transient network errors and `5xx`
|
|
166
|
+
responses are retried only for idempotent methods (`GET`, `HEAD`, `OPTIONS`); a `401` is recovered
|
|
167
|
+
once, for any method, by refreshing or re-minting the token and resending. Size request timeouts with
|
|
168
|
+
the rate-limit wait in mind, since rate limiting alone can attempt a write up to three times, and the
|
|
169
|
+
one-time 401 recovery can add one more. Exhausted
|
|
170
|
+
network failures raise `Wefunder::Error` with `status` 0 and `type` `"network_error"`, from namespaces
|
|
171
|
+
and `request` alike.
|
|
151
172
|
|
|
152
173
|
`timeout:` (seconds, default 30) applies to every request the client makes: API calls, `request`, and
|
|
153
174
|
the OAuth token round-trips for refresh and re-mint.
|
|
@@ -223,7 +244,7 @@ generated under `WefunderGenerated::<Tag>Api` and reachable through `wf.raw.<tag
|
|
|
223
244
|
the same auth, retries, and typed errors:
|
|
224
245
|
|
|
225
246
|
```ruby
|
|
226
|
-
members = wf.wrap { wf.raw.syndicate_members.list_syndicate_members("
|
|
247
|
+
members = wf.wrap { wf.raw.syndicate_members.list_syndicate_members("syn_aB3xQ9k2vF8mNp1zT5wY7Qc4") }
|
|
227
248
|
```
|
|
228
249
|
|
|
229
250
|
For a path the generated layer does not know yet, `wf.request(:get, path, query:, body:, headers:)`
|
|
@@ -269,12 +290,13 @@ Commit the specification and generated client together.
|
|
|
269
290
|
|
|
270
291
|
### Releasing
|
|
271
292
|
|
|
272
|
-
Set the version in `lib/wefunder/version.rb` (e.g. `
|
|
273
|
-
commit, then:
|
|
293
|
+
Set the version in `lib/wefunder/version.rb` (e.g. `1.1.0`; a prerelease is `1.2.0.beta1`), run
|
|
294
|
+
`bundle install` so `Gemfile.lock` follows, rebuild `examples_manifest.json`, commit, then:
|
|
274
295
|
|
|
275
296
|
```bash
|
|
276
|
-
git
|
|
277
|
-
git
|
|
297
|
+
git push origin main
|
|
298
|
+
git tag v1.1.0
|
|
299
|
+
git push origin v1.1.0 # push the tag explicitly: `--follow-tags` only pushes annotated tags
|
|
278
300
|
```
|
|
279
301
|
|
|
280
302
|
The release workflow verifies the tag, runs the checks, and publishes to RubyGems via trusted publishing.
|
data/lib/wefunder/client.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Wefunder
|
|
|
9
9
|
# Version-free base — the edge gateway serves the API at the host root; +/api/v2+ remains a
|
|
10
10
|
# back-compat alias. The API version is pinned via the +Wefunder-Version+ header, not the path.
|
|
11
11
|
DEFAULT_API_BASE_URL = "https://api.wefunder.com"
|
|
12
|
-
DEFAULT_API_VERSION = "
|
|
12
|
+
DEFAULT_API_VERSION = "2026-10-15"
|
|
13
13
|
API_VERSION_HEADER = "Wefunder-Version"
|
|
14
14
|
|
|
15
15
|
# "live" / "test" from the access-token prefix. UX only — never used for routing.
|
|
@@ -26,7 +26,8 @@ module Wefunder
|
|
|
26
26
|
# typed-error unwrapping, and lazy auto-pagination. +raw+ exposes every generated API.
|
|
27
27
|
class Client
|
|
28
28
|
attr_reader :mode, :users, :offerings, :investments, :portfolio, :campaigns, :syndicates, :intents,
|
|
29
|
-
:
|
|
29
|
+
:installations, :member_links, :referral_codes, :join_sessions, :investment_sessions,
|
|
30
|
+
:webhook_endpoints
|
|
30
31
|
|
|
31
32
|
def initialize(access_token: nil, tokens: nil, client_id: nil, client_secret: nil, client_credentials: nil,
|
|
32
33
|
api_version: DEFAULT_API_VERSION, base_url: DEFAULT_API_BASE_URL, authorize_base_url: nil,
|
|
@@ -52,8 +53,11 @@ module Wefunder
|
|
|
52
53
|
@campaigns = Campaigns.new(self)
|
|
53
54
|
@syndicates = Syndicates.new(self)
|
|
54
55
|
@intents = Intents.new(self)
|
|
55
|
-
@attribution = Attribution.new(self)
|
|
56
56
|
@installations = Installations.new(self)
|
|
57
|
+
@member_links = MemberLinks.new(self)
|
|
58
|
+
@referral_codes = ReferralCodes.new(self)
|
|
59
|
+
@join_sessions = JoinSessions.new(self)
|
|
60
|
+
@investment_sessions = InvestmentSessions.new(self)
|
|
57
61
|
@webhook_endpoints = WebhookEndpoints.new(self)
|
|
58
62
|
end
|
|
59
63
|
|
|
@@ -166,13 +170,14 @@ module Wefunder
|
|
|
166
170
|
# Lazily-built generated API instances, one per tag.
|
|
167
171
|
class Raw
|
|
168
172
|
APIS = {
|
|
169
|
-
activity: "ActivityApi",
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
activity: "ActivityApi", campaigns: "CampaignsApi", companies: "CompaniesApi", explore: "ExploreApi",
|
|
174
|
+
installations: "InstallationsApi", intents: "IntentsApi", investment_delta: "InvestmentDeltaApi",
|
|
175
|
+
investments: "InvestmentsApi", member_links: "MemberLinksApi",
|
|
176
|
+
partner_invites_sessions: "PartnerInvitesSessionsApi", portfolio: "PortfolioApi",
|
|
177
|
+
referral_codes: "ReferralCodesApi", syndicate_deals: "SyndicateDealsApi",
|
|
178
|
+
syndicate_members: "SyndicateMembersApi", syndicate_portfolio: "SyndicatePortfolioApi",
|
|
179
|
+
syndicate_statistics: "SyndicateStatisticsApi", syndicates: "SyndicatesApi", users: "UsersApi",
|
|
180
|
+
webhook_endpoints: "WebhookEndpointsApi"
|
|
176
181
|
}.freeze
|
|
177
182
|
|
|
178
183
|
def initialize(api_client)
|
|
@@ -272,8 +277,118 @@ module Wefunder
|
|
|
272
277
|
def preview(body) = data_of(wrap { raw.intents.preview_intent(WefunderGenerated::PreviewIntentRequest.new(body)) })
|
|
273
278
|
end
|
|
274
279
|
|
|
275
|
-
|
|
276
|
-
|
|
280
|
+
# /syndicates/{id}/join_sessions (write:syndicate_members to mint, read:syndicates to read; beta).
|
|
281
|
+
# Mint a hosted session for an email, send the person to +attributes["url"]+, and learn the
|
|
282
|
+
# outcome from +get+ or the +join_session.*+ webhooks. The spec publishes no response schema for
|
|
283
|
+
# these yet, so sessions come back as plain Hashes.
|
|
284
|
+
class JoinSessions < Namespace
|
|
285
|
+
def list(syndicate_id, **opts)
|
|
286
|
+
strings(wrap { raw.syndicate_members.list_syndicate_join_sessions(syndicate_id, norm(opts)) })
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def all(syndicate_id, **opts)
|
|
290
|
+
sessions = pages(opts) { |o| raw.syndicate_members.list_syndicate_join_sessions(syndicate_id, o) }
|
|
291
|
+
Enumerator.new { |y| sessions.each { |session| y << strings(session) } }
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def get(syndicate_id, session_id)
|
|
295
|
+
strings(data_of(wrap { raw.syndicate_members.get_syndicate_join_session(syndicate_id, session_id) }))
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# Mint a session for one person (+email:+ required). Needs a manager's user token or the syndicate's own.
|
|
299
|
+
def create(syndicate_id, **attrs)
|
|
300
|
+
body = WefunderGenerated::CreateSyndicateJoinSessionRequest.new(
|
|
301
|
+
join_session: WefunderGenerated::CreateSyndicateJoinSessionRequestJoinSession.new(attrs)
|
|
302
|
+
)
|
|
303
|
+
strings(data_of(wrap { raw.syndicate_members.create_syndicate_join_session(syndicate_id, body) }))
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
private
|
|
307
|
+
|
|
308
|
+
# The generated client parses an untyped +object+ response with symbol keys; hand it back the
|
|
309
|
+
# way the documented examples read it (+session["attributes"]["url"]+).
|
|
310
|
+
def strings(obj) = JSON.parse(JSON.generate(obj))
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# /offerings/{id}/investment_sessions and /investment_sessions (read:investment_sessions /
|
|
314
|
+
# write:investment_sessions; beta). A session puts a known investor straight into checkout for one
|
|
315
|
+
# offering and tracks that one investment.
|
|
316
|
+
class InvestmentSessions < Namespace
|
|
317
|
+
# Every session your app created, across offerings; the envelope.
|
|
318
|
+
def list(**opts) = wrap { raw.partner_invites_sessions.list_investment_sessions(norm(opts)) }
|
|
319
|
+
def all(**opts) = pages(opts) { |o| raw.partner_invites_sessions.list_investment_sessions(o) }
|
|
320
|
+
|
|
321
|
+
def list_for_offering(offering_id, **opts)
|
|
322
|
+
wrap { raw.partner_invites_sessions.list_offering_investment_sessions(offering_id, norm(opts)) }
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def all_for_offering(offering_id, **opts)
|
|
326
|
+
pages(opts) { |o| raw.partner_invites_sessions.list_offering_investment_sessions(offering_id, o) }
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def get(session_id) = data_of(wrap { raw.partner_invites_sessions.get_investment_session(session_id) })
|
|
330
|
+
|
|
331
|
+
# Create a session on an offering; +idempotency_key:+ makes a retry safe.
|
|
332
|
+
def create(offering_id, idempotency_key: nil, **attrs)
|
|
333
|
+
body = WefunderGenerated::CreateOfferingInvestmentSessionRequest.new(
|
|
334
|
+
investment_session: WefunderGenerated::InvestmentSessionCreateInput.new(attrs)
|
|
335
|
+
)
|
|
336
|
+
opts = idempotency_key ? { idempotency_key: idempotency_key } : {}
|
|
337
|
+
data_of(wrap { raw.partner_invites_sessions.create_offering_investment_session(offering_id, body, opts) })
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# Cancel a session the recipient has not completed.
|
|
341
|
+
def cancel(session_id) = data_of(wrap { raw.partner_invites_sessions.cancel_investment_session(session_id) })
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# /offerings/{id}/member_links and /member_links/{id} (read:invite_links / write:invite_links):
|
|
345
|
+
# your app's per-person links that send a member to one deal page and report what they did.
|
|
346
|
+
# Needs a company- or syndicate-owned token of an app installed on the offering's syndicate or
|
|
347
|
+
# company; a user token gets 404.
|
|
348
|
+
class MemberLinks < Namespace
|
|
349
|
+
# One page of the offering's links; the envelope.
|
|
350
|
+
def list(offering_id, **opts) = wrap { raw.member_links.list_offering_member_links(offering_id, norm(opts)) }
|
|
351
|
+
def all(offering_id) = pages({}) { |o| raw.member_links.list_offering_member_links(offering_id, o) }
|
|
352
|
+
|
|
353
|
+
# Mint a link (+reference:+, optional +wefunder_user_id:+). Repeating a +reference+ returns the
|
|
354
|
+
# live link instead of a second one; +idempotency_key:+ makes a retried request safe as well.
|
|
355
|
+
def create(offering_id, idempotency_key: nil, **attrs)
|
|
356
|
+
opts = {}
|
|
357
|
+
opts[:idempotency_key] = idempotency_key if idempotency_key
|
|
358
|
+
unless attrs.empty?
|
|
359
|
+
opts[:create_offering_member_link_request] =
|
|
360
|
+
WefunderGenerated::CreateOfferingMemberLinkRequest.new(member_link: WefunderGenerated::MemberLinkCreateInput.new(attrs))
|
|
361
|
+
end
|
|
362
|
+
data_of(wrap { raw.member_links.create_offering_member_link(offering_id, opts) })
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def get(link_id) = data_of(wrap { raw.member_links.get_member_link(link_id) })
|
|
366
|
+
# Stop an unused link from opening the deal page.
|
|
367
|
+
def cancel(link_id) = data_of(wrap { raw.member_links.cancel_member_link(link_id) })
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# /referral_codes (read:referral_codes / write:referral_codes; beta). Mint with your app's server
|
|
371
|
+
# key, add +?wfr=ref_…+ to any wefunder.com link, and read +stats+. What +stats+ shows per company
|
|
372
|
+
# depends on its +level+: +counts+ is weekly cohorts (+weeks+), +anonymized+ is per-investment rows
|
|
373
|
+
# with opaque tokens (+investments+), and +full+, for an app installed on the company with a
|
|
374
|
+
# founder-tier grant, carries investor names and emails.
|
|
375
|
+
class ReferralCodes < Namespace
|
|
376
|
+
def list(**opts) = wrap { raw.referral_codes.list_referral_codes(norm(opts)) }
|
|
377
|
+
def all(**opts) = pages(opts) { |o| raw.referral_codes.list_referral_codes(o) }
|
|
378
|
+
def get(code_id) = data_of(wrap { raw.referral_codes.get_referral_code(code_id) })
|
|
379
|
+
|
|
380
|
+
# Not idempotent: a retried create can mint a second code, which you can deactivate.
|
|
381
|
+
def create(**attrs)
|
|
382
|
+
data_of(wrap { raw.referral_codes.create_referral_code(WefunderGenerated::CreateReferralCodeRequest.new(attrs)) })
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def update(code_id, **changes)
|
|
386
|
+
body = WefunderGenerated::UpdateReferralCodeRequest.new(changes)
|
|
387
|
+
data_of(wrap { raw.referral_codes.update_referral_code(code_id, body) })
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# Weekly cohorts per company; the envelope (+meta.next_cursor+ pages the company list).
|
|
391
|
+
def stats(code_id, **opts) = wrap { raw.referral_codes.get_referral_code_stats(code_id, norm(opts)) }
|
|
277
392
|
end
|
|
278
393
|
|
|
279
394
|
# /installations (read:installations / write:installations; write does not imply read). An
|
data/lib/wefunder/version.rb
CHANGED
data/lib/wefunder/webhooks.rb
CHANGED
|
@@ -36,12 +36,15 @@ module Wefunder
|
|
|
36
36
|
# spec/webhooks_spec.rb, which fails when the two diverge.
|
|
37
37
|
EVENT_NAMES = %w[
|
|
38
38
|
investment.created investment.reinstated investment.canceled investment.converted
|
|
39
|
-
investment.amount_changed investment.executed investment.changed
|
|
39
|
+
investment.amount_changed investment.executed investment.changed investment.referred
|
|
40
40
|
offering.opened offering.closing offering.closed offering.canceled
|
|
41
41
|
investment_session.created investment_session.started investment_session.completed
|
|
42
42
|
investment_session.expired investment_session.canceled
|
|
43
43
|
syndicate_member.invited syndicate_member.reinvited syndicate_member.applied
|
|
44
|
-
syndicate_member.approved syndicate_member.joined
|
|
44
|
+
syndicate_member.approved syndicate_member.joined syndicate_member.left syndicate_member.declined
|
|
45
|
+
join_session.pending_approval join_session.completed join_session.rejected join_session.ineligible
|
|
46
|
+
join_session.canceled join_session.expired
|
|
47
|
+
installation.created installation.revoked referral_cohorts.published
|
|
45
48
|
].freeze
|
|
46
49
|
|
|
47
50
|
# Raised by +construct_event+. Respond 400 and don't process.
|
|
@@ -19,98 +19,6 @@ module WefunderGenerated
|
|
|
19
19
|
def initialize(api_client = ApiClient.default)
|
|
20
20
|
@api_client = api_client
|
|
21
21
|
end
|
|
22
|
-
# List activity events
|
|
23
|
-
# Returns actions taken by OAuth apps authorized by the current user. This is the API backing the user-facing activity feed at Settings > Activity.
|
|
24
|
-
# @param [Hash] opts the optional parameters
|
|
25
|
-
# @option opts [Integer] :app_id Filter by connected app
|
|
26
|
-
# @option opts [String] :action_pattern Filter by action pattern (e.g. syndicates.* or syndicates.member.*)
|
|
27
|
-
# @option opts [String] :resource_type Filter by resource type (e.g. Club). Must be used with resource_id.
|
|
28
|
-
# @option opts [String] :resource_id Filter by specific resource ID. Must be used with resource_type. For Club resources, pass the syndicate's id (`syn_...`).
|
|
29
|
-
# @option opts [String] :status
|
|
30
|
-
# @option opts [Time] :since
|
|
31
|
-
# @option opts [Time] :_until
|
|
32
|
-
# @option opts [String] :cursor Opaque cursor from the previous response's `meta.next_cursor`.
|
|
33
|
-
# @option opts [Integer] :per_page (default to 25)
|
|
34
|
-
# @return [AuditEventListEnvelope]
|
|
35
|
-
def list_activity(opts = {})
|
|
36
|
-
data, _status_code, _headers = list_activity_with_http_info(opts)
|
|
37
|
-
data
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# List activity events
|
|
41
|
-
# Returns actions taken by OAuth apps authorized by the current user. This is the API backing the user-facing activity feed at Settings > Activity.
|
|
42
|
-
# @param [Hash] opts the optional parameters
|
|
43
|
-
# @option opts [Integer] :app_id Filter by connected app
|
|
44
|
-
# @option opts [String] :action_pattern Filter by action pattern (e.g. syndicates.* or syndicates.member.*)
|
|
45
|
-
# @option opts [String] :resource_type Filter by resource type (e.g. Club). Must be used with resource_id.
|
|
46
|
-
# @option opts [String] :resource_id Filter by specific resource ID. Must be used with resource_type. For Club resources, pass the syndicate's id (`syn_...`).
|
|
47
|
-
# @option opts [String] :status
|
|
48
|
-
# @option opts [Time] :since
|
|
49
|
-
# @option opts [Time] :_until
|
|
50
|
-
# @option opts [String] :cursor Opaque cursor from the previous response's `meta.next_cursor`.
|
|
51
|
-
# @option opts [Integer] :per_page (default to 25)
|
|
52
|
-
# @return [Array<(AuditEventListEnvelope, Integer, Hash)>] AuditEventListEnvelope data, response status code and response headers
|
|
53
|
-
def list_activity_with_http_info(opts = {})
|
|
54
|
-
if @api_client.config.debugging
|
|
55
|
-
@api_client.config.logger.debug 'Calling API: ActivityApi.list_activity ...'
|
|
56
|
-
end
|
|
57
|
-
allowable_values = ["success", "failure", "denied"]
|
|
58
|
-
if @api_client.config.client_side_validation && opts[:'status'] && !allowable_values.include?(opts[:'status'])
|
|
59
|
-
fail ArgumentError, "invalid value for \"status\", must be one of #{allowable_values}"
|
|
60
|
-
end
|
|
61
|
-
if @api_client.config.client_side_validation && !opts[:'per_page'].nil? && opts[:'per_page'] > 100
|
|
62
|
-
fail ArgumentError, 'invalid value for "opts[:"per_page"]" when calling ActivityApi.list_activity, must be smaller than or equal to 100.'
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# resource path
|
|
66
|
-
local_var_path = '/activity'
|
|
67
|
-
|
|
68
|
-
# query parameters
|
|
69
|
-
query_params = opts[:query_params] || {}
|
|
70
|
-
query_params[:'app_id'] = opts[:'app_id'] if !opts[:'app_id'].nil?
|
|
71
|
-
query_params[:'action_pattern'] = opts[:'action_pattern'] if !opts[:'action_pattern'].nil?
|
|
72
|
-
query_params[:'resource_type'] = opts[:'resource_type'] if !opts[:'resource_type'].nil?
|
|
73
|
-
query_params[:'resource_id'] = opts[:'resource_id'] if !opts[:'resource_id'].nil?
|
|
74
|
-
query_params[:'status'] = opts[:'status'] if !opts[:'status'].nil?
|
|
75
|
-
query_params[:'since'] = opts[:'since'] if !opts[:'since'].nil?
|
|
76
|
-
query_params[:'until'] = opts[:'_until'] if !opts[:'_until'].nil?
|
|
77
|
-
query_params[:'cursor'] = opts[:'cursor'] if !opts[:'cursor'].nil?
|
|
78
|
-
query_params[:'per_page'] = opts[:'per_page'] if !opts[:'per_page'].nil?
|
|
79
|
-
|
|
80
|
-
# header parameters
|
|
81
|
-
header_params = opts[:header_params] || {}
|
|
82
|
-
# HTTP header 'Accept' (if needed)
|
|
83
|
-
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
84
|
-
|
|
85
|
-
# form parameters
|
|
86
|
-
form_params = opts[:form_params] || {}
|
|
87
|
-
|
|
88
|
-
# http body (model)
|
|
89
|
-
post_body = opts[:debug_body]
|
|
90
|
-
|
|
91
|
-
# return_type
|
|
92
|
-
return_type = opts[:debug_return_type] || 'AuditEventListEnvelope'
|
|
93
|
-
|
|
94
|
-
# auth_names
|
|
95
|
-
auth_names = opts[:debug_auth_names] || ['bearerAuth', 'bearerAuth']
|
|
96
|
-
|
|
97
|
-
new_options = opts.merge(
|
|
98
|
-
:operation => :"ActivityApi.list_activity",
|
|
99
|
-
:header_params => header_params,
|
|
100
|
-
:query_params => query_params,
|
|
101
|
-
:form_params => form_params,
|
|
102
|
-
:body => post_body,
|
|
103
|
-
:auth_names => auth_names,
|
|
104
|
-
:return_type => return_type
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
|
|
108
|
-
if @api_client.config.debugging
|
|
109
|
-
@api_client.config.logger.debug "API called: ActivityApi#list_activity\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
110
|
-
end
|
|
111
|
-
return data, status_code, headers
|
|
112
|
-
end
|
|
113
|
-
|
|
114
22
|
# List connected apps
|
|
115
23
|
# Returns all OAuth apps the user has authorized, with summary stats.
|
|
116
24
|
# @param [Hash] opts the optional parameters
|
|
@@ -20,7 +20,7 @@ module WefunderGenerated
|
|
|
20
20
|
@api_client = api_client
|
|
21
21
|
end
|
|
22
22
|
# Get a company page
|
|
23
|
-
# The company page behind an offering, as structured data — the \"click a company\" step after `/explore`. Addressed by the `co_...` id every offering carries in `company.
|
|
23
|
+
# The company page behind an offering, as structured data — the \"click a company\" step after `/explore`. Addressed by the `co_...` id every offering carries in its top-level `company` field (a bare string). Keeps apart the three raised numbers the page shows and readers conflate: `current_raise.amount_raised` (this campaign's live rounds combined, on Wefunder), `past_rounds[]` (prior rounds the page lists, each tagged `source: wefunder` for rounds observed here or `reported` for founder-disclosed off-platform rounds), and `totals.profile_total_raised` (the number on the page's ticker bar). Every figure comes from the same policy the page uses, so the API never disagrees with the site. **Who has a page.** Every company whose profile wefunder.com lists publicly — the same set the site's search bar returns (published, not invite-only, searchable or with a live Form C; accredited-only companies need an accredited viewer) — plus the `/explore` set. A funded company, or one the viewer may see no round of, renders with `raising: false` and `current_raise: null`; its history is in `wefunder_rounds`. **Logged-in view (`read:explore`)** additionally covers the vault / syndicate-led companies the site shows an accredited viewer, and the round described is the one the page would show that viewer. A valid id for a company outside the viewer's set is a `404`, never a partial payload.
|
|
24
24
|
# @param id [String] The company's id (`co_...`).
|
|
25
25
|
# @param [Hash] opts the optional parameters
|
|
26
26
|
# @return [CompanyEnvelope]
|
|
@@ -30,7 +30,7 @@ module WefunderGenerated
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# Get a company page
|
|
33
|
-
# The company page behind an offering, as structured data — the \"click a company\" step after `/explore`. Addressed by the `co_...` id every offering carries in `company
|
|
33
|
+
# The company page behind an offering, as structured data — the \"click a company\" step after `/explore`. Addressed by the `co_...` id every offering carries in its top-level `company` field (a bare string). Keeps apart the three raised numbers the page shows and readers conflate: `current_raise.amount_raised` (this campaign's live rounds combined, on Wefunder), `past_rounds[]` (prior rounds the page lists, each tagged `source: wefunder` for rounds observed here or `reported` for founder-disclosed off-platform rounds), and `totals.profile_total_raised` (the number on the page's ticker bar). Every figure comes from the same policy the page uses, so the API never disagrees with the site. **Who has a page.** Every company whose profile wefunder.com lists publicly — the same set the site's search bar returns (published, not invite-only, searchable or with a live Form C; accredited-only companies need an accredited viewer) — plus the `/explore` set. A funded company, or one the viewer may see no round of, renders with `raising: false` and `current_raise: null`; its history is in `wefunder_rounds`. **Logged-in view (`read:explore`)** additionally covers the vault / syndicate-led companies the site shows an accredited viewer, and the round described is the one the page would show that viewer. A valid id for a company outside the viewer's set is a `404`, never a partial payload.
|
|
34
34
|
# @param id [String] The company's id (`co_...`).
|
|
35
35
|
# @param [Hash] opts the optional parameters
|
|
36
36
|
# @return [Array<(CompanyEnvelope, Integer, Hash)>] CompanyEnvelope data, response status code and response headers
|
|
@@ -521,10 +521,12 @@ module WefunderGenerated
|
|
|
521
521
|
end
|
|
522
522
|
|
|
523
523
|
# List public offerings
|
|
524
|
-
# Returns the offerings shown on wefunder.com/explore — the curated set of companies that meet Wefunder's discoverability bar (a soft-confirmed traction threshold plus approval), **one offering per company**. An \"offering\" is a fundraise, addressed by its id (`ofr_...`). **Public view (`read:public`).** Reachable with either a server-side (client_credentials) token or a user access token. Private rounds (e.g. Reg D 506(b)) are never listed, and low-traction or unapproved companies are excluded — exactly as they are on the website for a logged-out visitor. **Logged-in view (`read:explore`).** A user access token carrying `read:explore` gets what *that user* sees on wefunder.com/explore: the public offerings plus any the user qualifies for (accredited-only / Vault deals, invited private rounds), each checked against the same visibility policy the website applies. The response is a strict superset of the public one — same fields and ids — with two extra attributes, `publicly_visible` and `invested`, and `meta.personalized: true`. A server-side key can never hold `read:explore`; a token with `read:explore` but no resolvable user gets the public view. Order with `sort` (default: most raised); paginate with `cursor`. `meta.total_count` is the number of offerings across all pages, after filters. **Filters** are objective, per-offering terms — exemption family, security type, TTW vs. live, minimum investment ceiling, close date, amount raised floor. The response echoes the applied set in `meta.filters`. An out-of-vocabulary value is a `400` naming the accepted values. There are deliberately no relevance, quality, or ranking criteria. Use this endpoint to: - Discover and monitor active deals - Build deal aggregators and public listings
|
|
524
|
+
# Returns the offerings shown on wefunder.com/explore — the curated set of companies that meet Wefunder's discoverability bar (a soft-confirmed traction threshold plus approval), **one offering per company**. An \"offering\" is a fundraise, addressed by its id (`ofr_...`). **Public view (`read:public`).** Reachable with either a server-side (client_credentials) token or a user access token. Private rounds (e.g. Reg D 506(b)) are never listed, and low-traction or unapproved companies are excluded — exactly as they are on the website for a logged-out visitor. **Logged-in view (`read:explore`).** A user access token carrying `read:explore` gets what *that user* sees on wefunder.com/explore: the public offerings plus any the user qualifies for (accredited-only / Vault deals, invited private rounds), each checked against the same visibility policy the website applies. The response is a strict superset of the public one — same fields and ids — with two extra attributes, `publicly_visible` and `invested`, and `meta.personalized: true`. A server-side key can never hold `read:explore`; a token with `read:explore` but no resolvable user gets the public view. Order with `sort` (default: most raised); paginate with `cursor` and `per_page`. `meta.total_count` is the number of offerings across all pages, after filters. **Closed rounds (`status`).** By default the list is live rounds. `status=closed` lists rounds that finished raising instead, newest `closed_at` first. It is not limited to one per company or to the curated explore set: it covers every finished round that `GET /offerings/{id}` serves to a logged-out visitor, for companies listed in Wefunder's public directory. `status=all` returns the live list first, then the closed list. With `status=closed` or `status=all`, `exemption` is the only filter accepted, and `sort` orders only the live part. Closed rounds follow the public view even for a `read:explore` token. **Filters** are objective, per-offering terms — exemption family, security type, TTW vs. live, minimum investment ceiling, close date, amount raised floor. The response echoes the applied set in `meta.filters`. An out-of-vocabulary value is a `400` naming the accepted values. There are deliberately no relevance, quality, or ranking criteria. Use this endpoint to: - Discover and monitor active deals - Build deal aggregators and public listings - Bulk-list closed rounds (`status=closed`)
|
|
525
525
|
# @param [Hash] opts the optional parameters
|
|
526
526
|
# @option opts [Integer] :cursor Cursor-based pagination token. Use the `next_cursor` value from the previous response's `meta` object to retrieve the next page of results. Omit this parameter to retrieve the first page.
|
|
527
|
-
# @option opts [
|
|
527
|
+
# @option opts [Integer] :per_page Offerings per page. (default to 25)
|
|
528
|
+
# @option opts [String] :status Which rounds to list: - `live` (default): rounds accepting investments or reservations, as on wefunder.com/explore - `closed`: rounds that finished raising, newest `closed_at` first (id breaks ties) - `all`: the live list, then the closed list Any other value is a `400`. (default to 'live')
|
|
529
|
+
# @option opts [String] :sort Ordering of live rounds. A `400` with `status=closed`; with `status=all` it orders the live part only. - `most_raised` (default) — highest amount raised first - `closing_soon` — soonest funding close first - `newest` — most recently launched first - `most_investors` — highest investor count first (default to 'most_raised')
|
|
528
530
|
# @option opts [String] :exemption Only offerings under this SEC exemption family. Reg CF and Reg D are the supported public filters.
|
|
529
531
|
# @option opts [String] :security Only offerings issuing this kind of security — the `security.type` value on results.
|
|
530
532
|
# @option opts [Boolean] :testing_the_waters `false` — only live rounds accepting investments; `true` — only Testing-the-Waters rounds collecting non-binding reservations.
|
|
@@ -541,10 +543,12 @@ module WefunderGenerated
|
|
|
541
543
|
end
|
|
542
544
|
|
|
543
545
|
# List public offerings
|
|
544
|
-
# Returns the offerings shown on wefunder.com/explore — the curated set of companies that meet Wefunder's discoverability bar (a soft-confirmed traction threshold plus approval), **one offering per company**. An \"offering\" is a fundraise, addressed by its id (`ofr_...`). **Public view (`read:public`).** Reachable with either a server-side (client_credentials) token or a user access token. Private rounds (e.g. Reg D 506(b)) are never listed, and low-traction or unapproved companies are excluded — exactly as they are on the website for a logged-out visitor. **Logged-in view (`read:explore`).** A user access token carrying `read:explore` gets what *that user* sees on wefunder.com/explore: the public offerings plus any the user qualifies for (accredited-only / Vault deals, invited private rounds), each checked against the same visibility policy the website applies. The response is a strict superset of the public one — same fields and ids — with two extra attributes, `publicly_visible` and `invested`, and `meta.personalized: true`. A server-side key can never hold `read:explore`; a token with `read:explore` but no resolvable user gets the public view. Order with `sort` (default: most raised); paginate with `cursor`. `meta.total_count` is the number of offerings across all pages, after filters. **Filters** are objective, per-offering terms — exemption family, security type, TTW vs. live, minimum investment ceiling, close date, amount raised floor. The response echoes the applied set in `meta.filters`. An out-of-vocabulary value is a `400` naming the accepted values. There are deliberately no relevance, quality, or ranking criteria. Use this endpoint to: - Discover and monitor active deals - Build deal aggregators and public listings
|
|
546
|
+
# Returns the offerings shown on wefunder.com/explore — the curated set of companies that meet Wefunder's discoverability bar (a soft-confirmed traction threshold plus approval), **one offering per company**. An \"offering\" is a fundraise, addressed by its id (`ofr_...`). **Public view (`read:public`).** Reachable with either a server-side (client_credentials) token or a user access token. Private rounds (e.g. Reg D 506(b)) are never listed, and low-traction or unapproved companies are excluded — exactly as they are on the website for a logged-out visitor. **Logged-in view (`read:explore`).** A user access token carrying `read:explore` gets what *that user* sees on wefunder.com/explore: the public offerings plus any the user qualifies for (accredited-only / Vault deals, invited private rounds), each checked against the same visibility policy the website applies. The response is a strict superset of the public one — same fields and ids — with two extra attributes, `publicly_visible` and `invested`, and `meta.personalized: true`. A server-side key can never hold `read:explore`; a token with `read:explore` but no resolvable user gets the public view. Order with `sort` (default: most raised); paginate with `cursor` and `per_page`. `meta.total_count` is the number of offerings across all pages, after filters. **Closed rounds (`status`).** By default the list is live rounds. `status=closed` lists rounds that finished raising instead, newest `closed_at` first. It is not limited to one per company or to the curated explore set: it covers every finished round that `GET /offerings/{id}` serves to a logged-out visitor, for companies listed in Wefunder's public directory. `status=all` returns the live list first, then the closed list. With `status=closed` or `status=all`, `exemption` is the only filter accepted, and `sort` orders only the live part. Closed rounds follow the public view even for a `read:explore` token. **Filters** are objective, per-offering terms — exemption family, security type, TTW vs. live, minimum investment ceiling, close date, amount raised floor. The response echoes the applied set in `meta.filters`. An out-of-vocabulary value is a `400` naming the accepted values. There are deliberately no relevance, quality, or ranking criteria. Use this endpoint to: - Discover and monitor active deals - Build deal aggregators and public listings - Bulk-list closed rounds (`status=closed`)
|
|
545
547
|
# @param [Hash] opts the optional parameters
|
|
546
548
|
# @option opts [Integer] :cursor Cursor-based pagination token. Use the `next_cursor` value from the previous response's `meta` object to retrieve the next page of results. Omit this parameter to retrieve the first page.
|
|
547
|
-
# @option opts [
|
|
549
|
+
# @option opts [Integer] :per_page Offerings per page. (default to 25)
|
|
550
|
+
# @option opts [String] :status Which rounds to list: - `live` (default): rounds accepting investments or reservations, as on wefunder.com/explore - `closed`: rounds that finished raising, newest `closed_at` first (id breaks ties) - `all`: the live list, then the closed list Any other value is a `400`. (default to 'live')
|
|
551
|
+
# @option opts [String] :sort Ordering of live rounds. A `400` with `status=closed`; with `status=all` it orders the live part only. - `most_raised` (default) — highest amount raised first - `closing_soon` — soonest funding close first - `newest` — most recently launched first - `most_investors` — highest investor count first (default to 'most_raised')
|
|
548
552
|
# @option opts [String] :exemption Only offerings under this SEC exemption family. Reg CF and Reg D are the supported public filters.
|
|
549
553
|
# @option opts [String] :security Only offerings issuing this kind of security — the `security.type` value on results.
|
|
550
554
|
# @option opts [Boolean] :testing_the_waters `false` — only live rounds accepting investments; `true` — only Testing-the-Waters rounds collecting non-binding reservations.
|
|
@@ -559,6 +563,18 @@ module WefunderGenerated
|
|
|
559
563
|
if @api_client.config.debugging
|
|
560
564
|
@api_client.config.logger.debug 'Calling API: ExploreApi.list_offerings ...'
|
|
561
565
|
end
|
|
566
|
+
if @api_client.config.client_side_validation && !opts[:'per_page'].nil? && opts[:'per_page'] > 100
|
|
567
|
+
fail ArgumentError, 'invalid value for "opts[:"per_page"]" when calling ExploreApi.list_offerings, must be smaller than or equal to 100.'
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
if @api_client.config.client_side_validation && !opts[:'per_page'].nil? && opts[:'per_page'] < 1
|
|
571
|
+
fail ArgumentError, 'invalid value for "opts[:"per_page"]" when calling ExploreApi.list_offerings, must be greater than or equal to 1.'
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
allowable_values = ["live", "closed", "all"]
|
|
575
|
+
if @api_client.config.client_side_validation && opts[:'status'] && !allowable_values.include?(opts[:'status'])
|
|
576
|
+
fail ArgumentError, "invalid value for \"status\", must be one of #{allowable_values}"
|
|
577
|
+
end
|
|
562
578
|
allowable_values = ["most_raised", "closing_soon", "newest", "most_investors"]
|
|
563
579
|
if @api_client.config.client_side_validation && opts[:'sort'] && !allowable_values.include?(opts[:'sort'])
|
|
564
580
|
fail ArgumentError, "invalid value for \"sort\", must be one of #{allowable_values}"
|
|
@@ -585,6 +601,8 @@ module WefunderGenerated
|
|
|
585
601
|
# query parameters
|
|
586
602
|
query_params = opts[:query_params] || {}
|
|
587
603
|
query_params[:'cursor'] = opts[:'cursor'] if !opts[:'cursor'].nil?
|
|
604
|
+
query_params[:'per_page'] = opts[:'per_page'] if !opts[:'per_page'].nil?
|
|
605
|
+
query_params[:'status'] = opts[:'status'] if !opts[:'status'].nil?
|
|
588
606
|
query_params[:'sort'] = opts[:'sort'] if !opts[:'sort'].nil?
|
|
589
607
|
query_params[:'exemption'] = opts[:'exemption'] if !opts[:'exemption'].nil?
|
|
590
608
|
query_params[:'security'] = opts[:'security'] if !opts[:'security'].nil?
|
|
@@ -20,7 +20,7 @@ module WefunderGenerated
|
|
|
20
20
|
@api_client = api_client
|
|
21
21
|
end
|
|
22
22
|
# Propose an intent
|
|
23
|
-
# Propose a dangerous or irreversible action for human approval. Returns a `review_url` where a human must review the impact and approve before the action executes. The entity that proposes an intent can never approve it. Approval always happens on Wefunder's UI by a user with permission on the resource. Each action names the scope that may propose it and the resource type it targets (`syndicates.*` → `write:syndicates` on a syndicate; `comments.create` → `write:comments` on a `Company`). The token must hold that action's scope; holding another proposing scope is not enough (403 `insufficient_scope`). `comments.create` posts a question on a company's Ask tab, or an answer to one, as the requesting user once they approve on wefunder.com. `resource_id` is the company (`co_...`); `params` is `{ target_type: \"company\" | \"comment\", target: \"co_...\" | \"cmt_...\", body, disclosure_key? }` (`disclosure_key` ∈ investor, stockholder, promoter, financial_stakeholder). Who may post is the site's own rule: anyone the page is available to may ask (unless the company has closed questions); only the company's team may answer. Only the requester can approve. 20 proposals per user per day (429). An `idempotency_key` names one operation. Reusing it for the same operation returns the existing intent (200) while that intent is pending, approved, executing, or executed; reusing it for a different action, resource, or params is a 409 `idempotency_conflict`. An action still rolling out per account returns 403 `feature_disabled` for a user who is not yet enabled. `POST /intents/preview` runs the same checks without minting. See [Intents documentation](/concepts/intents) for the full pattern.
|
|
23
|
+
# Propose a dangerous or irreversible action for human approval. Returns a `review_url` where a human must review the impact and approve before the action executes. The entity that proposes an intent can never approve it. Approval always happens on Wefunder's UI by a user with permission on the resource. Each action names the scope that may propose it and the resource type it targets (`syndicates.*` → `write:syndicates` on a syndicate; `comments.create` → `write:comments` on a `Company`). The token must hold that action's scope; holding another proposing scope is not enough (403 `insufficient_scope`). `comments.create` posts a question on a company's Ask tab, or an answer to one, as the requesting user once they approve on wefunder.com. `resource_id` is the company (`co_...`); `params` is `{ target_type: \"company\" | \"comment\", target: \"co_...\" | \"cmt_...\", body, disclosure_key? }` (`disclosure_key` ∈ investor, stockholder, promoter, financial_stakeholder). Who may post is the site's own rule: anyone the page is available to may ask (unless the company has closed questions); only the company's team may answer. Only the requester can approve. 20 proposals per user per day (429). An `idempotency_key` names one operation. Reusing it for the same operation returns the existing intent (200) while that intent is pending, approved, executing, or executed; reusing it for a different action, resource, or params is a 409 `idempotency_conflict`. An action still rolling out per account returns 403 `feature_disabled` for a user who is not yet enabled. `POST /intents/preview` runs the same checks without minting. `syndicates.close_deal` and `syndicates.finalize_deal` were removed in `2026-10-15`: on this version they answer 400 `bad_request` (\"Unknown action\") with `details.removed_in_version`. A syndicate's managers close and finalize deals on wefunder.com. Intents minted before still appear in `GET /intents` with those action names. See [Intents documentation](/concepts/intents) for the full pattern.
|
|
24
24
|
# @param create_intent_request [CreateIntentRequest]
|
|
25
25
|
# @param [Hash] opts the optional parameters
|
|
26
26
|
# @return [IntentEnvelope]
|
|
@@ -30,7 +30,7 @@ module WefunderGenerated
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# Propose an intent
|
|
33
|
-
# Propose a dangerous or irreversible action for human approval. Returns a `review_url` where a human must review the impact and approve before the action executes. The entity that proposes an intent can never approve it. Approval always happens on Wefunder's UI by a user with permission on the resource. Each action names the scope that may propose it and the resource type it targets (`syndicates.*` → `write:syndicates` on a syndicate; `comments.create` → `write:comments` on a `Company`). The token must hold that action's scope; holding another proposing scope is not enough (403 `insufficient_scope`). `comments.create` posts a question on a company's Ask tab, or an answer to one, as the requesting user once they approve on wefunder.com. `resource_id` is the company (`co_...`); `params` is `{ target_type: \"company\" | \"comment\", target: \"co_...\" | \"cmt_...\", body, disclosure_key? }` (`disclosure_key` ∈ investor, stockholder, promoter, financial_stakeholder). Who may post is the site's own rule: anyone the page is available to may ask (unless the company has closed questions); only the company's team may answer. Only the requester can approve. 20 proposals per user per day (429). An `idempotency_key` names one operation. Reusing it for the same operation returns the existing intent (200) while that intent is pending, approved, executing, or executed; reusing it for a different action, resource, or params is a 409 `idempotency_conflict`. An action still rolling out per account returns 403 `feature_disabled` for a user who is not yet enabled. `POST /intents/preview` runs the same checks without minting. See [Intents documentation](/concepts/intents) for the full pattern.
|
|
33
|
+
# Propose a dangerous or irreversible action for human approval. Returns a `review_url` where a human must review the impact and approve before the action executes. The entity that proposes an intent can never approve it. Approval always happens on Wefunder's UI by a user with permission on the resource. Each action names the scope that may propose it and the resource type it targets (`syndicates.*` → `write:syndicates` on a syndicate; `comments.create` → `write:comments` on a `Company`). The token must hold that action's scope; holding another proposing scope is not enough (403 `insufficient_scope`). `comments.create` posts a question on a company's Ask tab, or an answer to one, as the requesting user once they approve on wefunder.com. `resource_id` is the company (`co_...`); `params` is `{ target_type: \"company\" | \"comment\", target: \"co_...\" | \"cmt_...\", body, disclosure_key? }` (`disclosure_key` ∈ investor, stockholder, promoter, financial_stakeholder). Who may post is the site's own rule: anyone the page is available to may ask (unless the company has closed questions); only the company's team may answer. Only the requester can approve. 20 proposals per user per day (429). An `idempotency_key` names one operation. Reusing it for the same operation returns the existing intent (200) while that intent is pending, approved, executing, or executed; reusing it for a different action, resource, or params is a 409 `idempotency_conflict`. An action still rolling out per account returns 403 `feature_disabled` for a user who is not yet enabled. `POST /intents/preview` runs the same checks without minting. `syndicates.close_deal` and `syndicates.finalize_deal` were removed in `2026-10-15`: on this version they answer 400 `bad_request` (\"Unknown action\") with `details.removed_in_version`. A syndicate's managers close and finalize deals on wefunder.com. Intents minted before still appear in `GET /intents` with those action names. See [Intents documentation](/concepts/intents) for the full pattern.
|
|
34
34
|
# @param create_intent_request [CreateIntentRequest]
|
|
35
35
|
# @param [Hash] opts the optional parameters
|
|
36
36
|
# @return [Array<(IntentEnvelope, Integer, Hash)>] IntentEnvelope data, response status code and response headers
|
|
@@ -19,8 +19,8 @@ module WefunderGenerated
|
|
|
19
19
|
def initialize(api_client = ApiClient.default)
|
|
20
20
|
@api_client = api_client
|
|
21
21
|
end
|
|
22
|
-
#
|
|
23
|
-
# The Investment Delta API: keep a copy of a company's investment records in sync by polling. Call without `cursor` to **bootstrap** (list every current record for the company); every response carries `meta.next_cursor`; call again with that cursor to receive only the records whose published state changed since. Records are the same shape in both modes. - Records are **published state**, not live rows: Wefunder publishes a record when the investment's founder-visible state changes, and serves exactly what was published. - `visible: false` records are **tombstones**: the investment is no longer visible to the company (canceled, converted to another round, hidden, or deleted). Delete your copy. - Apply records in `cursor` order. `observed_at` is when the payload was observed, not a version; a record you read late carries the *current* published state. - **410 Gone** means your cursor predates the 90-day retention window. Bootstrap again and **replace** your dataset for the company from the result (records absent from the bootstrap are deleted). - Investor identity fields (`investor.name`, `investor.legal_name`, `investor.email`, `investor.address`, `investor.bio`, `message`, `external_username`) are **omitted** unless the token carries `read:investors:pii`. - Money is integer minor units plus `amounts.currency` (`committed_cents`, `investment_size_cents`, `in_escrow_cents`, `contracts[].override_amount_cents`). `shares` and `average_share_price` are decimal strings, `null` on rounds without shares. `amounts.raised_cents` is the row's contribution to the public raised figure (0 while `needs_whitelisting`); sum it, not `committed_cents`, to match the deal page.
|
|
22
|
+
# Legacy alias: bootstrap or page investment changes for a company
|
|
23
|
+
# **Compatibility alias.** This path keeps working unchanged for partners already on it, but new integrations should use [List or sync investments](/api-reference/list-investments) (`GET /investments?company_id=…`): same records, interchangeable cursors. The [migration notes](/partner-api/investments/changes#migrating-from-companiescompany_idinvestmentschanges) list the differences. The Investment Delta API: keep a copy of a company's investment records in sync by polling. Call without `cursor` to **bootstrap** (list every current record for the company); every response carries `meta.next_cursor`; call again with that cursor to receive only the records whose published state changed since. Records are the same shape in both modes. - Records are **published state**, not live rows: Wefunder publishes a record when the investment's founder-visible state changes, and serves exactly what was published. - `visible: false` records are **tombstones**: the investment is no longer visible to the company (canceled, converted to another round, hidden, or deleted). Delete your copy. - Apply records in `cursor` order. `observed_at` is when the payload was observed, not a version; a record you read late carries the *current* published state. - **410 Gone** means your cursor predates the 90-day retention window. Bootstrap again and **replace** your dataset for the company from the result (records absent from the bootstrap are deleted). - Investor identity fields (`investor.name`, `investor.legal_name`, `investor.email`, `investor.address`, `investor.bio`, `message`, `external_username`) are **omitted** unless the token carries `read:investors:pii`. - Money is integer minor units plus `amounts.currency` (`committed_cents`, `investment_size_cents`, `in_escrow_cents`, `contracts[].override_amount_cents`). `shares` and `average_share_price` are decimal strings, `null` on rounds without shares. `amounts.raised_cents` is the row's contribution to the public raised figure (0 while `needs_whitelisting`); sum it, not `committed_cents`, to match the deal page.
|
|
24
24
|
# @param company_id [String] The company's external id (`co_…`).
|
|
25
25
|
# @param [Hash] opts the optional parameters
|
|
26
26
|
# @option opts [String] :cursor Opaque cursor from a previous response's `meta.next_cursor`. Omit to bootstrap.
|
|
@@ -31,8 +31,8 @@ module WefunderGenerated
|
|
|
31
31
|
data
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
#
|
|
35
|
-
# The Investment Delta API: keep a copy of a company's investment records in sync by polling. Call without `cursor` to **bootstrap** (list every current record for the company); every response carries `meta.next_cursor`; call again with that cursor to receive only the records whose published state changed since. Records are the same shape in both modes. - Records are **published state**, not live rows: Wefunder publishes a record when the investment's founder-visible state changes, and serves exactly what was published. - `visible: false` records are **tombstones**: the investment is no longer visible to the company (canceled, converted to another round, hidden, or deleted). Delete your copy. - Apply records in `cursor` order. `observed_at` is when the payload was observed, not a version; a record you read late carries the *current* published state. - **410 Gone** means your cursor predates the 90-day retention window. Bootstrap again and **replace** your dataset for the company from the result (records absent from the bootstrap are deleted). - Investor identity fields (`investor.name`, `investor.legal_name`, `investor.email`, `investor.address`, `investor.bio`, `message`, `external_username`) are **omitted** unless the token carries `read:investors:pii`. - Money is integer minor units plus `amounts.currency` (`committed_cents`, `investment_size_cents`, `in_escrow_cents`, `contracts[].override_amount_cents`). `shares` and `average_share_price` are decimal strings, `null` on rounds without shares. `amounts.raised_cents` is the row's contribution to the public raised figure (0 while `needs_whitelisting`); sum it, not `committed_cents`, to match the deal page.
|
|
34
|
+
# Legacy alias: bootstrap or page investment changes for a company
|
|
35
|
+
# **Compatibility alias.** This path keeps working unchanged for partners already on it, but new integrations should use [List or sync investments](/api-reference/list-investments) (`GET /investments?company_id=…`): same records, interchangeable cursors. The [migration notes](/partner-api/investments/changes#migrating-from-companiescompany_idinvestmentschanges) list the differences. The Investment Delta API: keep a copy of a company's investment records in sync by polling. Call without `cursor` to **bootstrap** (list every current record for the company); every response carries `meta.next_cursor`; call again with that cursor to receive only the records whose published state changed since. Records are the same shape in both modes. - Records are **published state**, not live rows: Wefunder publishes a record when the investment's founder-visible state changes, and serves exactly what was published. - `visible: false` records are **tombstones**: the investment is no longer visible to the company (canceled, converted to another round, hidden, or deleted). Delete your copy. - Apply records in `cursor` order. `observed_at` is when the payload was observed, not a version; a record you read late carries the *current* published state. - **410 Gone** means your cursor predates the 90-day retention window. Bootstrap again and **replace** your dataset for the company from the result (records absent from the bootstrap are deleted). - Investor identity fields (`investor.name`, `investor.legal_name`, `investor.email`, `investor.address`, `investor.bio`, `message`, `external_username`) are **omitted** unless the token carries `read:investors:pii`. - Money is integer minor units plus `amounts.currency` (`committed_cents`, `investment_size_cents`, `in_escrow_cents`, `contracts[].override_amount_cents`). `shares` and `average_share_price` are decimal strings, `null` on rounds without shares. `amounts.raised_cents` is the row's contribution to the public raised figure (0 while `needs_whitelisting`); sum it, not `committed_cents`, to match the deal page.
|
|
36
36
|
# @param company_id [String] The company's external id (`co_…`).
|
|
37
37
|
# @param [Hash] opts the optional parameters
|
|
38
38
|
# @option opts [String] :cursor Opaque cursor from a previous response's `meta.next_cursor`. Omit to bootstrap.
|