{"openapi":"3.0.0","paths":{"/health":{"get":{"operationId":"HealthController_health","parameters":[],"responses":{"200":{"description":""}}}},"/v1/links":{"get":{"operationId":"LinksController_list","summary":"List recent links (optionally filtered by org).","description":"Required scopes: links:read.","parameters":[{"name":"orgId","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Links"],"security":[{"x-api-key":[]}]},"post":{"operationId":"LinksController_create","summary":"Create a wrapped, tracked short link.","description":"Required scopes: links:write. If `parentLinkId` is supplied, an influence_edges row is auto-created.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"originalUrl":{"type":"string","example":"https://example.com/product/123"},"orgId":{"type":"string","format":"uuid","nullable":true},"campaignId":{"type":"string","format":"uuid","nullable":true},"parentLinkId":{"type":"string","format":"uuid","nullable":true},"utm":{"type":"object"}},"required":["originalUrl"]}}}},"responses":{"201":{"description":""}},"tags":["Links"],"security":[{"x-api-key":[]}]}},"/r/{code}":{"get":{"operationId":"LinksController_redirect","summary":"Public redirect: resolves shortcode to original URL and logs a click event.","parameters":[{"name":"code","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Links"],"security":[{"x-api-key":[]}]}},"/v1/events/convert":{"post":{"operationId":"EventsController_convert","summary":"Record a conversion event. Idempotent on (orgId, orderId).","description":"Required scopes: events:write. Triggers an attribution job via Postgres NOTIFY.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","nullable":true},"linkId":{"type":"string","format":"uuid"},"orderId":{"type":"string","example":"ORDER-12345"},"valueCents":{"type":"integer","example":1299},"currency":{"type":"string","example":"USD"},"userAccountId":{"type":"string","format":"uuid","nullable":true}},"required":["linkId","orderId"]}}}},"responses":{"201":{"description":""}},"tags":["Events"],"security":[{"x-api-key":[]}]}},"/v1/analytics/campaign/overview":{"get":{"operationId":"AnalyticsController_overview","summary":"Total clicks + conversions for an org/campaign window.","description":"Required scopes: analytics:read.","parameters":[{"name":"campaignId","required":false,"in":"query","schema":{}},{"name":"orgId","required":false,"in":"query","schema":{}}],"responses":{"200":{"description":""}},"tags":["Analytics"],"security":[{"x-api-key":[]}]}},"/v1/analytics/daily":{"get":{"operationId":"AnalyticsController_daily","summary":"Daily time series of clicks and conversions.","description":"Required scopes: analytics:read.","parameters":[{"name":"to","required":false,"in":"query","description":"ISO datetime (default: now)","schema":{}},{"name":"from","required":false,"in":"query","description":"ISO datetime (default: 30 days ago)","schema":{}},{"name":"campaignId","required":false,"in":"query","schema":{}},{"name":"orgId","required":false,"in":"query","schema":{}}],"responses":{"200":{"description":""}},"tags":["Analytics"],"security":[{"x-api-key":[]}]}},"/v1/analytics/top-links":{"get":{"operationId":"AnalyticsController_topLinks","summary":"Top links by clicks (descending) within a window.","description":"Required scopes: analytics:read.","parameters":[{"name":"limit","required":false,"in":"query","description":"default 10, max 1000","schema":{}}],"responses":{"200":{"description":""}},"tags":["Analytics"],"security":[{"x-api-key":[]}]}},"/v1/analytics/export.csv":{"get":{"operationId":"AnalyticsController_exportCsv","summary":"Export daily series as CSV.","description":"Required scopes: analytics:read.","parameters":[],"responses":{"200":{"description":""}},"tags":["Analytics"],"security":[{"x-api-key":[]}]}},"/v1/campaigns":{"get":{"operationId":"CampaignsController_list","summary":"List campaigns (optionally by org).","description":"Required scopes: campaigns:read.","parameters":[],"responses":{"200":{"description":""}},"tags":["Campaigns"],"security":[{"x-api-key":[]}]},"post":{"operationId":"CampaignsController_create","summary":"Create a campaign.","description":"Required scopes: campaigns:write.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid","nullable":true},"name":{"type":"string","example":"Launch Campaign"},"status":{"type":"string","enum":["draft","active","paused","archived"],"example":"active"}},"required":["name"]}}}},"responses":{"201":{"description":""}},"tags":["Campaigns"],"security":[{"x-api-key":[]}]}},"/v1/campaigns/{id}":{"patch":{"operationId":"CampaignsController_update","summary":"Update a campaign.","description":"Required scopes: campaigns:write.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Campaigns"],"security":[{"x-api-key":[]}]},"delete":{"operationId":"CampaignsController_archive","summary":"Archive a campaign (soft delete, status=archived).","description":"Required scopes: campaigns:write.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Campaigns"],"security":[{"x-api-key":[]}]}},"/v1/auth/magic-link":{"post":{"operationId":"AuthController_magicLink","summary":"Send a magic-link sign-in email via Resend.","description":"Public endpoint. No auth required.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","example":"you@example.com"}},"required":["email"]}}}},"responses":{"200":{"description":"Email accepted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}}},"tags":["Auth"]}},"/v1/auth/verify":{"post":{"operationId":"AuthController_verify","summary":"Verify a magic-link token and issue a JWT.","description":"Public endpoint. Returns the JWT in BOTH a cookie AND the response body so cross-domain clients (where 3rd-party cookies are blocked) can store it client-side.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","example":"token-from-email"}},"required":["token"]}}}},"responses":{"200":{"description":"Verified; jwt cookie set + jwt in body","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"user":{"type":"object"},"jwt":{"type":"string"}}}}}}},"tags":["Auth"]}},"/v1/auth/logout":{"post":{"operationId":"AuthController_logout","summary":"Clear the JWT cookie.","description":"Requires a valid JWT cookie.","parameters":[],"responses":{"201":{"description":""}},"tags":["Auth"]}},"/v1/auth/me":{"get":{"operationId":"AuthController_me","summary":"Return the currently signed-in user (from JWT cookie).","parameters":[],"responses":{"200":{"description":""}},"tags":["Auth"]}},"/v1/auth/accept-invite":{"post":{"operationId":"AuthController_acceptInvite","summary":"Accept an org invite token and join the org.","description":"Returns jwt in cookie + body.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"},"email":{"type":"string"}},"required":["token","email"]}}}},"responses":{"201":{"description":""}},"tags":["Auth"]}},"/v1/orgs":{"get":{"operationId":"OrgsController_list","summary":"List orgs visible to the caller.","description":"Required scopes: orgs:manage (when using API key). JWT cookie users see orgs they belong to.","parameters":[],"responses":{"200":{"description":"Array of orgs"}},"tags":["Orgs"],"security":[{"x-api-key":[]}]},"post":{"operationId":"OrgsController_create","summary":"Create a new org.","description":"Requires a signed-in user (JWT cookie) - the creator becomes brand_admin of the new org.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"Acme Brand"}},"required":["name"]}}}},"responses":{"201":{"description":""}},"tags":["Orgs"],"security":[{"x-api-key":[]}]}},"/v1/orgs/{id}":{"get":{"operationId":"OrgsController_get","summary":"Get org details.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Orgs"],"security":[{"x-api-key":[]}]},"patch":{"operationId":"OrgsController_update","summary":"Update org (brand_admin required).","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Orgs"],"security":[{"x-api-key":[]}]}},"/v1/orgs/{id}/invite":{"post":{"operationId":"OrgsController_invite","summary":"Invite a user to the org by email.","description":"Required scopes: orgs:manage. Required role (cookie): brand_admin.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","example":"invitee@example.com"},"role":{"type":"string","enum":["brand_admin","creator","analyst"],"example":"creator"}},"required":["email","role"]}}}},"responses":{"201":{"description":""}},"tags":["Orgs"],"security":[{"x-api-key":[]}]}},"/v1/keys":{"get":{"operationId":"KeysController_list","summary":"List API keys for an org.","description":"Required scopes: keys:manage. Returned rows expose hashes only, never plaintext keys.","parameters":[{"name":"orgId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["API Keys"],"security":[{"x-api-key":[]}]},"post":{"operationId":"KeysController_create","summary":"Create an API key for an org.","description":"Required scopes: keys:manage. Returns the plaintext key ONCE in the `key` field - store it securely.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"name":{"type":"string","example":"Server Key"},"scopes":{"type":"array","items":{"type":"string"},"example":["links:write","analytics:read"]}},"required":["orgId","name"]}}}},"responses":{"201":{"description":"Key created; plaintext returned once","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["API Keys"],"security":[{"x-api-key":[]}]}},"/v1/keys/{id}":{"delete":{"operationId":"KeysController_revoke","summary":"Revoke an API key.","description":"Required scopes: keys:manage.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["API Keys"],"security":[{"x-api-key":[]}]}},"/v1/webhooks":{"get":{"operationId":"WebhooksController_list","summary":"List webhook subscriptions for an org.","description":"Required scopes: webhooks:manage.","parameters":[{"name":"orgId","required":false,"in":"query","schema":{}}],"responses":{"200":{"description":""}},"tags":["Webhooks"],"security":[{"x-api-key":[]}]},"post":{"operationId":"WebhooksController_create","summary":"Register a webhook subscription. Returns secret ONCE.","description":"Required scopes: webhooks:manage. Webhook deliveries are signed: HMAC-SHA256(secret, body) sent in X-Wanadryve-Signature.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"string","format":"uuid"},"url":{"type":"string","example":"https://your-app.com/wanadryve/webhook"},"topics":{"type":"array","items":{"type":"string","enum":["click.created","conversion.created","attribution.finalized","reward.paid","reward.pending","fraud.flagged"]},"example":["conversion.created","attribution.finalized"]}},"required":["url","topics"]}}}},"responses":{"201":{"description":""}},"tags":["Webhooks"],"security":[{"x-api-key":[]}]}},"/v1/webhooks/{id}":{"delete":{"operationId":"WebhooksController_revoke","summary":"Delete a webhook subscription.","description":"Required scopes: webhooks:manage.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Webhooks"],"security":[{"x-api-key":[]}]}},"/v1/webhooks/deliveries":{"get":{"operationId":"WebhooksController_deliveries","summary":"List recent webhook deliveries (pending/delivered/failed/dead).","parameters":[],"responses":{"200":{"description":""}},"tags":["Webhooks"],"security":[{"x-api-key":[]}]}},"/v1/webhooks/deliveries/{id}/retry":{"post":{"operationId":"WebhooksController_retry","summary":"Manually re-queue a webhook delivery for an immediate retry.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Webhooks"],"security":[{"x-api-key":[]}]}},"/v1/rewards":{"get":{"operationId":"RewardsController_list","summary":"List rewards for an org (optionally filtered by status).","description":"Required scopes: rewards:read.","parameters":[{"name":"status","required":false,"in":"query","schema":{"enum":["pending","approved","paid","rejected"],"type":"string"}},{"name":"orgId","required":false,"in":"query","schema":{}}],"responses":{"200":{"description":""}},"tags":["Rewards"],"security":[{"x-api-key":[]}]}},"/v1/rewards/{id}":{"patch":{"operationId":"RewardsController_patch","summary":"Approve/pay/reject a reward.","description":"Required scopes: rewards:manage.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","approved","paid","rejected"]}},"required":["status"]}}}},"responses":{"200":{"description":""}},"tags":["Rewards"],"security":[{"x-api-key":[]}]}},"/v1/rewards/export.csv":{"get":{"operationId":"RewardsController_exportCsv","summary":"Export rewards ledger as CSV (importable to Stripe/Wise/PayPal).","description":"Required scopes: rewards:read.","parameters":[],"responses":{"200":{"description":""}},"tags":["Rewards"],"security":[{"x-api-key":[]}]}},"/v1/fraud/signals":{"get":{"operationId":"FraudController_signals","summary":"List recent fraud signals for an org.","description":"Required scopes: fraud:read.","parameters":[],"responses":{"200":{"description":""}},"tags":["Fraud"],"security":[{"x-api-key":[]}]}},"/v1/fraud/cases":{"get":{"operationId":"FraudController_cases","summary":"List fraud review cases.","description":"Required scopes: fraud:read.","parameters":[],"responses":{"200":{"description":""}},"tags":["Fraud"],"security":[{"x-api-key":[]}]},"post":{"operationId":"FraudController_openCase","summary":"Open a fraud review case.","description":"Required scopes: fraud:manage.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"string"},"caseKey":{"type":"string"},"reason":{"type":"string"},"evidence":{"type":"object"}},"required":["caseKey","reason"]}}}},"responses":{"201":{"description":""}},"tags":["Fraud"],"security":[{"x-api-key":[]}]}},"/v1/fraud/cases/{id}":{"patch":{"operationId":"FraudController_patch","summary":"Change the status of a fraud case (open|reviewing|allowed|denied).","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Fraud"],"security":[{"x-api-key":[]}]}},"/v1/orgs/{orgId}/members":{"get":{"operationId":"MembersController_list","summary":"List members of an org.","description":"Required scopes: orgs:manage.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Members"],"security":[{"x-api-key":[]}]},"post":{"operationId":"MembersController_add","summary":"Add a member to an org (creates the user if needed).","description":"Required scopes: orgs:manage.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"roles":{"type":"array","items":{"type":"string"}}},"required":["email","roles"]}}}},"responses":{"201":{"description":""}},"tags":["Members"],"security":[{"x-api-key":[]}]}},"/v1/orgs/{orgId}/members/{userId}":{"patch":{"operationId":"MembersController_patch","summary":"Update a member roles.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Members"],"security":[{"x-api-key":[]}]},"delete":{"operationId":"MembersController_remove","summary":"Remove a member from an org.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Members"],"security":[{"x-api-key":[]}]}},"/v1/billing/plans":{"get":{"operationId":"BillingController_plans","summary":"List available plans.","parameters":[],"responses":{"200":{"description":""}},"tags":["Billing"],"security":[{"x-api-key":[]}]}},"/v1/billing/orgs/{orgId}/subscription":{"get":{"operationId":"BillingController_sub","summary":"Get an org subscription + plan limits.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Billing"],"security":[{"x-api-key":[]}]},"patch":{"operationId":"BillingController_change","summary":"Change plan for an org.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"planId":{"type":"string","enum":["free","starter","growth","enterprise"]}},"required":["planId"]}}}},"responses":{"200":{"description":""}},"tags":["Billing"],"security":[{"x-api-key":[]}]}},"/v1/billing/orgs/{orgId}/usage":{"get":{"operationId":"BillingController_usage","summary":"Get current period usage counters for an org.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Billing"],"security":[{"x-api-key":[]}]}},"/v1/attribution/path":{"get":{"operationId":"AttributionController_path","summary":"Resolve the influence chain (ancestors) for a link.","description":"Required scopes: analytics:read.","parameters":[{"name":"linkId","required":true,"in":"query","schema":{"type":"string"}},{"name":"orgId","required":false,"in":"query","schema":{}}],"responses":{"200":{"description":""}},"tags":["Attribution"],"security":[{"x-api-key":[]}]}},"/v1/attribution/simulate":{"post":{"operationId":"AttributionController_simulate","summary":"Compute attribution weights for a link under any model (does not persist).","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"string"},"linkId":{"type":"string"},"model":{"type":"string","enum":["first_touch","last_touch","linear","time_decay","position_based","fractional"]},"decayHalfLifeDays":{"type":"integer"}},"required":["linkId","model"]}}}},"responses":{"201":{"description":""}},"tags":["Attribution"],"security":[{"x-api-key":[]}]}},"/v1/trust/users/{userId}":{"get":{"operationId":"TrustController_getUser","summary":"Get trust score + tier for a user.","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Trust"],"security":[{"x-api-key":[]}]}},"/v1/trust/users/{userId}/observations":{"get":{"operationId":"TrustController_listObs","summary":"List trust observations contributing to a user score.","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Trust"],"security":[{"x-api-key":[]}]}},"/v1/trust/observations":{"post":{"operationId":"TrustController_add","summary":"Submit a trust observation (platform integration, oauth verification, manual review).","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"string"},"userId":{"type":"string"},"source":{"type":"string","enum":["platform","oauth","manual","api"]},"observation":{"type":"object"},"weight":{"type":"number"}},"required":["userId","source","observation"]}}}},"responses":{"201":{"description":""}},"tags":["Trust"],"security":[{"x-api-key":[]}]}},"/v1/audits":{"get":{"operationId":"AuditsController_list","summary":"List audit log entries for an org.","parameters":[],"responses":{"200":{"description":""}},"tags":["Audits"],"security":[{"x-api-key":[]}]}},"/v1/virality/trending":{"get":{"operationId":"ViralityController_trending","summary":"Top trending links by score (rolling 24h).","parameters":[],"responses":{"200":{"description":""}},"tags":["Virality"],"security":[{"x-api-key":[]}]}},"/v1/virality/recompute":{"post":{"operationId":"ViralityController_recompute","summary":"Trigger an immediate virality recompute (also runs hourly in worker).","parameters":[],"responses":{"201":{"description":""}},"tags":["Virality"],"security":[{"x-api-key":[]}]}},"/v1/public/links/{shortcode}/stats":{"get":{"operationId":"PublicController_stats","summary":"Public coarse stats for a shortcode (no auth).","parameters":[{"name":"shortcode","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Public"]}},"/v1/payouts/accounts":{"get":{"operationId":"PayoutsController_accounts","summary":"List payout accounts for an org.","parameters":[],"responses":{"200":{"description":""}},"tags":["Payouts"],"security":[{"x-api-key":[]}]},"post":{"operationId":"PayoutsController_upsert","summary":"Upsert a payout account (Stripe Connect / Wise / PayPal / manual).","parameters":[],"responses":{"201":{"description":""}},"tags":["Payouts"],"security":[{"x-api-key":[]}]}},"/v1/payouts/batches":{"get":{"operationId":"PayoutsController_batches","summary":"List payout batches.","parameters":[],"responses":{"200":{"description":""}},"tags":["Payouts"],"security":[{"x-api-key":[]}]},"post":{"operationId":"PayoutsController_create","summary":"Create a payout batch from approved rewards.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"orgId":{"type":"string"},"provider":{"type":"string","enum":["stripe","wise","paypal","manual"]},"rewardIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["provider","rewardIds"]}}}},"responses":{"201":{"description":""}},"tags":["Payouts"],"security":[{"x-api-key":[]}]}},"/v1/payouts/batches/{id}":{"get":{"operationId":"PayoutsController_getBatch","summary":"Get a payout batch with items.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Payouts"],"security":[{"x-api-key":[]}]}},"/v1/payouts/batches/{id}/process":{"post":{"operationId":"PayoutsController_process","summary":"Process (send) a queued payout batch via the configured provider.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Payouts"],"security":[{"x-api-key":[]}]}},"/v1/security/2fa/start":{"post":{"operationId":"SecurityController_start","summary":"Start 2FA enrollment; returns otpauth URI for QR code.","parameters":[],"responses":{"201":{"description":""}},"tags":["Security"]}},"/v1/security/2fa/confirm":{"post":{"operationId":"SecurityController_confirm","summary":"Confirm 2FA enrollment with TOTP code; returns recovery codes ONCE.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string"}},"required":["code"]}}}},"responses":{"201":{"description":""}},"tags":["Security"]}},"/v1/security/2fa/disable":{"post":{"operationId":"SecurityController_disable","summary":"Disable 2FA for the signed-in user.","parameters":[],"responses":{"201":{"description":""}},"tags":["Security"]}},"/v1/security/sso/{orgId}":{"get":{"operationId":"SecurityController_ssoList","summary":"List SSO providers for an org.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Security"],"security":[{"x-api-key":[]}]},"post":{"operationId":"SecurityController_ssoCreate","summary":"Register a SAML/OIDC provider for an org.","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Security"],"security":[{"x-api-key":[]}]}},"/v1/security/sso/{id}/toggle":{"post":{"operationId":"SecurityController_ssoToggle","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Security"],"security":[{"x-api-key":[]}]}},"/v1/security/scim/{orgId}/token":{"post":{"operationId":"SecurityController_scimMint","summary":"Mint a SCIM token for IdP user provisioning (returned ONCE).","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Security"],"security":[{"x-api-key":[]}]}},"/v1/security/ip-allowlist/{orgId}":{"get":{"operationId":"SecurityController_ipList","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Security"],"security":[{"x-api-key":[]}]},"post":{"operationId":"SecurityController_ipAdd","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Security"],"security":[{"x-api-key":[]}]}},"/v1/security/ip-allowlist/{orgId}/{id}":{"delete":{"operationId":"SecurityController_ipRemove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Security"],"security":[{"x-api-key":[]}]}},"/v1/realtime/stream":{"get":{"operationId":"RealtimeController_stream","summary":"Server-Sent Events stream of live clicks/conversions for an org.","parameters":[],"responses":{"200":{"description":""}},"tags":["Realtime"],"security":[{"x-api-key":[]}]}},"/scim/v2/Users":{"get":{"operationId":"ScimController_listUsers","summary":"SCIM: list users in the calling org.","parameters":[],"responses":{"200":{"description":""}},"tags":["SCIM"]},"post":{"operationId":"ScimController_createUser","summary":"SCIM: create a user and add to the calling org.","parameters":[],"responses":{"201":{"description":""}},"tags":["SCIM"]}},"/scim/v2/Users/{id}":{"get":{"operationId":"ScimController_getUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["SCIM"]},"patch":{"operationId":"ScimController_patchUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["SCIM"]},"delete":{"operationId":"ScimController_deleteUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["SCIM"]}},"/v1/connect/providers":{"get":{"operationId":"ConnectionsController_providers","summary":"List supported social providers + which are configured server-side.","parameters":[],"responses":{"200":{"description":""}},"tags":["Connections"]}},"/v1/connect/connections":{"get":{"operationId":"ConnectionsController_list","summary":"List the signed-in user's connected social accounts.","parameters":[],"responses":{"200":{"description":""}},"tags":["Connections"]}},"/v1/connect/{provider}/start":{"post":{"operationId":"ConnectionsController_start","summary":"Begin OAuth: returns the URL to redirect the user to.","parameters":[{"name":"provider","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"returnTo":{"type":"string"}}}}}},"responses":{"201":{"description":""}},"tags":["Connections"]}},"/v1/connect/{provider}/callback":{"get":{"operationId":"ConnectionsController_callback","summary":"OAuth redirect target. Persists the connection and redirects back to the web app.","parameters":[{"name":"provider","required":true,"in":"path","schema":{"type":"string"}},{"name":"code","required":true,"in":"query","schema":{"type":"string"}},{"name":"state","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Connections"]}},"/v1/connect/connections/{id}":{"delete":{"operationId":"ConnectionsController_remove","summary":"Remove a connection.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Connections"]}},"/v1/connect/connections/{id}/disable":{"post":{"operationId":"ConnectionsController_disable","summary":"Disable a connection (keeps token but stops shares).","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Connections"]}},"/v1/connect/share":{"post":{"operationId":"ConnectionsController_share","summary":"Queue a post to one or more connected platforms.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"linkId":{"type":"string","format":"uuid"},"connectionIds":{"type":"array","items":{"type":"string"}},"text":{"type":"string"},"mediaUrls":{"type":"array","items":{"type":"string"}}},"required":["linkId","connectionIds","text"]}}}},"responses":{"201":{"description":""}},"tags":["Connections"]}},"/v1/connect/share-intents":{"get":{"operationId":"ConnectionsController_intents","summary":"List recent share intents for the signed-in user.","parameters":[{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Connections"]}},"/v1/connect/process-pending":{"post":{"operationId":"ConnectionsController_processPending","summary":"Worker hook: process pending share intents (called by cron).","parameters":[{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Connections"],"security":[{"x-api-key":[]}]}},"/v1/downloads/extension/debug":{"get":{"operationId":"DownloadsController_debug","summary":"Diagnostic: show where the API thinks the extension dist is and what is inside it.","parameters":[],"responses":{"200":{"description":""}},"tags":["Downloads"]}},"/v1/downloads/extension/catalog":{"get":{"operationId":"DownloadsController_catalog","summary":"Returns the catalog of available browser bundles.","parameters":[],"responses":{"200":{"description":""}},"tags":["Downloads"]}},"/v1/downloads/extension/{browser}":{"get":{"operationId":"DownloadsController_download","summary":"Download the extension bundle for a browser (chrome|edge|firefox|safari). Streams a zip on the fly if needed.","parameters":[{"name":"browser","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Downloads"]}}},"info":{"title":"Wanadryve API","description":"Universal attribution and trust API","version":"1.0.0","contact":{}},"tags":[],"servers":[{"url":"https://wanadryve-api-rq74.onrender.com"}],"components":{"schemas":{}}}