diff --git a/features/bounties/api/participant-dashboard-client.ts b/features/bounties/api/participant-dashboard-client.ts index b9fa5cee..582ca729 100644 --- a/features/bounties/api/participant-dashboard-client.ts +++ b/features/bounties/api/participant-dashboard-client.ts @@ -1,11 +1,11 @@ /** * Builder "my bounties" dashboard reads (boundless-nestjs #332). * - * These endpoints aren't in the generated OpenAPI schema yet, so they go through - * the legacy axios `api` (cookie auth, `{ success, data }` envelope) rather than - * the typed openapi-fetch client. Swap to the typed client + generated types once - * #332 lands and `npm run codegen` runs. Until the backend ships, calls 404 and - * the hooks degrade to empty. + * The row/page shapes are now generated from the OpenAPI schema (see + * `MyBountyApplicationRow` / `MyBountySubmissionRow` in ../types). Transport + * still goes through the legacy axios `api` (cookie auth, `{ success, data }` + * envelope) because these routes return the enveloped payload; the hooks degrade + * to empty if the backend is unreachable. */ import { api } from '@/lib/api/api'; diff --git a/features/bounties/index.ts b/features/bounties/index.ts index 6ffd9b21..52f765ad 100644 --- a/features/bounties/index.ts +++ b/features/bounties/index.ts @@ -89,8 +89,7 @@ export type { // ── Builder / participant data layer (#621) ────────────────────────────────── -// Participant types (aliased from the generated schema; MyBountyApplication is -// hand-typed until boundless-nestjs #331 lands and codegen runs). +// Participant types (all aliased from the generated schema). export type { BountyPublic, BountyPublicList, diff --git a/features/bounties/types.ts b/features/bounties/types.ts index 33089279..d24e57c1 100644 --- a/features/bounties/types.ts +++ b/features/bounties/types.ts @@ -95,80 +95,25 @@ export type CreateBountyApplicationRequest = export type EditBountyApplicationRequest = Schemas['EditBountyApplicationDto']; export type JoinCompetitionRequest = Schemas['JoinCompetitionDto']; -/** - * The caller's own application for a bounty (GET …/v2/applications/me). - * - * The backend `BountyApplicationResponseDto` (boundless-nestjs #331) is not yet - * in the generated schema, so this is hand-typed to its shape. Replace with - * `Schemas['BountyApplicationResponseDto']` after that lands and codegen runs. - */ -export type BountyApplicationStatus = - | 'SUBMITTED' - | 'SHORTLISTED' - | 'SELECTED' - | 'DECLINED' - | 'WITHDRAWN'; - -export interface MyBountyApplication { - id: string; - bountyId: string; - applicantAddress: string; - status: string; - applicationStatus: BountyApplicationStatus | null; - proposalShort: string | null; - proposalFull: string | null; - portfolioLinks: string[]; - estimatedDays: number | null; - qualifications: string | null; - videoIntroUrl: string | null; - declineReason: string | null; - shortlistedAt: string | null; - selectedAt: string | null; - declinedAt: string | null; - withdrawnAt: string | null; - createdAt: string; - updatedAt: string; -} +/** The caller's own application for a bounty (GET …/v2/applications/me). */ +export type MyBountyApplication = Schemas['BountyApplicationResponseDto']; -/** - * Cross-bounty "my activity" dashboard rows (boundless-nestjs #332). These - * endpoints (`/bounties/me/applications`, `/bounties/me/submissions`) are not - * yet in the generated schema, so the rows are hand-typed to the backend DTOs. - * Swap to `Schemas[...]` once #332 lands and codegen runs. - */ -export interface BountyActivitySummary { - id: string; - title: string; - status: string; - entryType: BountyEntryType | null; - claimType: BountyClaimType | null; - rewardCurrency: string; - deadline: string | null; -} +/** Application lifecycle status (derived from the generated DTO enum). */ +export type BountyApplicationStatus = NonNullable< + MyBountyApplication['applicationStatus'] +>; -export interface MyBountyApplicationRow { - id: string; - applicationStatus: BountyApplicationStatus | null; - status: string; - createdAt: string; - updatedAt: string; - bounty: BountyActivitySummary; -} +// ── Cross-bounty "my activity" dashboard ────────────────────────────────────── +// GET /bounties/me/applications and /bounties/me/submissions. -export interface MyBountySubmissionRow { - id: string; - status: string; - escrowAnchorStatus: string | null; - githubPullRequestUrl: string | null; - tierPosition: number | null; - tierAmount: string | null; - rewardTransactionHash: string | null; - paidAt: string | null; - createdAt: string; - updatedAt: string; - bounty: BountyActivitySummary; -} +/** Compact bounty summary embedded in each activity row. */ +export type BountyActivitySummary = Schemas['BountySummaryDto']; +/** A row in the "my applications" activity list. */ +export type MyBountyApplicationRow = Schemas['MyBountyApplicationRowDto']; +/** A row in the "my submissions" activity list. */ +export type MyBountySubmissionRow = Schemas['MyBountySubmissionRowDto']; +/** Generic paginated activity envelope (items + page meta). */ export interface BountyActivityPage { items: T[]; total: number; diff --git a/lib/api/generated/schema.d.ts b/lib/api/generated/schema.d.ts index d38ceaae..723dc97d 100644 --- a/lib/api/generated/schema.d.ts +++ b/lib/api/generated/schema.d.ts @@ -1569,23 +1569,6 @@ export interface paths { patch?: never; trace?: never; }; - '/api/crowdfunding/campaigns/{id}/v2/escrow/claim-milestone': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Claim a milestone payout (reviewStatus must be APPROVED) */ - post: operations['BuilderCrowdfundingV2Controller_claimMilestone']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; '/api/crowdfunding/campaigns/{id}/v2/escrow/contribute': { parameters: { query?: never; @@ -1791,6 +1774,40 @@ export interface paths { patch?: never; trace?: never; }; + '/api/crowdfunding/campaigns/{id}/v2/disputes': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Open a dispute on a campaign (backers only) */ + post: operations['CrowdfundingDisputesController_file']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/crowdfunding/campaigns/{id}/v2/disputes/mine': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List the caller’s disputes on a campaign */ + get: operations['CrowdfundingDisputesController_mine']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; '/api/wallet': { parameters: { query?: never; @@ -7121,7 +7138,7 @@ export interface paths { put?: never; /** * Create verification session - * @description Creates a Didit verification session. Returns session_token and verification_url for the frontend SDK. Authenticated user id is sent as vendor_data unless user_id is provided. + * @description Creates a Didit verification session for the authenticated user. Returns session_token and verification_url for the frontend SDK. */ post: operations['DiditController_createSession']; delete?: never; @@ -7141,7 +7158,7 @@ export interface paths { put?: never; /** * Didit webhook - * @description Receives verification completion events from Didit. Verifies X-Signature-V2 when DIDIT_WEBHOOK_SECRET is set. Updates user verification status and DiditVerificationSession. + * @description Receives verification completion events from Didit. The signature is verified by DiditWebhookGuard. Updates user verification status and DiditVerificationSession. */ post: operations['DiditController_webhook']; delete?: never; @@ -7215,18 +7232,15 @@ export interface paths { patch?: never; trace?: never; }; - '/api/prices': { + '/api/admin/v2/access/me': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Get USD prices for all supported assets - * @description Returns per-unit USD prices for XLM, USDC, EURC and USDGLO. Resolved from the Reflector on-chain oracle, with CoinGecko and stablecoin-peg fallbacks. Cached for 5 minutes (matches Reflector update cadence). - */ - get: operations['PricesController_getAll']; + /** The current staff principal and role */ + get: operations['AccessController_me']; put?: never; post?: never; delete?: never; @@ -7235,18 +7249,15 @@ export interface paths { patch?: never; trace?: never; }; - '/api/prices/debug': { + '/api/admin/v2/access/roles': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Per-provider price resolution (diagnostic) - * @description Bypasses the cache and pings Reflector + CoinGecko for every supported asset. Returns what each provider returned alongside which one the resolution chain would have picked. Use to verify both price paths are live. - */ - get: operations['PricesController_getDebug']; + /** The role and permission matrix (Super Admin only) */ + get: operations['AccessController_roles']; put?: never; post?: never; delete?: never; @@ -7255,18 +7266,15 @@ export interface paths { patch?: never; trace?: never; }; - '/api/prices/{symbol}': { + '/api/admin/v2/analytics': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Get USD price for a single asset - * @description Convenience lookup — internally reads from the same cached map as the list endpoint. - */ - get: operations['PricesController_getOne']; + /** Platform analytics (growth, breakdowns, trend) */ + get: operations['AnalyticsController_get']; put?: never; post?: never; delete?: never; @@ -7275,49 +7283,49 @@ export interface paths { patch?: never; trace?: never; }; - '/api/projects/drafts': { + '/api/admin/v2/overview': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Platform overview counts */ + get: operations['OverviewController_get']; put?: never; - /** Create a project draft (stepped form) */ - post: operations['ProjectsController_createDraft']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/projects/{id}/draft': { + '/api/admin/v2/users': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List users (paginated, searchable) */ + get: operations['UsersController_list']; put?: never; post?: never; delete?: never; options?: never; head?: never; - /** Update a project draft (stepped form autosave) */ - patch: operations['ProjectsController_saveDraft']; + patch?: never; trace?: never; }; - '/api/projects': { + '/api/admin/v2/users/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** List public projects (PRD products directory) */ - get: operations['ProjectsController_listPublicProjects']; + /** Get one user */ + get: operations['UsersController_getById']; put?: never; post?: never; delete?: never; @@ -7326,15 +7334,15 @@ export interface paths { patch?: never; trace?: never; }; - '/api/projects/search': { + '/api/admin/v2/users/{id}/earnings': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Search public projects */ - get: operations['ProjectsController_searchPublicProjects']; + /** Get a user's earnings (summary, breakdown, activity) */ + get: operations['UsersController_getEarnings']; put?: never; post?: never; delete?: never; @@ -7343,15 +7351,15 @@ export interface paths { patch?: never; trace?: never; }; - '/api/projects/featured': { + '/api/admin/v2/users/{id}/organizations': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** List featured projects */ - get: operations['ProjectsController_listFeaturedProjects']; + /** Get a user's organizations */ + get: operations['UsersController_getOrganizations']; put?: never; post?: never; delete?: never; @@ -7360,25 +7368,24 @@ export interface paths { patch?: never; trace?: never; }; - '/api/projects/{id}/edits': { + '/api/admin/v2/users/{id}/wallet': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** List edit history for your project */ - get: operations['ProjectsController_listProjectEdits']; + /** Get a user's wallet and live balances */ + get: operations['UsersController_getWallet']; put?: never; - /** Submit a major/minor edit for your project */ - post: operations['ProjectsController_submitProjectEdit']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/projects/{id}/publish': { + '/api/admin/v2/users/{id}/ban': { parameters: { query?: never; header?: never; @@ -7387,23 +7394,23 @@ export interface paths { }; get?: never; put?: never; - /** Publish/submit a project draft (Review & Submit) */ - post: operations['ProjectsController_publishProject']; + post?: never; delete?: never; options?: never; head?: never; - patch?: never; + /** Ban or unban a user (Tier 2: requires step-up) */ + patch: operations['UsersController_setBanned']; trace?: never; }; - '/api/projects/me': { + '/api/admin/v2/organizations': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** List my projects */ - get: operations['ProjectsController_getMyProjects']; + /** List organizations (paginated, searchable) */ + get: operations['OrganizationsController_list']; put?: never; post?: never; delete?: never; @@ -7412,80 +7419,70 @@ export interface paths { patch?: never; trace?: never; }; - '/api/projects/{slug}': { + '/api/admin/v2/organizations/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Get public project by slug */ - get: operations['ProjectsController_getPublicProjectBySlug']; + /** Get one organization */ + get: operations['OrganizationsController_getById']; put?: never; post?: never; delete?: never; options?: never; head?: never; - patch?: never; + /** Update organization details (Tier 2: requires step-up) */ + patch: operations['OrganizationsController_update']; trace?: never; }; - '/api/projects/me/{id}': { + '/api/admin/v2/organizations/{id}/suspend': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Get my project by ID */ - get: operations['ProjectsController_getProject']; + get?: never; put?: never; - post?: never; + /** + * Suspend an organization (Tier 2: requires step-up) + * @description Freezes member-initiated mutations (treasury, member management, owner config). Reversible via reinstate. + */ + post: operations['OrganizationsController_suspend']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/draft/{id}': { + '/api/admin/v2/organizations/{id}/reinstate': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Get a bounty draft for resume - * @description Returns the current section-keyed state of a bounty draft. - */ - get: operations['OrganizationBountiesDraftsController_getDraft']; + get?: never; put?: never; - post?: never; - /** - * Delete a bounty draft - * @description Deletes an unpublished bounty (draft / draft_awaiting_funding). - */ - delete: operations['OrganizationBountiesDraftsController_deleteDraft']; + /** Reinstate a suspended organization (Tier 2: requires step-up) */ + post: operations['OrganizationsController_reinstate']; + delete?: never; options?: never; head?: never; - /** - * Update one or more sections of a bounty draft - * @description Applies any subset of wizard sections in a single PATCH. Send one section for a per-step "Continue", or several for "Save draft". Each present section is validated and transformed independently, then merged into one write. The reward section replaces the prize tiers. - */ - patch: operations['OrganizationBountiesDraftsController_updateDraft']; + patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties': { + '/api/admin/v2/programs': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Get an organization's published bounties - * @description Lists bounties for an organization, newest first. - */ - get: operations['OrganizationBountiesDraftsController_getOrganizationBounties']; + /** List programs across a pillar (paginated, searchable) */ + get: operations['ProgramsController_list']; put?: never; post?: never; delete?: never; @@ -7494,47 +7491,41 @@ export interface paths { patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/draft': { + '/api/admin/v2/programs/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Get one program (type selects the pillar) */ + get: operations['ProgramsController_getById']; put?: never; - /** - * Create a new bounty draft for an organization - * @description Creates an empty bounty in draft status that organization members can edit section by section through the Configure wizard. - */ - post: operations['OrganizationBountiesDraftsController_createDraft']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/drafts': { + '/api/admin/v2/programs/{id}/feature': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Get an organization's bounty drafts - * @description Lists draft and draft_awaiting_funding bounties for an organization. - */ - get: operations['OrganizationBountiesDraftsController_getOrganizationDrafts']; + get?: never; put?: never; post?: never; delete?: never; options?: never; head?: never; - patch?: never; + /** Feature or unfeature a program (Tier 1; hackathons & bounties) */ + patch: operations['ProgramsController_setFeatured']; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{id}/escrow/publish': { + '/api/admin/v2/programs/{id}/status': { parameters: { query?: never; header?: never; @@ -7543,58 +7534,49 @@ export interface paths { }; get?: never; put?: never; - /** - * Publish a bounty draft to the events contract - * @description Validates the draft, transitions it to draft_awaiting_funding, and returns an unsigned XDR (EXTERNAL) or the op in PENDING_CONFIRM (MANAGED). Reconciliation transitions the bounty to OPEN on success. - */ - post: operations['OrganizationBountiesEscrowController_publish']; + post?: never; delete?: never; options?: never; head?: never; - patch?: never; + /** Set an admin lifecycle status (Tier 2: requires step-up) */ + patch: operations['ProgramsController_setStatus']; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{id}/escrow/cancel': { + '/api/admin/v2/disputes': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List disputes (paginated, searchable) */ + get: operations['DisputesController_list']; put?: never; - /** - * Cancel an active bounty - * @description Builds a cancel_event contract op. The contract refunds partner contributions first (in full), then the owner residual; or pro-rates partners if escrow is short. On settle, BountyEscrowSubscriber moves the bounty to CANCELLED and stamps the cancel audit columns. - */ - post: operations['OrganizationBountiesEscrowController_cancel']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{id}/escrow/select-winners': { + '/api/admin/v2/disputes/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Get one dispute */ + get: operations['DisputesController_getById']; put?: never; - /** - * Select winners for a bounty - * @description Builds a select_winners contract op that pays out per the on-chain winner_distribution and bumps each winner's profile credits / reputation / earnings. On settle, BountyEscrowSubscriber moves the bounty to COMPLETED and marks the winning BountySubmission rows accepted with the reward tx hash. - */ - post: operations['OrganizationBountiesEscrowController_selectWinners']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{id}/escrow/ops/{opRowId}/submit-signed': { + '/api/admin/v2/disputes/{id}/assign': { parameters: { query?: never; header?: never; @@ -7603,32 +7585,32 @@ export interface paths { }; get?: never; put?: never; - /** Submit signed XDR for a previously-built bounty escrow op */ - post: operations['OrganizationBountiesEscrowController_submitSigned']; + /** Assign a dispute to a staff handler, or unassign (Tier 1) */ + post: operations['DisputesController_assign']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{id}/escrow/ops/{opRowId}': { + '/api/admin/v2/disputes/{id}/note': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Read the current state of a bounty escrow op */ - get: operations['OrganizationBountiesEscrowController_getOp']; + get?: never; put?: never; - post?: never; + /** Add an internal note to a dispute (Tier 1) */ + post: operations['DisputesController_note']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{id}/escrow/apply': { + '/api/admin/v2/disputes/{id}/resolve': { parameters: { query?: never; header?: never; @@ -7637,18 +7619,15 @@ export interface paths { }; get?: never; put?: never; - /** - * Apply to a bounty - * @description Builds an apply_to_bounty contract op. EXTERNAL returns unsigned XDR; MANAGED signs and submits. The contract charges the bounty's application_credit_cost via the profile contract on settle. - */ - post: operations['BountyParticipantEscrowController_apply']; + /** Resolve a dispute with an outcome (Tier 2: requires step-up) */ + post: operations['DisputesController_resolve']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{id}/escrow/withdraw-application': { + '/api/admin/v2/disputes/{id}/escalate': { parameters: { query?: never; header?: never; @@ -7657,55 +7636,50 @@ export interface paths { }; get?: never; put?: never; - /** - * Withdraw a bounty application - * @description Builds a withdraw_application contract op. Contract refunds half the application_credit_cost via the profile contract on settle. - */ - post: operations['BountyParticipantEscrowController_withdrawApplication']; + /** Escalate a dispute to arbitration (Tier 2: requires step-up) */ + post: operations['DisputesController_escalate']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{id}/escrow/submit': { + '/api/admin/v2/escrow': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List escrow transactions (paginated, searchable) */ + get: operations['EscrowController_list']; put?: never; - /** - * Submit work for a bounty - * @description Builds a submit contract op. Requires the applicant's prior apply_to_bounty to be in active status (contract enforces; the service pre-checks for a cleaner 4xx). - */ - post: operations['BountyParticipantEscrowController_submit']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{id}/escrow/withdraw-submission': { + '/api/admin/v2/escrow/requests': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List escrow release/refund requests (maker-checker) */ + get: operations['EscrowController_listRequests']; put?: never; - /** Withdraw a bounty submission anchor */ - post: operations['BountyParticipantEscrowController_withdrawSubmission']; + /** Propose an escrow release/refund (Tier 3: step-up) */ + post: operations['EscrowController_propose']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{id}/escrow/contribute': { + '/api/admin/v2/escrow/requests/{id}/decision': { parameters: { query?: never; header?: never; @@ -7714,18 +7688,15 @@ export interface paths { }; get?: never; put?: never; - /** - * Contribute funds to a bounty pool - * @description Builds an add_funds contract op signed by the caller. Contract enforces a 10 USDC minimum. Anyone with a funded wallet can contribute; this v1 surface requires Boundless auth, so multiple top-ups from the same wallet are allowed (one row per attempt). - */ - post: operations['BountyParticipantEscrowController_contribute']; + /** Approve or reject a request (Tier 3: step-up, maker-checker) */ + post: operations['EscrowController_decide']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{id}/escrow/ops/{opRowId}/submit-signed': { + '/api/admin/v2/escrow/requests/{id}/execute': { parameters: { query?: never; header?: never; @@ -7734,23 +7705,23 @@ export interface paths { }; get?: never; put?: never; - /** Submit signed XDR for a previously-built participant op */ - post: operations['BountyParticipantEscrowController_submitSigned']; + /** Record an approved request as executed (Tier 3: step-up) */ + post: operations['EscrowController_execute']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{id}/escrow/ops/{opRowId}': { + '/api/admin/v2/payouts': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Read the state of a participant op */ - get: operations['BountyParticipantEscrowController_getOp']; + /** List platform payouts (paginated, searchable) */ + get: operations['PayoutsController_list']; put?: never; post?: never; delete?: never; @@ -7759,41 +7730,42 @@ export interface paths { patch?: never; trace?: never; }; - '/api/bounties/{bountyId}/v2/applications': { + '/api/admin/v2/payouts/requests': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List payout requests (maker-checker) */ + get: operations['PayoutsController_listRequests']; put?: never; - /** Submit an application for a application bounty */ - post: operations['BountyApplicationController_create']; + /** Propose a payout (Tier 3: step-up) */ + post: operations['PayoutsController_propose']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{bountyId}/v2/applications/me': { + '/api/admin/v2/payouts/requests/{id}/decision': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Read the caller's application for this bounty */ - get: operations['BountyApplicationController_getMine']; + get?: never; put?: never; - post?: never; + /** Approve or reject a payout request (Tier 3: step-up, maker-checker) */ + post: operations['PayoutsController_decide']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{bountyId}/v2/applications/{appId}': { + '/api/admin/v2/payouts/requests/{id}/build-xdr': { parameters: { query?: never; header?: never; @@ -7802,33 +7774,32 @@ export interface paths { }; get?: never; put?: never; - post?: never; - /** Withdraw a SUBMITTED application */ - delete: operations['BountyApplicationController_withdraw']; + /** Build the unsigned payout XDR for offline signing (Tier 3: step-up) */ + post: operations['PayoutsController_buildXdr']; + delete?: never; options?: never; head?: never; - /** Edit a SUBMITTED application (before shortlist) */ - patch: operations['BountyApplicationController_edit']; + patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications': { + '/api/admin/v2/payouts/requests/{id}/submit-signed': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** List applications on a bounty */ - get: operations['OrganizationBountyShortlistController_list']; + get?: never; put?: never; - post?: never; + /** Submit the offline-signed payout XDR; verifies + broadcasts (Tier 3: step-up) */ + post: operations['PayoutsController_submitSigned']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/select': { + '/api/admin/v2/payouts/requests/{id}/execute': { parameters: { query?: never; header?: never; @@ -7837,49 +7808,51 @@ export interface paths { }; get?: never; put?: never; - /** Select a single application (application (light) single claim / application (full) single claim) */ - post: operations['OrganizationBountyShortlistController_selectForSingleClaim']; + /** Fallback: record a payout signed + broadcast off-platform (Tier 3: step-up) */ + post: operations['PayoutsController_execute']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/shortlist': { + '/api/admin/v2/content': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List blog posts (paginated, searchable; archived via ?archived) */ + get: operations['ContentController_list']; put?: never; - /** Approve a shortlist (application (light) competition / application (full) competition) */ - post: operations['OrganizationBountyShortlistController_createShortlist']; + /** Create a blog post (MDX body) (Tier 1) */ + post: operations['ContentController_create']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/{appId}/decline': { + '/api/admin/v2/content/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Get one post (full body + metadata, for editing) */ + get: operations['ContentController_getById']; put?: never; - /** Decline an application with optional reason */ - post: operations['OrganizationBountyShortlistController_decline']; + post?: never; delete?: never; options?: never; head?: never; - patch?: never; + /** Update a blog post (Tier 1) */ + patch: operations['ContentController_update']; trace?: never; }; - '/api/bounties/{bountyId}/v2/competition/join': { + '/api/admin/v2/content/{id}/publish': { parameters: { query?: never; header?: never; @@ -7888,70 +7861,67 @@ export interface paths { }; get?: never; put?: never; - /** Join an open competition bounty */ - post: operations['BountyCompetitionJoinController_join']; - /** Leave an open competition before submitting */ - delete: operations['BountyCompetitionJoinController_leave']; + post?: never; + delete?: never; options?: never; head?: never; - patch?: never; + /** Publish or unpublish a post (Tier 1) */ + patch: operations['ContentController_setPublished']; trace?: never; }; - '/api/bounties': { + '/api/admin/v2/content/{id}/archive': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Public bounty marketplace list */ - get: operations['BountyPublicController_list']; + get?: never; put?: never; - post?: never; + /** Archive (soft-delete) a post (Tier 2: requires step-up) */ + post: operations['ContentController_archive']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/bounties/{id}': { + '/api/admin/v2/content/{id}/restore': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Public bounty detail */ - get: operations['BountyPublicController_findOne']; + get?: never; put?: never; - post?: never; + /** Restore an archived post (Tier 1) */ + post: operations['ContentController_restore']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/grants/{id}/escrow/publish': { + '/api/admin/v2/crowdfunding/review-checklist': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List active review checklist items (display order) */ + get: operations['CrowdfundingChecklistController_list']; put?: never; - /** - * Publish a grant draft to the events contract - * @description Validates the draft, transitions to DRAFT_AWAITING_FUNDING, and returns an unsigned XDR (EXTERNAL) or the op in PENDING_CONFIRM (MANAGED). Reconciliation transitions the grant to OPEN on success. - */ - post: operations['OrganizationGrantsEscrowController_publish']; + /** Add a checklist item (super_admin / operations) */ + post: operations['CrowdfundingChecklistController_create']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/grants/{id}/escrow/cancel': { + '/api/admin/v2/crowdfunding/review-checklist/reorder': { parameters: { query?: never; header?: never; @@ -7960,15 +7930,15 @@ export interface paths { }; get?: never; put?: never; - /** Cancel an active grant */ - post: operations['OrganizationGrantsEscrowController_cancel']; + /** Reorder checklist items (super_admin / operations) */ + post: operations['CrowdfundingChecklistController_reorder']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/grants/{id}/escrow/select-winners': { + '/api/admin/v2/crowdfunding/review-checklist/{itemId}': { parameters: { query?: never; header?: never; @@ -7977,38 +7947,50 @@ export interface paths { }; get?: never; put?: never; - /** - * Select grant recipients - * @description For Multi release_kind, select_winners records recipients with amount=0 — payouts happen per-milestone via claim_milestone. - */ - post: operations['OrganizationGrantsEscrowController_selectWinners']; + post?: never; + /** Archive a checklist item (super_admin / operations) */ + delete: operations['CrowdfundingChecklistController_archive']; + options?: never; + head?: never; + /** Edit a checklist item (super_admin / operations) */ + patch: operations['CrowdfundingChecklistController_update']; + trace?: never; + }; + '/api/admin/v2/crowdfunding': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List crowdfunding campaigns (defaults to the review queue) */ + get: operations['CrowdfundingController_list']; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/grants/{id}/escrow/claim-milestone': { + '/api/admin/v2/crowdfunding/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Get one campaign with its review history */ + get: operations['CrowdfundingController_getById']; put?: never; - /** - * Pay out a specific milestone for a recipient - * @description Builds a claim_milestone contract op. Contract pays the per-milestone amount to the recipient and bumps profile credits / reputation / earnings. - */ - post: operations['OrganizationGrantsEscrowController_claimMilestone']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/grants/{id}/escrow/ops/{opRowId}/submit-signed': { + '/api/admin/v2/crowdfunding/{id}/approve': { parameters: { query?: never; header?: never; @@ -8017,32 +7999,32 @@ export interface paths { }; get?: never; put?: never; - /** Submit signed XDR for a grant op */ - post: operations['OrganizationGrantsEscrowController_submitSigned']; + /** Approve a submitted campaign; assigns a reviewer (Tier 2: step-up) */ + post: operations['CrowdfundingController_approve']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/organizations/{organizationId}/grants/{id}/escrow/ops/{opRowId}': { + '/api/admin/v2/crowdfunding/{id}/reject': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Read the state of a grant op */ - get: operations['OrganizationGrantsEscrowController_getOp']; + get?: never; put?: never; - post?: never; + /** Reject a submitted campaign (Tier 2: step-up) */ + post: operations['CrowdfundingController_reject']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/grants/{id}/escrow/contribute': { + '/api/admin/v2/crowdfunding/{id}/request-revision': { parameters: { query?: never; header?: never; @@ -8051,58 +8033,49 @@ export interface paths { }; get?: never; put?: never; - /** - * Contribute funds to a grant pool - * @description Open add_funds op. Contract enforces a 10 USDC minimum. Anyone authenticated can contribute; multiple top-ups from the same wallet are allowed (one row per attempt). - */ - post: operations['GrantContributeEscrowController_contribute']; + /** Send a submitted campaign back for revisions (Tier 1) */ + post: operations['CrowdfundingController_requestRevision']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/grants': { + '/api/admin/v2/access/totp/enroll': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * List published grants - * @description Public, page-based list of grant programs. Parallel to /bounties and /hackathons. For a multi-pillar feed (Bounty, Hackathon, Grant, Crowdfunding), use /opportunities instead. - */ - get: operations['GrantsPublicController_list']; + get?: never; put?: never; - post?: never; + /** Begin TOTP enrollment (returns secret + QR URI) */ + post: operations['SecurityController_enroll']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/opportunities': { + '/api/admin/v2/access/totp/activate': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * List opportunities across all pillars - * @description Returns a unified, cursor-paginated feed across Bounty, Hackathon, Grant, and Crowdfunding. Pass type= to restrict to one. The cursor is opaque; pass it back as-is to fetch the next page. - */ - get: operations['OpportunitiesController_list']; + get?: never; put?: never; - post?: never; + /** Confirm TOTP enrollment with a code */ + post: operations['SecurityController_activate']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/subscribe': { + '/api/admin/v2/access/step-up': { parameters: { query?: never; header?: never; @@ -8111,29 +8084,23 @@ export interface paths { }; get?: never; put?: never; - /** - * Subscribe to the newsletter - * @description Subscribe an email address to the newsletter. Sends a confirmation email (double opt-in). Rate limited to 5 requests per minute. - */ - post: operations['NewsletterController_subscribe']; + /** Step up: verify a fresh TOTP code for sensitive actions */ + post: operations['SecurityController_stepUp']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/confirm/{token}': { + '/api/admin/v2/audit': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Confirm newsletter subscription - * @description Confirm a newsletter subscription via the token sent in the confirmation email. Redirects to the frontend on success. - */ - get: operations['NewsletterController_confirmSubscription']; + /** List admin audit log entries (paginated, searchable) */ + get: operations['AuditController_list']; put?: never; post?: never; delete?: never; @@ -8142,18 +8109,15 @@ export interface paths { patch?: never; trace?: never; }; - '/api/newsletter/unsubscribe/{token}': { + '/api/admin/v2/audit/stream': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Unsubscribe by token - * @description Unsubscribe from the newsletter using the one-click unsubscribe token from emails. Redirects to the frontend. - */ - get: operations['NewsletterController_unsubscribeByToken']; + /** Live stream of new audit entries (Server-Sent Events) */ + get: operations['AuditController_stream']; put?: never; post?: never; delete?: never; @@ -8162,27 +8126,24 @@ export interface paths { patch?: never; trace?: never; }; - '/api/newsletter/unsubscribe': { + '/api/admin/v2/feature-flags': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List feature flags */ + get: operations['FeatureFlagsController_list']; put?: never; - /** - * Unsubscribe by email - * @description Legacy unsubscribe endpoint. Unsubscribe a subscriber by their email address. - */ - post: operations['NewsletterController_unsubscribe']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/preferences': { + '/api/admin/v2/feature-flags/{key}': { parameters: { query?: never; header?: never; @@ -8195,25 +8156,19 @@ export interface paths { delete?: never; options?: never; head?: never; - /** - * Update subscription preferences - * @description Update topic tag preferences for a subscriber. Valid tags: bounties, hackathons, grants, updates. - */ - patch: operations['NewsletterController_updatePreferences']; + /** Toggle a feature flag (Tier 2: requires step-up) */ + patch: operations['FeatureFlagsController_toggle']; trace?: never; }; - '/api/newsletter/tracking/open/{campaignId}/{subscriberId}': { + '/api/admin/v2/staff': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Track email open - * @description Open tracking pixel endpoint. Returns a 1x1 transparent GIF and records the open event. Used in campaign emails. - */ - get: operations['NewsletterController_trackOpen']; + /** List staff members and their roles */ + get: operations['StaffController_list']; put?: never; post?: never; delete?: never; @@ -8222,151 +8177,127 @@ export interface paths { patch?: never; trace?: never; }; - '/api/newsletter/tracking/click/{campaignId}/{subscriberId}': { + '/api/admin/v2/staff/{id}/role': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Track email link click - * @description Click tracking endpoint. Records the click event and redirects the subscriber to the target URL. - */ - get: operations['NewsletterController_trackClick']; + get?: never; put?: never; post?: never; delete?: never; options?: never; head?: never; - patch?: never; + /** Assign a staff role (Tier 2: requires step-up) */ + patch: operations['StaffController_setRole']; trace?: never; }; - '/api/newsletter/subscribers': { + '/api/admin/v2/governance': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * List newsletter subscribers - * @description Get a paginated list of newsletter subscribers with optional filters by status, source, tags, and search. - */ - get: operations['NewsletterController_getSubscribers']; + /** List governance proposals (optionally by status) */ + get: operations['GovernanceController_list']; put?: never; - post?: never; + /** Propose a governance action (Tier 4: step-up) */ + post: operations['GovernanceController_propose']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/stats': { + '/api/admin/v2/governance/{id}/decision': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Get newsletter statistics - * @description Get subscriber counts by status, subscription sources, and campaign statistics (sent, opens, clicks). - */ - get: operations['NewsletterController_getStats']; + get?: never; put?: never; - post?: never; + /** Approve or reject a proposal (Tier 3: step-up, maker-checker) */ + post: operations['GovernanceController_decide']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/export': { + '/api/admin/v2/governance/{id}/execute': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Export subscribers as CSV - * @description Download a CSV file of subscribers with optional status and tag filters. - */ - get: operations['NewsletterController_exportSubscribers']; + get?: never; put?: never; - post?: never; + /** Record an approved proposal as executed (Tier 4: step-up) */ + post: operations['GovernanceController_execute']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/subscribers/{id}': { + '/api/admin/v2/kyc': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List identity-verification (KYC) records (paginated, filterable) */ + get: operations['KycController_list']; put?: never; post?: never; - /** - * Delete a subscriber - * @description Permanently delete a newsletter subscriber by ID. - */ - delete: operations['NewsletterController_deleteSubscriber']; + delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/campaigns': { + '/api/admin/v2/kyc/connection': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * List newsletter campaigns - * @description Get a paginated list of newsletter campaigns, ordered by most recent first. - */ - get: operations['NewsletterController_getCampaigns']; + /** Live Didit integration status (config presence) */ + get: operations['KycController_connection']; put?: never; - /** - * Create a new campaign - * @description Create a new newsletter campaign draft. Use {{name}} placeholder in content for personalization. Target specific subscribers using tags. - */ - post: operations['NewsletterController_createCampaign']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/campaigns/{id}': { + '/api/admin/v2/kyc/{userId}/sync': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** - * Get campaign details - * @description Get detailed information about a specific campaign, including the most recent 100 send logs. - */ - get: operations['NewsletterController_getCampaign']; + get?: never; put?: never; - post?: never; + /** Pull the latest decision live from Didit and reconcile (Tier 1) */ + post: operations['KycController_sync']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/newsletter/campaigns/{id}/send': { + '/api/admin/v2/kyc/{userId}/retrigger': { parameters: { query?: never; header?: never; @@ -8375,43 +8306,40 @@ export interface paths { }; get?: never; put?: never; - /** - * Send a campaign - * @description Send a campaign to all matching subscribers. Delivers in batches of 10 with 1-second delays. Cannot re-send an already sent campaign. - */ - post: operations['NewsletterController_sendCampaign']; + /** Create a fresh Didit verification session for the user (Tier 1) */ + post: operations['KycController_retrigger']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/admin/queues/dlq/depth': { + '/api/admin/v2/kyc/{userId}/override': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Current DLQ depth (admin only) */ - get: operations['DlqAdminController_getDepth']; + get?: never; put?: never; - post?: never; + /** Manually force a KYC decision, overriding Didit (Tier 2: step-up) */ + post: operations['KycController_override']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/admin/queues/dlq': { + '/api/admin/v2/milestones': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** List parked DLQ entries (admin only) */ - get: operations['DlqAdminController_list']; + /** List deliverable milestones across a pillar (paginated) */ + get: operations['MilestonesController_list']; put?: never; post?: never; delete?: never; @@ -8420,15 +8348,15 @@ export interface paths { patch?: never; trace?: never; }; - '/api/admin/queues/dlq/{jobId}': { + '/api/admin/v2/milestones/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** Fetch a single parked DLQ entry (admin only) */ - get: operations['DlqAdminController_getOne']; + /** Get full milestone detail for admin review */ + get: operations['MilestonesController_findOne']; put?: never; post?: never; delete?: never; @@ -8437,7 +8365,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/admin/queues/dlq/{jobId}/replay': { + '/api/admin/v2/milestones/{id}/approve': { parameters: { query?: never; header?: never; @@ -8446,18 +8374,15 @@ export interface paths { }; get?: never; put?: never; - /** - * Re-enqueue a parked DLQ entry on its original queue - * @description The DLQ row is removed on success. Replay uses the original queue's normal retry budget, so a job that died after 3 retries gets another 3 retries on replay. - */ - post: operations['DlqAdminController_replay']; + /** Approve a submitted crowdfunding milestone (Tier 3: step-up) */ + post: operations['MilestonesController_approve']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/sign-in/social': { + '/api/admin/v2/milestones/{id}/reject': { parameters: { query?: never; header?: never; @@ -8466,32 +8391,32 @@ export interface paths { }; get?: never; put?: never; - /** @description Sign in with a social provider */ - post: operations['socialSignIn']; + /** Reject a submitted crowdfunding milestone (Tier 2: step-up) */ + post: operations['MilestonesController_reject']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/get-session': { + '/api/admin/v2/milestones/{id}/release/build-xdr': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Get the current session */ - get: operations['getSession']; + get?: never; put?: never; - post?: never; + /** Build the unsigned release transaction for an APPROVED milestone (admin signs the envelope offline at the Lab). Tier 3: step-up. */ + post: operations['MilestonesController_buildReleaseXdr']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/sign-out': { + '/api/admin/v2/milestones/{id}/release/submit-signed': { parameters: { query?: never; header?: never; @@ -8500,194 +8425,109 @@ export interface paths { }; get?: never; put?: never; - /** @description Sign out the current user */ - post: operations['signOut']; + /** Submit the admin-signed release transaction for a milestone (verified against the built XDR). Tier 3: step-up. */ + post: operations['MilestonesController_submitReleaseSigned']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/sign-up/email': { + '/api/admin/v2/wallets': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List abstracted wallets (paginated, searchable) */ + get: operations['WalletsController_list']; put?: never; - /** @description Sign up a user using email and password */ - post: operations['signUpWithEmailAndPassword']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/sign-in/email': { + '/api/prices': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * Get USD prices for all supported assets + * @description Returns per-unit USD prices for XLM, USDC, EURC and USDGLO. Resolved from the Reflector on-chain oracle, with CoinGecko and stablecoin-peg fallbacks. Cached for 5 minutes (matches Reflector update cadence). + */ + get: operations['PricesController_getAll']; put?: never; - /** @description Sign in with email and password */ - post: operations['signInEmail']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/reset-password': { + '/api/prices/debug': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * Per-provider price resolution (diagnostic) + * @description Bypasses the cache and pings Reflector + CoinGecko for every supported asset. Returns what each provider returned alongside which one the resolution chain would have picked. Use to verify both price paths are live. + */ + get: operations['PricesController_getDebug']; put?: never; - /** @description Reset the password for a user */ - post: operations['resetPassword']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/verify-password': { + '/api/prices/{symbol}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * Get USD price for a single asset + * @description Convenience lookup — internally reads from the same cached map as the list endpoint. + */ + get: operations['PricesController_getOne']; put?: never; - /** @description Verify the current user's password */ - post: operations['verifyPassword']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/verify-email': { + '/api/projects/drafts': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Verify the email of the user */ - get: { - parameters: { - query: { - /** @description The token to verify the email */ - token: string; - /** @description The URL to redirect to after email verification */ - callbackURL?: string; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - user: components['schemas']['User']; - /** @description Indicates if the email was verified successfully */ - status: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + get?: never; put?: never; - post?: never; + /** Create a project draft (stepped form) */ + post: operations['ProjectsController_createDraft']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/send-verification-email': { + '/api/projects/{id}/draft': { parameters: { query?: never; header?: never; @@ -8696,82 +8536,84 @@ export interface paths { }; get?: never; put?: never; - /** @description Send a verification email to the user */ - post: operations['sendVerificationEmail']; + post?: never; delete?: never; options?: never; head?: never; - patch?: never; + /** Update a project draft (stepped form autosave) */ + patch: operations['ProjectsController_saveDraft']; trace?: never; }; - '/api/auth/change-email': { + '/api/projects': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List public projects (PRD products directory) */ + get: operations['ProjectsController_listPublicProjects']; put?: never; - post: operations['changeEmail']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/change-password': { + '/api/projects/search': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Search public projects */ + get: operations['ProjectsController_searchPublicProjects']; put?: never; - /** @description Change the password of the user */ - post: operations['changePassword']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/update-user': { + '/api/projects/featured': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List featured projects */ + get: operations['ProjectsController_listFeaturedProjects']; put?: never; - /** @description Update the current user */ - post: operations['updateUser']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/delete-user': { + '/api/projects/{id}/edits': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List edit history for your project */ + get: operations['ProjectsController_listProjectEdits']; put?: never; - /** @description Delete the user */ - post: operations['deleteUser']; + /** Submit a major/minor edit for your project */ + post: operations['ProjectsController_submitProjectEdit']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/request-password-reset': { + '/api/projects/{id}/publish': { parameters: { query?: never; header?: never; @@ -8780,23 +8622,23 @@ export interface paths { }; get?: never; put?: never; - /** @description Send a password reset email to the user */ - post: operations['requestPasswordReset']; + /** Publish/submit a project draft (Review & Submit) */ + post: operations['ProjectsController_publishProject']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/reset-password/{token}': { + '/api/projects/me': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Redirects the user to the callback URL with the token */ - get: operations['resetPasswordCallback']; + /** List my projects */ + get: operations['ProjectsController_getMyProjects']; put?: never; post?: never; delete?: never; @@ -8805,15 +8647,15 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/list-sessions': { + '/api/projects/{slug}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description List all active sessions for the user */ - get: operations['listUserSessions']; + /** Get public project by slug */ + get: operations['ProjectsController_getPublicProjectBySlug']; put?: never; post?: never; delete?: never; @@ -8822,228 +8664,72 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/revoke-session': { + '/api/projects/me/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Get my project by ID */ + get: operations['ProjectsController_getProject']; put?: never; - /** @description Revoke a single session */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: { - content: { - 'application/json': { - /** @description The token to revoke */ - token: string; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description Indicates if the session was revoked successfully */ - status: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/revoke-sessions': { + '/api/organizations/{organizationId}/bounties/draft/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * Get a bounty draft for resume + * @description Returns the current section-keyed state of a bounty draft. + */ + get: operations['OrganizationBountiesDraftsController_getDraft']; put?: never; - /** @description Revoke all sessions for the user */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: { - content: { - 'application/json': Record; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description Indicates if all sessions were revoked successfully */ - status: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + post?: never; + /** + * Delete a bounty draft + * @description Deletes an unpublished bounty (draft / draft_awaiting_funding). + */ + delete: operations['OrganizationBountiesDraftsController_deleteDraft']; + options?: never; + head?: never; + /** + * Update one or more sections of a bounty draft + * @description Applies any subset of wizard sections in a single PATCH. Send one section for a per-step "Continue", or several for "Save draft". Each present section is validated and transformed independently, then merged into one write. The reward section replaces the prize tiers. + */ + patch: operations['OrganizationBountiesDraftsController_updateDraft']; + trace?: never; + }; + '/api/organizations/{organizationId}/bounties': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + /** + * Get an organization's published bounties + * @description Lists bounties for an organization, newest first. + */ + get: operations['OrganizationBountiesDraftsController_getOrganizationBounties']; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/revoke-other-sessions': { + '/api/organizations/{organizationId}/bounties/draft': { parameters: { query?: never; header?: never; @@ -9052,254 +8738,98 @@ export interface paths { }; get?: never; put?: never; - /** @description Revoke all other sessions for the user except the current one */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: { - content: { - 'application/json': Record; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description Indicates if all other sessions were revoked successfully */ - status: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + /** + * Create a new bounty draft for an organization + * @description Creates an empty bounty in draft status that organization members can edit section by section through the Configure wizard. + */ + post: operations['OrganizationBountiesDraftsController_createDraft']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/link-social': { + '/api/organizations/{organizationId}/bounties/drafts': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * Get an organization's bounty drafts + * @description Lists draft and draft_awaiting_funding bounties for an organization. + */ + get: operations['OrganizationBountiesDraftsController_getOrganizationDrafts']; put?: never; - /** @description Link a social account to the user */ - post: operations['linkSocialAccount']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/list-accounts': { + '/api/organizations/{organizationId}/bounties/{id}/escrow/publish': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description List all accounts linked to the user */ - get: operations['listUserAccounts']; + get?: never; put?: never; - post?: never; + /** + * Publish a bounty draft to the events contract + * @description Validates the draft, transitions it to draft_awaiting_funding, and returns an unsigned XDR (EXTERNAL) or the op in PENDING_CONFIRM (MANAGED). Reconciliation transitions the bounty to OPEN on success. + */ + post: operations['OrganizationBountiesEscrowController_publish']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/delete-user/callback': { + '/api/organizations/{organizationId}/bounties/{id}/escrow/cancel': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Callback to complete user deletion with verification token */ - get: { - parameters: { - query?: { - token?: string; - callbackURL?: string | null; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description User successfully deleted */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description Indicates if the deletion was successful */ - success: boolean; - /** - * @description Confirmation message - * @enum {string} - */ - message: 'User deleted'; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + get?: never; + put?: never; + /** + * Cancel an active bounty + * @description Builds a cancel_event contract op. The contract refunds partner contributions first (in full), then the owner residual; or pro-rates partners if escrow is short. On settle, BountyEscrowSubscriber moves the bounty to CANCELLED and stamps the cancel audit columns. + */ + post: operations['OrganizationBountiesEscrowController_cancel']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/organizations/{organizationId}/bounties/{id}/escrow/select-winners': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + get?: never; put?: never; - post?: never; + /** + * Select winners for a bounty + * @description Builds a select_winners contract op that pays out per the on-chain winner_distribution and bumps each winner's profile credits / reputation / earnings. On settle, BountyEscrowSubscriber moves the bounty to COMPLETED and marks the winning BountySubmission rows accepted with the reward tx hash. + */ + post: operations['OrganizationBountiesEscrowController_selectWinners']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/unlink-account': { + '/api/organizations/{organizationId}/bounties/{id}/escrow/ops/{opRowId}/submit-signed': { parameters: { query?: never; header?: never; @@ -9308,109 +8838,32 @@ export interface paths { }; get?: never; put?: never; - /** @description Unlink an account */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - providerId: string; - accountId?: string | null; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - status?: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + /** Submit signed XDR for a previously-built bounty escrow op */ + post: operations['OrganizationBountiesEscrowController_submitSigned']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/organizations/{organizationId}/bounties/{id}/escrow/ops/{opRowId}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + /** Read the current state of a bounty escrow op */ + get: operations['OrganizationBountiesEscrowController_getOp']; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/refresh-token': { + '/api/bounties/{id}/escrow/apply': { parameters: { query?: never; header?: never; @@ -9419,116 +8872,38 @@ export interface paths { }; get?: never; put?: never; - /** @description Refresh the access token using a refresh token */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The provider ID for the OAuth provider */ - providerId: string; - /** @description The account ID associated with the refresh token */ - accountId?: string | null; - /** @description The user ID associated with the account */ - userId?: string | null; - }; - }; - }; - responses: { - /** @description Access token refreshed successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - tokenType?: string; - idToken?: string; - accessToken?: string; - refreshToken?: string; - /** Format: date-time */ - accessTokenExpiresAt?: string; - /** Format: date-time */ - refreshTokenExpiresAt?: string; - }; - }; - }; - /** @description Invalid refresh token or provider configuration */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + /** + * Apply to a bounty + * @description Builds an apply_to_bounty contract op. EXTERNAL returns unsigned XDR; MANAGED signs and submits. The contract charges the bounty's application_credit_cost via the profile contract on settle. + */ + post: operations['BountyParticipantEscrowController_apply']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/bounties/{id}/escrow/withdraw-application': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + get?: never; + put?: never; + /** + * Withdraw a bounty application + * @description Builds a withdraw_application contract op. Contract refunds half the application_credit_cost via the profile contract on settle. + */ + post: operations['BountyParticipantEscrowController_withdrawApplication']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/get-access-token': { + '/api/bounties/{id}/escrow/submit': { parameters: { query?: never; header?: never; @@ -9537,424 +8912,80 @@ export interface paths { }; get?: never; put?: never; - /** @description Get a valid access token, doing a refresh if needed */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The provider ID for the OAuth provider */ - providerId: string; - /** @description The account ID associated with the refresh token */ - accountId?: string | null; - /** @description The user ID associated with the account */ - userId?: string | null; - }; - }; - }; - responses: { - /** @description A Valid access token */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - tokenType?: string; - idToken?: string; - accessToken?: string; - /** Format: date-time */ - accessTokenExpiresAt?: string; - }; - }; - }; - /** @description Invalid refresh token or provider configuration */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + /** + * Submit work for a bounty + * @description Builds a submit contract op. Requires the applicant's prior apply_to_bounty to be in active status (contract enforces; the service pre-checks for a cleaner 4xx). + */ + post: operations['BountyParticipantEscrowController_submit']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/bounties/{id}/escrow/withdraw-submission': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + get?: never; + put?: never; + /** Withdraw a bounty submission anchor */ + post: operations['BountyParticipantEscrowController_withdrawSubmission']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/account-info': { + '/api/bounties/{id}/escrow/contribute': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Get the account info provided by the provider */ - get: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - user: { - id: string; - name?: string; - email?: string; - image?: string; - emailVerified: boolean; - }; - data: { - [key: string]: unknown; - }; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + get?: never; put?: never; - post?: never; + /** + * Contribute funds to a bounty pool + * @description Builds an add_funds contract op signed by the caller. Contract enforces a 10 USDC minimum. Anyone with a funded wallet can contribute; this v1 surface requires Boundless auth, so multiple top-ups from the same wallet are allowed (one row per attempt). + */ + post: operations['BountyParticipantEscrowController_contribute']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/ok': { + '/api/bounties/{id}/escrow/ops/{opRowId}/submit-signed': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Check if the API is working */ - get: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description API is working */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description Indicates if the API is working */ - ok: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + get?: never; put?: never; - post?: never; + /** Submit signed XDR for a previously-built participant op */ + post: operations['BountyParticipantEscrowController_submitSigned']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/error': { + '/api/bounties/{id}/escrow/ops/{opRowId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Displays an error page */ - get: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'text/html': string; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + /** Read the state of a participant op */ + get: operations['BountyParticipantEscrowController_getOp']; put?: never; post?: never; delete?: never; @@ -9963,7 +8994,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/sign-in/username': { + '/api/bounties/{bountyId}/v2/applications': { parameters: { query?: never; header?: never; @@ -9972,128 +9003,32 @@ export interface paths { }; get?: never; put?: never; - /** @description Sign in with username */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The username of the user */ - username: string; - /** @description The password of the user */ - password: string; - /** @description Remember the user session */ - rememberMe?: boolean | null; - /** @description The URL to redirect to after email verification */ - callbackURL?: string | null; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description Session token for the authenticated session */ - token: string; - user: components['schemas']['User']; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Unprocessable Entity. Validation error */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + /** Submit an application for a application bounty */ + post: operations['BountyApplicationController_create']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/bounties/{bountyId}/v2/applications/me': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + /** Read the caller's application for this bounty */ + get: operations['BountyApplicationController_getMine']; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/is-username-available': { + '/api/bounties/{bountyId}/v2/applications/{appId}': { parameters: { query?: never; header?: never; @@ -10102,97 +9037,33 @@ export interface paths { }; get?: never; put?: never; - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The username to check */ - username: string; - }; - }; - }; - responses: { - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + post?: never; + /** Withdraw a SUBMITTED application */ + delete: operations['BountyApplicationController_withdraw']; + options?: never; + head?: never; + /** Edit a SUBMITTED application (before shortlist) */ + patch: operations['BountyApplicationController_edit']; + trace?: never; + }; + '/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + /** List applications on a bounty */ + get: operations['OrganizationBountyShortlistController_list']; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/two-factor/get-totp-uri': { + '/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/select': { parameters: { query?: never; header?: never; @@ -10201,109 +9072,15 @@ export interface paths { }; get?: never; put?: never; - /** @description Use this endpoint to get the TOTP URI */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description User password */ - password: string; - }; - }; - }; - responses: { - /** @description Successful response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - totpURI?: string; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + /** Select a single application (application (light) single claim / application (full) single claim) */ + post: operations['OrganizationBountyShortlistController_selectForSingleClaim']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/two-factor/verify-totp': { + '/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/shortlist': { parameters: { query?: never; header?: never; @@ -10312,111 +9089,32 @@ export interface paths { }; get?: never; put?: never; - /** @description Verify two factor TOTP */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The otp code to verify. Eg: "012345" */ - code: string; - /** @description If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true */ - trustDevice?: boolean | null; - }; - }; - }; - responses: { - /** @description Successful response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - status?: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + /** Approve a shortlist (application (light) competition / application (full) competition) */ + post: operations['OrganizationBountyShortlistController_createShortlist']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/{appId}/decline': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + get?: never; + put?: never; + /** Decline an application with optional reason */ + post: operations['OrganizationBountyShortlistController_decline']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/two-factor/send-otp': { + '/api/bounties/{bountyId}/v2/competition/join': { parameters: { query?: never; header?: never; @@ -10425,750 +9123,135 @@ export interface paths { }; get?: never; put?: never; - /** @description Send two factor OTP to the user */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Successful response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - status?: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + /** Join an open competition bounty */ + post: operations['BountyCompetitionJoinController_join']; + /** Leave an open competition before submitting */ + delete: operations['BountyCompetitionJoinController_leave']; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/bounties/me/applications': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + /** List the caller's applications across all bounties */ + get: operations['BountyParticipantDashboardController_myApplications']; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/two-factor/verify-otp': { + '/api/bounties/me/submissions': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** List the caller's submissions across all bounties */ + get: operations['BountyParticipantDashboardController_mySubmissions']; put?: never; - /** @description Verify two factor OTP */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The otp code to verify. Eg: "012345" */ - code: string; - trustDevice?: boolean | null; - }; - }; - }; - responses: { - /** @description Two-factor OTP verified successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description Session token for the authenticated session */ - token: string; - /** @description The authenticated user object */ - user: { - /** @description Unique identifier of the user */ - id: string; - /** - * Format: email - * @description User's email address - */ - email?: string | null; - /** @description Whether the email is verified */ - emailVerified?: boolean | null; - /** @description User's name */ - name?: string | null; - /** - * Format: uri - * @description User's profile image URL - */ - image?: string | null; - /** - * Format: date-time - * @description Timestamp when the user was created - */ - createdAt: string; - /** - * Format: date-time - * @description Timestamp when the user was last updated - */ - updatedAt: string; - }; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/bounties/me/submissions/{bountyId}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; + /** Read the caller's submission for one bounty */ + get: operations['BountyParticipantDashboardController_mySubmissionForBounty']; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/two-factor/verify-backup-code': { + '/api/bounties/{id}/results': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Public results / leaderboard (winners by tier) */ + get: operations['BountyResultsController_getResults']; put?: never; - /** @description Verify a backup code for two-factor authentication */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description A backup code to verify. Eg: "123456" */ - code: string; - /** @description If true, the session cookie will not be set. */ - disableSession?: boolean | null; - /** @description If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true */ - trustDevice?: boolean | null; - }; - }; - }; - responses: { - /** @description Backup code verified successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description The authenticated user object with two-factor details */ - user: { - /** @description Unique identifier of the user */ - id: string; - /** - * Format: email - * @description User's email address - */ - email?: string | null; - /** @description Whether the email is verified */ - emailVerified?: boolean | null; - /** @description User's name */ - name?: string | null; - /** - * Format: uri - * @description User's profile image URL - */ - image?: string | null; - /** @description Whether two-factor authentication is enabled for the user */ - twoFactorEnabled: boolean; - /** - * Format: date-time - * @description Timestamp when the user was created - */ - createdAt: string; - /** - * Format: date-time - * @description Timestamp when the user was last updated - */ - updatedAt: string; - }; - /** @description The current session object, included unless disableSession is true */ - session: { - /** @description Session token */ - token: string; - /** @description ID of the user associated with the session */ - userId: string; - /** - * Format: date-time - * @description Timestamp when the session was created - */ - createdAt: string; - /** - * Format: date-time - * @description Timestamp when the session expires - */ - expiresAt: string; - }; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/two-factor/generate-backup-codes': { + '/api/bounties/{id}/submissions': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Submissions the caller may see (respects submissionVisibility) */ + get: operations['BountyResultsController_getSubmissions']; put?: never; - /** @description Generate new backup codes for two-factor authentication */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The users password. */ - password: string; - }; - }; - }; - responses: { - /** @description Backup codes generated successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** - * @description Indicates if the backup codes were generated successfully - * @enum {boolean} - */ - status: true; - /** @description Array of generated backup codes in plain text */ - backupCodes: string[]; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/two-factor/enable': { + '/api/bounties': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Public bounty marketplace list */ + get: operations['BountyPublicController_list']; put?: never; - /** @description Use this endpoint to enable two factor authentication. This will generate a TOTP URI and backup codes. Once the user verifies the TOTP URI, the two factor authentication will be enabled. */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description User password */ - password: string; - /** @description Custom issuer for the TOTP URI */ - issuer?: string | null; - }; - }; - }; - responses: { - /** @description Successful response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @description TOTP URI */ - totpURI?: string; - /** @description Backup codes */ - backupCodes?: string[]; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/two-factor/disable': { + '/api/bounties/{id}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Public bounty detail */ + get: operations['BountyPublicController_findOne']; put?: never; - /** @description Use this endpoint to disable two factor authentication. */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description User password */ - password: string; - }; - }; - }; - responses: { - /** @description Successful response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - status?: boolean; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/one-tap/callback': { + '/api/organizations/{organizationId}/grants/{id}/escrow/publish': { parameters: { query?: never; header?: never; @@ -11177,106 +9260,18 @@ export interface paths { }; get?: never; put?: never; - /** @description Use this endpoint to authenticate with Google One Tap */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description Google ID token, which the client obtains from the One Tap API */ - idToken: string; - }; - }; - }; - responses: { - /** @description Successful response */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - session?: components['schemas']['Session']; - user?: components['schemas']['User']; - }; - }; - }; - /** @description Invalid token */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + /** + * Publish a grant draft to the events contract + * @description Validates the draft, transitions to DRAFT_AWAITING_FUNDING, and returns an unsigned XDR (EXTERNAL) or the op in PENDING_CONFIRM (MANAGED). Reconciliation transitions the grant to OPEN on success. + */ + post: operations['OrganizationGrantsEscrowController_publish']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/email-otp/send-verification-otp': { + '/api/organizations/{organizationId}/grants/{id}/escrow/cancel': { parameters: { query?: never; header?: never; @@ -11285,15 +9280,15 @@ export interface paths { }; get?: never; put?: never; - /** @description Send a verification OTP to an email */ - post: operations['sendEmailVerificationOTP']; + /** Cancel an active grant */ + post: operations['OrganizationGrantsEscrowController_cancel']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/email-otp/check-verification-otp': { + '/api/organizations/{organizationId}/grants/{id}/escrow/select-winners': { parameters: { query?: never; header?: never; @@ -11302,15 +9297,18 @@ export interface paths { }; get?: never; put?: never; - /** @description Verify an email with an OTP */ - post: operations['verifyEmailWithOTP']; + /** + * Select grant recipients + * @description For Multi release_kind, select_winners records recipients with amount=0 — payouts happen per-milestone via claim_milestone. + */ + post: operations['OrganizationGrantsEscrowController_selectWinners']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/email-otp/verify-email': { + '/api/organizations/{organizationId}/grants/{id}/escrow/claim-milestone': { parameters: { query?: never; header?: never; @@ -11319,118 +9317,18 @@ export interface paths { }; get?: never; put?: never; - /** @description Verify email with OTP */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description Email address to verify */ - email: string; - /** @description OTP to verify */ - otp: string; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** - * @description Indicates if the verification was successful - * @enum {boolean} - */ - status: true; - /** @description Session token if autoSignInAfterVerification is enabled, otherwise null */ - token: string | null; - user: components['schemas']['User']; - }; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + /** + * Pay out a specific milestone for a recipient + * @description Builds a claim_milestone contract op. Contract pays the per-milestone amount to the recipient and bumps profile credits / reputation / earnings. + */ + post: operations['OrganizationGrantsEscrowController_claimMilestone']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/sign-in/email-otp': { + '/api/organizations/{organizationId}/grants/{id}/escrow/ops/{opRowId}/submit-signed': { parameters: { query?: never; header?: never; @@ -11439,32 +9337,32 @@ export interface paths { }; get?: never; put?: never; - /** @description Sign in with email and OTP */ - post: operations['signInWithEmailOTP']; + /** Submit signed XDR for a grant op */ + post: operations['OrganizationGrantsEscrowController_submitSigned']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/email-otp/request-password-reset': { + '/api/organizations/{organizationId}/grants/{id}/escrow/ops/{opRowId}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** Read the state of a grant op */ + get: operations['OrganizationGrantsEscrowController_getOp']; put?: never; - /** @description Request password reset with email and OTP */ - post: operations['requestPasswordResetWithEmailOTP']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/forget-password/email-otp': { + '/api/grants/{id}/escrow/contribute': { parameters: { query?: never; header?: never; @@ -11473,151 +9371,58 @@ export interface paths { }; get?: never; put?: never; - /** @description Deprecated: Use /email-otp/request-password-reset instead. */ - post: operations['forgetPasswordWithEmailOTP']; + /** + * Contribute funds to a grant pool + * @description Open add_funds op. Contract enforces a 10 USDC minimum. Anyone authenticated can contribute; multiple top-ups from the same wallet are allowed (one row per attempt). + */ + post: operations['GrantContributeEscrowController_contribute']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/email-otp/reset-password': { + '/api/grants': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * List published grants + * @description Public, page-based list of grant programs. Parallel to /bounties and /hackathons. For a multi-pillar feed (Bounty, Hackathon, Grant, Crowdfunding), use /opportunities instead. + */ + get: operations['GrantsPublicController_list']; put?: never; - /** @description Reset password with email and OTP */ - post: operations['resetPasswordWithEmailOTP']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/create': { + '/api/opportunities': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * List opportunities across all pillars + * @description Returns a unified, cursor-paginated feed across Bounty, Hackathon, Grant, and Crowdfunding. Pass type= to restrict to one. The cursor is opaque; pass it back as-is to fetch the next page. + */ + get: operations['OpportunitiesController_list']; put?: never; - /** @description Create an organization */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The name of the organization */ - name: string; - /** @description The slug of the organization */ - slug: string; - /** @description The user id of the organization creator. If not provided, the current user will be used. Should only be used by admins or when called by the server. server-only. Eg: "user-id" */ - userId?: string | null; - /** @description The logo of the organization */ - logo?: string | null; - /** @description The metadata of the organization */ - metadata?: string | null; - /** @description Whether to keep the current active organization active after creating a new one. Eg: true */ - keepCurrentActiveOrganization?: boolean | null; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['Organization']; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/update': { + '/api/newsletter/subscribe': { parameters: { query?: never; header?: never; @@ -11626,270 +9431,487 @@ export interface paths { }; get?: never; put?: never; - /** @description Update an organization */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - data: { - /** @description The name of the organization */ - name?: string | null; - /** @description The slug of the organization */ - slug?: string | null; - /** @description The logo of the organization */ - logo?: string | null; - /** @description The metadata of the organization */ - metadata?: string | null; - }; - /** @description The organization ID. Eg: "org-id" */ - organizationId?: string | null; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['Organization']; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + /** + * Subscribe to the newsletter + * @description Subscribe an email address to the newsletter. Sends a confirmation email (double opt-in). Rate limited to 5 requests per minute. + */ + post: operations['NewsletterController_subscribe']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/delete': { + '/api/newsletter/confirm/{token}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * Confirm newsletter subscription + * @description Confirm a newsletter subscription via the token sent in the confirmation email. Redirects to the frontend on success. + */ + get: operations['NewsletterController_confirmSubscription']; put?: never; - /** @description Delete an organization */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The organization id to delete */ - organizationId: string; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': string; - }; - }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/set-active': { + '/api/newsletter/unsubscribe/{token}': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** + * Unsubscribe by token + * @description Unsubscribe from the newsletter using the one-click unsubscribe token from emails. Redirects to the frontend. + */ + get: operations['NewsletterController_unsubscribeByToken']; put?: never; - /** @description Set the active organization */ - post: operations['setActiveOrganization']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/get-full-organization': { + '/api/newsletter/unsubscribe': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Get the full organization */ - get: operations['getOrganization']; + get?: never; put?: never; - post?: never; + /** + * Unsubscribe by email + * @description Legacy unsubscribe endpoint. Unsubscribe a subscriber by their email address. + */ + post: operations['NewsletterController_unsubscribe']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/list': { + '/api/newsletter/preferences': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description List all organizations */ - get: { - parameters: { - query?: never; + get?: never; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** + * Update subscription preferences + * @description Update topic tag preferences for a subscriber. Valid tags: bounties, hackathons, grants, updates. + */ + patch: operations['NewsletterController_updatePreferences']; + trace?: never; + }; + '/api/newsletter/tracking/open/{campaignId}/{subscriberId}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Track email open + * @description Open tracking pixel endpoint. Returns a 1x1 transparent GIF and records the open event. Used in campaign emails. + */ + get: operations['NewsletterController_trackOpen']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/newsletter/tracking/click/{campaignId}/{subscriberId}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Track email link click + * @description Click tracking endpoint. Records the click event and redirects the subscriber to the target URL. + */ + get: operations['NewsletterController_trackClick']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/newsletter/subscribers': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List newsletter subscribers + * @description Get a paginated list of newsletter subscribers with optional filters by status, source, tags, and search. + */ + get: operations['NewsletterController_getSubscribers']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/newsletter/stats': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get newsletter statistics + * @description Get subscriber counts by status, subscription sources, and campaign statistics (sent, opens, clicks). + */ + get: operations['NewsletterController_getStats']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/newsletter/export': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Export subscribers as CSV + * @description Download a CSV file of subscribers with optional status and tag filters. + */ + get: operations['NewsletterController_exportSubscribers']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/newsletter/subscribers/{id}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** + * Delete a subscriber + * @description Permanently delete a newsletter subscriber by ID. + */ + delete: operations['NewsletterController_deleteSubscriber']; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/newsletter/campaigns': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * List newsletter campaigns + * @description Get a paginated list of newsletter campaigns, ordered by most recent first. + */ + get: operations['NewsletterController_getCampaigns']; + put?: never; + /** + * Create a new campaign + * @description Create a new newsletter campaign draft. Use {{name}} placeholder in content for personalization. Target specific subscribers using tags. + */ + post: operations['NewsletterController_createCampaign']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/newsletter/campaigns/{id}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Get campaign details + * @description Get detailed information about a specific campaign, including the most recent 100 send logs. + */ + get: operations['NewsletterController_getCampaign']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/newsletter/campaigns/{id}/send': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Send a campaign + * @description Send a campaign to all matching subscribers. Delivers in batches of 10 with 1-second delays. Cannot re-send an already sent campaign. + */ + post: operations['NewsletterController_sendCampaign']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/admin/queues/dlq/depth': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Current DLQ depth (admin only) */ + get: operations['DlqAdminController_getDepth']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/admin/queues/dlq': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List parked DLQ entries (admin only) */ + get: operations['DlqAdminController_list']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/admin/queues/dlq/{jobId}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Fetch a single parked DLQ entry (admin only) */ + get: operations['DlqAdminController_getOne']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/admin/queues/dlq/{jobId}/replay': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Re-enqueue a parked DLQ entry on its original queue + * @description The DLQ row is removed on success. Replay uses the original queue's normal retry budget, so a job that died after 3 retries gets another 3 retries on replay. + */ + post: operations['DlqAdminController_replay']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/sign-in/social': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Sign in with a social provider */ + post: operations['socialSignIn']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/get-session': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get the current session */ + get: operations['getSession']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/sign-out': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Sign out the current user */ + post: operations['signOut']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/sign-up/email': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Sign up a user using email and password */ + post: operations['signUpWithEmailAndPassword']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/sign-in/email': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Sign in with email and password */ + post: operations['signInEmail']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/reset-password': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Reset the password for a user */ + post: operations['resetPassword']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/verify-password': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Verify the current user's password */ + post: operations['verifyPassword']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/verify-email': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Verify the email of the user */ + get: { + parameters: { + query: { + /** @description The token to verify the email */ + token: string; + /** @description The URL to redirect to after email verification */ + callbackURL?: string; + }; header?: never; path?: never; cookie?: never; @@ -11902,7 +9924,11 @@ export interface paths { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['Organization'][]; + 'application/json': { + user: components['schemas']['User']; + /** @description Indicates if the email was verified successfully */ + status: boolean; + }; }; }; /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ @@ -11981,7 +10007,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/organization/invite-member': { + '/api/auth/send-verification-email': { parameters: { query?: never; header?: never; @@ -11990,15 +10016,15 @@ export interface paths { }; get?: never; put?: never; - /** @description Create an invitation to an organization */ - post: operations['createOrganizationInvitation']; + /** @description Send a verification email to the user */ + post: operations['sendVerificationEmail']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/cancel-invitation': { + '/api/auth/change-email': { parameters: { query?: never; header?: never; @@ -12007,97 +10033,14 @@ export interface paths { }; get?: never; put?: never; - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - /** @description The ID of the invitation to cancel */ - invitationId: string; - }; - }; - }; - responses: { - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Unauthorized. Due to missing or invalid authentication. */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message: string; - }; - }; - }; - /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ - 403: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Not Found. The requested resource was not found. */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ - 429: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - message?: string; - }; - }; - }; - }; - }; + post: operations['changeEmail']; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/accept-invitation': { + '/api/auth/change-password': { parameters: { query?: never; header?: never; @@ -12106,19 +10049,121 @@ export interface paths { }; get?: never; put?: never; - /** @description Accept an invitation to an organization */ - post: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; + /** @description Change the password of the user */ + post: operations['changePassword']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/update-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Update the current user */ + post: operations['updateUser']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/delete-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Delete the user */ + post: operations['deleteUser']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/request-password-reset': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Send a password reset email to the user */ + post: operations['requestPasswordReset']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/reset-password/{token}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Redirects the user to the callback URL with the token */ + get: operations['resetPasswordCallback']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/list-sessions': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List all active sessions for the user */ + get: operations['listUserSessions']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/revoke-session': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Revoke a single session */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - requestBody: { + requestBody?: { content: { 'application/json': { - /** @description The ID of the invitation to accept */ - invitationId: string; + /** @description The token to revoke */ + token: string; }; }; }; @@ -12130,8 +10175,8 @@ export interface paths { }; content: { 'application/json': { - invitation?: Record; - member?: Record; + /** @description Indicates if the session was revoked successfully */ + status: boolean; }; }; }; @@ -12209,24 +10254,28 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/organization/get-invitation': { + '/api/auth/revoke-sessions': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Get an invitation by ID */ - get: { + get?: never; + put?: never; + /** @description Revoke all sessions for the user */ + post: { parameters: { - query?: { - id?: string; - }; + query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody?: { + content: { + 'application/json': Record; + }; + }; responses: { /** @description Success */ 200: { @@ -12235,16 +10284,8 @@ export interface paths { }; content: { 'application/json': { - id: string; - email: string; - role: string; - organizationId: string; - inviterId: string; - status: string; - expiresAt: string; - organizationName: string; - organizationSlug: string; - inviterEmail: string; + /** @description Indicates if all sessions were revoked successfully */ + status: boolean; }; }; }; @@ -12316,15 +10357,13 @@ export interface paths { }; }; }; - put?: never; - post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/reject-invitation': { + '/api/auth/revoke-other-sessions': { parameters: { query?: never; header?: never; @@ -12333,7 +10372,7 @@ export interface paths { }; get?: never; put?: never; - /** @description Reject an invitation to an organization */ + /** @description Revoke all other sessions for the user except the current one */ post: { parameters: { query?: never; @@ -12341,12 +10380,9 @@ export interface paths { path?: never; cookie?: never; }; - requestBody: { + requestBody?: { content: { - 'application/json': { - /** @description The ID of the invitation to reject */ - invitationId: string; - }; + 'application/json': Record; }; }; responses: { @@ -12357,8 +10393,8 @@ export interface paths { }; content: { 'application/json': { - invitation?: Record; - member?: Record | null; + /** @description Indicates if all other sessions were revoked successfully */ + status: boolean; }; }; }; @@ -12436,22 +10472,77 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/organization/list-invitations': { + '/api/auth/link-social': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Link a social account to the user */ + post: operations['linkSocialAccount']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/list-accounts': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; + /** @description List all accounts linked to the user */ + get: operations['listUserAccounts']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/delete-user/callback': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Callback to complete user deletion with verification token */ get: { parameters: { - query?: never; + query?: { + token?: string; + callbackURL?: string | null; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description User successfully deleted */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @description Indicates if the deletion was successful */ + success: boolean; + /** + * @description Confirmation message + * @enum {string} + */ + message: 'User deleted'; + }; + }; + }; /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ 400: { headers: { @@ -12528,22 +10619,31 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/organization/get-active-member': { + '/api/auth/unlink-account': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Get the member details of the active organization */ - get: { + get?: never; + put?: never; + /** @description Unlink an account */ + post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': { + providerId: string; + accountId?: string | null; + }; + }; + }; responses: { /** @description Success */ 200: { @@ -12552,10 +10652,7 @@ export interface paths { }; content: { 'application/json': { - id: string; - userId: string; - organizationId: string; - role: string; + status?: boolean; }; }; }; @@ -12627,15 +10724,13 @@ export interface paths { }; }; }; - put?: never; - post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/check-slug': { + '/api/auth/refresh-token': { parameters: { query?: never; header?: never; @@ -12644,6 +10739,7 @@ export interface paths { }; get?: never; put?: never; + /** @description Refresh the access token using a refresh token */ post: { parameters: { query?: never; @@ -12654,23 +10750,41 @@ export interface paths { requestBody: { content: { 'application/json': { - /** @description The organization slug to check. Eg: "my-org" */ - slug: string; + /** @description The provider ID for the OAuth provider */ + providerId: string; + /** @description The account ID associated with the refresh token */ + accountId?: string | null; + /** @description The user ID associated with the account */ + userId?: string | null; }; }; }; responses: { - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ - 400: { + /** @description Access token refreshed successfully */ + 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { - message: string; + tokenType?: string; + idToken?: string; + accessToken?: string; + refreshToken?: string; + /** Format: date-time */ + accessTokenExpiresAt?: string; + /** Format: date-time */ + refreshTokenExpiresAt?: string; }; }; }; + /** @description Invalid refresh token or provider configuration */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; /** @description Unauthorized. Due to missing or invalid authentication. */ 401: { headers: { @@ -12734,7 +10848,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/organization/remove-member': { + '/api/auth/get-access-token': { parameters: { query?: never; header?: never; @@ -12743,7 +10857,7 @@ export interface paths { }; get?: never; put?: never; - /** @description Remove a member from an organization */ + /** @description Get a valid access token, doing a refresh if needed */ post: { parameters: { query?: never; @@ -12754,40 +10868,37 @@ export interface paths { requestBody: { content: { 'application/json': { - /** @description The ID or email of the member to remove */ - memberIdOrEmail: string; - /** @description The ID of the organization to remove the member from. If not provided, the active organization will be used. Eg: "org-id" */ - organizationId?: string | null; + /** @description The provider ID for the OAuth provider */ + providerId: string; + /** @description The account ID associated with the refresh token */ + accountId?: string | null; + /** @description The user ID associated with the account */ + userId?: string | null; }; }; }; responses: { - /** @description Success */ + /** @description A Valid access token */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { - member: { - id: string; - userId: string; - organizationId: string; - role: string; - }; + tokenType?: string; + idToken?: string; + accessToken?: string; + /** Format: date-time */ + accessTokenExpiresAt?: string; }; }; }; - /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + /** @description Invalid refresh token or provider configuration */ 400: { headers: { [name: string]: unknown; }; - content: { - 'application/json': { - message: string; - }; - }; + content?: never; }; /** @description Unauthorized. Due to missing or invalid authentication. */ 401: { @@ -12852,48 +10963,148 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/organization/update-member-role': { + '/api/auth/account-info': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; + /** @description Get the account info provided by the provider */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + user: { + id: string; + name?: string; + email?: string; + image?: string; + emailVerified: boolean; + }; + data: { + [key: string]: unknown; + }; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; put?: never; - /** @description Update the role of a member in an organization */ - post: operations['updateOrganizationMemberRole']; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/leave': { + '/api/auth/ok': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get?: never; - put?: never; - post: { + /** @description Check if the API is working */ + get: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': { - /** @description The organization Id for the member to leave. Eg: "organization-id" */ - organizationId: string; + requestBody?: never; + responses: { + /** @description API is working */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @description Indicates if the API is working */ + ok: boolean; + }; }; }; - }; - responses: { /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ 400: { headers: { @@ -12962,20 +11173,22 @@ export interface paths { }; }; }; + put?: never; + post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/list-user-invitations': { + '/api/auth/error': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description List all invitations a user has received */ + /** @description Displays an error page */ get: { parameters: { query?: never; @@ -12991,20 +11204,7 @@ export interface paths { [name: string]: unknown; }; content: { - 'application/json': { - id: string; - email: string; - role: string; - organizationId: string; - organizationName: string; - /** @description The ID of the user who created the invitation */ - inviterId: string; - /** @description The ID of the team associated with the invitation */ - teamId?: string | null; - status: string; - expiresAt: string; - createdAt: string; - }[]; + 'text/html': string; }; }; /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ @@ -13083,22 +11283,51 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/organization/list-members': { + '/api/auth/sign-in/username': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get: { + get?: never; + put?: never; + /** @description Sign in with username */ + post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': { + /** @description The username of the user */ + username: string; + /** @description The password of the user */ + password: string; + /** @description Remember the user session */ + rememberMe?: boolean | null; + /** @description The URL to redirect to after email verification */ + callbackURL?: string | null; + }; + }; + }; responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @description Session token for the authenticated session */ + token: string; + user: components['schemas']['User']; + }; + }; + }; /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ 400: { headers: { @@ -13143,6 +11372,17 @@ export interface paths { }; }; }; + /** @description Unprocessable Entity. Validation error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ 429: { headers: { @@ -13167,29 +11407,36 @@ export interface paths { }; }; }; - put?: never; - post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/get-active-member-role': { + '/api/auth/is-username-available': { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - get: { + get?: never; + put?: never; + post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': { + /** @description The username to check */ + username: string; + }; + }; + }; responses: { /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ 400: { @@ -13259,15 +11506,13 @@ export interface paths { }; }; }; - put?: never; - post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/organization/has-permission': { + '/api/auth/two-factor/get-totp-uri': { parameters: { query?: never; header?: never; @@ -13276,7 +11521,7 @@ export interface paths { }; get?: never; put?: never; - /** @description Check if the user has permission */ + /** @description Use this endpoint to get the TOTP URI */ post: { parameters: { query?: never; @@ -13284,29 +11529,23 @@ export interface paths { path?: never; cookie?: never; }; - requestBody?: { + requestBody: { content: { 'application/json': { - /** - * @deprecated - * @description The permission to check - */ - permission?: Record; - /** @description The permission to check */ - permissions: Record; + /** @description User password */ + password: string; }; }; }; responses: { - /** @description Success */ + /** @description Successful response */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { - error?: string; - success: boolean; + totpURI?: string; }; }; }; @@ -13384,160 +11623,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/admin/set-role': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Set the role of a user */ - post: operations['setUserRole']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/get-user': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** @description Get an existing user */ - get: operations['getUser']; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/create-user': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Create a new user */ - post: operations['createUser']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/update-user': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Update a user's details */ - post: operations['updateUser']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/list-users': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** @description List users */ - get: operations['listUsers']; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/list-user-sessions': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description List user sessions */ - post: operations['listUserSessions']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/unban-user': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Unban a user */ - post: operations['unbanUser']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/ban-user': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Ban a user */ - post: operations['banUser']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/impersonate-user': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Impersonate a user */ - post: operations['impersonateUser']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/stop-impersonating': { + '/api/auth/two-factor/verify-totp': { parameters: { query?: never; header?: never; @@ -13546,6 +11632,7 @@ export interface paths { }; get?: never; put?: never; + /** @description Verify two factor TOTP */ post: { parameters: { query?: never; @@ -13553,8 +11640,28 @@ export interface paths { path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': { + /** @description The otp code to verify. Eg: "012345" */ + code: string; + /** @description If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true */ + trustDevice?: boolean | null; + }; + }; + }; responses: { + /** @description Successful response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + status?: boolean; + }; + }; + }; /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ 400: { headers: { @@ -13629,75 +11736,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/admin/revoke-user-session': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Revoke a user session */ - post: operations['revokeUserSession']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/revoke-user-sessions': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Revoke all user sessions */ - post: operations['revokeUserSessions']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/remove-user': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Delete a user and all their sessions and accounts. Cannot be undone. */ - post: operations['removeUser']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/set-user-password': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Set a user's password */ - post: operations['setUserPassword']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/admin/has-permission': { + '/api/auth/two-factor/send-otp': { parameters: { query?: never; header?: never; @@ -13706,7 +11745,7 @@ export interface paths { }; get?: never; put?: never; - /** @description Check if the user has permission */ + /** @description Send two factor OTP to the user */ post: { parameters: { query?: never; @@ -13714,29 +11753,16 @@ export interface paths { path?: never; cookie?: never; }; - requestBody?: { - content: { - 'application/json': { - /** - * @deprecated - * @description The permission to check - */ - permission?: Record; - /** @description The permission to check */ - permissions: Record; - }; - }; - }; + requestBody?: never; responses: { - /** @description Success */ + /** @description Successful response */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { - error?: string; - success: boolean; + status?: boolean; }; }; }; @@ -13814,58 +11840,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/passkey/generate-register-options': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** @description Generate registration options for a new passkey */ - get: operations['generatePasskeyRegistrationOptions']; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/passkey/generate-authenticate-options': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** @description Generate authentication options for a passkey */ - get: operations['passkeyGenerateAuthenticateOptions']; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/passkey/verify-registration': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** @description Verify registration of a new passkey */ - post: operations['passkeyVerifyRegistration']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/passkey/verify-authentication': { + '/api/auth/two-factor/verify-otp': { parameters: { query?: never; header?: never; @@ -13874,38 +11849,63 @@ export interface paths { }; get?: never; put?: never; - /** @description Verify authentication of a passkey */ - post: operations['passkeyVerifyAuthentication']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/passkey/list-user-passkeys': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** @description List all passkeys for the authenticated user */ - get: { + /** @description Verify two factor OTP */ + post: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': { + /** @description The otp code to verify. Eg: "012345" */ + code: string; + trustDevice?: boolean | null; + }; + }; + }; responses: { - /** @description Passkeys retrieved successfully */ + /** @description Two-factor OTP verified successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['Passkey'][]; + 'application/json': { + /** @description Session token for the authenticated session */ + token: string; + /** @description The authenticated user object */ + user: { + /** @description Unique identifier of the user */ + id: string; + /** + * Format: email + * @description User's email address + */ + email?: string | null; + /** @description Whether the email is verified */ + emailVerified?: boolean | null; + /** @description User's name */ + name?: string | null; + /** + * Format: uri + * @description User's profile image URL + */ + image?: string | null; + /** + * Format: date-time + * @description Timestamp when the user was created + */ + createdAt: string; + /** + * Format: date-time + * @description Timestamp when the user was last updated + */ + updatedAt: string; + }; + }; }; }; /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ @@ -13976,15 +11976,13 @@ export interface paths { }; }; }; - put?: never; - post?: never; delete?: never; options?: never; head?: never; patch?: never; trace?: never; }; - '/api/auth/passkey/delete-passkey': { + '/api/auth/two-factor/verify-backup-code': { parameters: { query?: never; header?: never; @@ -13993,7 +11991,7 @@ export interface paths { }; get?: never; put?: never; - /** @description Delete a specific passkey */ + /** @description Verify a backup code for two-factor authentication */ post: { parameters: { query?: never; @@ -14004,21 +12002,71 @@ export interface paths { requestBody: { content: { 'application/json': { - /** @description The ID of the passkey to delete. Eg: "some-passkey-id" */ - id: string; + /** @description A backup code to verify. Eg: "123456" */ + code: string; + /** @description If true, the session cookie will not be set. */ + disableSession?: boolean | null; + /** @description If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true */ + trustDevice?: boolean | null; }; }; }; responses: { - /** @description Passkey deleted successfully */ + /** @description Backup code verified successfully */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { - /** @description Indicates whether the deletion was successful */ - status: boolean; + /** @description The authenticated user object with two-factor details */ + user: { + /** @description Unique identifier of the user */ + id: string; + /** + * Format: email + * @description User's email address + */ + email?: string | null; + /** @description Whether the email is verified */ + emailVerified?: boolean | null; + /** @description User's name */ + name?: string | null; + /** + * Format: uri + * @description User's profile image URL + */ + image?: string | null; + /** @description Whether two-factor authentication is enabled for the user */ + twoFactorEnabled: boolean; + /** + * Format: date-time + * @description Timestamp when the user was created + */ + createdAt: string; + /** + * Format: date-time + * @description Timestamp when the user was last updated + */ + updatedAt: string; + }; + /** @description The current session object, included unless disableSession is true */ + session: { + /** @description Session token */ + token: string; + /** @description ID of the user associated with the session */ + userId: string; + /** + * Format: date-time + * @description Timestamp when the session was created + */ + createdAt: string; + /** + * Format: date-time + * @description Timestamp when the session expires + */ + expiresAt: string; + }; }; }; }; @@ -14096,7 +12144,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/passkey/update-passkey': { + '/api/auth/two-factor/generate-backup-codes': { parameters: { query?: never; header?: never; @@ -14105,7 +12153,7 @@ export interface paths { }; get?: never; put?: never; - /** @description Update a specific passkey's name */ + /** @description Generate new backup codes for two-factor authentication */ post: { parameters: { query?: never; @@ -14116,22 +12164,26 @@ export interface paths { requestBody: { content: { 'application/json': { - /** @description The ID of the passkey which will be updated. Eg: "passkey-id" */ - id: string; - /** @description The new name which the passkey will be updated to. Eg: "my-new-passkey-name" */ - name: string; + /** @description The users password. */ + password: string; }; }; }; responses: { - /** @description Passkey updated successfully */ + /** @description Backup codes generated successfully */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { - passkey: components['schemas']['Passkey']; + /** + * @description Indicates if the backup codes were generated successfully + * @enum {boolean} + */ + status: true; + /** @description Array of generated backup codes in plain text */ + backupCodes: string[]; }; }; }; @@ -14209,7 +12261,7 @@ export interface paths { patch?: never; trace?: never; }; - '/api/auth/sign-in/magic-link': { + '/api/auth/two-factor/enable': { parameters: { query?: never; header?: never; @@ -14218,1712 +12270,8190 @@ export interface paths { }; get?: never; put?: never; - /** @description Sign in with magic link */ - post: operations['signInWithMagicLink']; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - '/api/auth/magic-link/verify': { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** @description Verify magic link */ - get: operations['verifyMagicLink']; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; -} -export type webhooks = Record; -export interface components { - schemas: { - NotificationPreferencesDto: Record; - UpdatePrivacySettingsDto: { - /** - * @description Public profile - * @example true - */ - publicProfile: boolean; - /** + /** @description Use this endpoint to enable two factor authentication. This will generate a TOTP URI and backup codes. Once the user verifies the TOTP URI, the two factor authentication will be enabled. */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description User password */ + password: string; + /** @description Custom issuer for the TOTP URI */ + issuer?: string | null; + }; + }; + }; + responses: { + /** @description Successful response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @description TOTP URI */ + totpURI?: string; + /** @description Backup codes */ + backupCodes?: string[]; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/two-factor/disable': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Use this endpoint to disable two factor authentication. */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description User password */ + password: string; + }; + }; + }; + responses: { + /** @description Successful response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + status?: boolean; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/one-tap/callback': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Use this endpoint to authenticate with Google One Tap */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description Google ID token, which the client obtains from the One Tap API */ + idToken: string; + }; + }; + }; + responses: { + /** @description Successful response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + session?: components['schemas']['Session']; + user?: components['schemas']['User']; + }; + }; + }; + /** @description Invalid token */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/email-otp/send-verification-otp': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Send a verification OTP to an email */ + post: operations['sendEmailVerificationOTP']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/email-otp/check-verification-otp': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Verify an email with an OTP */ + post: operations['verifyEmailWithOTP']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/email-otp/verify-email': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Verify email with OTP */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description Email address to verify */ + email: string; + /** @description OTP to verify */ + otp: string; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** + * @description Indicates if the verification was successful + * @enum {boolean} + */ + status: true; + /** @description Session token if autoSignInAfterVerification is enabled, otherwise null */ + token: string | null; + user: components['schemas']['User']; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/sign-in/email-otp': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Sign in with email and OTP */ + post: operations['signInWithEmailOTP']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/email-otp/request-password-reset': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Request password reset with email and OTP */ + post: operations['requestPasswordResetWithEmailOTP']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/forget-password/email-otp': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Deprecated: Use /email-otp/request-password-reset instead. */ + post: operations['forgetPasswordWithEmailOTP']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/email-otp/reset-password': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Reset password with email and OTP */ + post: operations['resetPasswordWithEmailOTP']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/create': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Create an organization */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The name of the organization */ + name: string; + /** @description The slug of the organization */ + slug: string; + /** @description The user id of the organization creator. If not provided, the current user will be used. Should only be used by admins or when called by the server. server-only. Eg: "user-id" */ + userId?: string | null; + /** @description The logo of the organization */ + logo?: string | null; + /** @description The metadata of the organization */ + metadata?: string | null; + /** @description Whether to keep the current active organization active after creating a new one. Eg: true */ + keepCurrentActiveOrganization?: boolean | null; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Organization']; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/update': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Update an organization */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + data: { + /** @description The name of the organization */ + name?: string | null; + /** @description The slug of the organization */ + slug?: string | null; + /** @description The logo of the organization */ + logo?: string | null; + /** @description The metadata of the organization */ + metadata?: string | null; + }; + /** @description The organization ID. Eg: "org-id" */ + organizationId?: string | null; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Organization']; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/delete': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Delete an organization */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The organization id to delete */ + organizationId: string; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': string; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/set-active': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Set the active organization */ + post: operations['setActiveOrganization']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/get-full-organization': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get the full organization */ + get: operations['getOrganization']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/list': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List all organizations */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Organization'][]; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/invite-member': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Create an invitation to an organization */ + post: operations['createOrganizationInvitation']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/cancel-invitation': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The ID of the invitation to cancel */ + invitationId: string; + }; + }; + }; + responses: { + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/accept-invitation': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Accept an invitation to an organization */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The ID of the invitation to accept */ + invitationId: string; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + invitation?: Record; + member?: Record; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/get-invitation': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get an invitation by ID */ + get: { + parameters: { + query?: { + id?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + id: string; + email: string; + role: string; + organizationId: string; + inviterId: string; + status: string; + expiresAt: string; + organizationName: string; + organizationSlug: string; + inviterEmail: string; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/reject-invitation': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Reject an invitation to an organization */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The ID of the invitation to reject */ + invitationId: string; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + invitation?: Record; + member?: Record | null; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/list-invitations': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/get-active-member': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get the member details of the active organization */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + id: string; + userId: string; + organizationId: string; + role: string; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/check-slug': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The organization slug to check. Eg: "my-org" */ + slug: string; + }; + }; + }; + responses: { + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/remove-member': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Remove a member from an organization */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The ID or email of the member to remove */ + memberIdOrEmail: string; + /** @description The ID of the organization to remove the member from. If not provided, the active organization will be used. Eg: "org-id" */ + organizationId?: string | null; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + member: { + id: string; + userId: string; + organizationId: string; + role: string; + }; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/update-member-role': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Update the role of a member in an organization */ + post: operations['updateOrganizationMemberRole']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/leave': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The organization Id for the member to leave. Eg: "organization-id" */ + organizationId: string; + }; + }; + }; + responses: { + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/list-user-invitations': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List all invitations a user has received */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + id: string; + email: string; + role: string; + organizationId: string; + organizationName: string; + /** @description The ID of the user who created the invitation */ + inviterId: string; + /** @description The ID of the team associated with the invitation */ + teamId?: string | null; + status: string; + expiresAt: string; + createdAt: string; + }[]; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/list-members': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/get-active-member-role': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/organization/has-permission': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Check if the user has permission */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: { + content: { + 'application/json': { + /** + * @deprecated + * @description The permission to check + */ + permission?: Record; + /** @description The permission to check */ + permissions: Record; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + error?: string; + success: boolean; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/set-role': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Set the role of a user */ + post: operations['setUserRole']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/get-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Get an existing user */ + get: operations['getUser']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/create-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Create a new user */ + post: operations['createUser']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/update-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Update a user's details */ + post: operations['updateUser']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/list-users': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List users */ + get: operations['listUsers']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/list-user-sessions': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description List user sessions */ + post: operations['listUserSessions']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/unban-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Unban a user */ + post: operations['unbanUser']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/ban-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Ban a user */ + post: operations['banUser']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/impersonate-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Impersonate a user */ + post: operations['impersonateUser']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/stop-impersonating': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/revoke-user-session': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Revoke a user session */ + post: operations['revokeUserSession']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/revoke-user-sessions': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Revoke all user sessions */ + post: operations['revokeUserSessions']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/remove-user': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Delete a user and all their sessions and accounts. Cannot be undone. */ + post: operations['removeUser']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/set-user-password': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Set a user's password */ + post: operations['setUserPassword']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/admin/has-permission': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Check if the user has permission */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: { + content: { + 'application/json': { + /** + * @deprecated + * @description The permission to check + */ + permission?: Record; + /** @description The permission to check */ + permissions: Record; + }; + }; + }; + responses: { + /** @description Success */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + error?: string; + success: boolean; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/passkey/generate-register-options': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Generate registration options for a new passkey */ + get: operations['generatePasskeyRegistrationOptions']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/passkey/generate-authenticate-options': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Generate authentication options for a passkey */ + get: operations['passkeyGenerateAuthenticateOptions']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/passkey/verify-registration': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Verify registration of a new passkey */ + post: operations['passkeyVerifyRegistration']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/passkey/verify-authentication': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Verify authentication of a passkey */ + post: operations['passkeyVerifyAuthentication']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/passkey/list-user-passkeys': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description List all passkeys for the authenticated user */ + get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Passkeys retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Passkey'][]; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/passkey/delete-passkey': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Delete a specific passkey */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The ID of the passkey to delete. Eg: "some-passkey-id" */ + id: string; + }; + }; + }; + responses: { + /** @description Passkey deleted successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @description Indicates whether the deletion was successful */ + status: boolean; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/passkey/update-passkey': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Update a specific passkey's name */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + /** @description The ID of the passkey which will be updated. Eg: "passkey-id" */ + id: string; + /** @description The new name which the passkey will be updated to. Eg: "my-new-passkey-name" */ + name: string; + }; + }; + }; + responses: { + /** @description Passkey updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + passkey: components['schemas']['Passkey']; + }; + }; + }; + /** @description Bad Request. Usually due to missing parameters, or invalid parameters. */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Unauthorized. Due to missing or invalid authentication. */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message: string; + }; + }; + }; + /** @description Forbidden. You do not have permission to access this resource or to perform this action. */ + 403: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Not Found. The requested resource was not found. */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Too Many Requests. You have exceeded the rate limit. Try again later. */ + 429: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + /** @description Internal Server Error. This is a problem with the server that you cannot fix. */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + message?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/sign-in/magic-link': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** @description Sign in with magic link */ + post: operations['signInWithMagicLink']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/api/auth/magic-link/verify': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Verify magic link */ + get: operations['verifyMagicLink']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; +} +export type webhooks = Record; +export interface components { + schemas: { + NotificationPreferencesDto: Record; + UpdatePrivacySettingsDto: { + /** + * @description Public profile + * @example true + */ + publicProfile: boolean; + /** * @description Email visibility * @example true */ - emailVisibility: boolean; + emailVisibility: boolean; + /** + * @description Location visibility + * @example true + */ + locationVisibility: boolean; + /** + * @description Company visibility + * @example true + */ + companyVisibility: boolean; + /** + * @description Website visibility + * @example true + */ + websiteVisibility: boolean; + /** + * @description Social links visibility + * @example true + */ + socialLinksVisibility: boolean; + }; + UpdateAppearanceSettingsDto: { + /** + * @description Theme + * @example light + * @enum {string} + */ + theme: 'light' | 'dark' | 'auto'; + }; + PublicEarningsSummaryDto: { + /** + * @description All-time total earned (normalized, e.g. USDC 7 decimals) + * @example 50000 + */ + totalEarned: number; + }; + EarningsBreakdownDto: { + /** + * @description Total from hackathons + * @example 20000 + */ + hackathons: number; + /** + * @description Total from grants + * @example 10000 + */ + grants: number; + /** + * @description Total from crowdfunding + * @example 15000 + */ + crowdfunding: number; + /** + * @description Total from bounties + * @example 5000 + */ + bounties: number; + }; + PublicEarningActivityDto: { + /** @description Unique activity id */ + id: string; + /** + * @description Earnings source category + * @enum {string} + */ + source: 'hackathons' | 'grants' | 'crowdfunding' | 'bounties'; + /** + * @description Human-readable title + * @example Winner of Stellar Hackathon Q1 + */ + title: string; + /** + * @description Amount (normalized) + * @example 5000 + */ + amount: number; + /** + * @description Currency code + * @example USDC + */ + currency: string; + /** + * @description When the earning occurred (ISO date string) + * @example 2024-01-19T14:30:00Z + */ + occurredAt: string; + }; + PublicEarningsResponseDto: { + summary: components['schemas']['PublicEarningsSummaryDto']; + breakdown: components['schemas']['EarningsBreakdownDto']; + /** @description Verified activity history (completed only) */ + activities: components['schemas']['PublicEarningActivityDto'][]; + }; + EarningsSummaryDto: { + /** + * @description All-time total earned (normalized, e.g. USDC 7 decimals) + * @example 50000 + */ + totalEarned: number; + /** + * @description Amount currently claimable / pending withdrawal + * @example 10000 + */ + pendingWithdrawal: number; + /** + * @description Amount already paid out (completed withdrawals) + * @example 40000 + */ + completedWithdrawal: number; + }; + EarningActivityDto: { + /** @description Unique activity id (e.g. submissionId or milestoneId) */ + id: string; + /** + * @description Earnings source category + * @enum {string} + */ + source: 'hackathons' | 'grants' | 'crowdfunding' | 'bounties'; + /** + * @description Human-readable title + * @example Winner of Stellar Hackathon Q1 + */ + title: string; + /** + * @description Amount (normalized) + * @example 5000 + */ + amount: number; + /** + * @description Currency code + * @example USDC + */ + currency: string; + /** + * @description Activity status + * @enum {string} + */ + status: 'pending' | 'claimable' | 'completed'; + /** + * @description When the earning occurred (ISO date string) + * @example 2024-01-19T14:30:00Z + */ + occurredAt: string; + /** @description Entity id for claim (e.g. submissionId, milestoneId) */ + entityId?: string; + /** @description On-chain payout transaction hash (when settled). */ + txHash?: string; + }; + EarningsResponseDto: { + summary: components['schemas']['EarningsSummaryDto']; + breakdown: components['schemas']['EarningsBreakdownDto']; + /** @description Activity feed */ + activities: components['schemas']['EarningActivityDto'][]; + }; + DashboardUserStatsDto: { + followers: number; + following: number; + }; + DashboardUserDto: { + id: string; + name: string | null; + email: string; + username: string | null; + displayUsername: string | null; + image: string | null; + role: string; + /** Format: date-time */ + createdAt: string; + stats?: components['schemas']['DashboardUserStatsDto']; + }; + UserStatsDto: { + projectsCreated: number; + projectsFunded: number; + totalContributed: number; + commentsPosted: number; + votes: number; + grants: number; + hackathons: number; + followers: number; + following: number; + reputation: number; + communityScore: number; + }; + ChartDataPointDto: { + /** @description Date in YYYY-MM-DD format */ + date: string; + /** @description Count for that date */ + count: number; + }; + ChartDto: { + data: components['schemas']['ChartDataPointDto'][]; + }; + ActivitiesGraphDto: { + data: components['schemas']['ChartDataPointDto'][]; + }; + ActivityProjectDto: { + id: string; + title: string; + banner?: string | null; + logo?: string | null; + }; + ActivityOrganizationDto: { + id: string; + name: string; + }; + RecentActivityDto: { + id: string; + type: string; + userId: string; + projectId?: string | null; + organizationId?: string | null; + /** Format: date-time */ + createdAt: string; + project?: components['schemas']['ActivityProjectDto']; + organization?: components['schemas']['ActivityOrganizationDto']; + }; + DashboardDto: { + /** @description User profile data */ + user: components['schemas']['DashboardUserDto']; + stats: components['schemas']['UserStatsDto']; + chart: components['schemas']['ChartDto']; + activitiesGraph: components['schemas']['ActivitiesGraphDto']; + /** @description Recent activities */ + recentActivities: components['schemas']['RecentActivityDto'][]; + }; + UpdateProfileDto: Record; + UpdateUserDto: Record; + UploadResponseDto: Record; + MultipleUploadResponseDto: Record; + FileInfoResponseDto: Record; + SearchFilesResponseDto: Record; + OptimizedUrlResponseDto: Record; + ResponsiveUrlsResponseDto: Record; + UsageStatsResponseDto: Record; + RegisterDto: Record; + LoginDto: Record; + RefreshTokenDto: Record; + VerifySignatureDto: Record; + CreateConversationDto: { + /** @description User ID of the other participant */ + otherUserId: string; + }; + CreateMessageDto: { + /** @description Message text */ + body: string; + }; + ContactDto: Record; + CreateCampaignDto: { + /** + * @description Title of the campaign + * @example Web3 Campaign + */ + title: string; + /** + * @description Logo of the campaign + * @example https://example.com/logo.png + */ + logo: string; + /** + * @description Vision of the campaign + * @example Web3 Campaign + */ + vision: string; + /** + * @description Banner image URL of the campaign + * @example https://example.com/banner.png + */ + banner: string; + /** + * @description Category of the campaign + * @example web3 + */ + category: string; + /** + * @description Details of the campaign + * @example Web3 Campaign + */ + details: string; + /** + * @description Funding amount of the campaign + * @example 1000 + */ + fundingAmount: number; + /** + * @description Github URL of the campaign + * @example https://github.com/example/project + */ + githubUrl: string; + /** + * @description Gitlab URL of the campaign + * @example https://gitlab.com/example/project + */ + gitlabUrl: string; + /** + * @description Bitbucket URL of the campaign + * @example https://bitbucket.com/example/project + */ + bitbucketUrl: string; + /** + * @description Project website of the campaign + * @example https://example.com/project + */ + projectWebsite: string; + /** + * @description Demo video of the campaign + * @example https://example.com/demo.mp4 + */ + demoVideo: string; + /** + * @description Milestones of the campaign + * @example [ + * { + * "name": "Milestone 1", + * "description": "Milestone 1 description", + * "startDate": "2025-01-01", + * "endDate": "2025-01-02", + * "amount": 1000 + * } + * ] + */ + milestones: string[]; + /** + * @description Team of the campaign (optional; solo builders may omit) + * @example [ + * { + * "name": "John Doe", + * "role": "Developer", + * "email": "john.doe@example.com", + * "linkedin": "https://linkedin.com/in/john-doe", + * "twitter": "https://twitter.com/john-doe" + * } + * ] + */ + team?: string[]; + /** + * @description Contact of the campaign + * @example { + * "primary": "john.doe", + * "backup": "john.doe@example.com" + * } + */ + contact: components['schemas']['ContactDto']; + /** + * @description Social links of the campaign (optional) + * @example [ + * { + * "platform": "twitter", + * "url": "https://twitter.com/john-doe" + * } + * ] + */ + socialLinks?: string[]; + }; + CreateDraftDto: { + /** + * @description Working title for the campaign + * @example Stellar Analytics Dashboard + */ + title: string; + }; + UpdateCampaignDto: { + /** + * @description Title of the campaign + * @example Web3 Campaign + */ + title?: string; + /** + * @description Logo of the campaign + * @example https://example.com/logo.png + */ + logo?: string; + /** + * @description Vision of the campaign + * @example Web3 Campaign + */ + vision?: string; + /** + * @description Banner image URL of the campaign + * @example https://example.com/banner.png + */ + banner?: string; + /** + * @description Category of the campaign + * @example web3 + */ + category?: string; + /** + * @description Details of the campaign + * @example Web3 Campaign + */ + details?: string; + /** + * @description Funding amount of the campaign + * @example 1000 + */ + fundingAmount?: number; + /** + * @description Github URL of the campaign + * @example https://github.com/example/project + */ + githubUrl?: string; + /** + * @description Gitlab URL of the campaign + * @example https://gitlab.com/example/project + */ + gitlabUrl?: string; + /** + * @description Bitbucket URL of the campaign + * @example https://bitbucket.com/example/project + */ + bitbucketUrl?: string; + /** + * @description Project website of the campaign + * @example https://example.com/project + */ + projectWebsite?: string; + /** + * @description Demo video of the campaign + * @example https://example.com/demo.mp4 + */ + demoVideo?: string; + /** + * @description Milestones of the campaign + * @example [ + * { + * "name": "Milestone 1", + * "description": "Milestone 1 description", + * "startDate": "2025-01-01", + * "endDate": "2025-01-02", + * "amount": 1000 + * } + * ] + */ + milestones?: string[]; + /** + * @description Team of the campaign (optional; solo builders may omit) + * @example [ + * { + * "name": "John Doe", + * "role": "Developer", + * "email": "john.doe@example.com", + * "linkedin": "https://linkedin.com/in/john-doe", + * "twitter": "https://twitter.com/john-doe" + * } + * ] + */ + team?: string[]; + /** + * @description Contact of the campaign + * @example { + * "primary": "john.doe", + * "backup": "john.doe@example.com" + * } + */ + contact?: components['schemas']['ContactDto']; + /** + * @description Social links of the campaign (optional) + * @example [ + * { + * "platform": "twitter", + * "url": "https://twitter.com/john-doe" + * } + * ] + */ + socialLinks?: string[]; + }; + InviteTeamMemberDto: { + /** + * @description The email address of the team member to invite + * @example user@example.com + */ + email: string; + /** + * @description The role of the team member in the campaign + * @example Developer + */ + role: string; + }; + ValidateMilestoneSubmissionDto: { + /** + * @description Array of proof of work file URLs (documents, images, reports, etc.) - must be valid URLs with http, https, or ipfs protocol + * @example [ + * "https://example.com/report.pdf", + * "https://example.com/screenshot.png" + * ] + */ + proofOfWorkFiles: string[]; + /** + * @description Array of proof of work links (GitHub PRs, demos, deployed sites, etc.) - must be valid URLs + * @example [ + * "https://github.com/user/repo/pull/123", + * "https://demo.example.com" + * ] + */ + proofOfWorkLinks: string[]; + /** + * @description Additional notes about the submission - optional but must be at least 10 characters if provided + * @example Successfully deployed the MVP with all core features implemented and tested. + */ + submissionNotes?: string; + }; + UpdateMilestoneDto: { + /** @description Array of proof of work file URLs (documents, images, etc.) */ + proofOfWorkFiles: string[]; + /** @description Array of proof of work links (GitHub PRs, demos, etc.) */ + proofOfWorkLinks: string[]; + /** @description Additional notes about the submission */ + submissionNotes?: string; + }; + PublishCrowdfundingEscrowDto: { + /** + * @description Stellar G-address that signs create_event. Strictly the builder's Boundless abstracted wallet (D9). Optional: defaults to the authenticated builder's managed wallet, the only valid value. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS + */ + builderAddress?: string; + /** + * @description Whitelisted SAC token contract (USDC by default). + * @example CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA + */ + tokenAddress: string; + /** + * @description Funding goal in token-native units (e.g. 5000 = 5000 USDC). Informational on chain; backers determine the actual raised total. + * @example 5000 + */ + fundingGoal: string; + /** + * @description Number of milestones for ReleaseKind::Multi(n). + * @example 3 + */ + nMilestones: number; + /** + * @description Funding deadline as Unix seconds. + * @example 1735689600 + */ + fundingDeadline: number; + /** @description Override content URI. */ + contentUri?: string; + }; + CancelCrowdfundingEscrowDto: { + /** @description Builder G-address. Optional: defaults to the authenticated builder's managed wallet (the only valid value). */ + builderAddress?: string; + }; + ContributeCrowdfundingDto: { + /** + * @description G-address that signs add_funds. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS + */ + contributorAddress: string; + /** + * @description Wallet origin: BOUNDLESS uses the managed signer; EXTERNAL returns an unsigned XDR for the connected wallet (D9). + * @example BOUNDLESS + * @enum {string} + */ + walletOrigin: 'BOUNDLESS' | 'EXTERNAL'; + /** + * @description Amount in token-native units (10 USDC minimum). + * @example 25 + */ + amount: string; + /** @description Optional message attached. */ + message?: string; + /** + * @description Hide displayName / usernameSnapshot if true. + * @default false + */ + anonymous: boolean; + }; + CrowdfundingSubmitSignedXdrDto: { + /** @description Signed transaction XDR returned by the wallet. */ + signedXdr: string; + }; + CastCrowdfundingVoteDto: { + /** + * @description UP supports the campaign, DOWN opposes it. + * @example UP + * @enum {string} + */ + choice: 'UP' | 'DOWN'; + }; + ApproveCrowdfundingCampaignDto: { + /** + * @description The user delegated to validate this campaign's milestones. D6=A: exactly one reviewer per campaign, assigned at approval time. + * @example user_1234567890 + */ + delegatedReviewerId: string; + /** + * @description Minimum total community votes required to resolve the vote (quorum). Defaults to 1 for now (target is 10 at launch). + * @example 10 + */ + voteGoal?: number; + /** + * @description Bypass community voting and approve straight to launch-ready (REVIEW_APPROVED). Default false: the campaign enters community voting. + * @example false + */ + bypassVoting?: boolean; + }; + RejectCrowdfundingCampaignDto: { + /** @description Reason for rejection; surfaced to the builder. */ + reason?: string; + }; + ExtendCrowdfundingFundingDto: { + /** + * @description New funding deadline (ISO 8601). Must be in the future. Enforced off-chain by the contribute gate. + * @example 2026-08-01T00:00:00.000Z + */ + fundingEndDate: string; + }; + PauseCrowdfundingCampaignDto: { + /** @description Reason for the pause. */ + reason?: string; + }; + ApproveCrowdfundingMilestoneDto: Record; + RejectCrowdfundingMilestoneDto: { + /** @description Feedback shown to the builder. */ + rejectionFeedback: string; + /** @description Deadline by which the builder must resubmit (ISO 8601). */ + resubmissionDeadline?: string; + }; + FileDisputeDto: { + /** @description Specific milestone being disputed (optional). */ + milestoneId?: string; + /** @enum {string} */ + reason: + | 'MILESTONE_NOT_DELIVERED' + | 'POOR_QUALITY_WORK' + | 'DEADLINE_MISSED' + | 'MISUSE_OF_FUNDS' + | 'COMMUNICATION_ISSUES' + | 'SCOPE_CHANGE' + | 'OTHER'; + description: string; + /** @description Links to supporting evidence (max 10). */ + evidenceLinks?: string[]; + /** @description Uploaded evidence file references (max 10). */ + evidenceFiles?: string[]; + }; + DisputeResponseDto: { + id: string; + campaignId: string; + milestoneId: string | null; + reason: string; + status: string; + description: string; + /** @description ISO timestamp the dispute was filed */ + createdAt: string; + }; + ReclaimDormantDto: { + /** + * @description Minimum days a wallet must have been idle to be eligible. Default 90. + * @example 90 + */ + minIdleDays?: number; + /** + * @description Maximum number of wallets to reclaim in this call. Hard-capped at 100. + * @example 25 + */ + maxToProcess?: number; + /** + * @description When true (default), report what would be reclaimed without submitting transactions. Set false to actually merge accounts. + * @example true + */ + dryRun?: boolean; + }; + AddTrustlineDto: { + /** + * @description Asset code to add a trustline for (e.g. USDC, EURC) + * @example USDC + */ + assetCode: string; + }; + UserSendDto: { + /** + * @description Stellar destination public key (G...) + * @example GABCD... + */ + destinationPublicKey: string; + /** + * @description Amount to send (positive number) + * @example 100.5 + */ + amount: number; + /** + * @description Asset code (XLM, USDC, EURC, etc.) + * @example USDC + */ + currency: string; + /** @description Memo (required by some exchanges). Max 28 bytes UTF-8. */ + memo?: string; + /** @description If true, request fails when memo is missing (e.g. exchange requires it) */ + memoRequired?: boolean; + /** @description Idempotency key to prevent duplicate sends */ + idempotencyKey?: string; + }; + SendPayoutDto: { + /** + * @description Stellar destination public key (G...) + * @example GABCD... + */ + destinationPublicKey: string; + /** + * @description Amount to send (positive number) + * @example 100.5 + */ + amount: number; + /** + * @description Asset code (XLM, USDC, EURC, etc. – must be supported on network) + * @example USDC + */ + currency: string; + /** @description Memo (required by some exchanges). Max 28 bytes UTF-8. */ + memo?: string; + /** + * @description Memo type + * @enum {string} + */ + memoType?: 'text' | 'id'; + /** @description If true, request fails when memo is missing (e.g. exchange requires it) */ + memoRequired?: boolean; + /** @description Idempotency key to prevent duplicate payouts */ + idempotencyKey?: string; + /** @description Reference for audit (e.g. earnings-payout-123) */ + reference?: string; + }; + CreateCommentDto: { + /** + * @description Comment content + * @example This is a great project! + */ + content: string; + /** + * @description Entity type for the comment + * @example PROJECT + * @enum {string} + */ + entityType: + | 'PROJECT' + | 'BOUNTY' + | 'CROWDFUNDING_CAMPAIGN' + | 'GRANT' + | 'GRANT_APPLICATION' + | 'HACKATHON' + | 'HACKATHON_SUBMISSION' + | 'BLOG_POST'; + /** + * @description Entity ID for the comment + * @example cm12345abcde + */ + entityId: string; + /** + * @description Parent comment ID for threaded replies + * @example cm12345abcde + */ + parentId?: string; + }; + UpdateCommentDto: Record; + AddReactionDto: { + /** + * @description Type of reaction + * @example LIKE + * @enum {string} + */ + reactionType: + | 'LIKE' + | 'DISLIKE' + | 'LOVE' + | 'LAUGH' + | 'THUMBS_UP' + | 'THUMBS_DOWN' + | 'FIRE' + | 'ROCKET'; + }; + ReportCommentDto: { + /** + * @description Reason for reporting the comment + * @example SPAM + * @enum {string} + */ + reason: + | 'SPAM' + | 'HARASSMENT' + | 'HATE_SPEECH' + | 'INAPPROPRIATE_CONTENT' + | 'COPYRIGHT_VIOLATION' + | 'OTHER'; + /** + * @description Additional details about the report + * @example This comment contains unsolicited advertising + */ + description?: string; + }; + ResolveReportDto: { + /** + * @description Resolution status for the report + * @example RESOLVED + * @enum {string} + */ + status: 'PENDING' | 'REVIEWED' | 'RESOLVED' | 'DISMISSED'; + /** + * @description Moderator notes about the resolution + * @example Comment was reviewed and found to violate community guidelines + */ + resolution?: string; + }; + HackathonsListResponseDto: Record; + FeeEstimateResponseDto: { + /** + * @description Total prize pool (USDC) + * @example 5000 + */ + totalPool: number; + /** + * @description Fee rate as decimal + * @example 0.023 + */ + feeRate: number; + /** + * @description Fee rate as percentage + * @example 2.3 + */ + feeRatePercent: number; + /** + * @description Fee amount (USDC) + * @example 115 + */ + feeAmount: number; + /** + * @description Total to pay (prize pool + fee) + * @example 5115 + */ + totalFunds: number; + /** + * @description Display label for the fee + * @example Platform Fee (2.3%) + */ + feeLabel: string; + }; + ParticipantDto: { + /** @description Username of the participant */ + username: string; + /** @description Avatar URL of the participant */ + avatar?: Record; + }; + HackathonWinnerDto: { + /** @description Rank of the winner (1, 2, 3, etc.) */ + rank: number; + /** @description Name of the project */ + projectName: string; + /** @description Name of the team */ + teamName?: Record; + /** @description Logo of the project */ + logo?: Record; + /** @description List of participants */ + participants: components['schemas']['ParticipantDto'][]; + /** @description Prize information */ + prize: string; + /** @description Submission ID */ + submissionId: string; + }; + HackathonWinnersResponseDto: { + /** @description Hackathon ID */ + hackathonId: string; + /** @description List of winners */ + winners: components['schemas']['HackathonWinnerDto'][]; + }; + PublicAggregatedJudgingResultDto: { + submissionId: string; + projectName: string; + teamId?: Record; + participantId: string; + status: string; + /** Format: date-time */ + submittedAt: string; + averageScore: number; + totalScore: number; + judgeCount: number; + expectedJudgeCount: number; + judgingProgress: string; + rank?: Record; + isComplete: boolean; + isPending: boolean; + hasDisagreement: boolean; + }; + JudgingResultsMetadataDto: { + sortedBy: string; + includesVariance: boolean; + includesIndividualScores: boolean; + includesProgressTracking: boolean; + onlyWinners?: boolean; + }; + PublicJudgingResultsResponseDto: { + hackathonId: string; + totalSubmissions: number; + submissionsScoredCount: number; + submissionsPendingCount: number; + averageScoreAcrossAll: number; + resultsPublished: boolean; + judgesAssigned: number; + results: components['schemas']['PublicAggregatedJudgingResultDto'][]; + /** Format: date-time */ + generatedAt: string; + /** @description Manual winner assignments override (submissionId -> rank) */ + winnerOverrides?: { + [key: string]: number; + }; + metadata: components['schemas']['JudgingResultsMetadataDto']; + }; + CreatorRelationDto: { + id: string; + name: string; + username?: string; + image?: string; + }; + OrganizationRelationDto: { + id: string; + name: string; + logo?: string; + slug?: string; + }; + HackathonResponseDto: { + createdBy: components['schemas']['CreatorRelationDto']; + organization?: components['schemas']['OrganizationRelationDto']; + }; + VerifyHackathonAccessDto: { + /** @description The access password for a private hackathon */ + password: string; + }; + HackathonAccessTokenResponseDto: { + accessToken: string; + }; + JoinHackathonDto: { + /** + * @description Answers to REGISTRATION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). + * @example { + * "cq_role": "Backend developer" + * } + */ + customAnswers?: Record; + }; + ParticipationResponseDto: Record; + ParticipantResponseDto: Record; + HackathonParticipantsResponseDto: { + participants: components['schemas']['ParticipantResponseDto'][]; + }; + TeamMemberDto: { + /** + * @description User ID of the team member + * @example user_1234567890 + */ + userId: string; + /** + * @description Name of the team member + * @example John Doe + */ + name: string; + /** + * @description Username of the team member + * @example johndoe + */ + username?: string; + /** + * @description Role of the team member in the project + * @example Full Stack Developer + */ + role: string; + /** + * @description Avatar URL of the team member + * @example https://example.com/avatar.png + */ + avatar?: string; + }; + SubmissionLinkDto: { + /** + * @description Type of link. Each fixed type (github, demo, video, document, presentation) can be used at most once per submission. Use "other" for additional links, up to a maximum of 5. + * @example github + * @enum {string} + */ + type: 'github' | 'demo' | 'video' | 'document' | 'presentation' | 'other'; + /** + * @description URL of the link + * @example https://github.com/username/project + */ + url: string; + /** + * @description Optional description of the link + * @example Main repository with source code + */ + description?: string; + }; + SocialLinksDto: { + /** + * @description GitHub profile or repository + * @example https://github.com/username + */ + github?: string; + /** + * @description Telegram username or group + * @example https://t.me/username + */ + telegram?: string; + /** + * @description Twitter/X handle + * @example https://twitter.com/username + */ + twitter?: string; + /** + * @description Email address + * @example contact@example.com + */ + email?: string; + }; + SubmissionResponseDto: { + id: string; + hackathonId: string; + projectId: string; + participantId: string; + organizationId: string; + /** @enum {string} */ + participationType: 'INDIVIDUAL' | 'TEAM'; + teamId?: string; + teamName?: string; + teamMembers?: components['schemas']['TeamMemberDto'][]; + projectName: string; + category: string; + description: string; + logo?: string; + banner?: string; + videoUrl?: string; + introduction?: string; + links: components['schemas']['SubmissionLinkDto'][]; + socialLinks?: components['schemas']['SocialLinksDto']; + status: string; + rank?: number; + /** @description Track entries this submission has opted into. Each entry carries the track slug/name and a wonRank stamped when the submission won that track (null until results are published). */ + trackEntries?: unknown[][]; + tagline?: string; + builtWith?: string[]; + screenshots?: string[]; + license?: string; + /** Format: date-time */ + codeAttestedAt?: string; + /** Format: date-time */ + registeredAt: string; + /** Format: date-time */ + submittedAt?: string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + CreateSubmissionDto: { + /** + * @description Organization ID + * @example org_1234567890 + */ + organizationId: string; + /** + * @description Project ID (must be owned by the user or organization). If not provided, a base project will be created automatically. + * @example proj_1234567890 + */ + projectId?: string; + /** + * @description Type of participation + * @example INDIVIDUAL + * @enum {string} + */ + participationType: 'INDIVIDUAL' | 'TEAM'; + /** + * @deprecated + * @description [Ignored by backend.] Team ID is snapshotted from the user's authoritative team record at submission time. Field accepted for backwards compatibility only. + * @example team_1234567890 + */ + teamId?: string; + /** + * @deprecated + * @description [Ignored by backend.] Team name is snapshotted from the user's authoritative team record at submission time. + * @example Awesome Hackers + */ + teamName?: string; + /** + * @deprecated + * @description [Ignored by backend.] Team members are snapshotted from the user's authoritative team record at submission time. Sending this field has no effect. + */ + teamMembers?: components['schemas']['TeamMemberDto'][]; + /** + * @description Project name for the submission + * @example DeFi Lending Platform + */ + projectName: string; + /** + * @description Category of the project + * @example DeFi + */ + category: string; + /** + * @description Detailed description of the project + * @example A decentralized lending platform built on Stellar... + */ + description: string; + /** + * @description Project logo URL + * @example https://example.com/logo.png + */ + logo?: string; + /** + * @description Project banner image URL (wide hero image) + * @example https://example.com/banner.png + */ + banner?: string; + /** + * @description Video demonstration URL + * @example https://youtube.com/watch?v=xyz + */ + videoUrl?: string; + /** + * @description Brief introduction to the project + * @example We built a platform that allows users to... + */ + introduction?: string; + /** @description Links to project resources. Each fixed link type (github, demo, video, document, presentation) can appear at most once. Use "other" for additional links, up to a maximum of 5. */ + links: components['schemas']['SubmissionLinkDto'][]; + /** @description Social links for the project */ + socialLinks?: components['schemas']['SocialLinksDto']; + /** + * @description Optional list of track ids to enter. Only allowed when the hackathon has prizeStructure != OVERALL_ONLY. Capped at Hackathon.tracksMaxPerSubmission. + * @example [ + * "trk_abc", + * "trk_def" + * ] + */ + trackIds?: string[]; + /** + * @description Per-track answers. Keyed by trackId; each value is { promptAnswer?, customAnswers?, artifacts? }. Phase B. + * @example { + * "trk_abc": { + * "promptAnswer": "We focused on a one-tap escrow flow.", + * "customAnswers": { + * "q_audience": "Freelancers" + * }, + * "artifacts": { + * "figma": "https://figma.com/file/..." + * } + * } + * } + */ + trackAnswers?: Record; + /** + * @description Answers to hackathon-level SUBMISSION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). Validated against the question set. + * @example { + * "cq_audience": "Freelancers", + * "cq_stack": [ + * "Web", + * "AI" + * ] + * } + */ + customAnswers?: Record; + /** + * @description Short elevator pitch shown on cards / sidebars / judge queue. Max ~160 chars. + * @example Milestone-based escrow for one-time freelance gigs on Stellar. + */ + tagline?: string; + /** + * @description Free-form tech-stack tags. Max 20 entries, 40 chars each. + * @example [ + * "Soroban", + * "Stellar SDK", + * "Next.js", + * "Rust" + * ] + */ + builtWith?: string[]; + /** @description Up to 5 screenshot URLs for the project gallery. */ + screenshots?: string[]; + /** + * @description License the submission ships under. + * @enum {string} + */ + license?: + | 'MIT' + | 'Apache-2.0' + | 'GPL-3.0' + | 'BSD-3' + | 'PROPRIETARY' + | 'OTHER'; + /** @description Submitter attests the code is original or properly attributed. Required to mark a submission SUBMITTED (vs DRAFT). */ + codeAttested?: boolean; + }; + UpdateSubmissionDto: { + /** + * @description Project name for the submission + * @example DeFi Lending Platform + */ + projectName?: string; + /** + * @description Category of the project + * @example DeFi + */ + category?: string; + /** + * @description Detailed description of the project + * @example A decentralized lending platform built on Stellar... + */ + description?: string; + /** + * @description Project logo URL + * @example https://example.com/logo.png + */ + logo?: string; + /** + * @description Project banner image URL (wide hero image) + * @example https://example.com/banner.png + */ + banner?: string; + /** + * @description Video demonstration URL + * @example https://youtube.com/watch?v=xyz + */ + videoUrl?: string; + /** + * @description Brief introduction to the project + * @example We built a platform that allows users to... + */ + introduction?: string; + /** @description Links to project resources. Each fixed link type (github, demo, video, document, presentation) can appear at most once. Use "other" for additional links, up to a maximum of 5. */ + links?: components['schemas']['SubmissionLinkDto'][]; + /** @description Social links for the project */ + socialLinks?: components['schemas']['SocialLinksDto']; + /** @description Team members (for team submissions) */ + teamMembers?: components['schemas']['TeamMemberDto'][]; + /** @description Replace the submission's track picks. Omit to leave existing entries untouched; pass an empty array to clear all picks. */ + trackIds?: string[]; + /** @description Per-track answers, same shape as on create. Phase B. */ + trackAnswers?: Record; + /** + * @description Answers to hackathon-level SUBMISSION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). Replaces the stored answers when provided. + * @example { + * "cq_audience": "Freelancers", + * "cq_stack": [ + * "Web", + * "AI" + * ] + * } + */ + customAnswers?: Record; + tagline?: string; + builtWith?: string[]; + screenshots?: string[]; + /** @enum {string} */ + license?: + | 'MIT' + | 'Apache-2.0' + | 'GPL-3.0' + | 'BSD-3' + | 'PROPRIETARY' + | 'OTHER'; + codeAttested?: boolean; + }; + TeamMemberResponseDto: { + /** @description User ID */ + userId: string; + /** @description Username */ + username: string; + /** @description Display name */ + name: string; + /** @description Role in team (e.g. leader, member) */ + role: string; + /** @description Profile image URL */ + image?: string; + /** @description When the member joined the team (ISO string) */ + joinedAt: string; + }; + LookingForRoleDto: { + /** + * @description Role title (e.g. "Frontend Developer", "UI Designer") + * @example Frontend Developer + */ + role: string; + /** + * @description Optional free-form skills associated with this role + * @example [ + * "React", + * "TypeScript" + * ] + */ + skills?: unknown[][]; + }; + TeamRoleResponseDto: { + /** @description Skill/role name */ + skill: string; + /** @description Whether this role has been filled */ + hired: boolean; + }; + TeamResponseDto: { + /** + * @description Team ID + * @example team_1234567890 + */ + id: string; + /** + * @description Team name + * @example Stellar Innovators + */ + teamName: string; + /** @description Team description */ + description: string; + /** @description Hackathon ID */ + hackathonId: string; + /** @description Team leader information */ + leader: Record; + /** @description Team members */ + members: components['schemas']['TeamMemberResponseDto'][]; + /** + * @description Current number of members + * @example 3 + */ + memberCount: number; + /** + * @description Maximum team size allowed + * @example 5 + */ + maxSize: number; + /** @description Roles the team is looking for, with optional free-form skills */ + lookingFor?: components['schemas']['LookingForRoleDto'][]; + /** @description Hired status per role (when using lookingFor) */ + rolesStatus?: components['schemas']['TeamRoleResponseDto'][]; + /** @description Contact information (e.g. telegram, discord, email) */ + contactInfo?: Record; + /** + * @description Whether team is accepting new members + * @example true + */ + isOpen: boolean; + /** @description Team creation date */ + createdAt: string; + /** @description Last update date */ + updatedAt: string; + }; + TeamListResponseDto: { + /** @description List of teams */ + teams: components['schemas']['TeamResponseDto'][]; + /** @description Pagination metadata */ + pagination: Record; + }; + CreateTeamDto: { + /** + * @description Team name + * @example Stellar Innovators + */ + teamName: string; + /** + * @description Team description + * @example We are building the next generation DeFi platform + */ + description: string; + /** @description Roles the team is looking for. Each entry is a role title with optional free-form skills. Team will be CLOSED unless at least one role is specified. The number of roles is bounded by the hackathon's teamMin/teamMax (excluding the leader). */ + lookingFor?: components['schemas']['LookingForRoleDto'][]; + /** + * @description Contact information for interested members + * @example { + * "telegram": "@teamlead", + * "discord": "lead#1234" + * } + */ + contactInfo?: Record; + }; + UpdateTeamDto: { + /** + * @description Updated team name + * @example Stellar Innovators Pro + */ + teamName?: string; + /** @description Updated team description */ + description?: string; + /** @description Roles the team is looking for. Set to empty array to close the team. Each entry is a role title with optional free-form skills. */ + lookingFor?: components['schemas']['LookingForRoleDto'][]; + /** @description Updated contact information */ + contactInfo?: Record; + /** @description Explicitly set team open/closed status. Can only be true if lookingFor is not empty. */ + isOpen?: boolean; + }; + InviteToTeamDto: { + /** + * @description User ID or username of the person to invite + * @example user_1234567890 + */ + inviteeIdentifier: string; + /** + * @description Optional message to include with the invitation + * @example We would love to have you on our team! + */ + message?: string; + }; + TeamInvitationResponseDto: { + /** + * @description Invitation ID + * @example inv_1234567890 + */ + id: string; + /** + * @description Team ID + * @example team_1234567890 + */ + teamId: string; + /** @description Hackathon information */ + hackathon: Record; + /** @description Invitee information */ + invitee: Record; + /** @description Inviter information */ + inviter: Record; + /** + * @description Invitation status + * @example pending + * @enum {string} + */ + status: 'pending' | 'accepted' | 'rejected' | 'expired'; + /** + * @description Optional message from inviter + * @example We would love to have you on our team! + */ + message?: Record; + /** + * @description Role in the team + * @example member + */ + role: Record; + /** + * Format: date-time + * @description Invitation expiration date + * @example 2026-01-30T12:00:00.000Z + */ + expiresAt: string; + /** + * Format: date-time + * @description Invitation creation date + * @example 2026-01-23T12:00:00.000Z + */ + createdAt: string; + /** + * @description Date when invitation was responded to + * @example 2026-01-24T12:00:00.000Z + */ + respondedAt?: Record; + }; + TeamInvitationListResponseDto: { + /** @description List of invitations */ + invitations: components['schemas']['TeamInvitationResponseDto'][]; + /** + * @description Total count + * @example 5 + */ + total: number; + }; + InvitationActionResponseDto: { + /** + * @description Success message + * @example Successfully accepted team invitation + */ + message: string; + /** + * @description Team ID that was joined (only for accept) + * @example team_1234567890 + */ + teamId: string; + /** @description Updated invitation */ + invitation: components['schemas']['TeamInvitationResponseDto']; + }; + ToggleRoleHiredDto: { + /** + * @description Skill/role name to toggle hired status + * @example Rust Developer + */ + skill: string; + }; + TransferLeadershipDto: { + /** + * @description User ID of the new team leader (must be an existing member) + * @example user_1234567890 + */ + newLeaderId: string; + /** + * @description Optional reason for the leadership transfer + * @example Stepping down to focus on development tasks + */ + reason?: string; + }; + LeadershipTransferResponseDto: { + /** + * @description Success message + * @example Leadership successfully transferred + */ + message: string; + /** @description Updated team with new leader */ + team: components['schemas']['TeamResponseDto']; + /** + * @description Previous leader ID + * @example user_1234567890 + */ + previousLeaderId: string; + /** + * @description New leader ID + * @example user_0987654321 + */ + newLeaderId: string; + /** + * Format: date-time + * @description Timestamp of the transfer + * @example 2026-02-16T10:30:00.000Z + */ + transferredAt: string; + }; + InfoFormData: { + /** @description Hackathon title */ + name: string; + /** + * Format: uri + * @description Banner image URL + */ + banner: string; + /** @description Hackathon description */ + description: string; + /** @description One or more hackathon categories */ + categories: ( + | 'DeFi' + | 'Payments' + | 'Stablecoins' + | 'Lending & Borrowing' + | 'Trading & DEXs' + | 'Derivatives' + | 'Prediction Markets' + | 'NFTs' + | 'Creator Economy' + | 'Social' + | 'Social Tokens' + | 'DAOs' + | 'Governance' + | 'Web3 Gaming' + | 'Metaverse' + | 'Layer 1' + | 'Layer 2' + | 'Cross-chain' + | 'Interoperability' + | 'Infrastructure' + | 'Developer Tooling' + | 'Wallets' + | 'Account Abstraction' + | 'Oracles' + | 'Data & Indexing' + | 'Analytics' + | 'AI' + | 'AI Agents' + | 'DePIN' + | 'DeSci' + | 'Privacy' + | 'Zero-Knowledge' + | 'Security' + | 'Identity' + | 'Real World Assets' + | 'Tokenization' + | 'Supply Chain' + | 'Sustainability' + | 'Climate' + | 'Education' + | 'Healthcare' + | 'Consumer Apps' + | 'Mobile' + | 'Other' + )[]; + /** + * @description Venue type + * @enum {string} + */ + venueType: 'virtual' | 'physical'; + /** @description Short tagline */ + tagline: string; + country?: string; + state?: string; + city?: string; + venueName?: string; + venueAddress?: string; + /** @description Read-only URL slug (server-assigned) */ + slug?: string; + }; + PhaseDto: { + /** @description Phase name */ + name: string; + /** Format: date-time */ + startDate: string; + /** Format: date-time */ + endDate: string; + description?: string; + }; + TimelineFormData: { + /** Format: date-time */ + startDate: string; + /** Format: date-time */ + submissionDeadline: string; + /** @description IANA timezone */ + timezone: string; + /** Format: date-time */ + registrationDeadline?: string; + /** Format: date-time */ + judgingDeadline?: string; + phases?: components['schemas']['PhaseDto'][]; + /** + * Format: date-time + * @description Read-only: original submission deadline before any extension + */ + submissionDeadlineOriginal?: string; + /** + * Format: date-time + * @description Read-only: timestamp the submission deadline was last extended + */ + submissionDeadlineExtendedAt?: string; + }; + ParticipantFormData: { + /** @enum {string} */ + participantType: 'individual' | 'team' | 'team_or_individual'; + teamMin?: number; + teamMax?: number; + /** @description Participant cap; omit for unlimited */ + maxParticipants?: number; + require_github?: boolean; + require_demo_video?: boolean; + require_other_links?: boolean; + detailsTab?: boolean; + participantsTab?: boolean; + resourcesTab?: boolean; + submissionTab?: boolean; + announcementsTab?: boolean; + discussionTab?: boolean; + winnersTab?: boolean; + sponsorsTab?: boolean; + joinATeamTab?: boolean; + rulesTab?: boolean; + /** @enum {string} */ + submissionVisibility?: 'PUBLIC' | 'PARTICIPANTS_ONLY'; + /** @enum {string} */ + submissionStatusVisibility?: + | 'ALL' + | 'ACCEPTED_SHORTLISTED' + | 'HIDDEN_UNTIL_RESULTS'; + }; + HackathonDraftTracksDto: { + /** @description Max number of tracks a single submission may enter (1-20). */ + tracksMaxPerSubmission?: number; + }; + PrizeTierDto: { + /** @description Client-generated tier id */ + id: string; + /** @description Placement label, e.g. "1st Place" */ + place: string; + /** @description Prize amount as a decimal string */ + prizeAmount: string; + description?: string; + currency?: string; + passMark: number; + /** @enum {string} */ + kind?: 'OVERALL' | 'TRACK'; + trackId?: string; + }; + PrizePlacementWriteDto: { + /** @description 1 = 1st place; unique within a prize */ + position: number; + label?: string; + /** @description Prize amount as a decimal string */ + amount: string; + currency?: string; + passMark?: number; + }; + PrizeWriteDto: { + /** @description Prize name, e.g. "Grand Prize" or "Best UI/UX" */ + name: string; + description?: string; + /** @description Linked HackathonTrack ids; empty = overall prize */ + trackIds: string[]; + placements: components['schemas']['PrizePlacementWriteDto'][]; + }; + WinnerOverrideDto: { + /** @description Submission id the override targets */ + submissionId: string; + rank?: number; + prizeAmount?: string; + currency?: string; + }; + RewardsFormData: { + prizeTiers?: components['schemas']['PrizeTierDto'][]; + prizes?: components['schemas']['PrizeWriteDto'][]; + winnerOverrides?: components['schemas']['WinnerOverrideDto'][]; + /** @enum {string} */ + prizeStructure?: 'OVERALL_ONLY' | 'OVERALL_AND_TRACKS' | 'TRACKS_ONLY'; + tracksMaxPerSubmission?: number; + allowWinnerStacking?: boolean; + }; + ResourceItemDto: { + /** @description Client-generated resource id */ + id: string; + link?: string; + description?: string; + /** @description Uploaded file metadata */ + file?: { + url?: string; + name?: string; + }; + }; + ResourcesFormData: { + resources: components['schemas']['ResourceItemDto'][]; + }; + CriterionDto: { + /** @description Client-generated criterion id */ + id: string; + /** @description Criterion name */ + name: string; + weight: number; + description?: string; + }; + JudgingFormData: { + criteria: components['schemas']['CriterionDto'][]; + }; + SponsorPartnerDto: { + /** @description Client-generated sponsor/partner id */ + id: string; + name?: string; + logo?: string; + link?: string; + }; + CollaborationFormData: { + /** @description Organizer contact email */ + contactEmail: string; + telegram?: string; + discord?: string; + socialLinks?: string[]; + sponsorsPartners?: components['schemas']['SponsorPartnerDto'][]; + }; + HackathonDraftDataDto: { + information?: components['schemas']['InfoFormData']; + timeline?: components['schemas']['TimelineFormData']; + participation?: components['schemas']['ParticipantFormData']; + tracks?: components['schemas']['HackathonDraftTracksDto']; + rewards?: components['schemas']['RewardsFormData']; + resources?: components['schemas']['ResourcesFormData']; + judging?: components['schemas']['JudgingFormData']; + collaboration?: components['schemas']['CollaborationFormData']; + }; + HackathonDraftAiGenerationDto: { + /** @description AI generationId that produced or last-updated this draft. */ + generationId: string; + }; + HackathonDraftPrizePlacementDto: { + id: string; + /** @description 1 = 1st place, unique within a prize */ + position: number; + label?: string | null; + /** @description Decimal string in the prize currency */ + amount: string; + currency: string; + /** @description Minimum score (0-100) to win this placement */ + passMark: number; + }; + HackathonDraftPrizeDto: { + id: string; + name: string; + description?: string | null; + displayOrder: number; + /** @description Linked track ids; empty = overall prize */ + trackIds: string[]; + placements: components['schemas']['HackathonDraftPrizePlacementDto'][]; + }; + HackathonDraftResponseDto: { + id: string; + /** @enum {string} */ + status: + | 'DRAFT' + | 'DRAFT_AWAITING_FUNDING' + | 'PUBLISHED' + | 'ARCHIVED' + | 'CANCELLED'; + /** @description First incomplete step (1-based) */ + currentStep: number; + completedSteps: string[]; + data: components['schemas']['HackathonDraftDataDto']; + isValidForPublish: boolean; + /** @description Per-section validation messages, keyed by step */ + validationErrors: { + [key: string]: string[]; + }; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + /** @description Present when the draft was generated with Organizer Assist; enables per-section AI regenerate in the wizard. */ + aiGeneration?: components['schemas']['HackathonDraftAiGenerationDto']; + /** @description Prize entity (named prizes + linked tracks + placements). Additive read path alongside data.rewards.prizeTiers; becomes authoritative as readers cut over. */ + prizes: components['schemas']['HackathonDraftPrizeDto'][]; + }; + UpdateHackathonDraftDto: { + information?: components['schemas']['InfoFormData']; + timeline?: components['schemas']['TimelineFormData']; + participation?: components['schemas']['ParticipantFormData']; + rewards?: components['schemas']['RewardsFormData']; + resources?: components['schemas']['ResourcesFormData']; + judging?: components['schemas']['JudgingFormData']; + collaboration?: components['schemas']['CollaborationFormData']; + /** @description Hint that this is an autosave (no completion side effects). */ + autoSave?: boolean; + }; + GenerateDraftFromBriefDto: { + /** + * @description Free-text brief describing the hackathon to generate. + * @example A two-week hackathon for AI agent tooling on Stellar, aimed at indie builders. + */ + brief: string; + /** + * @description Total budget cap in USDC, as a decimal string. + * @example 10000 + */ + budgetCapUsdc: string; + /** + * @description Earliest the hackathon may start (YYYY-MM-DD). + * @example 2026-07-01 + */ + earliestStart: string; + /** @description Up to 3 example briefs/drafts to steer style. */ + examples?: string[]; + }; + AiGenerationMetaDto: { + generationId: string; + model: string; + promptVersion: string; + /** @description Cost in USD as a decimal string (never a float). */ + costUsd: string; + }; + GenerateDraftFromBriefResponseDto: { + /** @description Id of the created draft. */ + draftId: string; + draft: components['schemas']['HackathonDraftResponseDto']; + generation: components['schemas']['AiGenerationMetaDto']; + }; + RegenerateDraftSectionDto: { + /** @enum {string} */ + section: 'criteria' | 'prizes' | 'tracks' | 'timeline' | 'description'; + /** @description Optional steering instructions for the regeneration. */ + instructions?: string; + }; + RegenerateDraftSectionResponseDto: { + /** @enum {string} */ + section: 'criteria' | 'prizes' | 'tracks' | 'timeline' | 'description'; + /** @description Regenerated values in the wizard section shape. */ + data: { + [key: string]: unknown; + }; + generation: components['schemas']['AiGenerationMetaDto']; + }; + UpdateVisibilitySettingsDto: { + /** + * @description Who can view hackathon submissions + * @example PUBLIC + * @enum {string} + */ + submissionVisibility?: 'PUBLIC' | 'PARTICIPANTS_ONLY'; /** - * @description Location visibility - * @example true + * @description Which submission statuses are visible to others. ALL exposes SUBMITTED and SHORTLISTED. ACCEPTED_SHORTLISTED exposes only SHORTLISTED. HIDDEN_UNTIL_RESULTS hides every submission from non-owners and non-organizers until the hackathon results are published, then exposes only SHORTLISTED. DISQUALIFIED is never visible to anyone other than the owner or an organizer. + * @example ACCEPTED_SHORTLISTED + * @enum {string} */ - locationVisibility: boolean; + submissionStatusVisibility?: + | 'ALL' + | 'ACCEPTED_SHORTLISTED' + | 'HIDDEN_UNTIL_RESULTS'; + }; + ReviewSubmissionDto: { /** - * @description Company visibility - * @example true + * @description ID of the assigned judge performing the review + * @example user_1234567890 */ - companyVisibility: boolean; + judgeId: string; /** - * @description Website visibility - * @example true + * @description Review action + * @example SHORTLISTED + * @enum {string} */ - websiteVisibility: boolean; + status: 'SHORTLISTED' | 'SUBMITTED'; /** - * @description Social links visibility - * @example true + * @description Reviewer notes or feedback + * @example Great project with innovative approach */ - socialLinksVisibility: boolean; + notes?: string; + /** + * @description Rank/position for the submission + * @example 1 + */ + rank?: number; + /** + * @description Whether this is an organizational override (bypasses COI and assignment checks) + * @default false + */ + isOrganizerOverride: boolean; }; - UpdateAppearanceSettingsDto: { + OrganizationHackathonParticipantsResponseDto: Record; + DisqualifySubmissionDto: { /** - * @description Theme - * @example light + * @description Reason for disqualification + * @example Submission does not meet hackathon requirements + */ + disqualificationReason: string; + }; + BulkSubmissionActionDto: { + /** + * @description Array of submission IDs + * @example [ + * "sub_1234567890", + * "sub_0987654321" + * ] + */ + submissionIds: string[]; + /** + * @description Action to perform + * @example SHORTLISTED * @enum {string} */ - theme: 'light' | 'dark' | 'auto'; + action: 'SHORTLISTED' | 'SUBMITTED' | 'DISQUALIFIED'; + /** + * @description Reason (required for DISQUALIFIED action) + * @example Does not meet requirements + */ + reason?: string; }; - PublicEarningsSummaryDto: { + SummaryMetricsDto: { + /** @example 120 */ + participantsCount: number; + /** @example 45 */ + submissionsCount: number; + /** @example 6 */ + activeJudges: number; + /** @example 3 */ + completedMilestones: number; + }; + TrendPointDto: { + /** @example 2026-02-01 */ + date: string; + /** @example 5 */ + count: number; + }; + TrendsDto: { + submissionsOverTime: components['schemas']['TrendPointDto'][]; + participantSignupsOverTime: components['schemas']['TrendPointDto'][]; + }; + TimelinePhaseDto: { + /** @example Registration */ + phase: string; + /** @example Individuals and teams are signing up to participate in the hackathon. */ + description: string; + /** @example 2026-01-20 */ + date: string; + /** @enum {string} */ + status: 'upcoming' | 'ongoing' | 'completed'; + }; + HackathonAnalyticsResponseDto: { + /** @example hack_1234567890 */ + hackathonId: string; + summary: components['schemas']['SummaryMetricsDto']; + trends: components['schemas']['TrendsDto']; + timeline: components['schemas']['TimelinePhaseDto'][]; + }; + AnnouncementAuthorDto: { + id: string; + name: string; + image?: string; + username?: string; + }; + AnnouncementResponseDto: { + id: string; + hackathonId: string; + title: string; + content: string; + isDraft: boolean; + isPinned: boolean; + /** Format: date-time */ + publishedAt?: string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + author: components['schemas']['AnnouncementAuthorDto']; + }; + CreateAnnouncementDto: { /** - * @description All-time total earned (normalized, e.g. USDC 7 decimals) - * @example 50000 + * @description Title of the announcement + * @example Hackathon Starts Now! */ - totalEarned: number; + title: string; + /** + * @description Content of the announcement in Markdown + * @example # Welcome + * + * We are excited to start... + */ + content: string; + /** + * @description Whether the announcement is a draft + * @default true + */ + isDraft: boolean; + /** + * @description Whether the announcement should be pinned + * @default false + */ + isPinned: boolean; }; - EarningsBreakdownDto: { + UpdateAnnouncementDto: { /** - * @description Total from hackathons - * @example 20000 + * @description Title of the announcement + * @example Hackathon Starts Now! */ - hackathons: number; + title?: string; /** - * @description Total from grants - * @example 10000 + * @description Content of the announcement in Markdown + * @example # Welcome + * + * We are excited to start... */ - grants: number; + content?: string; + /** @description Whether the announcement is a draft */ + isDraft?: boolean; + /** @description Whether the announcement should be pinned */ + isPinned?: boolean; + }; + CriterionScoreDto: { /** - * @description Total from crowdfunding - * @example 15000 + * @description Criterion ID or name + * @example Technical Complexity */ - crowdfunding: number; + criterionId: string; /** - * @description Total from bounties - * @example 5000 + * @description Score for this criterion (0-10) + * @example 8.5 */ - bounties: number; + score: number; + /** + * @description Optional comment for this criterion + * @example Great technical implementation + */ + comment?: string; }; - PublicEarningActivityDto: { - /** @description Unique activity id */ + ScoreSubmissionDto: { + /** + * @description Submission ID being judged + * @example sub_1234567890 + */ + submissionId: string; + /** @description Scores for each individual criterion */ + criteriaScores: components['schemas']['CriterionScoreDto'][]; + /** + * @description Optional ID of the judge to attribute this score to (defaults to calling user) + * @example user_123 + */ + judgeId?: string; + /** + * @description Optional admin notes + * @example Score adjusted per appeal + */ + notes?: string; + /** + * @description Whether this is an organizational override (bypasses COI and assignment checks) + * @default false + */ + isOrganizerOverride: boolean; + }; + UserDetailsDto: { + id: string; + email: string; + name: string; + username: string; + image?: string; + }; + JudgingSubmissionParticipantDto: { + id: string; + userId: string; + user: components['schemas']['UserDetailsDto']; + participationType: string; + teamId?: string; + teamName?: string; + teamMembers?: Record[]; + }; + JudgingSubmissionDataDto: { id: string; + projectName: string; + category: string; + description: string; + logo?: string; + videoUrl?: string; + introduction?: string; + links?: Record[]; + socialLinks?: { + [key: string]: unknown; + }; + submissionDate: string; + status: string; + rank?: number; + }; + IndividualJudgingResultDto: { + judgeId: string; + judgeName: string; + criteriaScores: components['schemas']['CriterionScoreDto'][]; + totalScore: number; + /** Format: date-time */ + submittedAt: string; + }; + JudgingSubmissionDto: { + participant: components['schemas']['JudgingSubmissionParticipantDto']; + submission: components['schemas']['JudgingSubmissionDataDto']; + myScore?: components['schemas']['IndividualJudgingResultDto']; + averageScore: Record | null; + judgeCount: number; + }; + JudgingPaginationDto: { + page: number; + limit: number; + total: number; + totalPages: number; + }; + JudgingSubmissionsResponseDto: { + submissions: components['schemas']['JudgingSubmissionDto'][]; + criteria: components['schemas']['CriterionDto'][]; + pagination: components['schemas']['JudgingPaginationDto']; + /** @description Number of submissions in this hackathon that the calling judge has already scored. Independent of pagination so the progress strip is accurate even when the user is on page 2. */ + scoredCount?: number; + }; + AddJudgeDto: { /** - * @description Earnings source category + * @description Email address of the user to be assigned as a judge + * @example judge@example.com + */ + email: string; + }; + JudgeResponseDto: { + id: string; + userId: string; + name: string; + image?: Record; + }; + IndividualScoreDto: { + judgeId: string; + judgeName: string; + score: number; + }; + ScoreRangeDto: { + min: number; + max: number; + }; + CriteriaBreakdownDto: { + criterionId: string; + averageScore: number; + min: number; + max: number; + variance: number; + }; + AggregatedJudgingResultDto: { + submissionId: string; + projectName: string; + teamId?: Record; + participantId: string; + status: string; + /** Format: date-time */ + submittedAt: string; + averageScore: number; + totalScore: number; + judgeCount: number; + expectedJudgeCount: number; + judgingProgress: string; + individualScores: components['schemas']['IndividualScoreDto'][]; + scoreVariance: number; + scoreRange: components['schemas']['ScoreRangeDto']; + criteriaBreakdown: components['schemas']['CriteriaBreakdownDto'][]; + rank?: Record; + computedRank?: number; + prize?: string; + isComplete: boolean; + isPending: boolean; + hasDisagreement: boolean; + trackIds?: string[]; + /** @description True when this submission is in the top X% overall per the recommendation threshold. */ + recommendedOverall?: boolean; + /** @description Track ids where this submission is in the top X% per the per-track recommendation threshold. */ + recommendedTrackIds?: string[]; + }; + JudgingResultsResponseDto: { + hackathonId: string; + totalSubmissions: number; + submissionsScoredCount: number; + submissionsPendingCount: number; + averageScoreAcrossAll: number; + resultsPublished: boolean; + judgesAssigned: number; + results: components['schemas']['AggregatedJudgingResultDto'][]; + /** Format: date-time */ + generatedAt: string; + /** @description Manual winner assignments override (submissionId -> rank) */ + winnerOverrides?: { + [key: string]: number; + }; + metadata: components['schemas']['JudgingResultsMetadataDto']; + }; + SetPlacementWinnerDto: { + /** @description The submission to award this placement to. */ + submissionId: string; + }; + InviteJudgeDto: { + /** @example judge@example.com */ + email: string; + /** @description Optional public display name for the judge */ + displayName?: string; + /** @description Optional title/role shown with the judge (e.g. "Time Traveler"). */ + title?: string; + /** @description Personal message included in the invitation email */ + message?: string; + /** @description Override expiry in days (default 14). Maximum 60 to prevent indefinite invitations. */ + expiresInDays?: number; + }; + BulkInviteJudgesDto: { + /** @description Up to 25 judges per request */ + invites: components['schemas']['InviteJudgeDto'][]; + }; + BulkInviteRowResultDto: { + email: string; + /** + * @description 'invited' = sent; 'failed' = skipped with a reason. * @enum {string} */ - source: 'hackathons' | 'grants' | 'crowdfunding' | 'bounties'; + status: 'invited' | 'failed'; + /** @description Failure reason when status is failed. */ + reason?: string; + }; + BulkInviteResultDto: { + results: components['schemas']['BulkInviteRowResultDto'][]; + /** @description Count of invitations sent. */ + invited: number; + /** @description Count of rows that failed / were skipped. */ + failed: number; + }; + RecommendationThresholdDto: { + id: string; + hackathonId: string; + /** @description null = overall threshold; otherwise the scoped track id. */ + trackId?: string | null; + /** @description Top percent (0-100). */ + topPercent: number; + }; + SetRecommendationThresholdDto: { + /** @description Track id to scope the threshold to; omit for the overall cut. */ + trackId?: string; /** - * @description Human-readable title - * @example Winner of Stellar Hackathon Q1 + * @description Top percent (0-100) of submissions flagged as recommended. + * @example 10 */ - title: string; + topPercent: number; + }; + RecommendationComputeDiagnosticsDto: { + /** @description Submissions currently SHORTLISTED. */ + shortlistedSubmissions: number; + /** @description Shortlisted submissions with at least one counted score (active judge or promoted AI scorecard; advisory AI_ASSIST excluded). These are the only submissions a threshold can rank. */ + scoredSubmissions: number; + /** @description Whether an overall (all-submissions) cut is set. */ + overallThresholdConfigured: boolean; + /** @description Number of per-track cuts configured. */ + trackThresholdsConfigured: number; /** - * @description Amount (normalized) - * @example 5000 + * @description Human-readable reasons explaining the outcome (e.g. why nothing was flagged). Empty when the compute produced recommendations with nothing outstanding. + * @example [ + * "No recommendation thresholds are configured. Set a top-X% cut (overall or per track), then recompute." + * ] */ - amount: number; + reasons: string[]; + }; + RecommendationComputeResultDto: { + /** @description Submissions flagged recommendedOverall. */ + overallRecommended: number; /** - * @description Currency code - * @example USDC + * @description Per-track recommended counts. + * @example [ + * { + * "trackId": "trk_1", + * "recommended": 3 + * } + * ] */ - currency: string; + tracks: string[]; + /** @description Why the compute produced what it did, so an empty result is never silent. */ + diagnostics: components['schemas']['RecommendationComputeDiagnosticsDto']; + }; + AcceptJudgeInvitationDto: { + /** @description Optional display name override. If omitted, the inviter-provided displayName (or the user’s account name) is used. */ + displayName?: string; + }; + PublishedInfoFormDataDto: { + /** @example Web3 Innovation Hackathon */ + name: string; + /** @example https://example.com/banner.png */ + banner: string; + /** @example Build products for the decentralized future. */ + description: string; + categories: ( + | 'DeFi' + | 'NFTs' + | 'DAOs' + | 'Layer 2' + | 'Cross-chain' + | 'Web3 Gaming' + | 'Social Tokens' + | 'Infrastructure' + | 'Privacy' + | 'Sustainability' + | 'Real World Assets' + | 'Other' + )[]; + /** + * @example virtual + * @enum {string} + */ + venueType: 'virtual' | 'physical'; + /** @example Build the future of Web3 */ + tagline: string; + /** @example Nigeria */ + country?: string; + /** @example Lagos */ + state?: string; + /** @example Ikeja */ + city?: string; + /** @example Eko Convention Center */ + venueName?: string; + /** @example Plot 1415 Adetokunbo Ademola St */ + venueAddress?: string; + /** @example web3-innovation-hackathon */ + slug?: string; + }; + PublishedSponsorPartnerDto: { + /** @example sp-1 */ + id: string; + /** @example Stellar Foundation */ + name?: string; + /** @example https://example.com/logo.png */ + logo?: string; + /** @example https://stellar.org */ + link?: string; + }; + PublishedCollaborationFormDataDto: { + /** @example organizer@boundless.dev */ + contactEmail: string; + /** @example @boundless */ + telegram?: string; + /** @example boundless-hackathon */ + discord?: string; /** - * @description When the earning occurred (ISO date string) - * @example 2024-01-19T14:30:00Z + * @example [ + * "https://x.com/boundless" + * ] */ - occurredAt: string; + socialLinks: string[]; + sponsorsPartners: components['schemas']['PublishedSponsorPartnerDto'][]; }; - PublicEarningsResponseDto: { - summary: components['schemas']['PublicEarningsSummaryDto']; - breakdown: components['schemas']['EarningsBreakdownDto']; - /** @description Verified activity history (completed only) */ - activities: components['schemas']['PublicEarningActivityDto'][]; + UpdatePublishedHackathonContentDto: { + information?: components['schemas']['PublishedInfoFormDataDto']; + collaboration?: components['schemas']['PublishedCollaborationFormDataDto']; }; - EarningsSummaryDto: { + PublishedPhaseDto: { + /** @example Building Phase */ + name: string; + /** @example 2026-04-01T00:00:00.000Z */ + startDate: string; + /** @example 2026-04-10T00:00:00.000Z */ + endDate: string; + /** @example Core build phase for teams */ + description?: string; + }; + PublishedTimelineFormDataDto: { + /** @example 2026-04-01T00:00:00.000Z */ + startDate?: string; + /** @example 2026-04-15T00:00:00.000Z */ + submissionDeadline?: string; + /** @example Africa/Lagos */ + timezone?: string; /** - * @description All-time total earned (normalized, e.g. USDC 7 decimals) - * @example 50000 + * @description Optional. When null, registration stays open until submission deadline. + * @example 2026-04-02T00:00:00.000Z */ - totalEarned: number; + registrationDeadline?: string; /** - * @description Amount currently claimable / pending withdrawal - * @example 10000 + * @description Optional judging deadline. When null, no judging phase is rendered on the timeline. + * @example 2026-04-18T00:00:00.000Z */ - pendingWithdrawal: number; + judgingDeadline?: string; + phases?: components['schemas']['PublishedPhaseDto'][]; + }; + PublishedParticipantFormDataDto: { + /** @enum {string} */ + participantType: 'individual' | 'team' | 'team_or_individual'; + /** @example 2 */ + teamMin?: number; + /** @example 5 */ + teamMax?: number; /** - * @description Amount already paid out (completed withdrawals) - * @example 40000 + * @description Optional cap on total participants. null = unlimited. Can be updated after publishing. + * @example 200 */ - completedWithdrawal: number; + maxParticipants?: number; + /** @example true */ + require_github?: boolean; + /** @example false */ + require_demo_video?: boolean; + /** @example true */ + require_other_links?: boolean; + detailsTab?: boolean; + participantsTab?: boolean; + resourcesTab?: boolean; + submissionTab?: boolean; + announcementsTab?: boolean; + discussionTab?: boolean; + winnersTab?: boolean; + sponsorsTab?: boolean; + joinATeamTab?: boolean; + rulesTab?: boolean; }; - EarningActivityDto: { - /** @description Unique activity id (e.g. submissionId or milestoneId) */ + UpdatePublishedHackathonScheduleDto: { + timeline?: components['schemas']['PublishedTimelineFormDataDto']; + participation?: components['schemas']['PublishedParticipantFormDataDto']; + }; + PublishedPrizeTierDto: { + /** @example tier-1 */ id: string; + /** @example 1st Place */ + place: string; + /** @example 5000 */ + prizeAmount: string; + /** @example USDC */ + currency?: string; + /** @example Top overall project */ + description?: string; /** - * @description Earnings source category - * @enum {string} + * @description Display rank / ordering of the tier (1 = highest) + * @example 1 */ - source: 'hackathons' | 'grants' | 'crowdfunding' | 'bounties'; + rank?: number; + /** @example 70 */ + passMark: number; + /** @enum {string} */ + kind?: 'OVERALL' | 'TRACK'; + /** @description Required when kind=TRACK. References a HackathonTrack id. */ + trackId?: string; + }; + PublishedRewardsFormDataDto: { + prizeTiers?: components['schemas']['PublishedPrizeTierDto'][]; + prizes?: components['schemas']['PrizeWriteDto'][]; /** - * @description Human-readable title - * @example Winner of Stellar Hackathon Q1 + * @description Manual winner assignments override (submissionId -> rank) + * @example { + * "sub-1": 1, + * "sub-2": 2 + * } */ - title: string; + winnerOverrides?: { + [key: string]: number; + }; + /** @enum {string} */ + prizeStructure?: 'OVERALL_ONLY' | 'OVERALL_AND_TRACKS' | 'TRACKS_ONLY'; + tracksMaxPerSubmission?: number; + allowWinnerStacking?: boolean; + }; + UpdatePublishedHackathonFinancialDto: { + rewards: components['schemas']['PublishedRewardsFormDataDto']; + }; + AdvancedSettingsFormDataDto: { + /** @example true */ + isPublic: boolean; + /** @example false */ + allowLateRegistration: boolean; + /** @example true */ + requireApproval: boolean; + /** @example 500 */ + maxParticipants?: number; + /** @example hackathons.boundless.dev */ + customDomain?: string; + /** @example true */ + enableDiscord: boolean; + /** @example https://discord.gg/boundless */ + discordInviteLink?: string; + /** @example true */ + enableTelegram: boolean; + /** @example https://t.me/boundless */ + telegramInviteLink?: string; + }; + UpdatePublishedHackathonAdvancedSettingsDto: { + advancedSettings: components['schemas']['AdvancedSettingsFormDataDto']; + }; + SetHackathonAccessDto: { + /** @enum {string} */ + visibility: 'PUBLIC' | 'PRIVATE'; + /** @description Access password. Required when first making a hackathon private; ignored (cleared) when visibility is PUBLIC. */ + password?: string; + }; + InvitePartnerDto: { + /** @example sponsor@partner.io */ + partnerEmail: string; + /** @example Acme Corp */ + partnerName: string; + /** @example https://cdn.example.com/logo.png */ + partnerLogo?: string; + /** @example https://acme.io */ + partnerLink?: string; /** - * @description Amount (normalized) - * @example 5000 + * @description Pledged amount in USDC + * @example 1000 */ - amount: number; + pledgedAmount: number; /** - * @description Currency code + * @default USDC * @example USDC */ currency: string; + /** @description Optional message included in the invite */ + message?: string; /** - * @description Activity status - * @enum {string} - */ - status: 'pending' | 'claimable' | 'completed'; - /** - * @description When the earning occurred (ISO date string) - * @example 2024-01-19T14:30:00Z + * @description Whether the partner is shown publicly on the hackathon page + * @default true */ - occurredAt: string; - /** @description Entity id for claim (e.g. submissionId, milestoneId) */ - entityId?: string; - }; - EarningsResponseDto: { - summary: components['schemas']['EarningsSummaryDto']; - breakdown: components['schemas']['EarningsBreakdownDto']; - /** @description Activity feed */ - activities: components['schemas']['EarningActivityDto'][]; - }; - DashboardUserStatsDto: { - followers: number; - following: number; - }; - DashboardUserDto: { - id: string; - name: string | null; - email: string; - username: string | null; - displayUsername: string | null; - image: string | null; - role: string; - /** Format: date-time */ - createdAt: string; - stats?: components['schemas']['DashboardUserStatsDto']; + showPublicly: boolean; }; - UserStatsDto: { - projectsCreated: number; - projectsFunded: number; - totalContributed: number; - commentsPosted: number; - votes: number; - grants: number; - hackathons: number; - followers: number; - following: number; - reputation: number; - communityScore: number; + AllocationTargetDto: { + /** @description PrizePlacement id (the fundable slot) this allocation adds to. Placements are created in the Rewards step. */ + placementId: string; + /** @description Net amount (USDC) to add to the placement */ + amount: number; }; - ChartDataPointDto: { - /** @description Date in YYYY-MM-DD format */ - date: string; - /** @description Count for that date */ - count: number; + AllocateContributionDto: { + /** @description One or more tiers to allocate this contribution into */ + targets: components['schemas']['AllocationTargetDto'][]; }; - ChartDto: { - data: components['schemas']['ChartDataPointDto'][]; + PrepareFundTransactionDto: { + /** @description Stellar address of the partner wallet that will sign the transaction */ + signerAddress: string; }; - ActivitiesGraphDto: { - data: components['schemas']['ChartDataPointDto'][]; + SubmitSignedTransactionDto: { + /** @description Signed transaction XDR returned by the partner wallet */ + signedXdr: string; }; - ActivityProjectDto: { + TrackCustomQuestionDto: { + /** @description Stable id, unique within the track. */ id: string; - title: string; - banner?: string | null; - logo?: string | null; + /** @description Question label shown on the submission form. */ + label: string; + /** + * @description Input type. 'short' = single-line, 'long' = textarea, 'url' = URL field. + * @enum {string} + */ + type: 'short' | 'long' | 'url'; + /** @description Optional maxLength override (defaults: short=200, long=1000). */ + maxLength?: number; + /** @description Whether an answer is required. */ + required?: boolean; }; - ActivityOrganizationDto: { + TrackRequiredArtifactDto: { + /** @description Stable id, unique within the track. */ id: string; - name: string; + /** @description Artifact label (e.g. "Figma file URL"). */ + label: string; + /** + * @description Artifact type — drives the placeholder + light hint UI. + * @enum {string} + */ + type: 'figma' | 'github' | 'video' | 'pdf' | 'url'; + /** @description Whether submitting this artifact is required. */ + required?: boolean; }; - RecentActivityDto: { + TrackResponseDto: { id: string; - type: string; - userId: string; - projectId?: string | null; - organizationId?: string | null; + hackathonId: string; + slug: string; + name: string; + description?: string; + type?: string; + /** @enum {string} */ + eligibility: 'OPT_IN' | 'OPEN'; + displayOrder: number; + isArchived: boolean; + /** @description Count of submissions that have opted into this track. Useful for organizer dashboards. */ + entryCount: number; + /** @description Per-track customization (Phase B). */ + prompt?: string; + customQuestions?: components['schemas']['TrackCustomQuestionDto'][]; + requiredArtifacts?: components['schemas']['TrackRequiredArtifactDto'][]; /** Format: date-time */ createdAt: string; - project?: components['schemas']['ActivityProjectDto']; - organization?: components['schemas']['ActivityOrganizationDto']; - }; - DashboardDto: { - /** @description User profile data */ - user: components['schemas']['DashboardUserDto']; - stats: components['schemas']['UserStatsDto']; - chart: components['schemas']['ChartDto']; - activitiesGraph: components['schemas']['ActivitiesGraphDto']; - /** @description Recent activities */ - recentActivities: components['schemas']['RecentActivityDto'][]; + /** Format: date-time */ + updatedAt: string; }; - UpdateProfileDto: Record; - UpdateUserDto: Record; - UploadResponseDto: Record; - MultipleUploadResponseDto: Record; - FileInfoResponseDto: Record; - SearchFilesResponseDto: Record; - OptimizedUrlResponseDto: Record; - ResponsiveUrlsResponseDto: Record; - UsageStatsResponseDto: Record; - RegisterDto: Record; - LoginDto: Record; - RefreshTokenDto: Record; - VerifySignatureDto: Record; - CreateConversationDto: { - /** @description User ID of the other participant */ - otherUserId: string; + CustomQuestionResponseDto: { + id: string; + hackathonId: string; + /** @enum {string} */ + scope: 'REGISTRATION' | 'SUBMISSION'; + label: string; + helpText?: string | null; + /** @enum {string} */ + type: + | 'SHORT' + | 'LONG' + | 'URL' + | 'SINGLE_SELECT' + | 'MULTI_SELECT' + | 'BOOLEAN'; + required: boolean; + options?: string[] | null; + maxLength?: number | null; + displayOrder: number; }; - CreateMessageDto: { - /** @description Message text */ - body: string; + UpdateTracksConfigDto: { + /** @description Max number of tracks a single submission may enter (1-20). */ + tracksMaxPerSubmission?: number; }; - ContactDto: Record; - CreateCampaignDto: { - /** - * @description Title of the campaign - * @example Web3 Campaign - */ - title: string; + CreateTrackDto: { /** - * @description Logo of the campaign - * @example https://example.com/logo.png + * @description Human-readable track name shown on the hackathon page. + * @example Best UI/UX */ - logo: string; + name: string; /** - * @description Vision of the campaign - * @example Web3 Campaign + * @description URL-safe handle, unique within the hackathon. Auto-generated from name if omitted. + * @example best-ui-ux */ - vision: string; + slug?: string; /** - * @description Banner image URL of the campaign - * @example https://example.com/banner.png + * @description Short blurb shown in the track picker and on results. + * @example Best end-to-end user experience and visual polish. */ - banner: string; + description?: string; /** - * @description Category of the campaign - * @example web3 + * @description Free-form classifier for badge styling. Common values: skill, technology, theme, special. + * @example skill */ - category: string; + type?: string; /** - * @description Details of the campaign - * @example Web3 Campaign + * @description OPT_IN (default): submitters explicitly enter. OPEN: every submission auto-eligible. + * @default OPT_IN + * @enum {string} */ - details: string; + eligibility: 'OPT_IN' | 'OPEN'; /** - * @description Funding amount of the campaign - * @example 1000 + * @description Sort order. Lower numbers render first. Defaults to 0. + * @example 10 */ - fundingAmount: number; + displayOrder?: number; /** - * @description Github URL of the campaign - * @example https://github.com/example/project + * @description Single open-ended prompt shown on the submission form. When set, the submitter must answer to opt in. + * @example Why does this project fit Best UI/UX? */ - githubUrl: string; + prompt?: string; + customQuestions?: components['schemas']['TrackCustomQuestionDto'][]; + requiredArtifacts?: components['schemas']['TrackRequiredArtifactDto'][]; + }; + UpdateTrackDto: { + name?: string; + slug?: string; + description?: string; + type?: string; + /** @enum {string} */ + eligibility?: 'OPT_IN' | 'OPEN'; + displayOrder?: number; + /** @description Soft-archive instead of delete when entries already exist. Cannot be unset via this endpoint; recreate the track if needed. */ + isArchived?: boolean; + /** @description Single open-ended prompt. */ + prompt?: string; + customQuestions?: components['schemas']['TrackCustomQuestionDto'][]; + requiredArtifacts?: components['schemas']['TrackRequiredArtifactDto'][]; + }; + CustomQuestionWriteDto: { + /** @enum {string} */ + scope: 'REGISTRATION' | 'SUBMISSION'; + /** @description Question shown to the participant. */ + label: string; + /** @description Optional helper text under the field. */ + helpText?: string; /** - * @description Gitlab URL of the campaign - * @example https://gitlab.com/example/project + * @default SHORT + * @enum {string} */ - gitlabUrl: string; + type: + | 'SHORT' + | 'LONG' + | 'URL' + | 'SINGLE_SELECT' + | 'MULTI_SELECT' + | 'BOOLEAN'; + /** @description Whether an answer is required. */ + required?: boolean; + /** @description Choices for SINGLE_SELECT / MULTI_SELECT. */ + options?: string[]; + /** @description Optional length cap for SHORT / LONG answers. */ + maxLength?: number; + /** @description Sort order; lower renders first. */ + displayOrder?: number; + }; + UpsertCustomQuestionsDto: { + questions: components['schemas']['CustomQuestionWriteDto'][]; + }; + RequestFundingOtpResponseDto: { + /** @description Whether funding step-up is enforced for this action */ + required: boolean; + /** @description True when a recent verification is still valid; the client can fund without entering a new code */ + alreadyVerified: boolean; + /** @description True when a fresh code was just emailed */ + sent: boolean; + /** @description Seconds until the emailed code expires (0 when none sent) */ + expiresInSeconds: number; + }; + VerifyFundingOtpDto: { /** - * @description Bitbucket URL of the campaign - * @example https://bitbucket.com/example/project + * @description The 6-digit code emailed to the organizer + * @example 123456 */ - bitbucketUrl: string; + code: string; + }; + VerifyFundingOtpResponseDto: { + /** @description True when the code was accepted */ + verified: boolean; + /** @description Seconds the funding authorization remains valid */ + expiresInSeconds: number; + }; + WinnerDistributionEntryDto: { /** - * @description Project website of the campaign - * @example https://example.com/project + * @description Winner position (1-indexed; 1 = top winner). + * @example 1 */ - projectWebsite: string; + position: number; /** - * @description Demo video of the campaign - * @example https://example.com/demo.mp4 + * @description Percentage of the total budget allocated to this position. All entries must sum to exactly 100. + * @example 100 */ - demoVideo: string; - /** - * @description Milestones of the campaign - * @example [ - * { - * "name": "Milestone 1", - * "description": "Milestone 1 description", - * "startDate": "2025-01-01", - * "endDate": "2025-01-02", - * "amount": 1000 - * } - * ] + percent: number; + }; + PublishHackathonEscrowDto: { + /** + * @description Stellar G-address that will own and sign the on-chain create_event transaction. For managed wallets, this is the platform-derived address tied to the organizer's account; for connected/multisig, it's the org treasury's G-address. + * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ */ - milestones: string[]; + ownerAddress: string; /** - * @description Team of the campaign (optional; solo builders may omit) - * @example [ - * { - * "name": "John Doe", - * "role": "Developer", - * "email": "john.doe@example.com", - * "linkedin": "https://linkedin.com/in/john-doe", - * "twitter": "https://twitter.com/john-doe" - * } - * ] + * @description Stellar Asset Contract (SAC) address the prize pool is denominated in. Must be whitelisted on the events contract (see admin runbook). + * @example CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA */ - team?: string[]; + tokenAddress: string; /** - * @description Contact of the campaign - * @example { - * "primary": "john.doe", - * "backup": "john.doe@example.com" - * } + * @description Total prize budget in token-native units (e.g. 1000 = 1000 USDC, NOT stroops). Use a string when the value exceeds JavaScript's safe integer range. The backend converts to stroops via *10^7. + * @example 1000 */ - contact: components['schemas']['ContactDto']; + budget: string; + /** @description Optional override for the winner distribution. Each entry maps a position to a percent of total_budget. Percents must sum to exactly 100. Defaults to a single winner at position 1 taking 100%. */ + winnerDistribution?: components['schemas']['WinnerDistributionEntryDto'][]; /** - * @description Social links of the campaign (optional) - * @example [ - * { - * "platform": "twitter", - * "url": "https://twitter.com/john-doe" - * } - * ] + * @description Override for the public content_uri the contract stores against the event. Defaults to https://api.boundless.fi/hackathons//content. + * @example https://api.boundless.fi/hackathons/abc/content */ - socialLinks?: string[]; - }; - CreateDraftDto: { + contentUri?: string; /** - * @description Working title for the campaign - * @example Stellar Analytics Dashboard + * @description Signing path. Defaults to EXTERNAL (return unsigned XDR for the caller to sign). Set to MANAGED to have the backend sign + submit using the caller user's managed wallet; the response carries the op in PENDING_CONFIRM with a txHash. + * @default EXTERNAL + * @example MANAGED + * @enum {string} */ - title: string; + fundingMode: 'EXTERNAL' | 'MANAGED'; + /** @description For MANAGED funding, the organization treasury wallet to fund from. When set, the backend signs with that treasury (managed) wallet instead of the caller's personal wallet; ownerAddress must match the treasury wallet address. Omit to fund from the personal managed wallet. */ + sourceWalletId?: string; }; - UpdateCampaignDto: { + HackathonEscrowOpResponseDto: { /** - * @description Title of the campaign - * @example Web3 Campaign + * @description Internal uuid for the EscrowOp row. Use this for follow-up calls. + * @example cmpwiox7u0000yy4404ojbk9t */ - title?: string; + id: string; /** - * @description Logo of the campaign - * @example https://example.com/logo.png + * @description Hex-encoded 32-byte op_id derived deterministically from the operation parameters. Used by the on-chain idempotency check. + * @example 3cc257d743b1b44423dc8dbd417aedfe6e47ad489b5d301a2fbec5284d36de1c */ - logo?: string; + opId: string; /** - * @description Vision of the campaign - * @example Web3 Campaign + * @description Contract operation kind. + * @example CREATE_EVENT + * @enum {string} */ - vision?: string; + kind: + | 'CREATE_EVENT' + | 'CANCEL_EVENT' + | 'ADD_FUNDS' + | 'APPLY_TO_BOUNTY' + | 'WITHDRAW_APPLICATION' + | 'SUBMIT' + | 'WITHDRAW_SUBMISSION' + | 'SELECT_WINNERS' + | 'CLAIM_MILESTONE'; /** - * @description Banner image URL of the campaign - * @example https://example.com/banner.png + * @description Status of the EscrowOp in its lifecycle. + * @example PENDING_SIGN + * @enum {string} */ - banner?: string; + status: + | 'PENDING_BUILD' + | 'PENDING_SIGN' + | 'PENDING_SUBMIT' + | 'PENDING_CONFIRM' + | 'COMPLETED' + | 'FAILED' + | 'CANCELLED'; /** - * @description Category of the campaign - * @example web3 + * @description Entity kind the op operates on. Matches the application-level row (hackathon, bounty, grant, etc.). + * @example HACKATHON */ - category?: string; + entityKind: string; /** - * @description Details of the campaign - * @example Web3 Campaign + * @description Application-level row id this op acts on. + * @example cmpwihilf0000fd44iln3dzbg */ - details?: string; + entityId: string; /** - * @description Funding amount of the campaign - * @example 1000 + * @description Unsigned XDR transaction the wallet must sign. Present after the build phase completes (PENDING_SIGN onwards). + * @example AAAAAgAAAACdiamX7q...truncated... */ - fundingAmount?: number; + unsignedXdr?: string | null; /** - * @description Github URL of the campaign - * @example https://github.com/example/project + * @description Stellar G-address expected to sign this op. The wallet routing layer on the webapp uses this to pick the right signer. + * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ */ - githubUrl?: string; + signerHint?: string | null; /** - * @description Gitlab URL of the campaign - * @example https://gitlab.com/example/project + * @description Soroban tx hash assigned at submit time. Set once the op reaches PENDING_CONFIRM or beyond. + * @example daafec9027da007b54eec34c54a5919edd7a8682bc96ccf7c7072982305cfa3b */ - gitlabUrl?: string; + txHash?: string | null; /** - * @description Bitbucket URL of the campaign - * @example https://bitbucket.com/example/project + * @description Contract error code when the op transitions to FAILED. Mirrors the on-chain error name (e.g. "InsufficientEscrow", "OpAlreadySeen", "txBadAuth"). + * @example txBadAuth */ - bitbucketUrl?: string; + errorCode?: string | null; /** - * @description Project website of the campaign - * @example https://example.com/project + * Format: date-time + * @description Row creation time. + * @example 2026-06-02T11:45:36.927Z */ - projectWebsite?: string; + createdAt: string; /** - * @description Demo video of the campaign - * @example https://example.com/demo.mp4 + * Format: date-time + * @description Row last-updated time. + * @example 2026-06-02T11:45:44.310Z */ - demoVideo?: string; + updatedAt: string; + }; + CancelHackathonEscrowDto: { /** - * @description Milestones of the campaign - * @example [ - * { - * "name": "Milestone 1", - * "description": "Milestone 1 description", - * "startDate": "2025-01-01", - * "endDate": "2025-01-02", - * "amount": 1000 - * } - * ] + * @description Organizer's Stellar G-address. Must match the on-chain hackathon owner. + * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ */ - milestones?: string[]; + ownerAddress: string; /** - * @description Team of the campaign (optional; solo builders may omit) - * @example [ - * { - * "name": "John Doe", - * "role": "Developer", - * "email": "john.doe@example.com", - * "linkedin": "https://linkedin.com/in/john-doe", - * "twitter": "https://twitter.com/john-doe" - * } - * ] + * @description Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side with the caller's platform-held wallet. + * @default EXTERNAL + * @enum {string} */ - team?: string[]; + fundingMode: 'EXTERNAL' | 'MANAGED'; + /** @description For MANAGED, the organization treasury wallet to sign with (the event contract-auth identity). ownerAddress must match it. Omit to use the caller's personal managed wallet. */ + sourceWalletId?: string; + }; + HackathonWinnerSelectionDto: { /** - * @description Contact of the campaign - * @example { - * "primary": "john.doe", - * "backup": "john.doe@example.com" - * } + * @description ID of the winning submission. The payout recipient is resolved server-side = the submitter's (team leader's) Boundless managed wallet; no on-chain submission anchor is required. + * @example cmq7sgwst0001abcd1234efgh */ - contact?: components['schemas']['ContactDto']; + submissionId: string; /** - * @description Social links of the campaign (optional) - * @example [ - * { - * "platform": "twitter", - * "url": "https://twitter.com/john-doe" - * } - * ] + * @description Winner position, 1-indexed. Must exist in the hackathon's on-chain winner_distribution. + * @example 1 */ - socialLinks?: string[]; - }; - InviteTeamMemberDto: { + position: number; /** - * @description The email address of the team member to invite - * @example user@example.com + * @description Override the platform default credit_earn for this position. Defaults to 20/10/5 for positions 1/2/3 and 3 for the rest. Capped at 100 by the contract. + * @example 20 */ - email: string; + creditEarn?: number; /** - * @description The role of the team member in the campaign - * @example Developer + * @description Override the platform default reputation_bump for this position. Defaults to 50/25/10 for positions 1/2/3 and 5 for the rest. + * @example 50 */ - role: string; + reputationBump?: number; }; - ValidateMilestoneSubmissionDto: { + SelectHackathonWinnersDto: { /** - * @description Array of proof of work file URLs (documents, images, reports, etc.) - must be valid URLs with http, https, or ipfs protocol - * @example [ - * "https://example.com/report.pdf", - * "https://example.com/screenshot.png" - * ] + * @description Organizer's Stellar G-address — a hint only. select_winners is authorized by the event manager resolved on-chain (the org treasury for new events), which the backend signs with server-side; this value is used only as a fallback when that on-chain read is unavailable (legacy/pre-upgrade events). Omit for the MANAGED flow. + * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ */ - proofOfWorkFiles: string[]; + ownerAddress?: string; + /** @description Winners to declare, each by winning submissionId + position. The payout recipient is resolved server-side = the submitter's (team leader's) Boundless managed wallet; no on-chain submission anchor is required. Positions and submissionIds must be unique within the array. */ + selections: components['schemas']['HackathonWinnerSelectionDto'][]; /** - * @description Array of proof of work links (GitHub PRs, demos, deployed sites, etc.) - must be valid URLs - * @example [ - * "https://github.com/user/repo/pull/123", - * "https://demo.example.com" - * ] + * @description Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side. + * @default EXTERNAL + * @enum {string} */ - proofOfWorkLinks: string[]; + fundingMode: 'EXTERNAL' | 'MANAGED'; + /** @description For MANAGED, the organization treasury wallet to sign with (the event contract-auth identity). ownerAddress must match it. Omit to use the caller's personal managed wallet. */ + sourceWalletId?: string; + }; + HackathonSubmitSignedXdrDto: { /** - * @description Additional notes about the submission - optional but must be at least 10 characters if provided - * @example Successfully deployed the MVP with all core features implemented and tested. + * @description The fully-signed XDR returned by the wallet (Freighter, Albedo, platform-managed signer, or a multisig coordinator). Backend submits this verbatim to Soroban RPC. + * @example AAAAAgAAAACdiamX7q...truncated... */ - submissionNotes?: string; - }; - UpdateMilestoneDto: { - /** @description Array of proof of work file URLs (documents, images, etc.) */ - proofOfWorkFiles: string[]; - /** @description Array of proof of work links (GitHub PRs, demos, etc.) */ - proofOfWorkLinks: string[]; - /** @description Additional notes about the submission */ - submissionNotes?: string; + signedXdr: string; }; - PublishCrowdfundingEscrowDto: { + SubmitHackathonDto: { /** - * @description Stellar G-address that signs create_event. Strictly the builder's Boundless abstracted wallet (D9). MANAGED funding is the only path. + * @description Caller's Stellar G-address. Must match the caller's linked wallet. * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - builderAddress: string; + applicantAddress: string; /** - * @description Whitelisted SAC token contract (USDC by default). - * @example CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA + * @description Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet. + * @default EXTERNAL + * @enum {string} */ - tokenAddress: string; + fundingMode: 'EXTERNAL' | 'MANAGED'; /** - * @description Funding goal in token-native units (e.g. 5000 = 5000 USDC). Informational on chain; backers determine the actual raised total. - * @example 5000 + * @description On-chain content URI for the submission. Stored verbatim in the contract's submission anchor; off-chain content lives wherever the URI points (IPFS, S3, GitHub PR, etc.). + * @example ipfs://Qm.../project.json */ - fundingGoal: string; + contentUri: string; + }; + WithdrawHackathonSubmissionDto: { /** - * @description Number of milestones for ReleaseKind::Multi(n). - * @example 3 + * @description Caller's Stellar G-address. Must match the caller's linked wallet. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - nMilestones: number; + applicantAddress: string; /** - * @description Funding deadline as Unix seconds. - * @example 1735689600 + * @description Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet. + * @default EXTERNAL + * @enum {string} */ - fundingDeadline: number; - /** @description Override content URI. */ - contentUri?: string; - }; - CancelCrowdfundingEscrowDto: { - /** @description Builder G-address. */ - builderAddress: string; - }; - ClaimCrowdfundingMilestoneDto: { - /** @description Builder G-address (must match campaign). */ - builderAddress: string; - /** @description Crowdfunding milestone id. */ - crowdfundingMilestoneId: string; + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - ContributeCrowdfundingDto: { + ContributeHackathonDto: { /** - * @description G-address that signs add_funds. + * @description Caller's Stellar G-address. Must match the caller's linked wallet. * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - contributorAddress: string; + applicantAddress: string; /** - * @description Wallet origin: BOUNDLESS uses the managed signer; EXTERNAL returns an unsigned XDR for the connected wallet (D9). - * @example BOUNDLESS + * @description Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet. + * @default EXTERNAL * @enum {string} */ - walletOrigin: 'BOUNDLESS' | 'EXTERNAL'; + fundingMode: 'EXTERNAL' | 'MANAGED'; /** - * @description Amount in token-native units (10 USDC minimum). - * @example 25 + * @description Amount in token-native units (e.g. 30 = 30 USDC, NOT stroops). Must be >= 10 USDC (contract minimum). + * @example 30 */ amount: string; - /** @description Optional message attached. */ - message?: string; + }; + CreateOrganizationDto: Record; + OrganizationProfileStatsDto: { /** - * @description Hide displayName / usernameSnapshot if true. - * @default false + * @description Number of projects under this organization + * @example 12 */ - anonymous: boolean; - }; - CrowdfundingSubmitSignedXdrDto: { - /** @description Signed transaction XDR returned by the wallet. */ - signedXdr: string; - }; - CastCrowdfundingVoteDto: { + projectsCount: number; /** - * @description UP supports the campaign, DOWN opposes it. - * @example UP - * @enum {string} + * @description Total hackathons run by this organization + * @example 5 */ - choice: 'UP' | 'DOWN'; - }; - ApproveCrowdfundingCampaignDto: { + totalHackathons: number; /** - * @description The user delegated to validate this campaign's milestones. D6=A: exactly one reviewer per campaign, assigned at approval time. - * @example user_1234567890 + * @description Total bounties offered by this organization + * @example 8 */ - delegatedReviewerId: string; + totalBounties: number; /** - * @description Minimum total community votes required to resolve the vote (quorum). Defaults to 1 for now (target is 10 at launch). - * @example 10 + * @description Total grants (projects with grants) under this organization + * @example 3 */ - voteGoal?: number; - }; - RejectCrowdfundingCampaignDto: { - /** @description Reason for rejection; surfaced to the builder. */ - reason?: string; + totalGrants: number; }; - ExtendCrowdfundingFundingDto: { + OrganizationProfileDto: { /** - * @description New funding deadline (ISO 8601). Must be in the future. Enforced off-chain by the contribute gate. - * @example 2026-08-01T00:00:00.000Z + * @description Organization ID + * @example org_1234567890 */ - fundingEndDate: string; - }; - PauseCrowdfundingCampaignDto: { - /** @description Reason for the pause. */ - reason?: string; - }; - ApproveCrowdfundingMilestoneDto: Record; - RejectCrowdfundingMilestoneDto: { - /** @description Feedback shown to the builder. */ - rejectionFeedback: string; - /** @description Deadline by which the builder must resubmit (ISO 8601). */ - resubmissionDeadline?: string; - }; - ReclaimDormantDto: { + id: string; /** - * @description Minimum days a wallet must have been idle to be eligible. Default 90. - * @example 90 + * @description Organization name + * @example Tech Innovators */ - minIdleDays?: number; + name: string; /** - * @description Maximum number of wallets to reclaim in this call. Hard-capped at 100. - * @example 25 + * @description Organization slug + * @example tech-innovators */ - maxToProcess?: number; + slug: string; /** - * @description When true (default), report what would be reclaimed without submitting transactions. Set false to actually merge accounts. - * @example true + * @description Logo URL + * @example https://example.com/logo.png */ - dryRun?: boolean; + logoUrl: string; + /** + * @description Organization description (from about or tagline) + * @example We are a community of developers building the future. + */ + description: string; + /** @description Key stats for the organization profile */ + stats: components['schemas']['OrganizationProfileStatsDto']; }; - AddTrustlineDto: { + UpdateOrganizationDto: Record; + UpdateMemberRoleDto: Record; + InviteMemberDto: Record; + TreasuryWalletResponseDto: { + id: string; + organizationId: string; + /** @enum {string} */ + kind: 'MANAGED' | 'CONNECTED'; + publicKey: string; + label: string; + isDefault: boolean; + /** @enum {string} */ + status: 'ACTIVE' | 'ARCHIVED' | 'NEEDS_REVIEW'; + isMultisig: boolean; + multisigThreshold: number | null; + connectionMethod: string | null; + lastVerifiedAt: string | null; + createdAt: string; + updatedAt: string; + }; + CreateManagedWalletDto: { /** - * @description Asset code to add a trustline for (e.g. USDC, EURC) - * @example USDC + * @description Display label for the wallet + * @example Main treasury */ - assetCode: string; + label: string; }; - UserSendDto: { + RegisterConnectedWalletDto: { + /** @description G-address of the external wallet */ + publicKey: string; /** - * @description Stellar destination public key (G...) - * @example GABCD... + * @description Display label + * @example Company multisig */ - destinationPublicKey: string; + label: string; + /** @enum {string} */ + connectionMethod: + | 'freighter' + | 'lobstr' + | 'albedo' + | 'xbull' + | 'hana' + | 'rabet' + | 'walletkit_generic'; + }; + UpdateTreasuryWalletDto: { + /** @description New display label */ + label?: string; + /** @description Make this the organization default */ + isDefault?: boolean; + }; + WalletBalanceResponseDto: { + publicKey: string; + /** @description USDC balance */ + usdc: string; + /** @description XLM balance (fee float) */ + xlm: string; + }; + TreasuryPolicyRuleDto: { + /** @example 0 */ + min_usdc: number; + /** @example 1000 */ + max_usdc?: Record | null; + /** @example 1 */ + required_approvals: number; /** - * @description Amount to send (positive number) - * @example 100.5 + * @example [ + * "owner", + * "admin" + * ] */ - amount: number; + approver_roles: string[]; + }; + TreasuryPolicyResponseDto: { + organizationId: string; + defaultWalletId: string | null; + rules: components['schemas']['TreasuryPolicyRuleDto'][]; + /** @description True when no policy is saved yet (defaults returned) */ + isDefault: boolean; + updatedAt: string | null; + }; + UpdateTreasuryPolicyDto: { + rules: components['schemas']['TreasuryPolicyRuleDto'][]; + /** @description Default source wallet id */ + defaultWalletId?: string; + }; + InitiateSpendDto: { + /** @description Treasury wallet to spend from */ + sourceWalletId: string; + /** @description Destination G-address or escrow contract id */ + destination: string; /** - * @description Asset code (XLM, USDC, EURC, etc.) - * @example USDC + * @description Amount in USDC + * @example 2500.00 + */ + amount: string; + /** + * @description What the spend funds + * @example fund_hackathon_escrow */ + purpose: string; + /** @enum {string} */ + referenceType?: 'hackathon' | 'bounty' | 'grant'; + referenceId?: string; + }; + SpendRequestResponseDto: { + id: string; + organizationId: string; + sourceWalletId: string; + destination: string; + amount: string; currency: string; - /** @description Memo (required by some exchanges). Max 28 bytes UTF-8. */ - memo?: string; - /** @description If true, request fails when memo is missing (e.g. exchange requires it) */ - memoRequired?: boolean; - /** @description Idempotency key to prevent duplicate sends */ - idempotencyKey?: string; + purpose: string; + referenceType: string | null; + referenceId: string | null; + initiatorUserId: string; + requiredApprovals: number; + approvals: Record[]; + status: string; + onChainTxHash: string | null; + createdAt: string; + approvedAt: string | null; }; - SendPayoutDto: { + SendTreasuryFundsDto: { + /** @description Wallet to send from */ + sourceWalletId: string; /** - * @description Stellar destination public key (G...) - * @example GABCD... + * @description Recipient Stellar address (starts with G) + * @example GA... */ - destinationPublicKey: string; + destination: string; /** - * @description Amount to send (positive number) - * @example 100.5 + * @description Amount in USDC + * @example 250.00 */ - amount: number; + amount: string; /** - * @description Asset code (XLM, USDC, EURC, etc. – must be supported on network) - * @example USDC + * @description What this payment is for (shown in your activity log) + * @example Contributor payout */ + note?: string; + }; + SendDestinationReadinessDto: { + /** @description Whether the recipient account exists on-chain */ + exists: boolean; + /** @description Whether the recipient has a USDC trustline (so it can receive USDC) */ + hasUsdcTrustline: boolean; + }; + SpendDecisionDto: { + /** @description Optional note for the decision */ + note?: string; + }; + BuildSpendXdrResponseDto: { + /** @description Unsigned transaction XDR to sign in-browser */ + unsignedXdr: string; + request: components['schemas']['SpendRequestResponseDto']; + }; + SubmitSpendSignedXdrDto: { + /** @description The browser-signed transaction XDR */ + signedXdr: string; + }; + TreasuryActorDto: { + id: string; + name: string | null; + image: string | null; + }; + TreasuryAuditEntryDto: { + id: string; + action: string; + actorUserId: string | null; + actorKind: string; + /** @description Resolved profile of the actor (name + avatar), if a user. */ + actor: components['schemas']['TreasuryActorDto'] | null; + walletId: string | null; + spendRequestId: string | null; + details: { + [key: string]: unknown; + } | null; + createdAt: string; + }; + TreasuryAuditLogResponseDto: { + data: components['schemas']['TreasuryAuditEntryDto'][]; + total: number; + page: number; + limit: number; + }; + ReceiptResponseDto: { + id: string; + /** @example RCPT-100001 */ + receiptNumber: string; + organizationId: string; + /** @example TREASURY_SEND */ + type: string; + /** @example Funds sent */ + typeLabel: string; + /** @example ISSUED */ + status: string; + /** @example OUTGOING */ + direction: string; + /** @example 250.00 */ + amount: string; + /** @example USDC */ currency: string; - /** @description Memo (required by some exchanges). Max 28 bytes UTF-8. */ - memo?: string; - /** - * @description Memo type - * @enum {string} - */ - memoType?: 'text' | 'id'; - /** @description If true, request fails when memo is missing (e.g. exchange requires it) */ - memoRequired?: boolean; - /** @description Idempotency key to prevent duplicate payouts */ - idempotencyKey?: string; - /** @description Reference for audit (e.g. earnings-payout-123) */ - reference?: string; + fromLabel: Record | null; + fromAddress: Record | null; + toLabel: Record | null; + toAddress: Record | null; + description: Record | null; + onChainTxHash: Record | null; + explorerUrl: Record | null; + network: Record | null; + issuedByUserId: Record | null; + issuedAt: string; + voidedAt: Record | null; }; - CreateCommentDto: { - /** - * @description Comment content - * @example This is a great project! - */ - content: string; + ReceiptListResponseDto: { + data: components['schemas']['ReceiptResponseDto'][]; + total: number; + page: number; + limit: number; + }; + SendReceiptDto: { + /** @description Where to email the receipt. Defaults to your account email. */ + email?: string; + }; + VoidReceiptDto: { + /** @description Why the receipt is being voided */ + reason?: string; + }; + CreateVoteDto: { + /** @description ID of the project being voted on */ + projectId: string; /** - * @description Entity type for the comment - * @example PROJECT + * @description Type of entity being voted on * @enum {string} */ entityType: | 'PROJECT' - | 'BOUNTY' | 'CROWDFUNDING_CAMPAIGN' - | 'GRANT' - | 'GRANT_APPLICATION' - | 'HACKATHON' | 'HACKATHON_SUBMISSION' - | 'BLOG_POST'; - /** - * @description Entity ID for the comment - * @example cm12345abcde - */ - entityId: string; - /** - * @description Parent comment ID for threaded replies - * @example cm12345abcde - */ - parentId?: string; - }; - UpdateCommentDto: Record; - AddReactionDto: { + | 'GRANT'; /** - * @description Type of reaction - * @example LIKE + * @description Type of vote (UPVOTE or DOWNVOTE) + * @default UPVOTE * @enum {string} */ - reactionType: - | 'LIKE' - | 'DISLIKE' - | 'LOVE' - | 'LAUGH' - | 'THUMBS_UP' - | 'THUMBS_DOWN' - | 'FIRE' - | 'ROCKET'; - }; - ReportCommentDto: { + voteType: 'UPVOTE' | 'DOWNVOTE'; /** - * @description Reason for reporting the comment - * @example SPAM - * @enum {string} + * @description Weight of the vote + * @default 1 */ - reason: - | 'SPAM' - | 'HARASSMENT' - | 'HATE_SPEECH' - | 'INAPPROPRIATE_CONTENT' - | 'COPYRIGHT_VIOLATION' - | 'OTHER'; + weight: number; + }; + CreateBlogPostDto: { /** - * @description Additional details about the report - * @example This comment contains unsolicited advertising + * @description Blog post title + * @example Getting Started with Stellar Smart Contracts */ - description?: string; - }; - ResolveReportDto: { + title: string; /** - * @description Resolution status for the report - * @example RESOLVED - * @enum {string} + * @description Blog post content in markdown format + * @example # Introduction + * + * This tutorial will teach you... */ - status: 'PENDING' | 'REVIEWED' | 'RESOLVED' | 'DISMISSED'; + content: string; /** - * @description Moderator notes about the resolution - * @example Comment was reviewed and found to violate community guidelines + * @description Short excerpt or summary + * @example Learn how to build your first smart contract on Stellar */ - resolution?: string; - }; - HackathonsListResponseDto: Record; - FeeEstimateResponseDto: { + excerpt?: string; /** - * @description Total prize pool (USDC) - * @example 5000 + * @description Cover image URL + * @example https://res.cloudinary.com/demo/image/upload/v1234567890/post-cover.jpg */ - totalPool: number; + coverImage?: string; /** - * @description Fee rate as decimal - * @example 0.023 + * @description Post status + * @default DRAFT + * @example DRAFT + * @enum {string} */ - feeRate: number; + status: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED' | 'SCHEDULED'; /** - * @description Fee rate as percentage - * @example 2.3 + * @description Post tags + * @example [ + * "smart-contracts", + * "soroban", + * "tutorial" + * ] */ - feeRatePercent: number; + tags?: string[]; /** - * @description Fee amount (USDC) - * @example 115 + * @description Post categories + * @example [ + * "tutorials" + * ] */ - feeAmount: number; + categories?: string[]; /** - * @description Total to pay (prize pool + fee) - * @example 5115 + * @description Mark as featured post + * @default false + * @example false */ - totalFunds: number; + isFeatured: boolean; /** - * @description Display label for the fee - * @example Platform Fee (2.3%) + * @description Pin post to top + * @default false + * @example false */ - feeLabel: string; - }; - ParticipantDto: { - /** @description Username of the participant */ - username: string; - /** @description Avatar URL of the participant */ - avatar?: Record; - }; - HackathonWinnerDto: { - /** @description Rank of the winner (1, 2, 3, etc.) */ - rank: number; - /** @description Name of the project */ - projectName: string; - /** @description Name of the team */ - teamName?: Record; - /** @description Logo of the project */ - logo?: Record; - /** @description List of participants */ - participants: components['schemas']['ParticipantDto'][]; - /** @description Prize information */ - prize: string; - /** @description Submission ID */ - submissionId: string; - }; - HackathonWinnersResponseDto: { - /** @description Hackathon ID */ - hackathonId: string; - /** @description List of winners */ - winners: components['schemas']['HackathonWinnerDto'][]; - }; - PublicAggregatedJudgingResultDto: { - submissionId: string; - projectName: string; - teamId?: Record; - participantId: string; - status: string; - /** Format: date-time */ - submittedAt: string; - averageScore: number; - totalScore: number; - judgeCount: number; - expectedJudgeCount: number; - judgingProgress: string; - rank?: Record; - isComplete: boolean; - isPending: boolean; - hasDisagreement: boolean; - }; - JudgingResultsMetadataDto: { - sortedBy: string; - includesVariance: boolean; - includesIndividualScores: boolean; - includesProgressTracking: boolean; - onlyWinners?: boolean; - }; - PublicJudgingResultsResponseDto: { - hackathonId: string; - totalSubmissions: number; - submissionsScoredCount: number; - submissionsPendingCount: number; - averageScoreAcrossAll: number; - resultsPublished: boolean; - judgesAssigned: number; - results: components['schemas']['PublicAggregatedJudgingResultDto'][]; - /** Format: date-time */ - generatedAt: string; - /** @description Manual winner assignments override (submissionId -> rank) */ - winnerOverrides?: { - [key: string]: number; - }; - metadata: components['schemas']['JudgingResultsMetadataDto']; - }; - CreatorRelationDto: { - id: string; - name: string; - username?: string; - image?: string; - }; - OrganizationRelationDto: { - id: string; - name: string; - logo?: string; - slug?: string; - }; - HackathonResponseDto: { - createdBy: components['schemas']['CreatorRelationDto']; - organization?: components['schemas']['OrganizationRelationDto']; - }; - VerifyHackathonAccessDto: { - /** @description The access password for a private hackathon */ - password: string; - }; - HackathonAccessTokenResponseDto: { - accessToken: string; - }; - JoinHackathonDto: { + isPinned: boolean; /** - * @description Answers to REGISTRATION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). - * @example { - * "cq_role": "Backend developer" - * } + * @description Reading time in minutes (auto-calculated if not provided) + * @example 5 */ - customAnswers?: Record; - }; - ParticipationResponseDto: Record; - ParticipantResponseDto: Record; - HackathonParticipantsResponseDto: { - participants: components['schemas']['ParticipantResponseDto'][]; - }; - TeamMemberDto: { + readingTime?: number; + /** @description SEO title (overrides post title) */ + seoTitle?: string; + /** @description SEO meta description */ + seoDescription?: string; /** - * @description User ID of the team member - * @example user_1234567890 + * @description SEO keywords + * @example [ + * "stellar", + * "blockchain", + * "smart contracts" + * ] */ - userId: string; + seoKeywords?: string[]; /** - * @description Name of the team member - * @example John Doe + * @description Schedule publication date (for SCHEDULED status) + * @example 2025-12-31T10:00:00Z */ - name: string; + scheduledFor?: string; /** - * @description Username of the team member - * @example johndoe + * @description Generate AI content (excerpt, reading time, SEO, tags, category) if not provided + * @default false + * @example true */ - username?: string; + generateAI: boolean; + }; + UpdateBlogPostDto: Record; + MetricDataDto: { /** - * @description Role of the team member in the project - * @example Full Stack Developer + * @description The metric value + * @example 1250 */ - role: string; + value: number; /** - * @description Avatar URL of the team member - * @example https://example.com/avatar.png + * @description Percentage change + * @example 12.5 */ - avatar?: string; - }; - SubmissionLinkDto: { + change: number; /** - * @description Type of link. Each fixed type (github, demo, video, document, presentation) can be used at most once per submission. Use "other" for additional links, up to a maximum of 5. - * @example github + * @description Type of change + * @example positive * @enum {string} */ - type: 'github' | 'demo' | 'video' | 'document' | 'presentation' | 'other'; + changeType: 'positive' | 'negative' | 'neutral'; /** - * @description URL of the link - * @example https://github.com/username/project + * @description Metric label + * @example Total Users */ - url: string; + label: string; /** - * @description Optional description of the link - * @example Main repository with source code + * @description Additional description + * @example Active users in the platform */ description?: string; }; - SocialLinksDto: { - /** - * @description GitHub profile or repository - * @example https://github.com/username - */ - github?: string; - /** - * @description Telegram username or group - * @example https://t.me/username - */ - telegram?: string; - /** - * @description Twitter/X handle - * @example https://twitter.com/username - */ - twitter?: string; + HackathonMetricDataDto: { /** - * @description Email address - * @example contact@example.com + * @description The metric value + * @example 1250 */ - email?: string; - }; - SubmissionResponseDto: { - id: string; - hackathonId: string; - projectId: string; - participantId: string; - organizationId: string; - /** @enum {string} */ - participationType: 'INDIVIDUAL' | 'TEAM'; - teamId?: string; - teamName?: string; - teamMembers?: components['schemas']['TeamMemberDto'][]; - projectName: string; - category: string; - description: string; - logo?: string; - banner?: string; - videoUrl?: string; - introduction?: string; - links: components['schemas']['SubmissionLinkDto'][]; - socialLinks?: components['schemas']['SocialLinksDto']; - status: string; - rank?: number; - /** @description Track entries this submission has opted into. Each entry carries the track slug/name and a wonRank stamped when the submission won that track (null until results are published). */ - trackEntries?: unknown[][]; - tagline?: string; - builtWith?: string[]; - screenshots?: string[]; - license?: string; - /** Format: date-time */ - codeAttestedAt?: string; - /** Format: date-time */ - registeredAt: string; - /** Format: date-time */ - submittedAt?: string; - /** Format: date-time */ - createdAt: string; - /** Format: date-time */ - updatedAt: string; - }; - CreateSubmissionDto: { + value: number; /** - * @description Organization ID - * @example org_1234567890 + * @description Percentage change + * @example 12.5 */ - organizationId: string; + change: number; /** - * @description Project ID (must be owned by the user or organization). If not provided, a base project will be created automatically. - * @example proj_1234567890 + * @description Type of change + * @example positive + * @enum {string} */ - projectId?: string; + changeType: 'positive' | 'negative' | 'neutral'; /** - * @description Type of participation - * @example INDIVIDUAL - * @enum {string} + * @description Metric label + * @example Total Users */ - participationType: 'INDIVIDUAL' | 'TEAM'; + label: string; /** - * @deprecated - * @description [Ignored by backend.] Team ID is snapshotted from the user's authoritative team record at submission time. Field accepted for backwards compatibility only. - * @example team_1234567890 + * @description Additional description + * @example Active users in the platform */ - teamId?: string; + description?: string; /** - * @deprecated - * @description [Ignored by backend.] Team name is snapshotted from the user's authoritative team record at submission time. - * @example Awesome Hackers + * @description Additional hackathon info + * @example 3 active, 7 upcoming */ - teamName?: string; + additionalInfo?: string; + }; + OverviewMetricsDto: { + totalUsers: components['schemas']['MetricDataDto']; + organizations: components['schemas']['MetricDataDto']; + projects: components['schemas']['MetricDataDto']; + hackathons: components['schemas']['HackathonMetricDataDto']; + }; + OverviewChartDataDto: { + data: components['schemas']['ChartDataPointDto'][]; /** - * @deprecated - * @description [Ignored by backend.] Team members are snapshotted from the user's authoritative team record at submission time. Sending this field has no effect. + * @description Time range for the chart + * @example 7d + * @enum {string} */ - teamMembers?: components['schemas']['TeamMemberDto'][]; + timeRange: '7d' | '30d' | '90d'; + }; + AdminOverviewResponseDto: { + metrics: components['schemas']['OverviewMetricsDto']; + chart: components['schemas']['OverviewChartDataDto']; /** - * @description Project name for the submission - * @example DeFi Lending Platform + * @description Last updated timestamp + * @example 2025-12-26T10:30:00Z */ - projectName: string; + lastUpdated: string; + }; + AdminCrowdfundingRejectDto: { /** - * @description Category of the project - * @example DeFi + * @description Reason for rejection + * @example Campaign does not meet requirements */ - category: string; + reason?: string; + }; + AdminCrowdfundingRequestRevisionDto: { /** - * @description Detailed description of the project - * @example A decentralized lending platform built on Stellar... + * @description Message for the creator explaining requested revisions + * @example Please update the project description to be more detailed */ - description: string; + message: string; /** - * @description Project logo URL - * @example https://example.com/logo.png + * @description Optional structured reasons + * @example [ + * "incomplete_description", + * "missing_team_info" + * ] */ - logo?: string; + reasons?: string[]; + }; + AdminCrowdfundingNoteDto: { /** - * @description Project banner image URL (wide hero image) - * @example https://example.com/banner.png + * @description Short admin note or comment + * @example Reviewed initial submission */ - banner?: string; + note: string; + }; + AdminCrowdfundingAssignDto: { /** - * @description Video demonstration URL - * @example https://youtube.com/watch?v=xyz + * @description Reviewer (user) id to assign + * @example 550e8400-e29b-41d4-a716-446655440000 */ - videoUrl?: string; + reviewerId: string; + }; + ApproveMilestoneDto: { /** - * @description Brief introduction to the project - * @example We built a platform that allows users to... + * @description Optional approval notes + * @example Milestone completed successfully */ - introduction?: string; - /** @description Links to project resources. Each fixed link type (github, demo, video, document, presentation) can appear at most once. Use "other" for additional links, up to a maximum of 5. */ - links: components['schemas']['SubmissionLinkDto'][]; - /** @description Social links for the project */ - socialLinks?: components['schemas']['SocialLinksDto']; + notes?: string; + }; + RejectMilestoneDto: { + /** @description Feedback shown to the builder; what needs to change. */ + rejectionFeedback: string; + /** @description Optional ISO date by which the builder must resubmit. */ + resubmissionDeadline?: string; + }; + RequestMilestoneResubmissionDto: { /** - * @description Optional list of track ids to enter. Only allowed when the hackathon has prizeStructure != OVERALL_ONLY. Capped at Hackathon.tracksMaxPerSubmission. - * @example [ - * "trk_abc", - * "trk_def" - * ] + * @description Feedback explaining what needs to change + * @example Please improve the documentation and add more test cases */ - trackIds?: string[]; + feedback: string; /** - * @description Per-track answers. Keyed by trackId; each value is { promptAnswer?, customAnswers?, artifacts? }. Phase B. - * @example { - * "trk_abc": { - * "promptAnswer": "We focused on a one-tap escrow flow.", - * "customAnswers": { - * "q_audience": "Freelancers" - * }, - * "artifacts": { - * "figma": "https://figma.com/file/..." - * } - * } - * } + * @description Deadline for resubmission + * @example 2025-02-15 */ - trackAnswers?: Record; + resubmissionDeadline: string; + }; + AddMilestoneReviewNoteDto: { /** - * @description Answers to hackathon-level SUBMISSION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). Validated against the question set. - * @example { - * "cq_audience": "Freelancers", - * "cq_stack": [ - * "Web", - * "AI" - * ] - * } + * @description Review note content + * @example Reviewed the code quality and found it satisfactory */ - customAnswers?: Record; + note: string; + }; + ManualEscrowActionDto: { /** - * @description Short elevator pitch shown on cards / sidebars / judge queue. Max ~160 chars. - * @example Milestone-based escrow for one-time freelance gigs on Stellar. + * @description Type of escrow action to execute + * @example RELEASE + * @enum {string} */ - tagline?: string; + action: 'RELEASE' | 'REFUND' | 'PAUSE' | 'RESUME'; /** - * @description Free-form tech-stack tags. Max 20 entries, 40 chars each. - * @example [ - * "Soroban", - * "Stellar SDK", - * "Next.js", - * "Rust" - * ] + * @description Amount to transfer (for RELEASE/REFUND) + * @example 1000 */ - builtWith?: string[]; - /** @description Up to 5 screenshot URLs for the project gallery. */ - screenshots?: string[]; + amount?: number; /** - * @description License the submission ships under. - * @enum {string} + * @description Optional notes for this action + * @example Releasing funds for completed milestone */ - license?: - | 'MIT' - | 'Apache-2.0' - | 'GPL-3.0' - | 'BSD-3' - | 'PROPRIETARY' - | 'OTHER'; - /** @description Submitter attests the code is original or properly attributed. Required to mark a submission SUBMITTED (vs DRAFT). */ - codeAttested?: boolean; - }; - UpdateSubmissionDto: { + notes?: string; /** - * @description Project name for the submission - * @example DeFi Lending Platform + * @description Recipient address (for RELEASE/REFUND) + * @example GAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ - projectName?: string; + recipientAddress?: string; + }; + AssignDisputeDto: { + /** @description staff_users id to assign the dispute to, or null to unassign. */ + assignedToStaffId: string | null; + }; + AddDisputeNoteDto: { /** - * @description Category of the project - * @example DeFi + * @description Message content + * @example Contacted the project creator for more information */ - category?: string; + message: string; /** - * @description Detailed description of the project - * @example A decentralized lending platform built on Stellar... + * @description Whether this is an internal note (not visible to parties) + * @example false */ - description?: string; + isInternal?: boolean; + }; + ResolveDisputeDto: { /** - * @description Project logo URL - * @example https://example.com/logo.png + * @description Resolution outcome recorded on the dispute. + * @enum {string} */ - logo?: string; + resolution: + | 'APPROVED_WITH_CONDITIONS' + | 'REQUIRE_RESUBMISSION' + | 'PARTIAL_REFUND' + | 'FULL_REFUND' + | 'DISMISSED' + | 'ARBITRATION'; + /** @description Resolution notes shown to the reporter and campaign creator. */ + resolutionNotes: string; + }; + EscalateDisputeDto: { + /** @description Why this dispute is being escalated to arbitration. Recorded in the audit log. */ + reason: string; + }; + RejectManualProjectDto: Record; + RequestManualProjectChangesDto: Record; + RejectProjectEditDto: Record; + AdminWalletStatsDto: { + totalWallets: components['schemas']['MetricDataDto']; + activatedWallets: components['schemas']['MetricDataDto']; + inactiveWallets: components['schemas']['MetricDataDto']; + }; + AdminWalletUserDto: { + id: string; + name: string; + email: string; + username?: string; + image?: string; + }; + AdminWalletListItemDto: { + id: string; + publicKey: string; + isActivated: boolean; + /** Format: date-time */ + createdAt: string; + users: components['schemas']['AdminWalletUserDto'][]; + }; + AdminWalletListResponseDto: { + wallets: components['schemas']['AdminWalletListItemDto'][]; + total: number; + page: number; + limit: number; + totalPages: number; + }; + AdminWalletBalanceDto: { + balance: string; + assetCode: string; + assetIssuer?: string; + assetType: string; + }; + AdminWalletDetailsDto: { + id: string; + publicKey: string; + isActivated: boolean; + /** Format: date-time */ + createdAt: string; + balances: components['schemas']['AdminWalletBalanceDto'][]; + users: components['schemas']['AdminWalletUserDto'][]; + }; + ReviewWindowDto: { + /** @example 1 */ + minBusinessDays: number; + /** @example 3 */ + maxBusinessDays: number; + /** @description ISO timestamp by which the review is expected to complete. */ + estimatedCompletionAt: string; + }; + DeclineDetailsDto: { + /** @description Human-readable reason from Didit, if available. */ + reason?: string; /** - * @description Project banner image URL (wide hero image) - * @example https://example.com/banner.png + * @description Whether the user is allowed to start a new verification. + * @example true */ - banner?: string; + canRetry: boolean; + }; + VerificationStatusDto: { /** - * @description Video demonstration URL - * @example https://youtube.com/watch?v=xyz + * @description Normalized verification state. Frontend should hide the verify button unless this is one of: not_started, declined, abandoned, expired. + * @enum {string} */ - videoUrl?: string; + state: + | 'not_started' + | 'in_progress' + | 'in_review' + | 'approved' + | 'declined' + | 'abandoned' + | 'expired'; + /** @description Whether the user can start a new verification session. */ + canStartNew: boolean; + /** @description Polite, render-ready copy summarising the current state. */ + message: string; + /** @description ISO timestamp when the user became verified. */ + verifiedAt?: string; + /** @description ISO timestamp of the last status transition. */ + reviewedAt?: string; + /** @description Estimated review window. Present only when state === "in_review". */ + reviewWindow?: components['schemas']['ReviewWindowDto']; + /** @description Decline details. Present only when state === "declined". */ + decline?: components['schemas']['DeclineDetailsDto']; + }; + PricingPreviewResponseDto: { + /** @description Effective rate applied to this preview. */ + feeBps: number; + /** @description Fee in stroops. String to preserve i128 precision. */ + feeStroops: string; + /** @description Pool released to winners; equals the requested budget. */ + poolStroops: string; + /** @description budgetStroops + feeStroops; what the organizer signs for. */ + totalDepositStroops: string; + /** @description Audit label for the rate choice: default | foundation-tier | sales-override:* | waiver:*. */ + reason: string; + }; + StaffPrincipalDto: { + id: string; + email: string; + name: string; + role: string; + /** @description Whether an authenticator (TOTP) is activated */ + totpEnabled: boolean; + /** @description ISO timestamp of the last successful step-up */ + lastStepUpAt: string | null; + }; + MeResponseDto: { + staff: components['schemas']['StaffPrincipalDto']; + }; + AnalyticsTotalsDto: { + users: number; + organizations: number; + /** @description All pillars combined */ + programs: number; + disputes: number; + wallets: number; + }; + ProgramsByPillarDto: { + hackathons: number; + bounties: number; + grants: number; + crowdfunding: number; + }; + AnalyticsBucketDto: { + label: string; + count: number; + }; + AnalyticsTrendPointDto: { + /** @description UTC day, YYYY-MM-DD */ + date: string; + count: number; + }; + AnalyticsDto: { + totals: components['schemas']['AnalyticsTotalsDto']; + /** @description New users in the last 30 days */ + newUsers30d: number; + programsByPillar: components['schemas']['ProgramsByPillarDto']; + disputesByStatus: components['schemas']['AnalyticsBucketDto'][]; + crowdfundingByStatus: components['schemas']['AnalyticsBucketDto'][]; + /** @description New users per day, last 14 days */ + newUsersTrend: components['schemas']['AnalyticsTrendPointDto'][]; + }; + OverviewDto: { + users: number; + organizations: number; + hackathons: number; + crowdfundingCampaigns: number; + /** @description Disputes in OPEN status */ + openDisputes: number; + }; + AdminUserListItemDto: { + id: string; + name: string; + email: string; + /** @description Profile photo URL, when set */ + image: string | null; + username: string | null; + role: string | null; + /** @enum {string} */ + status: 'active' | 'banned'; + /** @description ISO timestamp the user joined */ + joined: string; + }; + PaginatedUsersDto: { + items: components['schemas']['AdminUserListItemDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; + }; + AdminUserDetailDto: { + id: string; + name: string; + email: string; + /** @description Profile photo URL, when set */ + image: string | null; + username: string | null; + role: string | null; + /** @enum {string} */ + status: 'active' | 'banned'; + /** @description Reason, when banned */ + banReason: string | null; + /** @description Identity (KYC) verification status, when known */ + verification: string | null; + /** @description Public key of the user's abstracted wallet, when one exists */ + walletAddress: string | null; + /** @description Number of organizations the user belongs to */ + organizations: number; + /** @description ISO timestamp the user joined */ + joined: string; + }; + AdminUserOrganizationDto: { + id: string; + name: string; + slug: string | null; + /** @description The user's role in this organization */ + role: string; + /** @description ISO timestamp the user joined the organization */ + joinedAt: string; + }; + AdminUserWalletBalanceDto: { + /** @description On-chain balance, as a decimal string */ + balance: string; + /** @description Asset code, e.g. XLM or USDC */ + assetCode: string; + /** @description Asset issuer (null for native XLM) */ + assetIssuer: string | null; + /** @description Stellar asset type, e.g. native or credit_alphanum4 */ + assetType: string; + /** @description Estimated USD value, when priced */ + usdValue: number | null; + }; + AdminUserWalletDto: { + /** @description Whether the user has an abstracted wallet */ + hasWallet: boolean; + /** @description Stellar public key (G-address) */ + address: string | null; + /** @description Whether the on-chain account is activated */ + isActivated: boolean; + /** @description ISO timestamp the wallet was created */ + createdAt: string | null; + /** @description Live on-chain balances. Empty when the account is unfunded or Horizon is unreachable. */ + balances: components['schemas']['AdminUserWalletBalanceDto'][]; + }; + BanUserDto: { + /** @description true to ban, false to lift the ban */ + banned: boolean; + /** @description Reason for the ban (recorded in the audit log) */ + reason?: string; + }; + BanUserResponseDto: { + id: string; + banned: boolean; + }; + AdminOrgListItemDto: { + id: string; + name: string; + slug: string | null; + /** @description Member count */ + members: number; + /** @description Programs run by the org (hackathons + bounties) */ + programs: number; + /** @description ISO timestamp the org was suspended, or null if active */ + suspendedAt: string | null; + /** @description ISO timestamp the org was created */ + created: string; + }; + PaginatedOrganizationsDto: { + items: components['schemas']['AdminOrgListItemDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; + }; + AdminOrgDetailDto: { + id: string; + name: string; + slug: string | null; + /** @description Member count */ + members: number; + /** @description Hackathons run by the org */ + hackathons: number; + /** @description Bounties run by the org */ + bounties: number; + /** @description ISO timestamp the org was suspended, or null if active */ + suspendedAt: string | null; + suspendedByEmail: string | null; + suspensionReason: string | null; + /** @description ISO timestamp the org was created */ + created: string; + }; + UpdateOrgDto: { + name?: string; + /** @description URL slug (lowercase letters, numbers, hyphens) */ + slug?: string; + /** @description Logo URL */ + logo?: string; + /** @description Whether org announcements are enabled */ + announcementsEnabled?: boolean; + }; + OrgActionResponseDto: { + id: string; + name: string; + slug: string | null; + announcementsEnabled: boolean; + }; + SuspendOrgDto: { + /** @description Why the organization is being suspended (shown in audit log) */ + reason: string; + }; + OrgSuspensionResponseDto: { + id: string; + name: string; + slug: string | null; + /** @description ISO timestamp the org was suspended, or null if active */ + suspendedAt: string | null; + suspensionReason: string | null; + }; + ReinstateOrgDto: { + /** @description Optional note recorded with the reinstatement */ + note?: string; + }; + AdminProgramListItemDto: { + id: string; + /** @enum {string} */ + type: 'hackathon' | 'bounty' | 'grant' | 'crowdfunding'; + title: string; + /** @description Pillar-specific lifecycle status */ + status: string; + /** @description Owning organization name, when the pillar has one */ + organization: string | null; + /** @description Marketplace featured boost (always false for pillars without it) */ + isFeatured: boolean; + /** @description ISO timestamp the program was created */ + created: string; + }; + PaginatedProgramsDto: { + items: components['schemas']['AdminProgramListItemDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; + }; + AdminProgramDetailDto: { + id: string; + /** @enum {string} */ + type: 'hackathon' | 'bounty' | 'grant' | 'crowdfunding'; + title: string; + status: string; + organization: string | null; + description: string | null; + /** @description ISO timestamp the program was created */ + created: string; + }; + SetFeaturedDto: { /** - * @description Brief introduction to the project - * @example We built a platform that allows users to... + * @description Which pillar the id is in. + * @enum {string} */ - introduction?: string; - /** @description Links to project resources. Each fixed link type (github, demo, video, document, presentation) can appear at most once. Use "other" for additional links, up to a maximum of 5. */ - links?: components['schemas']['SubmissionLinkDto'][]; - /** @description Social links for the project */ - socialLinks?: components['schemas']['SocialLinksDto']; - /** @description Team members (for team submissions) */ - teamMembers?: components['schemas']['TeamMemberDto'][]; - /** @description Replace the submission's track picks. Omit to leave existing entries untouched; pass an empty array to clear all picks. */ - trackIds?: string[]; - /** @description Per-track answers, same shape as on create. Phase B. */ - trackAnswers?: Record; + type: 'hackathon' | 'bounty' | 'grant' | 'crowdfunding'; + /** @description Feature (true) or unfeature (false) the program. */ + featured: boolean; + }; + ProgramActionResponseDto: { + id: string; + /** @enum {string} */ + type: 'hackathon' | 'bounty' | 'grant' | 'crowdfunding'; + /** @description Status after the action */ + status: string; + /** @description Whether the program is featured (false if unsupported) */ + isFeatured: boolean; + }; + SetProgramStatusDto: { /** - * @description Answers to hackathon-level SUBMISSION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). Replaces the stored answers when provided. - * @example { - * "cq_audience": "Freelancers", - * "cq_stack": [ - * "Web", - * "AI" - * ] - * } + * @description Which pillar the id is in. + * @enum {string} */ - customAnswers?: Record; - tagline?: string; - builtWith?: string[]; - screenshots?: string[]; + type: 'hackathon' | 'bounty' | 'grant' | 'crowdfunding'; + /** @description Target lifecycle status. Must be one of the admin-settable states for the pillar (archive/suspend/cancel-type). */ + status: string; + }; + AdminDisputeListItemDto: { + id: string; + /** @description Title of the campaign the dispute is against */ + campaign: string | null; + /** @description Reported reason */ + reason: string; + /** @description Dispute lifecycle status */ + status: string; + /** @description Reporter name */ + reportedBy: string | null; + /** @description Assigned staff name, when assigned */ + assignedTo: string | null; + /** @description ISO timestamp the dispute was opened */ + created: string; + }; + PaginatedDisputesDto: { + items: components['schemas']['AdminDisputeListItemDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; + }; + AdminDisputeDetailDto: { + id: string; + campaign: string | null; + reason: string; + status: string; + description: string; + /** @description Title of the disputed milestone, if the dispute names one */ + milestone: string | null; + /** @description Evidence links the reporter provided */ + evidenceLinks: string[]; + /** @description Evidence file references the reporter provided */ + evidenceFiles: string[]; + reportedBy: string | null; + /** @description Assigned staff email, when assigned */ + assignedTo: string | null; + /** @description Assigned staff id (for pre-selecting the assignee) */ + assignedToStaffId: string | null; + /** @description Resolution outcome */ + resolution: string | null; + resolutionNotes: string | null; + /** @description ISO timestamp the dispute was opened */ + created: string; + }; + DisputeAssignmentResponseDto: { + id: string; + /** @description Assigned staff email, or null when unassigned */ + assignedTo: string | null; + assignedAt: string | null; + }; + NoteDisputeDto: { + /** @description Internal note recorded on the dispute audit trail. */ + note: string; + }; + DisputeNoteResponseDto: { + id: string; + note: string; + /** @description ISO timestamp the note was recorded */ + createdAt: string; + }; + DisputeActionResponseDto: { + id: string; + /** @description New dispute lifecycle status */ + status: string; + /** @description Resolution outcome, when resolved */ + resolution: string | null; + /** @description Whether the dispute is escalated to arbitration */ + escalatedToArbitration: boolean; + }; + AdminMoneyEntryDto: { + id: string; + /** @enum {string} */ + kind: 'escrow' | 'payout'; + /** @description On-chain reference: tx hash or destination key */ + reference: string; + /** @description What the movement is (tx type, or "Payout") */ + label: string; + /** @description Amount, as a precise string */ + amount: string; + /** @description Currency, if known */ + currency: string | null; + /** @description Settlement status */ + status: string; + /** @description ISO timestamp the movement was created */ + created: string; + }; + PaginatedMoneyDto: { + items: components['schemas']['AdminMoneyEntryDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; + }; + EscrowRequestDto: { + id: string; + /** @enum {string} */ + kind: 'release' | 'refund'; + campaignId: string; + milestoneId: string | null; + /** @description Amount as a string (decimal-safe) */ + amount: string; + currency: string; + toAddress: string | null; + reason: string | null; + /** @description PROPOSED | APPROVED | REJECTED | EXECUTED */ + status: string; + /** @description Maker email */ + proposedBy: string; + /** @description Checker email */ + decidedBy: string | null; + decidedAt: string | null; + decisionNote: string | null; + /** @description Settled tx hash */ + txHash: string | null; + executedBy: string | null; + executedAt: string | null; + created: string; + }; + EscrowRequestListResponseDto: { + items: components['schemas']['EscrowRequestDto'][]; + }; + ProposeEscrowRequestDto: { + /** @enum {string} */ + kind: 'release' | 'refund'; + /** @description Campaign whose escrow is being acted on */ + campaignId: string; + /** @description Milestone id, for a milestone release */ + milestoneId?: string; + /** @description Amount to move */ + amount: number; + /** @default USDC */ + currency: string; + /** @description Destination address (for a release) */ + toAddress?: string; + /** @description Why the funds are being moved */ + reason?: string; + }; + DecideEscrowRequestDto: { + /** @enum {string} */ + decision: 'approve' | 'reject'; + /** @description Note recorded with the decision */ + note?: string; + }; + ExecuteEscrowRequestDto: { + /** @description Hash of the settled, offline-signed release/refund tx */ + txHash: string; + }; + PayoutRequestDto: { + id: string; + destinationPublicKey: string; + /** @description Amount as a string (decimal-safe) */ + amount: string; + currency: string; + memo: string | null; + memoType: string | null; + reason: string | null; + /** @description PROPOSED | APPROVED | AWAITING_SIGNATURE | REJECTED | EXECUTED */ + status: string; + /** @description Platform source address the payout is sent from */ + sourcePublicKey: string | null; + /** @description Unsigned XDR awaiting an offline signature (when AWAITING_SIGNATURE) */ + unsignedXdr: string | null; + /** @description Maker email */ + proposedBy: string; + /** @description Checker email */ + decidedBy: string | null; + decidedAt: string | null; + decisionNote: string | null; + /** @description Settled tx hash */ + txHash: string | null; + executedBy: string | null; + executedAt: string | null; + created: string; + }; + PayoutRequestListResponseDto: { + items: components['schemas']['PayoutRequestDto'][]; + }; + ProposePayoutRequestDto: { + /** @description Stellar destination address (G…) */ + destinationPublicKey: string; + /** @description Platform Stellar source address (G…) the payout is sent FROM. Defaults to the configured platform payout wallet (PLATFORM_ADDRESS). */ + sourcePublicKey?: string; + /** @description Amount to send */ + amount: number; + /** @default USDC */ + currency: string; + /** @description Optional memo (required by some exchanges) */ + memo?: string; /** @enum {string} */ - license?: - | 'MIT' - | 'Apache-2.0' - | 'GPL-3.0' - | 'BSD-3' - | 'PROPRIETARY' - | 'OTHER'; - codeAttested?: boolean; + memoType?: 'text' | 'id'; + /** @description Why the payout is being sent */ + reason?: string; }; - TeamMemberResponseDto: { - /** @description User ID */ - userId: string; - /** @description Username */ - username: string; - /** @description Display name */ - name: string; - /** @description Role in team (e.g. leader, member) */ - role: string; - /** @description Profile image URL */ - image?: string; - /** @description When the member joined the team (ISO string) */ - joinedAt: string; + DecidePayoutRequestDto: { + /** @enum {string} */ + decision: 'approve' | 'reject'; + /** @description Note recorded with the decision */ + note?: string; }; - LookingForRoleDto: { - /** - * @description Role title (e.g. "Frontend Developer", "UI Designer") - * @example Frontend Developer - */ - role: string; + BuildXdrResponseDto: { + /** @description Unsigned transaction XDR to sign offline (Stellar Lab / hardware / multisig). */ + unsignedXdr: string; /** - * @description Optional free-form skills associated with this role - * @example [ - * "React", - * "TypeScript" - * ] + * @description Network the transaction targets. + * @enum {string} */ - skills?: unknown[][]; + network: 'public' | 'testnet'; + /** @description Network passphrase to select when signing. */ + passphrase: string; + /** @description Source G-address that must sign this transaction. */ + source: string; + /** @description Deep-link to the Stellar Lab Sign Transaction page. Paste the copied XDR there. */ + labUrl: string; }; - TeamRoleResponseDto: { - /** @description Skill/role name */ - skill: string; - /** @description Whether this role has been filled */ - hired: boolean; + SubmitPayoutSignedXdrDto: { + /** @description Fully-signed payout XDR returned by the wallet / multisig coordinator. Verified against the built unsigned XDR before broadcast. */ + signedXdr: string; }; - TeamResponseDto: { - /** - * @description Team ID - * @example team_1234567890 - */ + ExecutePayoutRequestDto: { + /** @description Hash of the settled, offline-signed payout tx */ + txHash: string; + }; + AdminContentListItemDto: { id: string; - /** - * @description Team name - * @example Stellar Innovators - */ - teamName: string; - /** @description Team description */ - description: string; - /** @description Hackathon ID */ - hackathonId: string; - /** @description Team leader information */ - leader: Record; - /** @description Team members */ - members: components['schemas']['TeamMemberResponseDto'][]; - /** - * @description Current number of members - * @example 3 - */ - memberCount: number; - /** - * @description Maximum team size allowed - * @example 5 - */ - maxSize: number; - /** @description Roles the team is looking for, with optional free-form skills */ - lookingFor?: components['schemas']['LookingForRoleDto'][]; - /** @description Hired status per role (when using lookingFor) */ - rolesStatus?: components['schemas']['TeamRoleResponseDto'][]; - /** @description Contact information (e.g. telegram, discord, email) */ - contactInfo?: Record; - /** - * @description Whether team is accepting new members - * @example true - */ - isOpen: boolean; - /** @description Team creation date */ - createdAt: string; - /** @description Last update date */ - updatedAt: string; + title: string; + slug: string; + /** @description Publishing status */ + status: string; + /** @description Author name */ + author: string; + /** @description View count */ + views: number; + /** @description Whether the post is archived (soft-deleted) */ + archived: boolean; + /** @description ISO timestamp the post was created */ + created: string; + }; + PaginatedContentDto: { + items: components['schemas']['AdminContentListItemDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; }; - TeamListResponseDto: { - /** @description List of teams */ - teams: components['schemas']['TeamResponseDto'][]; - /** @description Pagination metadata */ - pagination: Record; + AdminContentDetailDto: { + id: string; + title: string; + slug: string; + /** @description Post body in MDX (markdown + JSX) */ + content: string; + excerpt: string | null; + coverImage: string | null; + /** @description Publishing status */ + status: string; + categories: string[]; + /** @description Tag names */ + tags: string[]; + isFeatured: boolean; + isPinned: boolean; + seoTitle: string | null; + seoDescription: string | null; + seoKeywords: string[]; + /** @description ISO timestamp for a scheduled publish */ + scheduledFor: string | null; + /** @description Whether the post is archived (soft-deleted) */ + archived: boolean; + created: string; + updated: string; + }; + ContentMutationResponseDto: { + id: string; + /** @description Generated (or existing) URL slug */ + slug: string; + /** @description Publishing status */ + status: string; }; - CreateTeamDto: { - /** - * @description Team name - * @example Stellar Innovators - */ - teamName: string; + UpdateContentDto: { /** - * @description Team description - * @example We are building the next generation DeFi platform + * @description Blog post title + * @example Getting Started with Stellar Smart Contracts */ - description: string; - /** @description Roles the team is looking for. Each entry is a role title with optional free-form skills. Team will be CLOSED unless at least one role is specified. The number of roles is bounded by the hackathon's teamMin/teamMax (excluding the leader). */ - lookingFor?: components['schemas']['LookingForRoleDto'][]; + title?: string; /** - * @description Contact information for interested members - * @example { - * "telegram": "@teamlead", - * "discord": "lead#1234" - * } + * @description Blog post content in markdown format + * @example # Introduction + * + * This tutorial will teach you... */ - contactInfo?: Record; - }; - UpdateTeamDto: { + content?: string; /** - * @description Updated team name - * @example Stellar Innovators Pro + * @description Short excerpt or summary + * @example Learn how to build your first smart contract on Stellar */ - teamName?: string; - /** @description Updated team description */ - description?: string; - /** @description Roles the team is looking for. Set to empty array to close the team. Each entry is a role title with optional free-form skills. */ - lookingFor?: components['schemas']['LookingForRoleDto'][]; - /** @description Updated contact information */ - contactInfo?: Record; - /** @description Explicitly set team open/closed status. Can only be true if lookingFor is not empty. */ - isOpen?: boolean; - }; - InviteToTeamDto: { + excerpt?: string; /** - * @description User ID or username of the person to invite - * @example user_1234567890 + * @description Cover image URL + * @example https://res.cloudinary.com/demo/image/upload/v1234567890/post-cover.jpg */ - inviteeIdentifier: string; + coverImage?: string; /** - * @description Optional message to include with the invitation - * @example We would love to have you on our team! + * @description Post status + * @default DRAFT + * @example DRAFT + * @enum {string} */ - message?: string; - }; - TeamInvitationResponseDto: { + status: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED' | 'SCHEDULED'; /** - * @description Invitation ID - * @example inv_1234567890 + * @description Post tags + * @example [ + * "smart-contracts", + * "soroban", + * "tutorial" + * ] */ - id: string; + tags?: string[]; /** - * @description Team ID - * @example team_1234567890 + * @description Post categories + * @example [ + * "tutorials" + * ] */ - teamId: string; - /** @description Hackathon information */ - hackathon: Record; - /** @description Invitee information */ - invitee: Record; - /** @description Inviter information */ - inviter: Record; + categories?: string[]; /** - * @description Invitation status - * @example pending - * @enum {string} + * @description Mark as featured post + * @default false + * @example false */ - status: 'pending' | 'accepted' | 'rejected' | 'expired'; + isFeatured: boolean; /** - * @description Optional message from inviter - * @example We would love to have you on our team! + * @description Pin post to top + * @default false + * @example false */ - message?: Record; + isPinned: boolean; /** - * @description Role in the team - * @example member + * @description Reading time in minutes (auto-calculated if not provided) + * @example 5 */ - role: Record; + readingTime?: number; + /** @description SEO title (overrides post title) */ + seoTitle?: string; + /** @description SEO meta description */ + seoDescription?: string; /** - * Format: date-time - * @description Invitation expiration date - * @example 2026-01-30T12:00:00.000Z + * @description SEO keywords + * @example [ + * "stellar", + * "blockchain", + * "smart contracts" + * ] */ - expiresAt: string; + seoKeywords?: string[]; /** - * Format: date-time - * @description Invitation creation date - * @example 2026-01-23T12:00:00.000Z + * @description Schedule publication date (for SCHEDULED status) + * @example 2025-12-31T10:00:00Z */ - createdAt: string; + scheduledFor?: string; /** - * @description Date when invitation was responded to - * @example 2026-01-24T12:00:00.000Z + * @description Generate AI content (excerpt, reading time, SEO, tags, category) if not provided + * @default false + * @example true */ - respondedAt?: Record; + generateAI: boolean; }; - TeamInvitationListResponseDto: { - /** @description List of invitations */ - invitations: components['schemas']['TeamInvitationResponseDto'][]; - /** - * @description Total count - * @example 5 - */ + SetPublishedDto: { + /** @description true publishes the post; false unpublishes (back to draft). */ + published: boolean; + }; + ContentActionResponseDto: { + id: string; + /** @description Publishing status after the action */ + status: string; + /** @description Whether the post is currently published */ + published: boolean; + /** @description Whether the post is archived (soft-deleted) */ + archived: boolean; + }; + ArchiveContentDto: { + /** @description Why the post is being archived. Recorded in the audit log. */ + reason?: string; + }; + ChecklistItemDto: { + id: string; + /** @description What the reviewer should verify */ + label: string; + /** @description Optional help text */ + description: string | null; + /** @description Whether this is a required check */ + required: boolean; + /** @description Position in the list */ + orderIndex: number; + }; + CreateChecklistItemDto: { + label: string; + description?: string; + /** @default false */ + required: boolean; + }; + ReorderChecklistDto: { + /** @description All active item ids in the desired order (a permutation). */ + orderedIds: string[]; + }; + UpdateChecklistItemDto: { + label?: string; + /** @description Pass an empty string to clear the help text */ + description?: string | null; + required?: boolean; + }; + AdminCrowdfundingListItemDto: { + id: string; + title: string; + /** @description v2 lifecycle status */ + status: string; + /** @description Creator name */ + creator: string | null; + /** @description Funding goal */ + fundingGoal: number; + /** @description ISO timestamp the campaign was submitted for review */ + submittedForReviewAt: string | null; + /** @description ISO timestamp the campaign was created */ + created: string; + }; + PaginatedCrowdfundingDto: { + items: components['schemas']['AdminCrowdfundingListItemDto'][]; + page: number; + limit: number; total: number; + totalPages: number; }; - InvitationActionResponseDto: { - /** - * @description Success message - * @example Successfully accepted team invitation - */ - message: string; - /** - * @description Team ID that was joined (only for accept) - * @example team_1234567890 - */ - teamId: string; - /** @description Updated invitation */ - invitation: components['schemas']['TeamInvitationResponseDto']; + AdminCrowdfundingProjectDto: { + description: string | null; + summary: string | null; + /** @description Vision statement */ + vision: string | null; + /** @description Markdown details / pitch */ + details: string | null; + category: string | null; + tags: string[]; + /** @description Tech stack */ + techStack: string[]; + /** @description Team members ({ name?, role, ... }) */ + teamMembers: { + [key: string]: unknown; + }[]; + /** @description Social links ({ platform, url }) */ + socialLinks: + | { + [key: string]: unknown; + }[] + | null; + /** @description Contact ({ primary, backup }) */ + contact: { + [key: string]: unknown; + } | null; + githubUrl: string | null; + gitlabUrl: string | null; + bitbucketUrl: string | null; + projectWebsite: string | null; + liveUrl: string | null; + docsUrl: string | null; + demoVideo: string | null; + pitchVideoUrl: string | null; + whitepaperUrl: string | null; + logo: string | null; + banner: string | null; + thumbnail: string | null; + screenshots: string[]; + }; + AdminCrowdfundingReviewDto: { + /** @description NOTE | REQUEST_REVISION | APPROVED | REJECTED */ + action: string; + reason: string | null; + /** @description Reviewer name (User) or null when a staff member reviewed */ + reviewer: string | null; + /** @description Staff email when a staff member reviewed */ + reviewerStaffEmail: string | null; + createdAt: string; }; - ToggleRoleHiredDto: { + AdminCrowdfundingMilestoneDto: { + id: string; + title: string; + /** @description Position in the release sequence */ + orderIndex: number; + /** @description Planned share of the goal (percent) */ + fundingPercentage: number; + /** @description Planned amount */ + amount: number; + /** @description Off-chain review status */ + reviewStatus: string; + /** @description What the milestone delivers */ + description: string; + /** @description Concrete deliverable */ + deliverable: string | null; + /** @description Acceptance / success criteria */ + successCriteria: string | null; + /** @description Expected delivery date */ + expectedDeliveryDate: string | null; + submittedAt: string | null; + /** @description On-chain claim anchor: pending_confirm | confirmed | failed */ + escrowAnchorStatus: string | null; + escrowClaimTxHash: string | null; + claimedAt: string | null; + }; + AdminCrowdfundingDetailDto: { + id: string; + title: string; + tagline: string | null; + /** @description v2 lifecycle status */ + status: string; + /** @description Creator name */ + creator: string | null; + /** @description Full submitted project content for review */ + project: components['schemas']['AdminCrowdfundingProjectDto']; + fundingGoal: number; + fundingRaised: number; + fundingCurrency: string; + /** @description Funding deadline */ + fundingEndDate: string | null; + /** @description Total released to the builder so far (across milestones) */ + totalDisbursed: number; + /** @description Per-campaign voting quorum */ + voteGoal: number; + /** @description Builder's wallet (escrow owner) */ + builderAddress: string | null; + /** @description Number of milestones */ + nMilestones: number | null; + /** @description On-chain event id once the escrow is live (FUNDING) */ + escrowEventId: string | null; + /** @description create_event tx hash */ + escrowTxHash: string | null; + escrowSettledLedger: number | null; + escrowToken: string | null; + /** @description Total escrow budget (stroops/decimal) */ + escrowBudget: string | null; + /** @description Escrow failure code if create_event failed (FAILED) */ + escrowFailureCode: string | null; + escrowFailedAt: string | null; + completedAt: string | null; + cancelledAt: string | null; + /** @description Assigned delegated reviewer (User id), set at approval */ + assignedReviewerId: string | null; + submittedForReviewAt: string | null; + reviewedAt: string | null; + /** @description ISO timestamp the campaign was created */ + created: string; + /** @description Review history */ + reviews: components['schemas']['AdminCrowdfundingReviewDto'][]; + /** @description Milestones with review + on-chain claim status */ + milestones: components['schemas']['AdminCrowdfundingMilestoneDto'][]; + }; + ApproveCampaignDto: { + /** @description StaffUser id of the delegated reviewer who signs off milestones for this campaign. Must be an active staff member. */ + delegatedReviewerId: string; + /** @description Per-campaign voting quorum. Defaults to the contract default. */ + voteGoal?: number; /** - * @description Skill/role name to toggle hired status - * @example Rust Developer + * @description Bypass community voting and approve straight to launch-ready (REVIEW_APPROVED). Default false: the campaign enters community voting. + * @default false */ - skill: string; + bypassVoting: boolean; }; - TransferLeadershipDto: { - /** - * @description User ID of the new team leader (must be an existing member) - * @example user_1234567890 - */ - newLeaderId: string; - /** - * @description Optional reason for the leadership transfer - * @example Stepping down to focus on development tasks - */ + CrowdfundingActionResponseDto: { + id: string; + /** @description New v2 lifecycle status */ + status: string; + }; + RejectCampaignDto: { + /** @description Reason shown to the builder in the review history. */ reason?: string; }; - LeadershipTransferResponseDto: { - /** - * @description Success message - * @example Leadership successfully transferred - */ - message: string; - /** @description Updated team with new leader */ - team: components['schemas']['TeamResponseDto']; + RequestRevisionDto: { + /** @description What the builder needs to change. Shown in the review history. */ + reason: string; + }; + TotpEnrollResponseDto: { + /** @description Base32 secret, shown once for manual entry */ + secret: string; + /** @description otpauth:// URI for QR enrollment */ + otpauthUri: string; + }; + TotpCodeDto: { + /** @description Six-digit code from the authenticator app */ + code: string; + }; + OkResponseDto: { + /** @default true */ + ok: boolean; + }; + AdminAuditListItemDto: { + id: string; + /** @description Email of the staff member who acted */ + actor: string; + /** @description Dotted action name, e.g. "users.ban" */ + action: string; + /** @description Permission resource the action belongs to */ + resource: string; + /** @description Affected entity id */ + targetId: string | null; + /** @description Human note captured with the action (e.g. ban reason) */ + details: string | null; + /** @description ISO timestamp the action was recorded */ + created: string; + }; + PaginatedAuditDto: { + items: components['schemas']['AdminAuditListItemDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; + }; + FeatureFlagDto: { + /** @description Stable flag key, e.g. "crowdfunding.public_launch" */ + key: string; + /** @description Human description of what the flag gates */ + description: string; + enabled: boolean; + /** @description ISO timestamp the flag was last changed */ + updated: string; + }; + FeatureFlagsResponseDto: { + items: components['schemas']['FeatureFlagDto'][]; + }; + ToggleFeatureFlagDto: { + /** @description Desired enabled state */ + enabled: boolean; + }; + StaffListItemDto: { + id: string; + name: string; + email: string; + /** @description Staff role token, e.g. "operations" */ + role: string; + /** @description active | disabled */ + status: string; + /** @description Whether the staff has an activated authenticator */ + totpEnabled: boolean; + /** @description ISO timestamp the staff record was created */ + created: string; + }; + StaffListResponseDto: { + items: components['schemas']['StaffListItemDto'][]; + }; + SetRoleDto: { /** - * @description Previous leader ID - * @example user_1234567890 + * @description The role to assign + * @enum {string} */ - previousLeaderId: string; + role: + | 'super_admin' + | 'operations' + | 'finance' + | 'compliance' + | 'content' + | 'support'; + }; + GovernanceProposalDto: { + id: string; + title: string; + description: string | null; + /** @description Target contract, e.g. "boundless-events" */ + contract: string; + /** @description Contract action, e.g. "upgrade" */ + action: string; + /** @description Action parameters for the offline signers */ + params?: { + [key: string]: unknown; + } | null; + /** @description PROPOSED | APPROVED | REJECTED | EXECUTED */ + status: string; + /** @description Email of the maker who proposed */ + proposedBy: string; + /** @description Checker email */ + decidedBy: string | null; + decidedAt: string | null; + decisionNote: string | null; + /** @description Offline-signed tx hash */ + txHash: string | null; + executedBy: string | null; + executedAt: string | null; + created: string; + }; + GovernanceListResponseDto: { + items: components['schemas']['GovernanceProposalDto'][]; + }; + CreateProposalDto: { + title: string; + description?: string; + /** @description Target contract */ + contract: string; + /** @description Contract action */ + action: string; + params?: { + [key: string]: unknown; + }; + }; + DecideProposalDto: { + /** @enum {string} */ + decision: 'approve' | 'reject'; + /** @description Note recorded with the decision */ + note?: string; + }; + ExecuteProposalDto: { + /** @description Hash of the offline-signed, executed transaction */ + txHash: string; + }; + AdminKycListItemDto: { + /** @description User id */ + id: string; + name: string; + email: string; + /** @enum {string} */ + status: 'in_review' | 'approved' | 'declined'; + /** @description Decline reason from Didit, when declined */ + declineReason: string | null; + /** @description ISO timestamp of the last verification activity */ + reviewedAt: string; + /** @description ISO timestamp the user became verified */ + verifiedAt: string | null; + }; + PaginatedKycDto: { + items: components['schemas']['AdminKycListItemDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; + }; + DiditConnectionDto: { + /** @description DIDIT_API_KEY is configured */ + apiKey: boolean; + /** @description DIDIT_WORKFLOW_ID is configured */ + workflowId: boolean; + /** @description DIDIT_WEBHOOK_SECRET is configured */ + webhookSecret: boolean; + /** @description API key + workflow present: live calls (sync, re-trigger) work */ + connected: boolean; + }; + KycSyncResponseDto: { + userId: string; + /** @description Raw Didit status after the sync */ + status: string; + /** @description Whether the user record status changed */ + changed: boolean; + /** @description False if no Boundless user could be linked to the session */ + userResolved: boolean; + }; + KycRetriggerResponseDto: { + userId: string; + /** @description The new Didit session id */ + sessionId: string; + /** @description Hosted verification URL to share with the user */ + verificationUrl: string; + /** @description Initial Didit session status */ + status: string; + /** @description Whether the user was notified (in-app + email) with the link. If false, share the URL manually. */ + notified: boolean; + }; + KycOverrideDto: { /** - * @description New leader ID - * @example user_0987654321 + * @description The decision to force onto the user record. + * @enum {string} */ - newLeaderId: string; + decision: 'approved' | 'declined'; + /** @description Why the automated Didit decision is being overridden. Recorded in the audit log. */ + reason: string; + }; + KycOverrideResponseDto: { + userId: string; /** - * Format: date-time - * @description Timestamp of the transfer - * @example 2026-02-16T10:30:00.000Z + * @description The resulting normalized state + * @enum {string} */ - transferredAt: string; + status: 'approved' | 'declined'; }; - InfoFormData: { - /** @description Hackathon title */ - name: string; + AdminMilestoneListItemDto: { + id: string; + /** @enum {string} */ + type: 'crowdfunding' | 'grant'; + /** @description Parent program title */ + program: string | null; + title: string; + /** @description Milestone amount */ + amount: number; + /** @description Review/lifecycle status */ + status: string; + /** @description ISO timestamp the milestone was submitted, if any */ + submitted: string | null; /** - * Format: uri - * @description Banner image URL + * @description Crowdfunding only: on-chain payout release state (derived from the escrow anchor status). Null for grant milestones. + * @enum {string|null} */ - banner: string; - /** @description Hackathon description */ + releaseStatus: + | 'NOT_RELEASED' + | 'RELEASING' + | 'RELEASED' + | 'FAILED' + | null; + }; + PaginatedMilestonesDto: { + items: components['schemas']['AdminMilestoneListItemDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; + }; + AdminMilestoneDetailDto: { + id: string; + title: string; description: string; - /** @description One or more hackathon categories */ - categories: ( - | 'DeFi' - | 'Payments' - | 'Stablecoins' - | 'Lending & Borrowing' - | 'Trading & DEXs' - | 'Derivatives' - | 'Prediction Markets' - | 'NFTs' - | 'Creator Economy' - | 'Social' - | 'Social Tokens' - | 'DAOs' - | 'Governance' - | 'Web3 Gaming' - | 'Metaverse' - | 'Layer 1' - | 'Layer 2' - | 'Cross-chain' - | 'Interoperability' - | 'Infrastructure' - | 'Developer Tooling' - | 'Wallets' - | 'Account Abstraction' - | 'Oracles' - | 'Data & Indexing' - | 'Analytics' - | 'AI' - | 'AI Agents' - | 'DePIN' - | 'DeSci' - | 'Privacy' - | 'Zero-Knowledge' - | 'Security' - | 'Identity' - | 'Real World Assets' - | 'Tokenization' - | 'Supply Chain' - | 'Sustainability' - | 'Climate' - | 'Education' - | 'Healthcare' - | 'Consumer Apps' - | 'Mobile' - | 'Other' - )[]; + deliverable: string | null; + successCriteria: string | null; + expectedDeliveryDate: string | null; + reviewStatus: string; + completedAt: string | null; + submittedAt: string | null; + campaignId: string; + proofOfWorkFiles: string[]; + proofOfWorkLinks: string[]; + submissionNotes: string | null; + fundingPercentage: number; + orderIndex: number; + rejectionReason: string | null; + rejectionFeedback: string | null; + resubmissionDeadline: string | null; + releaseTransactionHash: string | null; + claimedAt: string | null; + /** @description Derived payout release state. */ + releaseStatus: string; + }; + MilestoneActionResponseDto: { + id: string; + /** @description New milestone review status */ + status: string; + }; + MilestoneReleaseXdrDto: { + /** @description EscrowOp row id tracking this release. */ + opId: string; + milestoneId: string; + /** @description On-chain contract admin G-address. This is the transaction source and the account that must sign at the Lab. */ + source: string; + /** @description Unsigned transaction XDR (the builder managed auth entry is already signed server-side; the admin signs the envelope offline). */ + unsignedXdr: string; + /** @description Stellar Lab "Sign Transaction" deep link. */ + labUrl: string; + /** @enum {string} */ + network: 'public' | 'testnet'; + /** @description Network passphrase the signer must use. */ + passphrase: string; + }; + SubmitMilestoneReleaseDto: { + /** @description Base64 transaction XDR signed offline by the admin at the Stellar Lab. Must be the exact transaction returned by build-xdr (hash-checked). */ + signedXdr: string; + }; + MilestoneReleaseResultDto: { + opId: string; + milestoneId: string; + /** @description EscrowOp status after submission. */ + status: string; + txHash: string | null; + }; + AdminWalletUserPreviewDto: { + id: string; + name: string; + /** @description Profile photo URL, when set */ + image: string | null; + }; + AdminWalletRowDto: { + id: string; + /** @description Stellar public key (G-address) */ + address: string; /** - * @description Venue type + * @description Activation state * @enum {string} */ - venueType: 'virtual' | 'physical'; - /** @description Short tagline */ - tagline: string; - country?: string; - state?: string; - city?: string; - venueName?: string; - venueAddress?: string; - /** @description Read-only URL slug (server-assigned) */ - slug?: string; + status: 'active' | 'inactive'; + /** @description Number of users linked to this wallet */ + users: number; + /** @description A capped preview of the linked users, for avatars in the list */ + userPreviews: components['schemas']['AdminWalletUserPreviewDto'][]; + /** @description ISO timestamp the wallet was created */ + created: string; }; - PhaseDto: { - /** @description Phase name */ - name: string; - /** Format: date-time */ - startDate: string; - /** Format: date-time */ - endDate: string; - description?: string; + PaginatedWalletsDto: { + items: components['schemas']['AdminWalletRowDto'][]; + page: number; + limit: number; + total: number; + totalPages: number; }; - TimelineFormData: { - /** Format: date-time */ - startDate: string; - /** Format: date-time */ - submissionDeadline: string; - /** @description IANA timezone */ - timezone: string; - /** Format: date-time */ - registrationDeadline?: string; - /** Format: date-time */ - judgingDeadline?: string; - phases?: components['schemas']['PhaseDto'][]; + Function: Record; + BountyScopeSectionDto: { + /** @description Bounty title */ + title: string; + /** @description Bounty description */ + description: string; /** - * Format: date-time - * @description Read-only: original submission deadline before any extension + * @description Discipline the bounty falls under. DEVELOPMENT requires githubIssueUrl. + * @enum {string} */ - submissionDeadlineOriginal?: string; + category?: 'DESIGN' | 'DEVELOPMENT' | 'CONTENT' | 'GROWTH' | 'COMMUNITY'; + /** @description Country where the bounty is created. */ + country?: string | null; /** - * Format: date-time - * @description Read-only: timestamp the submission deadline was last extended + * Format: uri + * @description Required when category = DEVELOPMENT. */ - submissionDeadlineExtendedAt?: string; + githubIssueUrl?: string | null; + projectId?: string | null; + bountyWindowId?: string | null; }; - ParticipantFormData: { - /** @enum {string} */ - participantType: 'individual' | 'team' | 'team_or_individual'; - teamMin?: number; - teamMax?: number; - /** @description Participant cap; omit for unlimited */ - maxParticipants?: number; - require_github?: boolean; - require_demo_video?: boolean; - require_other_links?: boolean; - detailsTab?: boolean; - participantsTab?: boolean; - resourcesTab?: boolean; - submissionTab?: boolean; - announcementsTab?: boolean; - discussionTab?: boolean; - winnersTab?: boolean; - sponsorsTab?: boolean; - joinATeamTab?: boolean; - rulesTab?: boolean; + BountyModeSectionDto: { /** @enum {string} */ - submissionVisibility?: 'PUBLIC' | 'PARTICIPANTS_ONLY'; + claimType: 'SINGLE_CLAIM' | 'COMPETITION'; /** @enum {string} */ - submissionStatusVisibility?: - | 'ALL' - | 'ACCEPTED_SHORTLISTED' - | 'HIDDEN_UNTIL_RESULTS'; - }; - HackathonDraftTracksDto: { - /** @description Max number of tracks a single submission may enter (1-20). */ - tracksMaxPerSubmission?: number; + entryType: 'OPEN' | 'APPLICATION_LIGHT' | 'APPLICATION_FULL'; }; - PrizeTierDto: { - /** @description Client-generated tier id */ - id: string; - /** @description Placement label, e.g. "1st Place" */ - place: string; - /** @description Prize amount as a decimal string */ - prizeAmount: string; - description?: string; - currency?: string; - passMark: number; + BountySubmissionSectionDto: { + /** Format: date-time */ + submissionDeadline: string; + /** Format: date-time */ + applicationWindowCloseAt?: string | null; + maxApplicants?: number | null; + shortlistSize?: number | null; + reputationMinimum?: number | null; /** @enum {string} */ - kind?: 'OVERALL' | 'TRACK'; - trackId?: string; + submissionVisibility?: 'ORGANIZER_ONLY' | 'HIDDEN_UNTIL_DEADLINE'; + /** @description Credits required to apply (anti-spam). Supplied to the contract at publish via PublishBountyEscrowDto; not a Bounty column. */ + applicationCreditCost?: number | null; }; - PrizePlacementWriteDto: { - /** @description 1 = 1st place; unique within a prize */ + BountyPrizeTierInputDto: { + /** @description 1 = 1st place; unique within a bounty */ position: number; - label?: string; - /** @description Prize amount as a decimal string */ + /** @description Tier amount as a positive decimal string */ amount: string; - currency?: string; - passMark?: number; - }; - PrizeWriteDto: { - /** @description Prize name, e.g. "Grand Prize" or "Best UI/UX" */ - name: string; - description?: string; - /** @description Linked HackathonTrack ids; empty = overall prize */ - trackIds: string[]; - placements: components['schemas']['PrizePlacementWriteDto'][]; - }; - WinnerOverrideDto: { - /** @description Submission id the override targets */ - submissionId: string; - rank?: number; - prizeAmount?: string; - currency?: string; + passMark?: number | null; }; - RewardsFormData: { - prizeTiers?: components['schemas']['PrizeTierDto'][]; - prizes?: components['schemas']['PrizeWriteDto'][]; - winnerOverrides?: components['schemas']['WinnerOverrideDto'][]; - /** @enum {string} */ - prizeStructure?: 'OVERALL_ONLY' | 'OVERALL_AND_TRACKS' | 'TRACKS_ONLY'; - tracksMaxPerSubmission?: number; - allowWinnerStacking?: boolean; + BountyRewardSectionDto: { + /** @description Token / currency code the prize is denominated in */ + rewardCurrency: string; + /** @description 1 tier for single claim; 1-3 tiers for a competition (multiple winners). */ + prizeTiers: components['schemas']['BountyPrizeTierInputDto'][]; }; - ResourceItemDto: { + BountyResourceItemDto: { /** @description Client-generated resource id */ id: string; link?: string; @@ -15934,2932 +20464,2916 @@ export interface components { name?: string; }; }; - ResourcesFormData: { - resources: components['schemas']['ResourceItemDto'][]; - }; - CriterionDto: { - /** @description Client-generated criterion id */ - id: string; - /** @description Criterion name */ - name: string; - weight: number; - description?: string; - }; - JudgingFormData: { - criteria: components['schemas']['CriterionDto'][]; - }; - SponsorPartnerDto: { - /** @description Client-generated sponsor/partner id */ - id: string; - name?: string; - logo?: string; - link?: string; - }; - CollaborationFormData: { - /** @description Organizer contact email */ - contactEmail: string; - telegram?: string; - discord?: string; - socialLinks?: string[]; - sponsorsPartners?: components['schemas']['SponsorPartnerDto'][]; - }; - HackathonDraftDataDto: { - information?: components['schemas']['InfoFormData']; - timeline?: components['schemas']['TimelineFormData']; - participation?: components['schemas']['ParticipantFormData']; - tracks?: components['schemas']['HackathonDraftTracksDto']; - rewards?: components['schemas']['RewardsFormData']; - resources?: components['schemas']['ResourcesFormData']; - judging?: components['schemas']['JudgingFormData']; - collaboration?: components['schemas']['CollaborationFormData']; + BountyResourcesSectionDto: { + resources: components['schemas']['BountyResourceItemDto'][]; }; - HackathonDraftAiGenerationDto: { - /** @description AI generationId that produced or last-updated this draft. */ - generationId: string; + BountyDraftDataDto: { + scope?: components['schemas']['BountyScopeSectionDto']; + mode?: components['schemas']['BountyModeSectionDto']; + submission?: components['schemas']['BountySubmissionSectionDto']; + reward?: components['schemas']['BountyRewardSectionDto']; + resources?: components['schemas']['BountyResourcesSectionDto']; }; - HackathonDraftPrizePlacementDto: { - id: string; - /** @description 1 = 1st place, unique within a prize */ + BountyDraftPrizeTierDto: { position: number; - label?: string | null; - /** @description Decimal string in the prize currency */ + /** @description Tier amount as a decimal string */ amount: string; - currency: string; - /** @description Minimum score (0-100) to win this placement */ - passMark: number; - }; - HackathonDraftPrizeDto: { - id: string; - name: string; - description?: string | null; - displayOrder: number; - /** @description Linked track ids; empty = overall prize */ - trackIds: string[]; - placements: components['schemas']['HackathonDraftPrizePlacementDto'][]; + passMark?: number | null; }; - HackathonDraftResponseDto: { + BountyDraftResponseDto: { id: string; - /** @enum {string} */ - status: - | 'DRAFT' - | 'DRAFT_AWAITING_FUNDING' - | 'PUBLISHED' - | 'ARCHIVED' - | 'CANCELLED'; + /** + * @description Bounty lifecycle state (lowercase). + * @example draft + */ + status: string; /** @description First incomplete step (1-based) */ currentStep: number; completedSteps: string[]; - data: components['schemas']['HackathonDraftDataDto']; + /** @description Plain mode label derived from (entryType, claimType, winner count), e.g. "Open competition (multiple winners)". */ + modeLabel?: string | null; + data: components['schemas']['BountyDraftDataDto']; + prizeTiers: components['schemas']['BountyDraftPrizeTierDto'][]; isValidForPublish: boolean; /** @description Per-section validation messages, keyed by step */ validationErrors: { - [key: string]: string[]; + [key: string]: Record[]; }; /** Format: date-time */ createdAt: string; /** Format: date-time */ updatedAt: string; - /** @description Present when the draft was generated with Organizer Assist; enables per-section AI regenerate in the wizard. */ - aiGeneration?: components['schemas']['HackathonDraftAiGenerationDto']; - /** @description Prize entity (named prizes + linked tracks + placements). Additive read path alongside data.rewards.prizeTiers; becomes authoritative as readers cut over. */ - prizes: components['schemas']['HackathonDraftPrizeDto'][]; }; - UpdateHackathonDraftDto: { - information?: components['schemas']['InfoFormData']; - timeline?: components['schemas']['TimelineFormData']; - participation?: components['schemas']['ParticipantFormData']; - rewards?: components['schemas']['RewardsFormData']; - resources?: components['schemas']['ResourcesFormData']; - judging?: components['schemas']['JudgingFormData']; - collaboration?: components['schemas']['CollaborationFormData']; + UpdateBountyDraftDto: { + scope?: components['schemas']['BountyScopeSectionDto']; + mode?: components['schemas']['BountyModeSectionDto']; + submission?: components['schemas']['BountySubmissionSectionDto']; + reward?: components['schemas']['BountyRewardSectionDto']; + resources?: components['schemas']['BountyResourcesSectionDto']; /** @description Hint that this is an autosave (no completion side effects). */ autoSave?: boolean; }; - GenerateDraftFromBriefDto: { + BountyWinnerDistributionEntryDto: { /** - * @description Free-text brief describing the hackathon to generate. - * @example A two-week hackathon for AI agent tooling on Stellar, aimed at indie builders. + * @description 1-indexed winner position. + * @example 1 */ - brief: string; + position: number; /** - * @description Total budget cap in USDC, as a decimal string. - * @example 10000 + * @description Percent of total_budget for this position. All entries sum to 100. + * @example 100 */ - budgetCapUsdc: string; + percent: number; + }; + PublishBountyEscrowDto: { /** - * @description Earliest the hackathon may start (YYYY-MM-DD). - * @example 2026-07-01 + * @description Stellar G-address that will own and sign the create_event transaction. + * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ */ - earliestStart: string; - /** @description Up to 3 example briefs/drafts to steer style. */ - examples?: string[]; - }; - AiGenerationMetaDto: { - generationId: string; - model: string; - promptVersion: string; - /** @description Cost in USD as a decimal string (never a float). */ - costUsd: string; - }; - GenerateDraftFromBriefResponseDto: { - /** @description Id of the created draft. */ - draftId: string; - draft: components['schemas']['HackathonDraftResponseDto']; - generation: components['schemas']['AiGenerationMetaDto']; - }; - RegenerateDraftSectionDto: { - /** @enum {string} */ - section: 'criteria' | 'prizes' | 'tracks' | 'timeline' | 'description'; - /** @description Optional steering instructions for the regeneration. */ - instructions?: string; - }; - RegenerateDraftSectionResponseDto: { - /** @enum {string} */ - section: 'criteria' | 'prizes' | 'tracks' | 'timeline' | 'description'; - /** @description Regenerated values in the wizard section shape. */ - data: { - [key: string]: unknown; - }; - generation: components['schemas']['AiGenerationMetaDto']; - }; - UpdateVisibilitySettingsDto: { + ownerAddress: string; /** - * @description Who can view hackathon submissions - * @example PUBLIC - * @enum {string} + * @description Whitelisted Stellar Asset Contract address the prize is in. + * @example CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA */ - submissionVisibility?: 'PUBLIC' | 'PARTICIPANTS_ONLY'; + tokenAddress: string; /** - * @description Which submission statuses are visible to others. ALL exposes SUBMITTED and SHORTLISTED. ACCEPTED_SHORTLISTED exposes only SHORTLISTED. HIDDEN_UNTIL_RESULTS hides every submission from non-owners and non-organizers until the hackathon results are published, then exposes only SHORTLISTED. DISQUALIFIED is never visible to anyone other than the owner or an organizer. - * @example ACCEPTED_SHORTLISTED + * @description Total prize in token-native units (e.g. 500 = 500 USDC, NOT stroops). String is required when the value exceeds the JS safe-integer range. + * @example 500 + */ + budget: string; + /** + * @description Submission deadline as a Unix timestamp in seconds. Required for bounties that close at a specific time. Pass null only for always-open bounties (rare). + * @example 1804383600 + */ + submissionDeadline: number | null; + /** + * @description Credits required to apply. Defaults to 1; raise on high-value bounties to deter spam. Max 100 (enforced by the contract). + * @default 1 + * @example 1 + */ + applicationCreditCost: number; + /** @description Override for the winner distribution. Defaults to 100% to position 1. */ + winnerDistribution?: components['schemas']['BountyWinnerDistributionEntryDto'][]; + /** @description Override for the content URI stored on chain. Defaults to https://api.boundless.fi/bounties//content. */ + contentUri?: string; + /** + * @description Signing path. EXTERNAL (default) returns unsigned XDR for the wallet or multisig coordinator to sign. MANAGED has the backend sign and submit using the caller's platform-held wallet; the response is PENDING_CONFIRM with a txHash. + * @default EXTERNAL + * @example MANAGED * @enum {string} */ - submissionStatusVisibility?: - | 'ALL' - | 'ACCEPTED_SHORTLISTED' - | 'HIDDEN_UNTIL_RESULTS'; + fundingMode: 'EXTERNAL' | 'MANAGED'; + /** @description For MANAGED funding, the organization treasury wallet to fund from. When set, the backend signs with that treasury (managed) wallet instead of the caller's personal wallet; ownerAddress must match the treasury wallet address. Omit to fund from the personal managed wallet. */ + sourceWalletId?: string; }; - ReviewSubmissionDto: { + BountyEscrowOpResponseDto: { + /** @description Internal EscrowOp uuid. */ + id: string; + /** @description Hex-encoded 32-byte contract op_id. */ + opId: string; + /** @description Contract operation kind. */ + kind: string; + /** @description EscrowOp status. */ + status: string; + /** @description EntityKind (BOUNTY for this surface). */ + entityKind: string; + /** @description Bounty id. */ + entityId: string; + /** @description Unsigned XDR for the wallet to sign (PENDING_SIGN onward). */ + unsignedXdr?: string | null; + /** @description Stellar G-address expected to sign this op. */ + signerHint?: string | null; + /** @description Soroban tx hash (set once the op reaches PENDING_CONFIRM). */ + txHash?: string | null; + /** @description On-chain or platform-side error code when the op transitions to FAILED. */ + errorCode?: string | null; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + CancelBountyEscrowDto: { /** - * @description ID of the assigned judge performing the review - * @example user_1234567890 + * @description Organizer's Stellar G-address that signs cancel_event. Must match the bounty's on-chain owner. + * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ */ - judgeId: string; + ownerAddress: string; /** - * @description Review action - * @example SHORTLISTED + * @description Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side with the caller's platform-held wallet and submits. + * @default EXTERNAL * @enum {string} */ - status: 'SHORTLISTED' | 'SUBMITTED'; + fundingMode: 'EXTERNAL' | 'MANAGED'; + }; + BountyWinnerSelectionDto: { /** - * @description Reviewer notes or feedback - * @example Great project with innovative approach + * @description Stellar G-address of the applicant being declared winner. Must have an active submission anchor for this bounty. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - notes?: string; + applicantAddress: string; /** - * @description Rank/position for the submission + * @description Winner position, 1-indexed. Must exist in the bounty's on-chain winner_distribution (the contract rejects unknown positions). * @example 1 */ - rank?: number; + position: number; /** - * @description Whether this is an organizational override (bypasses COI and assignment checks) - * @default false + * @description Override the platform default credit_earn for this position. Defaults to 20/10/5 for positions 1/2/3 and 3 for the rest. Capped at 100 by the contract. + * @example 20 */ - isOrganizerOverride: boolean; - }; - OrganizationHackathonParticipantsResponseDto: Record; - DisqualifySubmissionDto: { + creditEarn?: number; /** - * @description Reason for disqualification - * @example Submission does not meet hackathon requirements + * @description Override the platform default reputation_bump for this position. Defaults to 50/25/10 for positions 1/2/3 and 5 for the rest. + * @example 50 */ - disqualificationReason: string; + reputationBump?: number; }; - BulkSubmissionActionDto: { + SelectBountyWinnersDto: { /** - * @description Array of submission IDs - * @example [ - * "sub_1234567890", - * "sub_0987654321" - * ] + * @description Organizer's Stellar G-address that signs select_winners. Must match the bounty's on-chain owner. + * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ */ - submissionIds: string[]; + ownerAddress: string; + /** @description Winners to declare. Each entry must reference an applicant with an active submission. Positions must be unique within the array. */ + selections: components['schemas']['BountyWinnerSelectionDto'][]; /** - * @description Action to perform - * @example SHORTLISTED + * @description Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side with the caller's platform-held wallet and submits. + * @default EXTERNAL * @enum {string} */ - action: 'SHORTLISTED' | 'SUBMITTED' | 'DISQUALIFIED'; - /** - * @description Reason (required for DISQUALIFIED action) - * @example Does not meet requirements - */ - reason?: string; - }; - SummaryMetricsDto: { - /** @example 120 */ - participantsCount: number; - /** @example 45 */ - submissionsCount: number; - /** @example 6 */ - activeJudges: number; - /** @example 3 */ - completedMilestones: number; - }; - TrendPointDto: { - /** @example 2026-02-01 */ - date: string; - /** @example 5 */ - count: number; - }; - TrendsDto: { - submissionsOverTime: components['schemas']['TrendPointDto'][]; - participantSignupsOverTime: components['schemas']['TrendPointDto'][]; - }; - TimelinePhaseDto: { - /** @example Registration */ - phase: string; - /** @example Individuals and teams are signing up to participate in the hackathon. */ - description: string; - /** @example 2026-01-20 */ - date: string; - /** @enum {string} */ - status: 'upcoming' | 'ongoing' | 'completed'; - }; - HackathonAnalyticsResponseDto: { - /** @example hack_1234567890 */ - hackathonId: string; - summary: components['schemas']['SummaryMetricsDto']; - trends: components['schemas']['TrendsDto']; - timeline: components['schemas']['TimelinePhaseDto'][]; + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - AnnouncementAuthorDto: { - id: string; - name: string; - image?: string; - username?: string; + BountySubmitSignedXdrDto: { + /** @description Fully-signed XDR returned by the wallet or coordinator. */ + signedXdr: string; }; - AnnouncementResponseDto: { - id: string; - hackathonId: string; - title: string; - content: string; - isDraft: boolean; - isPinned: boolean; - /** Format: date-time */ - publishedAt?: string; - /** Format: date-time */ - createdAt: string; - /** Format: date-time */ - updatedAt: string; - author: components['schemas']['AnnouncementAuthorDto']; + ApplyBountyDto: { + /** + * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS + */ + applicantAddress: string; + /** + * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. + * @default EXTERNAL + * @enum {string} + */ + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - CreateAnnouncementDto: { + WithdrawApplicationDto: { /** - * @description Title of the announcement - * @example Hackathon Starts Now! + * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - title: string; + applicantAddress: string; /** - * @description Content of the announcement in Markdown - * @example # Welcome - * - * We are excited to start... + * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. + * @default EXTERNAL + * @enum {string} + */ + fundingMode: 'EXTERNAL' | 'MANAGED'; + }; + SubmitBountyDto: { + /** + * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - content: string; + applicantAddress: string; /** - * @description Whether the announcement is a draft - * @default true + * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. + * @default EXTERNAL + * @enum {string} */ - isDraft: boolean; + fundingMode: 'EXTERNAL' | 'MANAGED'; /** - * @description Whether the announcement should be pinned - * @default false + * @description URI of the participant's submission content. Stored on chain in the contract's submission anchor; off-chain content lives wherever the URI points (S3, IPFS, GitHub PR, etc.). + * @example https://github.com/me/boundless-fix/pull/1 */ - isPinned: boolean; + contentUri: string; }; - UpdateAnnouncementDto: { + WithdrawSubmissionDto: { /** - * @description Title of the announcement - * @example Hackathon Starts Now! + * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - title?: string; + applicantAddress: string; /** - * @description Content of the announcement in Markdown - * @example # Welcome - * - * We are excited to start... + * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. + * @default EXTERNAL + * @enum {string} */ - content?: string; - /** @description Whether the announcement is a draft */ - isDraft?: boolean; - /** @description Whether the announcement should be pinned */ - isPinned?: boolean; + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - CriterionScoreDto: { + ContributeBountyDto: { /** - * @description Criterion ID or name - * @example Technical Complexity + * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - criterionId: string; + applicantAddress: string; /** - * @description Score for this criterion (0-10) - * @example 8.5 + * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. + * @default EXTERNAL + * @enum {string} */ - score: number; + fundingMode: 'EXTERNAL' | 'MANAGED'; /** - * @description Optional comment for this criterion - * @example Great technical implementation + * @description Amount in token-native units (e.g. 30 = 30 USDC, NOT stroops). Pass a string when the value exceeds the JS safe-integer range. Must be >= 10 USDC (contract minimum). + * @example 30 */ - comment?: string; + amount: string; }; - ScoreSubmissionDto: { + CreateBountyApplicationDto: { /** - * @description Submission ID being judged - * @example sub_1234567890 + * @description G-address that will receive payout if selected. + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - submissionId: string; - /** @description Scores for each individual criterion */ - criteriaScores: components['schemas']['CriterionScoreDto'][]; + applicantAddress: string; + /** @description Light proposal text (light application): 100 to 300 words. Required for APPLICATION_LIGHT mode. */ + proposalShort?: string; + /** @description Full proposal text (full application): 500 to 2000 words. Required for APPLICATION_FULL mode. */ + proposalFull?: string; + /** @description Portfolio links. APPLICATION_LIGHT: up to 3. APPLICATION_FULL: up to 6. */ + portfolioLinks?: string[]; + /** @description Estimated days to complete (APPLICATION_LIGHT). Required for APPLICATION_LIGHT mode. */ + estimatedDays?: number; + /** @description Qualifications text (APPLICATION_FULL). Required for APPLICATION_FULL mode. */ + qualifications?: string; + /** @description Optional video intro URL (APPLICATION_FULL). */ + videoIntroUrl?: string; + }; + BountyApplicationResponseDto: { + id: string; + bountyId: string; + /** @description G-address that receives payout if selected. */ + applicantAddress: string; + /** @description Escrow lifecycle: pending_confirm | active | withdrawn | failed. */ + status: string; /** - * @description Optional ID of the judge to attribute this score to (defaults to calling user) - * @example user_123 - */ - judgeId?: string; + * @description Application lifecycle (SUBMITTED/SHORTLISTED/SELECTED/DECLINED/WITHDRAWN). Null for legacy OPEN + SINGLE_CLAIM rows. + * @enum {string|null} + */ + applicationStatus?: + | 'SUBMITTED' + | 'SHORTLISTED' + | 'SELECTED' + | 'DECLINED' + | 'WITHDRAWN' + | null; + proposalShort?: string | null; + proposalFull?: string | null; + portfolioLinks: string[]; + estimatedDays?: number | null; + qualifications?: string | null; + videoIntroUrl?: string | null; + declineReason?: string | null; + /** Format: date-time */ + shortlistedAt?: string | null; + /** Format: date-time */ + selectedAt?: string | null; + /** Format: date-time */ + declinedAt?: string | null; + /** Format: date-time */ + withdrawnAt?: string | null; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + EditBountyApplicationDto: { + /** @description Light proposal text. */ + proposalShort?: string; + /** @description Full proposal text. */ + proposalFull?: string; + portfolioLinks?: string[]; + estimatedDays?: number; + qualifications?: string; + videoIntroUrl?: string; + }; + SelectForSingleClaimDto: { + /** @description Application id to select as the single winner. */ + applicationId: string; + }; + CreateShortlistDto: { + /** @description Application ids to include in the shortlist. */ + applicationIds: string[]; + }; + DeclineApplicationDto: { + /** @description Reason for decline (surfaced to builder). */ + reason?: string; + }; + JoinCompetitionDto: { /** - * @description Optional admin notes - * @example Score adjusted per appeal + * @description G-address that will receive payout if winning + * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS */ - notes?: string; + applicantAddress: string; + }; + BountySummaryDto: { + id: string; + title: string; + /** @description Pillar lifecycle state (lowercase). */ + status: string; + /** @enum {string|null} */ + entryType?: 'OPEN' | 'APPLICATION_LIGHT' | 'APPLICATION_FULL' | null; + /** @enum {string|null} */ + claimType?: 'SINGLE_CLAIM' | 'COMPETITION' | null; + rewardCurrency: string; /** - * @description Whether this is an organizational override (bypasses COI and assignment checks) - * @default false + * Format: date-time + * @description Work/submission deadline (published value, falling back to the draft). */ - isOrganizerOverride: boolean; + deadline?: string | null; }; - UserDetailsDto: { + MyBountyApplicationRowDto: { id: string; - email: string; - name: string; - username: string; - image?: string; + /** + * @description SUBMITTED / SHORTLISTED / SELECTED / DECLINED / WITHDRAWN. + * @enum {string|null} + */ + applicationStatus?: + | 'SUBMITTED' + | 'SHORTLISTED' + | 'SELECTED' + | 'DECLINED' + | 'WITHDRAWN' + | null; + /** @description Escrow lifecycle: pending_confirm | active | withdrawn | failed. */ + status: string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + bounty: components['schemas']['BountySummaryDto']; }; - JudgingSubmissionParticipantDto: { - id: string; - userId: string; - user: components['schemas']['UserDetailsDto']; - participationType: string; - teamId?: string; - teamName?: string; - teamMembers?: Record[]; + MyBountyApplicationListDto: { + items: components['schemas']['MyBountyApplicationRowDto'][]; + total: number; + page: number; + limit: number; }; - JudgingSubmissionDataDto: { + MyBountySubmissionRowDto: { id: string; - projectName: string; - category: string; - description: string; - logo?: string; - videoUrl?: string; - introduction?: string; - links?: Record[]; - socialLinks?: { - [key: string]: unknown; - }; - submissionDate: string; + /** @description Off-chain review state. */ status: string; - rank?: number; - }; - IndividualJudgingResultDto: { - judgeId: string; - judgeName: string; - criteriaScores: components['schemas']['CriterionScoreDto'][]; - totalScore: number; + escrowAnchorStatus?: string | null; + githubPullRequestUrl?: string | null; + tierPosition?: number | null; + /** @description Won amount in token-native units (decimal string). */ + tierAmount?: string | null; + rewardTransactionHash?: string | null; /** Format: date-time */ - submittedAt: string; - }; - JudgingSubmissionDto: { - participant: components['schemas']['JudgingSubmissionParticipantDto']; - submission: components['schemas']['JudgingSubmissionDataDto']; - myScore?: components['schemas']['IndividualJudgingResultDto']; - averageScore: Record | null; - judgeCount: number; + paidAt?: string | null; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; + bounty: components['schemas']['BountySummaryDto']; }; - JudgingPaginationDto: { + MyBountySubmissionListDto: { + items: components['schemas']['MyBountySubmissionRowDto'][]; + total: number; page: number; limit: number; - total: number; - totalPages: number; }; - JudgingSubmissionsResponseDto: { - submissions: components['schemas']['JudgingSubmissionDto'][]; - criteria: components['schemas']['CriterionDto'][]; - pagination: components['schemas']['JudgingPaginationDto']; - /** @description Number of submissions in this hackathon that the calling judge has already scored. Independent of pagination so the progress strip is accurate even when the user is on page 2. */ - scoredCount?: number; + BountyWinnerDto: { + submissionId: string; + /** @description 1 = 1st place. */ + tierPosition: number; + /** @description Won amount (token-native units, decimal string). */ + tierAmount: string; + /** @description User id of the winner. */ + submittedBy: string; + applicantAddress?: string | null; + githubPullRequestUrl?: string | null; + contentUri?: string | null; + rewardTransactionHash?: string | null; + /** Format: date-time */ + paidAt?: string | null; }; - AddJudgeDto: { - /** - * @description Email address of the user to be assigned as a judge - * @example judge@example.com - */ - email: string; + BountyResultsDto: { + bountyId: string; + /** @description Pillar lifecycle state (lowercase). */ + status: string; + /** @description True once the bounty has completed. */ + isComplete: boolean; + rewardCurrency: string; + /** @description Winners, by tier. */ + winners: components['schemas']['BountyWinnerDto'][]; }; - JudgeResponseDto: { + BountySubmissionViewDto: { id: string; - userId: string; - name: string; - image?: Record; + submittedBy: string; + /** @description True when this is the caller’s own submission. */ + isOwn: boolean; + /** @description Off-chain review state. */ + status: string; + escrowAnchorStatus?: string | null; + applicantAddress?: string | null; + githubPullRequestUrl?: string | null; + contentUri?: string | null; + tierPosition?: number | null; + tierAmount?: string | null; + /** Format: date-time */ + createdAt: string; }; - IndividualScoreDto: { - judgeId: string; - judgeName: string; - score: number; + BountySubmissionListDto: { + items: components['schemas']['BountySubmissionViewDto'][]; + /** @enum {string} */ + visibility: 'ORGANIZER_ONLY' | 'HIDDEN_UNTIL_DEADLINE'; + /** @description Whether peer submissions are visible to the caller (organizer, or HIDDEN_UNTIL_DEADLINE past the deadline). When false, only the caller’s own submission is returned. */ + peersVisible: boolean; }; - ScoreRangeDto: { - min: number; - max: number; + BountyPrizeTierPublicDto: { + position: number; + /** @description Tier amount in token-native units. */ + amount: string; + /** @description Optional minimum quality bar. */ + passMark?: number | null; }; - CriteriaBreakdownDto: { - criterionId: string; - averageScore: number; - min: number; - max: number; - variance: number; + BountyOrganizationPublicDto: { + id: string; + name: string; + slug?: string | null; + logo?: string | null; }; - AggregatedJudgingResultDto: { - submissionId: string; - projectName: string; - teamId?: Record; - participantId: string; + BountyPublicDto: { + id: string; + title: string; + description: string; + /** @description Pillar lifecycle state (lowercase). */ status: string; + type: string; + rewardAmount: number; + rewardCurrency: string; + /** @enum {string} */ + entryType?: 'OPEN' | 'APPLICATION_LIGHT' | 'APPLICATION_FULL'; + /** @enum {string} */ + claimType?: 'SINGLE_CLAIM' | 'COMPETITION'; + /** @enum {string} */ + submissionVisibility: 'ORGANIZER_ONLY' | 'HIDDEN_UNTIL_DEADLINE'; /** Format: date-time */ - submittedAt: string; - averageScore: number; - totalScore: number; - judgeCount: number; - expectedJudgeCount: number; - judgingProgress: string; - individualScores: components['schemas']['IndividualScoreDto'][]; - scoreVariance: number; - scoreRange: components['schemas']['ScoreRangeDto']; - criteriaBreakdown: components['schemas']['CriteriaBreakdownDto'][]; - rank?: Record; - computedRank?: number; - prize?: string; - isComplete: boolean; - isPending: boolean; - hasDisagreement: boolean; - trackIds?: string[]; - /** @description True when this submission is in the top X% overall per the recommendation threshold. */ - recommendedOverall?: boolean; - /** @description Track ids where this submission is in the top X% per the per-track recommendation threshold. */ - recommendedTrackIds?: string[]; - }; - JudgingResultsResponseDto: { - hackathonId: string; - totalSubmissions: number; - submissionsScoredCount: number; - submissionsPendingCount: number; - averageScoreAcrossAll: number; - resultsPublished: boolean; - judgesAssigned: number; - results: components['schemas']['AggregatedJudgingResultDto'][]; + applicationWindowCloseAt?: string | null; + maxApplicants?: number | null; + shortlistSize?: number | null; + reputationMinimum?: number | null; + prizeTiers: components['schemas']['BountyPrizeTierPublicDto'][]; + organization: components['schemas']['BountyOrganizationPublicDto']; + /** @description On-chain event id once published; null while in draft. */ + escrowEventId?: string | null; + escrowTxHash?: string | null; /** Format: date-time */ - generatedAt: string; - /** @description Manual winner assignments override (submissionId -> rank) */ - winnerOverrides?: { - [key: string]: number; - }; - metadata: components['schemas']['JudgingResultsMetadataDto']; - }; - SetPlacementWinnerDto: { - /** @description The submission to award this placement to. */ - submissionId: string; - }; - InviteJudgeDto: { - /** @example judge@example.com */ - email: string; - /** @description Optional public display name for the judge */ - displayName?: string; - /** @description Optional title/role shown with the judge (e.g. "Time Traveler"). */ - title?: string; - /** @description Personal message included in the invitation email */ - message?: string; - /** @description Override expiry in days (default 14). Maximum 60 to prevent indefinite invitations. */ - expiresInDays?: number; + createdAt: string; }; - BulkInviteJudgesDto: { - /** @description Up to 25 judges per request */ - invites: components['schemas']['InviteJudgeDto'][]; + BountyPublicListDto: { + bounties: components['schemas']['BountyPublicDto'][]; + total: number; + page: number; + limit: number; }; - BulkInviteRowResultDto: { - email: string; + GrantWinnerDistributionEntryDto: { /** - * @description 'invited' = sent; 'failed' = skipped with a reason. - * @enum {string} + * @description 1-indexed winner position + * @example 1 */ - status: 'invited' | 'failed'; - /** @description Failure reason when status is failed. */ - reason?: string; - }; - BulkInviteResultDto: { - results: components['schemas']['BulkInviteRowResultDto'][]; - /** @description Count of invitations sent. */ - invited: number; - /** @description Count of rows that failed / were skipped. */ - failed: number; - }; - RecommendationThresholdDto: { - id: string; - hackathonId: string; - /** @description null = overall threshold; otherwise the scoped track id. */ - trackId?: string | null; - /** @description Top percent (0-100). */ - topPercent: number; - }; - SetRecommendationThresholdDto: { - /** @description Track id to scope the threshold to; omit for the overall cut. */ - trackId?: string; + position: number; /** - * @description Top percent (0-100) of submissions flagged as recommended. - * @example 10 + * @description Percent of total_budget for this position. All sum to 100. + * @example 100 */ - topPercent: number; + percent: number; }; - RecommendationComputeDiagnosticsDto: { - /** @description Submissions currently SHORTLISTED. */ - shortlistedSubmissions: number; - /** @description Shortlisted submissions with at least one counted score (active judge or promoted AI scorecard; advisory AI_ASSIST excluded). These are the only submissions a threshold can rank. */ - scoredSubmissions: number; - /** @description Whether an overall (all-submissions) cut is set. */ - overallThresholdConfigured: boolean; - /** @description Number of per-track cuts configured. */ - trackThresholdsConfigured: number; + PublishGrantEscrowDto: { /** - * @description Human-readable reasons explaining the outcome (e.g. why nothing was flagged). Empty when the compute produced recommendations with nothing outstanding. - * @example [ - * "No recommendation thresholds are configured. Set a top-X% cut (overall or per track), then recompute." - * ] + * @description Organizer's Stellar G-address that signs the create_event transaction. + * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ */ - reasons: string[]; - }; - RecommendationComputeResultDto: { - /** @description Submissions flagged recommendedOverall. */ - overallRecommended: number; + ownerAddress: string; /** - * @description Per-track recommended counts. - * @example [ - * { - * "trackId": "trk_1", - * "recommended": 3 - * } - * ] + * @description Whitelisted Stellar Asset Contract address. + * @example CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA */ - tracks: string[]; - /** @description Why the compute produced what it did, so an empty result is never silent. */ - diagnostics: components['schemas']['RecommendationComputeDiagnosticsDto']; + tokenAddress: string; + /** + * @description Total budget in token-native units (NOT stroops). + * @example 500 + */ + budget: string; + /** + * @description Number of milestones (n) for the ReleaseKind::Multi(n) release_kind. Per-recipient amount is total_budget * winner_share% / 100 / n_milestones. + * @example 2 + */ + nMilestones: number; + /** + * @description Optional submission deadline (Unix seconds). + * @example 1804383600 + */ + submissionDeadline?: number; + /** @description Override the winner distribution. Defaults to 100% to position 1. */ + winnerDistribution?: components['schemas']['GrantWinnerDistributionEntryDto'][]; + /** @description Override the public content_uri. Defaults to /grants//content. */ + contentUri?: string; + /** + * @description Signing path. EXTERNAL (default) or MANAGED. + * @default EXTERNAL + * @enum {string} + */ + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - AcceptJudgeInvitationDto: { - /** @description Optional display name override. If omitted, the inviter-provided displayName (or the user’s account name) is used. */ - displayName?: string; + GrantEscrowOpResponseDto: { + id: string; + opId: string; + kind: string; + status: string; + entityKind: string; + entityId: string; + unsignedXdr?: string | null; + signerHint?: string | null; + txHash?: string | null; + errorCode?: string | null; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + updatedAt: string; }; - PublishedInfoFormDataDto: { - /** @example Web3 Innovation Hackathon */ - name: string; - /** @example https://example.com/banner.png */ - banner: string; - /** @example Build products for the decentralized future. */ - description: string; - categories: ( - | 'DeFi' - | 'NFTs' - | 'DAOs' - | 'Layer 2' - | 'Cross-chain' - | 'Web3 Gaming' - | 'Social Tokens' - | 'Infrastructure' - | 'Privacy' - | 'Sustainability' - | 'Real World Assets' - | 'Other' - )[]; + CancelGrantEscrowDto: { + /** @description Organizer's Stellar G-address. */ + ownerAddress: string; /** - * @example virtual + * @default EXTERNAL * @enum {string} */ - venueType: 'virtual' | 'physical'; - /** @example Build the future of Web3 */ - tagline: string; - /** @example Nigeria */ - country?: string; - /** @example Lagos */ - state?: string; - /** @example Ikeja */ - city?: string; - /** @example Eko Convention Center */ - venueName?: string; - /** @example Plot 1415 Adetokunbo Ademola St */ - venueAddress?: string; - /** @example web3-innovation-hackathon */ - slug?: string; + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - PublishedSponsorPartnerDto: { - /** @example sp-1 */ - id: string; - /** @example Stellar Foundation */ - name?: string; - /** @example https://example.com/logo.png */ - logo?: string; - /** @example https://stellar.org */ - link?: string; + GrantWinnerSelectionDto: { + /** @description GrantApplication.id to declare as a winner. The application must already have applicantAddress set (the Stellar G-address receiving the grant). */ + grantApplicationId: string; + /** + * @description Winner position, 1-indexed. + * @example 1 + */ + position: number; + /** @example 20 */ + creditEarn?: number; + /** @example 50 */ + reputationBump?: number; }; - PublishedCollaborationFormDataDto: { - /** @example organizer@boundless.dev */ - contactEmail: string; - /** @example @boundless */ - telegram?: string; - /** @example boundless-hackathon */ - discord?: string; + SelectGrantWinnersDto: { + ownerAddress: string; + selections: components['schemas']['GrantWinnerSelectionDto'][]; /** - * @example [ - * "https://x.com/boundless" - * ] + * @default EXTERNAL + * @enum {string} */ - socialLinks: string[]; - sponsorsPartners: components['schemas']['PublishedSponsorPartnerDto'][]; + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - UpdatePublishedHackathonContentDto: { - information?: components['schemas']['PublishedInfoFormDataDto']; - collaboration?: components['schemas']['PublishedCollaborationFormDataDto']; + ClaimGrantMilestoneDto: { + ownerAddress: string; + /** @description GrantMilestone.id to claim payment for. */ + grantMilestoneId: string; + /** + * @default EXTERNAL + * @enum {string} + */ + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - PublishedPhaseDto: { - /** @example Building Phase */ - name: string; - /** @example 2026-04-01T00:00:00.000Z */ - startDate: string; - /** @example 2026-04-10T00:00:00.000Z */ - endDate: string; - /** @example Core build phase for teams */ - description?: string; + GrantSubmitSignedXdrDto: { + signedXdr: string; }; - PublishedTimelineFormDataDto: { - /** @example 2026-04-01T00:00:00.000Z */ - startDate?: string; - /** @example 2026-04-15T00:00:00.000Z */ - submissionDeadline?: string; - /** @example Africa/Lagos */ - timezone?: string; + ContributeGrantDto: { + /** @description Contributor's Stellar G-address. Must match caller's wallet. */ + applicantAddress: string; /** - * @description Optional. When null, registration stays open until submission deadline. - * @example 2026-04-02T00:00:00.000Z + * @description Amount in token-native units. Must be >= 10 USDC. + * @example 30 */ - registrationDeadline?: string; + amount: string; /** - * @description Optional judging deadline. When null, no judging phase is rendered on the timeline. - * @example 2026-04-18T00:00:00.000Z + * @default EXTERNAL + * @enum {string} */ - judgingDeadline?: string; - phases?: components['schemas']['PublishedPhaseDto'][]; + fundingMode: 'EXTERNAL' | 'MANAGED'; }; - PublishedParticipantFormDataDto: { - /** @enum {string} */ - participantType: 'individual' | 'team' | 'team_or_individual'; - /** @example 2 */ - teamMin?: number; - /** @example 5 */ - teamMax?: number; + GrantPublicListItemDto: { /** - * @description Optional cap on total participants. null = unlimited. Can be updated after publishing. - * @example 200 + * @description Grant id. + * @example grant_123 */ - maxParticipants?: number; - /** @example true */ - require_github?: boolean; - /** @example false */ - require_demo_video?: boolean; - /** @example true */ - require_other_links?: boolean; - detailsTab?: boolean; - participantsTab?: boolean; - resourcesTab?: boolean; - submissionTab?: boolean; - announcementsTab?: boolean; - discussionTab?: boolean; - winnersTab?: boolean; - sponsorsTab?: boolean; - joinATeamTab?: boolean; - rulesTab?: boolean; - }; - UpdatePublishedHackathonScheduleDto: { - timeline?: components['schemas']['PublishedTimelineFormDataDto']; - participation?: components['schemas']['PublishedParticipantFormDataDto']; - }; - PublishedPrizeTierDto: { - /** @example tier-1 */ id: string; - /** @example 1st Place */ - place: string; - /** @example 5000 */ - prizeAmount: string; - /** @example USDC */ - currency?: string; - /** @example Top overall project */ - description?: string; /** - * @description Display rank / ordering of the tier (1 = highest) - * @example 1 + * @description Underlying project title used as the card title. + * @example On-chain governance research */ - rank?: number; - /** @example 70 */ - passMark: number; - /** @enum {string} */ - kind?: 'OVERALL' | 'TRACK'; - /** @description Required when kind=TRACK. References a HackathonTrack id. */ - trackId?: string; - }; - PublishedRewardsFormDataDto: { - prizeTiers?: components['schemas']['PublishedPrizeTierDto'][]; - prizes?: components['schemas']['PrizeWriteDto'][]; + title: string; /** - * @description Manual winner assignments override (submissionId -> rank) - * @example { - * "sub-1": 1, - * "sub-2": 2 - * } + * @description Short tagline/summary. Empty string when none is available. + * @example Funding research into delegated voting models. */ - winnerOverrides?: { - [key: string]: number; - }; - /** @enum {string} */ - prizeStructure?: 'OVERALL_ONLY' | 'OVERALL_AND_TRACKS' | 'TRACKS_ONLY'; - tracksMaxPerSubmission?: number; - allowWinnerStacking?: boolean; - }; - UpdatePublishedHackathonFinancialDto: { - rewards: components['schemas']['PublishedRewardsFormDataDto']; - }; - AdvancedSettingsFormDataDto: { - /** @example true */ - isPublic: boolean; - /** @example false */ - allowLateRegistration: boolean; - /** @example true */ - requireApproval: boolean; - /** @example 500 */ - maxParticipants?: number; - /** @example hackathons.boundless.dev */ - customDomain?: string; - /** @example true */ - enableDiscord: boolean; - /** @example https://discord.gg/boundless */ - discordInviteLink?: string; - /** @example true */ - enableTelegram: boolean; - /** @example https://t.me/boundless */ - telegramInviteLink?: string; - }; - UpdatePublishedHackathonAdvancedSettingsDto: { - advancedSettings: components['schemas']['AdvancedSettingsFormDataDto']; - }; - SetHackathonAccessDto: { - /** @enum {string} */ - visibility: 'PUBLIC' | 'PRIVATE'; - /** @description Access password. Required when first making a hackathon private; ignored (cleared) when visibility is PUBLIC. */ - password?: string; - }; - InvitePartnerDto: { - /** @example sponsor@partner.io */ - partnerEmail: string; - /** @example Acme Corp */ - partnerName: string; - /** @example https://cdn.example.com/logo.png */ - partnerLogo?: string; - /** @example https://acme.io */ - partnerLink?: string; + summary: string; /** - * @description Pledged amount in USDC - * @example 1000 + * @description Banner or thumbnail image URL. + * @example https://cdn.boundless.dev/grants/abc.png */ - pledgedAmount: number; + coverImageUrl: string | null; /** - * @default USDC - * @example USDC + * @description Lowercased grant status. + * @example open */ - currency: string; - /** @description Optional message included in the invite */ - message?: string; + status: string; /** - * @description Whether the partner is shown publicly on the hackathon page - * @default true + * @description Total program budget in USDC, stringified. + * @example 50000 */ - showPublicly: boolean; - }; - AllocationTargetDto: { - /** @description PrizePlacement id (the fundable slot) this allocation adds to. Placements are created in the Rewards step. */ - placementId: string; - /** @description Net amount (USDC) to add to the placement */ - amount: number; - }; - AllocateContributionDto: { - /** @description One or more tiers to allocate this contribution into */ - targets: components['schemas']['AllocationTargetDto'][]; - }; - PrepareFundTransactionDto: { - /** @description Stellar address of the partner wallet that will sign the transaction */ - signerAddress: string; - }; - SubmitSignedTransactionDto: { - /** @description Signed transaction XDR returned by the partner wallet */ - signedXdr: string; - }; - TrackCustomQuestionDto: { - /** @description Stable id, unique within the track. */ - id: string; - /** @description Question label shown on the submission form. */ - label: string; + totalBudgetUsdc: string | null; /** - * @description Input type. 'short' = single-line, 'long' = textarea, 'url' = URL field. - * @enum {string} + * @description Owning organization id, if any. + * @example org_123 */ - type: 'short' | 'long' | 'url'; - /** @description Optional maxLength override (defaults: short=200, long=1000). */ - maxLength?: number; - /** @description Whether an answer is required. */ - required?: boolean; - }; - TrackRequiredArtifactDto: { - /** @description Stable id, unique within the track. */ - id: string; - /** @description Artifact label (e.g. "Figma file URL"). */ - label: string; + organizationId: string | null; /** - * @description Artifact type — drives the placeholder + light hint UI. - * @enum {string} + * @description Owning organization display name. + * @example Boundless Labs + */ + organizationName: string | null; + /** + * @description Owning organization logo URL. + * @example https://cdn.boundless.dev/orgs/boundless.png + */ + organizationLogoUrl: string | null; + /** + * @description Underlying project category, if any. + * @example governance + */ + category: string | null; + /** + * @description Total submitted applications count. + * @example 12 + */ + applicationCount: number; + /** + * @description When the grant was created. + * @example 2026-05-01T12:00:00.000Z */ - type: 'figma' | 'github' | 'video' | 'pdf' | 'url'; - /** @description Whether submitting this artifact is required. */ - required?: boolean; - }; - TrackResponseDto: { - id: string; - hackathonId: string; - slug: string; - name: string; - description?: string; - type?: string; - /** @enum {string} */ - eligibility: 'OPT_IN' | 'OPEN'; - displayOrder: number; - isArchived: boolean; - /** @description Count of submissions that have opted into this track. Useful for organizer dashboards. */ - entryCount: number; - /** @description Per-track customization (Phase B). */ - prompt?: string; - customQuestions?: components['schemas']['TrackCustomQuestionDto'][]; - requiredArtifacts?: components['schemas']['TrackRequiredArtifactDto'][]; - /** Format: date-time */ createdAt: string; - /** Format: date-time */ - updatedAt: string; - }; - CustomQuestionResponseDto: { - id: string; - hackathonId: string; - /** @enum {string} */ - scope: 'REGISTRATION' | 'SUBMISSION'; - label: string; - helpText?: string | null; - /** @enum {string} */ - type: - | 'SHORT' - | 'LONG' - | 'URL' - | 'SINGLE_SELECT' - | 'MULTI_SELECT' - | 'BOOLEAN'; - required: boolean; - options?: string[] | null; - maxLength?: number | null; - displayOrder: number; }; - UpdateTracksConfigDto: { - /** @description Max number of tracks a single submission may enter (1-20). */ - tracksMaxPerSubmission?: number; + GrantPublicListResponseDto: { + items: components['schemas']['GrantPublicListItemDto'][]; + /** + * @description Total count of grants matching the filters. + * @example 84 + */ + total: number; + /** + * @description Current page (1-indexed). + * @example 1 + */ + page: number; + /** + * @description Items per page. + * @example 20 + */ + limit: number; }; - CreateTrackDto: { + /** + * @description The pillar this opportunity belongs to. + * @enum {string} + */ + OpportunityType: 'BOUNTY' | 'HACKATHON' | 'GRANT' | 'CROWDFUNDING'; + OpportunityListItemDto: { /** - * @description Human-readable track name shown on the hackathon page. - * @example Best UI/UX + * @description The pillar this opportunity belongs to. + * @example BOUNTY */ - name: string; + type: components['schemas']['OpportunityType']; /** - * @description URL-safe handle, unique within the hackathon. Auto-generated from name if omitted. - * @example best-ui-ux + * @description Pillar-local primary key. Globally unique within a type. + * @example ckxyz123 */ - slug?: string; + id: string; /** - * @description Short blurb shown in the track picker and on results. - * @example Best end-to-end user experience and visual polish. + * @description Optional URL slug. Hackathons and crowdfunding campaigns expose one; bounties and grants do not. + * @example open-defi-hack */ - description?: string; + slug: string | null; /** - * @description Free-form classifier for badge styling. Common values: skill, technology, theme, special. - * @example skill + * @description Display title for the card. + * @example Build a DAO governance dashboard */ - type?: string; + title: string; /** - * @description OPT_IN (default): submitters explicitly enter. OPEN: every submission auto-eligible. - * @default OPT_IN - * @enum {string} + * @description Short blurb shown under the title. Empty string when the underlying pillar has no summary; never null. + * @example Ship a React dashboard that visualizes on-chain governance votes. */ - eligibility: 'OPT_IN' | 'OPEN'; + summary: string; /** - * @description Sort order. Lower numbers render first. Defaults to 0. - * @example 10 + * @description Banner or hero image URL for the card. + * @example https://cdn.boundless.dev/banners/abc.png */ - displayOrder?: number; + coverImageUrl: string | null; /** - * @description Single open-ended prompt shown on the submission form. When set, the submitter must answer to opt in. - * @example Why does this project fit Best UI/UX? + * @description Owning organization id. Null on crowdfunding or grants that lack an organization. + * @example org_123 */ - prompt?: string; - customQuestions?: components['schemas']['TrackCustomQuestionDto'][]; - requiredArtifacts?: components['schemas']['TrackRequiredArtifactDto'][]; - }; - UpdateTrackDto: { - name?: string; - slug?: string; - description?: string; - type?: string; - /** @enum {string} */ - eligibility?: 'OPT_IN' | 'OPEN'; - displayOrder?: number; - /** @description Soft-archive instead of delete when entries already exist. Cannot be unset via this endpoint; recreate the track if needed. */ - isArchived?: boolean; - /** @description Single open-ended prompt. */ - prompt?: string; - customQuestions?: components['schemas']['TrackCustomQuestionDto'][]; - requiredArtifacts?: components['schemas']['TrackRequiredArtifactDto'][]; - }; - CustomQuestionWriteDto: { - /** @enum {string} */ - scope: 'REGISTRATION' | 'SUBMISSION'; - /** @description Question shown to the participant. */ - label: string; - /** @description Optional helper text under the field. */ - helpText?: string; + organizationId: string | null; /** - * @default SHORT - * @enum {string} + * @description Owning organization display name. + * @example Boundless Labs */ - type: - | 'SHORT' - | 'LONG' - | 'URL' - | 'SINGLE_SELECT' - | 'MULTI_SELECT' - | 'BOOLEAN'; - /** @description Whether an answer is required. */ - required?: boolean; - /** @description Choices for SINGLE_SELECT / MULTI_SELECT. */ - options?: string[]; - /** @description Optional length cap for SHORT / LONG answers. */ - maxLength?: number; - /** @description Sort order; lower renders first. */ - displayOrder?: number; - }; - UpsertCustomQuestionsDto: { - questions: components['schemas']['CustomQuestionWriteDto'][]; - }; - RequestFundingOtpResponseDto: { - /** @description Whether funding step-up is enforced for this action */ - required: boolean; - /** @description True when a recent verification is still valid; the client can fund without entering a new code */ - alreadyVerified: boolean; - /** @description True when a fresh code was just emailed */ - sent: boolean; - /** @description Seconds until the emailed code expires (0 when none sent) */ - expiresInSeconds: number; - }; - VerifyFundingOtpDto: { + organizationName: string | null; /** - * @description The 6-digit code emailed to the organizer - * @example 123456 + * @description Owning organization logo URL. + * @example https://cdn.boundless.dev/orgs/boundless.png */ - code: string; - }; - VerifyFundingOtpResponseDto: { - /** @description True when the code was accepted */ - verified: boolean; - /** @description Seconds the funding authorization remains valid */ - expiresInSeconds: number; - }; - WinnerDistributionEntryDto: { + organizationLogoUrl: string | null; /** - * @description Winner position (1-indexed; 1 = top winner). - * @example 1 + * @description Lowercased pillar-specific status (e.g. "open", "upcoming", "active"). + * @example open */ - position: number; + status: string; /** - * @description Percentage of the total budget allocated to this position. All entries must sum to exactly 100. - * @example 100 + * @description Total advertised reward in USDC, stringified. Null when not applicable to the pillar. + * @example 5000.00 */ - percent: number; - }; - PublishHackathonEscrowDto: { + totalRewardUsdc: string | null; /** - * @description Stellar G-address that will own and sign the on-chain create_event transaction. For managed wallets, this is the platform-derived address tied to the organizer's account; for connected/multisig, it's the org treasury's G-address. - * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ + * @description Funded amount so far in USDC, crowdfunding only. Null elsewhere. + * @example 1234.56 */ - ownerAddress: string; + fundedAmountUsdc: string | null; /** - * @description Stellar Asset Contract (SAC) address the prize pool is denominated in. Must be whitelisted on the events contract (see admin runbook). - * @example CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA + * @description When this opportunity went live. Falls back to createdAt when the pillar lacks publishedAt. + * @example 2026-05-01T12:00:00.000Z */ - tokenAddress: string; + publishedAt: string; /** - * @description Total prize budget in token-native units (e.g. 1000 = 1000 USDC, NOT stroops). Use a string when the value exceeds JavaScript's safe integer range. The backend converts to stroops via *10^7. - * @example 1000 + * @description When the opportunity window opens. + * @example 2026-05-15T00:00:00.000Z + */ + startsAt: string | null; + /** + * @description Application or submission deadline. Null for open-ended pillars (notably grants). + * @example 2026-06-30T23:59:59.000Z + */ + endsAt: string | null; + /** + * @description Approximate participant count. Null when the pillar has no relation to count from. + * @example 42 + */ + participantCount: number | null; + /** + * @description Pillar-defined tags. Empty array for pillars without a tag field; never null. + * @example [ + * "stellar", + * "defi" + * ] + */ + tags: string[]; + /** + * @description Path to the detail page on the frontend. + * @example /bounties/ckxyz123 + */ + detailUrl: string; + /** + * @description True when this opportunity is currently featured. Drives the page-1 boost in the marketplace. + * @example false */ - budget: string; - /** @description Optional override for the winner distribution. Each entry maps a position to a percent of total_budget. Percents must sum to exactly 100. Defaults to a single winner at position 1 taking 100%. */ - winnerDistribution?: components['schemas']['WinnerDistributionEntryDto'][]; + isFeatured: boolean; + }; + OpportunityListResponseDto: { + /** @description Cards in the current page, post-merge. */ + items: components['schemas']['OpportunityListItemDto'][]; /** - * @description Override for the public content_uri the contract stores against the event. Defaults to https://api.boundless.fi/hackathons//content. - * @example https://api.boundless.fi/hackathons/abc/content + * @description Opaque cursor for the next page. Null when no more results are available. + * @example eyJzb3J0IjoibmV3ZXN0IiwicHJpbWFyeSI6IjIwMjYtMDUtMTVUMDA6MDA6MDAuMDAwWiIsImlkIjoiY2t4eXoxMjMifQ */ - contentUri?: string; + nextCursor: string | null; /** - * @description Signing path. Defaults to EXTERNAL (return unsigned XDR for the caller to sign). Set to MANAGED to have the backend sign + submit using the caller user's managed wallet; the response carries the op in PENDING_CONFIRM with a txHash. - * @default EXTERNAL - * @example MANAGED - * @enum {string} + * @description Total rows matching the current filter combo (type, status, search, tags), summed across pillar adapters. Cursor-blind, so stable across paginated requests with the same filters. + * @example 137 */ - fundingMode: 'EXTERNAL' | 'MANAGED'; - /** @description For MANAGED funding, the organization treasury wallet to fund from. When set, the backend signs with that treasury (managed) wallet instead of the caller's personal wallet; ownerAddress must match the treasury wallet address. Omit to fund from the personal managed wallet. */ - sourceWalletId?: string; + total: number; }; - HackathonEscrowOpResponseDto: { + SubscribeDto: { /** - * @description Internal uuid for the EscrowOp row. Use this for follow-up calls. - * @example cmpwiox7u0000yy4404ojbk9t + * @description Email address to subscribe + * @example user@example.com */ - id: string; + email: string; /** - * @description Hex-encoded 32-byte op_id derived deterministically from the operation parameters. Used by the on-chain idempotency check. - * @example 3cc257d743b1b44423dc8dbd417aedfe6e47ad489b5d301a2fbec5284d36de1c + * @description Subscriber name + * @example John Doe */ - opId: string; + name?: string; /** - * @description Contract operation kind. - * @example CREATE_EVENT - * @enum {string} + * @description Subscription source + * @example website */ - kind: - | 'CREATE_EVENT' - | 'CANCEL_EVENT' - | 'ADD_FUNDS' - | 'APPLY_TO_BOUNTY' - | 'WITHDRAW_APPLICATION' - | 'SUBMIT' - | 'WITHDRAW_SUBMISSION' - | 'SELECT_WINNERS' - | 'CLAIM_MILESTONE'; + source?: string; /** - * @description Status of the EscrowOp in its lifecycle. - * @example PENDING_SIGN - * @enum {string} + * @description Topic tags for subscription preferences + * @example [ + * "updates", + * "hackathons" + * ] */ - status: - | 'PENDING_BUILD' - | 'PENDING_SIGN' - | 'PENDING_SUBMIT' - | 'PENDING_CONFIRM' - | 'COMPLETED' - | 'FAILED' - | 'CANCELLED'; + tags?: string[]; + }; + UnsubscribeDto: { /** - * @description Entity kind the op operates on. Matches the application-level row (hackathon, bounty, grant, etc.). - * @example HACKATHON + * @description Email address to unsubscribe + * @example user@example.com */ - entityKind: string; + email: string; + }; + UpdatePreferencesDto: { /** - * @description Application-level row id this op acts on. - * @example cmpwihilf0000fd44iln3dzbg + * @description Subscriber email address + * @example user@example.com */ - entityId: string; + email: string; /** - * @description Unsigned XDR transaction the wallet must sign. Present after the build phase completes (PENDING_SIGN onwards). - * @example AAAAAgAAAACdiamX7q...truncated... + * @description Topic tags to subscribe to. Valid: bounties, hackathons, grants, updates + * @example [ + * "updates", + * "hackathons" + * ] */ - unsignedXdr?: string | null; + tags: string[]; + }; + CreateNewsletterCampaignDto: { /** - * @description Stellar G-address expected to sign this op. The wallet routing layer on the webapp uses this to pick the right signer. - * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ + * @description Campaign email subject line + * @example Boundless Weekly: New Hackathon Announced! */ - signerHint?: string | null; + subject: string; /** - * @description Soroban tx hash assigned at submit time. Set once the op reaches PENDING_CONFIRM or beyond. - * @example daafec9027da007b54eec34c54a5919edd7a8682bc96ccf7c7072982305cfa3b + * @description Campaign HTML content. Supports {{name}} placeholder. + * @example

Hello {{name}}

Check out our latest hackathon!

*/ - txHash?: string | null; + content: string; /** - * @description Contract error code when the op transitions to FAILED. Mirrors the on-chain error name (e.g. "InsufficientEscrow", "OpAlreadySeen", "txBadAuth"). - * @example txBadAuth + * @description Preview text shown in email clients + * @example New hackathon with $10k in prizes */ - errorCode?: string | null; + previewText?: string; + /** + * @description Target subscriber tags — only subscribers with matching tags receive the campaign + * @example [ + * "hackathons", + * "updates" + * ] + */ + tags?: string[]; + }; + User: { + id?: string; + name: string; + email: string; + /** @default false */ + readonly emailVerified: boolean; + image?: string; /** * Format: date-time - * @description Row creation time. - * @example 2026-06-02T11:45:36.927Z + * @default Generated at runtime */ createdAt: string; /** * Format: date-time - * @description Row last-updated time. - * @example 2026-06-02T11:45:44.310Z + * @default Generated at runtime */ updatedAt: string; + username?: string; + displayUsername?: string; + /** @default false */ + readonly twoFactorEnabled: boolean; + readonly lastLoginMethod?: string; + readonly role?: string; + /** @default false */ + readonly banned: boolean; + readonly banReason?: string; + /** Format: date-time */ + readonly banExpires?: string; }; - CancelHackathonEscrowDto: { - /** - * @description Organizer's Stellar G-address. Must match the on-chain hackathon owner. - * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ - */ - ownerAddress: string; + Session: { + id?: string; + /** Format: date-time */ + expiresAt: string; + token: string; /** - * @description Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side with the caller's platform-held wallet. - * @default EXTERNAL - * @enum {string} + * Format: date-time + * @default Generated at runtime */ - fundingMode: 'EXTERNAL' | 'MANAGED'; - /** @description For MANAGED, the organization treasury wallet to sign with (the event contract-auth identity). ownerAddress must match it. Omit to use the caller's personal managed wallet. */ - sourceWalletId?: string; + createdAt: string; + /** Format: date-time */ + updatedAt: string; + ipAddress?: string; + userAgent?: string; + userId: string; + activeOrganizationId?: string; + impersonatedBy?: string; }; - HackathonWinnerSelectionDto: { + Account: { + id?: string; + accountId: string; + providerId: string; + userId: string; + accessToken?: string; + refreshToken?: string; + idToken?: string; + /** Format: date-time */ + accessTokenExpiresAt?: string; + /** Format: date-time */ + refreshTokenExpiresAt?: string; + scope?: string; + password?: string; /** - * @description ID of the winning submission. The payout recipient is resolved server-side = the submitter's (team leader's) Boundless managed wallet; no on-chain submission anchor is required. - * @example cmq7sgwst0001abcd1234efgh + * Format: date-time + * @default Generated at runtime */ - submissionId: string; + createdAt: string; + /** Format: date-time */ + updatedAt: string; + }; + Verification: { + id?: string; + identifier: string; + value: string; + /** Format: date-time */ + expiresAt: string; /** - * @description Winner position, 1-indexed. Must exist in the hackathon's on-chain winner_distribution. - * @example 1 + * Format: date-time + * @default Generated at runtime */ - position: number; + createdAt: string; /** - * @description Override the platform default credit_earn for this position. Defaults to 20/10/5 for positions 1/2/3 and 3 for the rest. Capped at 100 by the contract. - * @example 20 + * Format: date-time + * @default Generated at runtime */ - creditEarn?: number; + updatedAt: string; + }; + TwoFactor: { + id?: string; + secret: string; + backupCodes: string; + userId: string; + }; + Organization: { + id?: string; + name: string; + slug: string; + logo?: string; + /** Format: date-time */ + createdAt: string; + metadata?: string; + }; + Member: { + id?: string; + organizationId: string; + userId: string; + /** @default member */ + role: string; + /** Format: date-time */ + createdAt: string; + }; + Invitation: { + id?: string; + organizationId: string; + email: string; + role?: string; + /** @default pending */ + status: string; + /** Format: date-time */ + expiresAt: string; /** - * @description Override the platform default reputation_bump for this position. Defaults to 50/25/10 for positions 1/2/3 and 5 for the rest. - * @example 50 + * Format: date-time + * @default Generated at runtime */ - reputationBump?: number; + createdAt: string; + inviterId: string; + }; + Passkey: { + id?: string; + name?: string; + publicKey: string; + userId: string; + credentialID: string; + counter: number; + deviceType: string; + backedUp: boolean; + transports?: string; + /** Format: date-time */ + createdAt?: string; + aaguid?: string; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} +export type $defs = Record; +export interface operations { + AppController_getHello: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_getNotifications: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_getUnreadCount: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_markAsRead: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_markAllAsRead: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_deleteNotification: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_getPreferences: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_updatePreferences: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['NotificationPreferencesDto']; + }; + }; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_sendTestNotification: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + NotificationsController_triggerMarketingCron: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SettingsController_getSettings: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Settings retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + SettingsController_updateNotificationSettings: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** @description Notification settings object */ + requestBody: { + content: { + 'application/json': string; + }; + }; + responses: { + /** @description Notification settings updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - SelectHackathonWinnersDto: { - /** - * @description Organizer's Stellar G-address — a hint only. select_winners is authorized by the event manager resolved on-chain (the org treasury for new events), which the backend signs with server-side; this value is used only as a fallback when that on-chain read is unavailable (legacy/pre-upgrade events). Omit for the MANAGED flow. - * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ - */ - ownerAddress?: string; - /** @description Winners to declare, each by winning submissionId + position. The payout recipient is resolved server-side = the submitter's (team leader's) Boundless managed wallet; no on-chain submission anchor is required. Positions and submissionIds must be unique within the array. */ - selections: components['schemas']['HackathonWinnerSelectionDto'][]; - /** - * @description Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; - /** @description For MANAGED, the organization treasury wallet to sign with (the event contract-auth identity). ownerAddress must match it. Omit to use the caller's personal managed wallet. */ - sourceWalletId?: string; + }; + SettingsController_updatePrivacySettings: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - HackathonSubmitSignedXdrDto: { - /** - * @description The fully-signed XDR returned by the wallet (Freighter, Albedo, platform-managed signer, or a multisig coordinator). Backend submits this verbatim to Soroban RPC. - * @example AAAAAgAAAACdiamX7q...truncated... - */ - signedXdr: string; + requestBody: { + content: { + 'application/json': components['schemas']['UpdatePrivacySettingsDto']; + }; }; - SubmitHackathonDto: { - /** - * @description Caller's Stellar G-address. Must match the caller's linked wallet. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; - /** - * @description On-chain content URI for the submission. Stored verbatim in the contract's submission anchor; off-chain content lives wherever the URI points (IPFS, S3, GitHub PR, etc.). - * @example ipfs://Qm.../project.json - */ - contentUri: string; + responses: { + /** @description Privacy settings updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - WithdrawHackathonSubmissionDto: { - /** - * @description Caller's Stellar G-address. Must match the caller's linked wallet. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + }; + SettingsController_updateAppearanceSettings: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - ContributeHackathonDto: { - /** - * @description Caller's Stellar G-address. Must match the caller's linked wallet. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; - /** - * @description Amount in token-native units (e.g. 30 = 30 USDC, NOT stroops). Must be >= 10 USDC (contract minimum). - * @example 30 - */ - amount: string; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateAppearanceSettingsDto']; + }; }; - CreateOrganizationDto: Record; - OrganizationProfileStatsDto: { - /** - * @description Number of projects under this organization - * @example 12 - */ - projectsCount: number; - /** - * @description Total hackathons run by this organization - * @example 5 - */ - totalHackathons: number; - /** - * @description Total bounties offered by this organization - * @example 8 - */ - totalBounties: number; - /** - * @description Total grants (projects with grants) under this organization - * @example 3 - */ - totalGrants: number; + responses: { + /** @description Appearance settings updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - OrganizationProfileDto: { - /** - * @description Organization ID - * @example org_1234567890 - */ - id: string; - /** - * @description Organization name - * @example Tech Innovators - */ - name: string; - /** - * @description Organization slug - * @example tech-innovators - */ - slug: string; - /** - * @description Logo URL - * @example https://example.com/logo.png - */ - logoUrl: string; - /** - * @description Organization description (from about or tagline) - * @example We are a community of developers building the future. - */ - description: string; - /** @description Key stats for the organization profile */ - stats: components['schemas']['OrganizationProfileStatsDto']; + }; + EarningsController_getEarningsPublic: { + parameters: { + query: { + /** @description Max activities to return (default 100) */ + limit?: number; + /** @description Offset for activity pagination */ + offset?: number; + /** @description Username of the profile to fetch earnings for */ + username: string; + }; + header?: never; + path?: never; + cookie?: never; }; - UpdateOrganizationDto: Record; - UpdateMemberRoleDto: Record; - InviteMemberDto: Record; - TreasuryWalletResponseDto: { - id: string; - organizationId: string; - /** @enum {string} */ - kind: 'MANAGED' | 'CONNECTED'; - publicKey: string; - label: string; - isDefault: boolean; - /** @enum {string} */ - status: 'ACTIVE' | 'ARCHIVED' | 'NEEDS_REVIEW'; - isMultisig: boolean; - multisigThreshold: number | null; - connectionMethod: string | null; - lastVerifiedAt: string | null; - createdAt: string; - updatedAt: string; + requestBody?: never; + responses: { + /** @description Public earnings retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['PublicEarningsResponseDto']; + }; + }; + /** @description Missing or invalid username */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - CreateManagedWalletDto: { - /** - * @description Display label for the wallet - * @example Main treasury - */ - label: string; + }; + EarningsController_getEarnings: { + parameters: { + query?: { + /** @description Max activities to return (default 100) */ + limit?: number; + /** @description Offset for activity pagination */ + offset?: number; + }; + header?: never; + path?: never; + cookie?: never; }; - RegisterConnectedWalletDto: { - /** @description G-address of the external wallet */ - publicKey: string; - /** - * @description Display label - * @example Company multisig - */ - label: string; - /** @enum {string} */ - connectionMethod: - | 'freighter' - | 'lobstr' - | 'albedo' - | 'xbull' - | 'hana' - | 'rabet' - | 'walletkit_generic'; + requestBody?: never; + responses: { + /** @description Earnings data retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['EarningsResponseDto']; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - UpdateTreasuryWalletDto: { - /** @description New display label */ - label?: string; - /** @description Make this the organization default */ - isDefault?: boolean; + }; + UserController_getProfile: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - WalletBalanceResponseDto: { - publicKey: string; - /** @description USDC balance */ - usdc: string; - /** @description XLM balance (fee float) */ - xlm: string; + requestBody?: never; + responses: { + /** @description User dashboard with profile, stats, chart data, activities graph, and recent activities retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['DashboardDto']; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - TreasuryPolicyRuleDto: { - /** @example 0 */ - min_usdc: number; - /** @example 1000 */ - max_usdc?: Record | null; - /** @example 1 */ - required_approvals: number; - /** - * @example [ - * "owner", - * "admin" - * ] - */ - approver_roles: string[]; + }; + UserController_getPublic: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - TreasuryPolicyResponseDto: { - organizationId: string; - defaultWalletId: string | null; - rules: components['schemas']['TreasuryPolicyRuleDto'][]; - /** @description True when no policy is saved yet (defaults returned) */ - isDefault: boolean; - updatedAt: string | null; + requestBody?: never; + responses: { + /** @description Public route accessed successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - UpdateTreasuryPolicyDto: { - rules: components['schemas']['TreasuryPolicyRuleDto'][]; - /** @description Default source wallet id */ - defaultWalletId?: string; + }; + UserController_getOptional: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - InitiateSpendDto: { - /** @description Treasury wallet to spend from */ - sourceWalletId: string; - /** @description Destination G-address or escrow contract id */ - destination: string; - /** - * @description Amount in USDC - * @example 2500.00 - */ - amount: string; - /** - * @description What the spend funds - * @example fund_hackathon_escrow - */ - purpose: string; - /** @enum {string} */ - referenceType?: 'hackathon' | 'bounty' | 'grant'; - referenceId?: string; + requestBody?: never; + responses: { + /** @description Optional auth route accessed successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - SpendRequestResponseDto: { - id: string; - organizationId: string; - sourceWalletId: string; - destination: string; - amount: string; - currency: string; - purpose: string; - referenceType: string | null; - referenceId: string | null; - initiatorUserId: string; - requiredApprovals: number; - approvals: Record[]; - status: string; - onChainTxHash: string | null; - createdAt: string; - approvedAt: string | null; + }; + UserController_getUserByUsername: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Username of the user to retrieve */ + username: string; + }; + cookie?: never; }; - SendTreasuryFundsDto: { - /** @description Wallet to send from */ - sourceWalletId: string; - /** - * @description Recipient Stellar address (starts with G) - * @example GA... - */ - destination: string; - /** - * @description Amount in USDC - * @example 250.00 - */ - amount: string; - /** - * @description What this payment is for (shown in your activity log) - * @example Contributor payout - */ - note?: string; + requestBody?: never; + responses: { + /** @description User profile retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - SendDestinationReadinessDto: { - /** @description Whether the recipient account exists on-chain */ - exists: boolean; - /** @description Whether the recipient has a USDC trustline (so it can receive USDC) */ - hasUsdcTrustline: boolean; + }; + UserController_getUserFollowers: { + parameters: { + query?: { + /** @description Pagination offset */ + offset?: number; + /** @description Number of followers to return */ + limit?: number; + }; + header?: never; + path: { + /** @description Username of the user */ + username: string; + }; + cookie?: never; }; - SpendDecisionDto: { - /** @description Optional note for the decision */ - note?: string; + requestBody?: never; + responses: { + /** @description Followers retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - BuildSpendXdrResponseDto: { - /** @description Unsigned transaction XDR to sign in-browser */ - unsignedXdr: string; - request: components['schemas']['SpendRequestResponseDto']; + }; + UserController_getUserFollowing: { + parameters: { + query?: { + /** @description Filter by entity type */ + entityType?: + | 'USER' + | 'PROJECT' + | 'ORGANIZATION' + | 'CROWDFUNDING_CAMPAIGN' + | 'BOUNTY' + | 'GRANT' + | 'HACKATHON'; + /** @description Pagination offset */ + offset?: number; + /** @description Number of following to return */ + limit?: number; + }; + header?: never; + path: { + /** @description Username of the user */ + username: string; + }; + cookie?: never; }; - SubmitSpendSignedXdrDto: { - /** @description The browser-signed transaction XDR */ - signedXdr: string; + requestBody?: never; + responses: { + /** @description Following list retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - TreasuryActorDto: { - id: string; - name: string | null; - image: string | null; + }; + ProfileController_getProfile: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - TreasuryAuditEntryDto: { - id: string; - action: string; - actorUserId: string | null; - actorKind: string; - /** @description Resolved profile of the actor (name + avatar), if a user. */ - actor: components['schemas']['TreasuryActorDto'] | null; - walletId: string | null; - spendRequestId: string | null; - details: { - [key: string]: unknown; - } | null; - createdAt: string; + requestBody?: never; + responses: { + /** @description Profile retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - TreasuryAuditLogResponseDto: { - data: components['schemas']['TreasuryAuditEntryDto'][]; - total: number; - page: number; - limit: number; + }; + ProfileController_updateProfile: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - ReceiptResponseDto: { - id: string; - /** @example RCPT-100001 */ - receiptNumber: string; - organizationId: string; - /** @example TREASURY_SEND */ - type: string; - /** @example Funds sent */ - typeLabel: string; - /** @example ISSUED */ - status: string; - /** @example OUTGOING */ - direction: string; - /** @example 250.00 */ - amount: string; - /** @example USDC */ - currency: string; - fromLabel: Record | null; - fromAddress: Record | null; - toLabel: Record | null; - toAddress: Record | null; - description: Record | null; - onChainTxHash: Record | null; - explorerUrl: Record | null; - network: Record | null; - issuedByUserId: Record | null; - issuedAt: string; - voidedAt: Record | null; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateProfileDto']; + }; }; - ReceiptListResponseDto: { - data: components['schemas']['ReceiptResponseDto'][]; - total: number; - page: number; - limit: number; + responses: { + /** @description Profile updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - SendReceiptDto: { - /** @description Where to email the receipt. Defaults to your account email. */ - email?: string; + }; + ProfileController_getProfileStats: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - VoidReceiptDto: { - /** @description Why the receipt is being voided */ - reason?: string; + requestBody?: never; + responses: { + /** @description Profile stats retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - CreateVoteDto: { - /** @description ID of the project being voted on */ - projectId: string; - /** - * @description Type of entity being voted on - * @enum {string} - */ - entityType: - | 'PROJECT' - | 'CROWDFUNDING_CAMPAIGN' - | 'HACKATHON_SUBMISSION' - | 'GRANT'; - /** - * @description Type of vote (UPVOTE or DOWNVOTE) - * @default UPVOTE - * @enum {string} - */ - voteType: 'UPVOTE' | 'DOWNVOTE'; - /** - * @description Weight of the vote - * @default 1 - */ - weight: number; + }; + ProfileController_getActivity: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - CreateBlogPostDto: { - /** - * @description Blog post title - * @example Getting Started with Stellar Smart Contracts - */ - title: string; - /** - * @description Blog post content in markdown format - * @example # Introduction - * - * This tutorial will teach you... - */ - content: string; - /** - * @description Short excerpt or summary - * @example Learn how to build your first smart contract on Stellar - */ - excerpt?: string; - /** - * @description Cover image URL - * @example https://res.cloudinary.com/demo/image/upload/v1234567890/post-cover.jpg - */ - coverImage?: string; - /** - * @description Post status - * @default DRAFT - * @example DRAFT - * @enum {string} - */ - status: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED' | 'SCHEDULED'; - /** - * @description Post tags - * @example [ - * "smart-contracts", - * "soroban", - * "tutorial" - * ] - */ - tags?: string[]; - /** - * @description Post categories - * @example [ - * "tutorials" - * ] - */ - categories?: string[]; - /** - * @description Mark as featured post - * @default false - * @example false - */ - isFeatured: boolean; - /** - * @description Pin post to top - * @default false - * @example false - */ - isPinned: boolean; - /** - * @description Reading time in minutes (auto-calculated if not provided) - * @example 5 - */ - readingTime?: number; - /** @description SEO title (overrides post title) */ - seoTitle?: string; - /** @description SEO meta description */ - seoDescription?: string; - /** - * @description SEO keywords - * @example [ - * "stellar", - * "blockchain", - * "smart contracts" - * ] - */ - seoKeywords?: string[]; - /** - * @description Schedule publication date (for SCHEDULED status) - * @example 2025-12-31T10:00:00Z - */ - scheduledFor?: string; - /** - * @description Generate AI content (excerpt, reading time, SEO, tags, category) if not provided - * @default false - * @example true - */ - generateAI: boolean; + requestBody?: never; + responses: { + /** @description Activity retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - UpdateBlogPostDto: Record; - MetricDataDto: { - /** - * @description The metric value - * @example 1250 - */ - value: number; - /** - * @description Percentage change - * @example 12.5 - */ - change: number; - /** - * @description Type of change - * @example positive - * @enum {string} - */ - changeType: 'positive' | 'negative' | 'neutral'; - /** - * @description Metric label - * @example Total Users - */ - label: string; - /** - * @description Additional description - * @example Active users in the platform - */ - description?: string; + }; + ProfileController_uploadAvatar: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - HackathonMetricDataDto: { - /** - * @description The metric value - * @example 1250 - */ - value: number; - /** - * @description Percentage change - * @example 12.5 - */ - change: number; - /** - * @description Type of change - * @example positive - * @enum {string} - */ - changeType: 'positive' | 'negative' | 'neutral'; - /** - * @description Metric label - * @example Total Users - */ - label: string; - /** - * @description Additional description - * @example Active users in the platform - */ - description?: string; - /** - * @description Additional hackathon info - * @example 3 active, 7 upcoming - */ - additionalInfo?: string; + requestBody: { + content: { + 'multipart/form-data': { + /** + * Format: binary + * @description Avatar image file + */ + avatar?: string; + }; + }; }; - OverviewMetricsDto: { - totalUsers: components['schemas']['MetricDataDto']; - organizations: components['schemas']['MetricDataDto']; - projects: components['schemas']['MetricDataDto']; - hackathons: components['schemas']['HackathonMetricDataDto']; + responses: { + /** @description Avatar uploaded successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - OverviewChartDataDto: { - data: components['schemas']['ChartDataPointDto'][]; - /** - * @description Time range for the chart - * @example 7d - * @enum {string} - */ - timeRange: '7d' | '30d' | '90d'; + }; + PreferencesController_getPreferences: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - AdminOverviewResponseDto: { - metrics: components['schemas']['OverviewMetricsDto']; - chart: components['schemas']['OverviewChartDataDto']; - /** - * @description Last updated timestamp - * @example 2025-12-26T10:30:00Z - */ - lastUpdated: string; + requestBody?: never; + responses: { + /** @description Preferences retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - AdminCrowdfundingRejectDto: { - /** - * @description Reason for rejection - * @example Campaign does not meet requirements - */ - reason?: string; + }; + PreferencesController_updateLanguage: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - AdminCrowdfundingRequestRevisionDto: { - /** - * @description Message for the creator explaining requested revisions - * @example Please update the project description to be more detailed - */ - message: string; - /** - * @description Optional structured reasons - * @example [ - * "incomplete_description", - * "missing_team_info" - * ] - */ - reasons?: string[]; + requestBody: { + content: { + 'application/json': { + /** @example en */ + language?: string; + }; + }; }; - AdminCrowdfundingNoteDto: { - /** - * @description Short admin note or comment - * @example Reviewed initial submission - */ - note: string; + responses: { + /** @description Language preference updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - AdminCrowdfundingAssignDto: { - /** - * @description Reviewer (user) id to assign - * @example 550e8400-e29b-41d4-a716-446655440000 - */ - reviewerId: string; + }; + PreferencesController_updateTimezone: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - ApproveMilestoneDto: { - /** - * @description Optional approval notes - * @example Milestone completed successfully - */ - notes?: string; + requestBody: { + content: { + 'application/json': { + /** @example America/New_York */ + timezone?: string; + }; + }; }; - RejectMilestoneDto: { - /** - * @description Rejection reason - * @example Incomplete deliverables - */ - reason: string; - /** - * @description Detailed feedback for rejection - * @example The submitted work does not meet the project requirements. Please revise and resubmit. - */ - feedback: string; - /** - * @description Deadline for resubmission - * @example 2025-02-01 - */ - resubmissionDeadline?: string; + responses: { + /** @description Timezone preference updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - RequestMilestoneResubmissionDto: { - /** - * @description Feedback explaining what needs to change - * @example Please improve the documentation and add more test cases - */ - feedback: string; - /** - * @description Deadline for resubmission - * @example 2025-02-15 - */ - resubmissionDeadline: string; + }; + PreferencesController_updateCategoryPreferences: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - AddMilestoneReviewNoteDto: { - /** - * @description Review note content - * @example Reviewed the code quality and found it satisfactory - */ - note: string; + requestBody: { + content: { + 'application/json': { + /** + * @example [ + * "tech", + * "design" + * ] + */ + categories?: string[]; + }; + }; }; - ManualEscrowActionDto: { - /** - * @description Type of escrow action to execute - * @example RELEASE - * @enum {string} - */ - action: 'RELEASE' | 'REFUND' | 'PAUSE' | 'RESUME'; - /** - * @description Amount to transfer (for RELEASE/REFUND) - * @example 1000 - */ - amount?: number; - /** - * @description Optional notes for this action - * @example Releasing funds for completed milestone - */ - notes?: string; - /** - * @description Recipient address (for RELEASE/REFUND) - * @example GAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - */ - recipientAddress?: string; + responses: { + /** @description Category preferences updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - AssignDisputeDto: { - /** - * @description Admin user ID to assign dispute to - * @example 550e8400-e29b-41d4-a716-446655440000 - */ - adminId: string; + }; + PreferencesController_updateSkillPreferences: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - AddDisputeNoteDto: { - /** - * @description Message content - * @example Contacted the project creator for more information - */ - message: string; - /** - * @description Whether this is an internal note (not visible to parties) - * @example false - */ - isInternal?: boolean; + requestBody: { + content: { + 'application/json': { + /** + * @example [ + * "javascript", + * "react" + * ] + */ + skills?: string[]; + }; + }; }; - ResolveDisputeDto: { - /** - * @description Resolution type - * @example APPROVED_WITH_CONDITIONS - * @enum {string} - */ - resolution: - | 'APPROVED_WITH_CONDITIONS' - | 'REQUIRE_RESUBMISSION' - | 'PARTIAL_REFUND' - | 'FULL_REFUND' - | 'DISMISSED' - | 'ARBITRATION'; - /** - * @description Detailed notes explaining the resolution - * @example Approved with condition that milestone is completed by next week - */ - resolutionNotes: string; + responses: { + /** @description Skill preferences updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - EscalateDisputeDto: { - /** - * @description Reason for escalation to arbitration - * @example Parties cannot agree on resolution terms - */ - reason: string; + }; + UsersController_getUsers: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - RejectManualProjectDto: Record; - RequestManualProjectChangesDto: Record; - RejectProjectEditDto: Record; - AdminWalletStatsDto: { - totalWallets: components['schemas']['MetricDataDto']; - activatedWallets: components['schemas']['MetricDataDto']; - inactiveWallets: components['schemas']['MetricDataDto']; + requestBody?: never; + responses: { + /** @description Users retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - AdminWalletUserDto: { - id: string; - name: string; - email: string; - username?: string; - image?: string; + }; + UsersController_getUser: { + parameters: { + query?: never; + header?: never; + path: { + /** @description User ID */ + id: string; + }; + cookie?: never; }; - AdminWalletListItemDto: { - id: string; - publicKey: string; - isActivated: boolean; - /** Format: date-time */ - createdAt: string; - users: components['schemas']['AdminWalletUserDto'][]; + requestBody?: never; + responses: { + /** @description User retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid user ID */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - AdminWalletListResponseDto: { - wallets: components['schemas']['AdminWalletListItemDto'][]; - total: number; - page: number; - limit: number; - totalPages: number; + }; + UsersController_updateUser: { + parameters: { + query?: never; + header?: never; + path: { + /** @description User ID */ + id: string; + }; + cookie?: never; }; - AdminWalletBalanceDto: { - balance: string; - assetCode: string; - assetIssuer?: string; - assetType: string; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateUserDto']; + }; }; - AdminWalletDetailsDto: { - id: string; - publicKey: string; - isActivated: boolean; - /** Format: date-time */ - createdAt: string; - balances: components['schemas']['AdminWalletBalanceDto'][]; - users: components['schemas']['AdminWalletUserDto'][]; + responses: { + /** @description User updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - ReviewWindowDto: { - /** @example 1 */ - minBusinessDays: number; - /** @example 3 */ - maxBusinessDays: number; - /** @description ISO timestamp by which the review is expected to complete. */ - estimatedCompletionAt: string; + }; + UsersController_deleteUser: { + parameters: { + query?: never; + header?: never; + path: { + /** @description User ID */ + id: string; + }; + cookie?: never; }; - DeclineDetailsDto: { - /** @description Human-readable reason from Didit, if available. */ - reason?: string; - /** - * @description Whether the user is allowed to start a new verification. - * @example true - */ - canRetry: boolean; + requestBody?: never; + responses: { + /** @description User deleted successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - VerificationStatusDto: { - /** - * @description Normalized verification state. Frontend should hide the verify button unless this is one of: not_started, declined, abandoned, expired. - * @enum {string} - */ - state: - | 'not_started' - | 'in_progress' - | 'in_review' - | 'approved' - | 'declined' - | 'abandoned' - | 'expired'; - /** @description Whether the user can start a new verification session. */ - canStartNew: boolean; - /** @description Polite, render-ready copy summarising the current state. */ - message: string; - /** @description ISO timestamp when the user became verified. */ - verifiedAt?: string; - /** @description ISO timestamp of the last status transition. */ - reviewedAt?: string; - /** @description Estimated review window. Present only when state === "in_review". */ - reviewWindow?: components['schemas']['ReviewWindowDto']; - /** @description Decline details. Present only when state === "declined". */ - decline?: components['schemas']['DeclineDetailsDto']; + }; + UsersController_getUserProfile: { + parameters: { + query?: never; + header?: never; + path: { + /** @description User ID */ + id: string; + }; + cookie?: never; }; - CreateDiditSessionDto: Record; - PricingPreviewResponseDto: { - /** @description Effective rate applied to this preview. */ - feeBps: number; - /** @description Fee in stroops. String to preserve i128 precision. */ - feeStroops: string; - /** @description Pool released to winners; equals the requested budget. */ - poolStroops: string; - /** @description budgetStroops + feeStroops; what the organizer signs for. */ - totalDepositStroops: string; - /** @description Audit label for the rate choice: default | foundation-tier | sales-override:* | waiver:*. */ - reason: string; + requestBody?: never; + responses: { + /** @description User profile retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - Function: Record; - BountyScopeSectionDto: { - /** @description Bounty title */ - title: string; - /** @description Bounty description */ - description: string; - /** Format: uri */ - githubIssueUrl?: string | null; - githubIssueNumber?: number | null; - projectId?: string | null; - bountyWindowId?: string | null; + }; + UploadController_uploadSingle: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - BountyModeSectionDto: { - /** @enum {string} */ - claimType: 'SINGLE_CLAIM' | 'COMPETITION'; - /** @enum {string} */ - entryType: 'OPEN' | 'APPLICATION_LIGHT' | 'APPLICATION_FULL'; + /** @description File upload data */ + requestBody: { + content: { + 'multipart/form-data': { + /** + * Format: binary + * @description File to upload + */ + file?: string; + /** + * @description Folder to upload to + * @example boundless/projects/project123 + */ + folder?: string; + /** + * @description Tags for the file + * @example [ + * "project", + * "logo" + * ] + */ + tags?: string[]; + /** @description Image transformation options */ + transformation?: { + /** @example 400 */ + width?: number; + /** @example 400 */ + height?: number; + /** @example fit */ + crop?: string; + /** @example auto */ + quality?: string; + /** @example auto */ + format?: string; + }; + }; + }; }; - BountySubmissionSectionDto: { - /** Format: date-time */ - submissionDeadline: string; - /** Format: date-time */ - applicationWindowCloseAt?: string | null; - maxApplicants?: number | null; - shortlistSize?: number | null; - reputationMinimum?: number | null; - /** @enum {string} */ - submissionVisibility?: 'ORGANIZER_ONLY' | 'HIDDEN_UNTIL_DEADLINE'; - /** @description Credits required to apply (anti-spam). Supplied to the contract at publish via PublishBountyEscrowDto; not a Bounty column. */ - applicationCreditCost?: number | null; + responses: { + /** @description File uploaded successfully */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['UploadResponseDto']; + }; + }; + /** @description Invalid file or upload failed */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - BountyPrizeTierInputDto: { - /** @description 1 = 1st place; unique within a bounty */ - position: number; - /** @description Tier amount as a positive decimal string */ - amount: string; - passMark?: number | null; + }; + UploadController_uploadMultiple: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - BountyRewardSectionDto: { - /** @description Token / currency code the prize is denominated in */ - rewardCurrency: string; - /** @description 1 tier for single claim; 1-3 tiers for a competition (multiple winners). */ - prizeTiers: components['schemas']['BountyPrizeTierInputDto'][]; + /** @description Multiple files upload data */ + requestBody: { + content: { + 'multipart/form-data': { + /** @description Files to upload */ + files?: string[]; + /** + * @description Folder to upload to + * @example boundless/projects/project123/gallery + */ + folder?: string; + /** + * @description Tags for the files + * @example [ + * "project", + * "gallery" + * ] + */ + tags?: string[]; + }; + }; }; - BountyDraftDataDto: { - scope?: components['schemas']['BountyScopeSectionDto']; - mode?: components['schemas']['BountyModeSectionDto']; - submission?: components['schemas']['BountySubmissionSectionDto']; - reward?: components['schemas']['BountyRewardSectionDto']; + responses: { + /** @description Files uploaded successfully */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['MultipleUploadResponseDto']; + }; + }; + /** @description Invalid files or upload failed */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - BountyDraftPrizeTierDto: { - position: number; - /** @description Tier amount as a decimal string */ - amount: string; - passMark?: number | null; + }; + UploadController_deleteFile: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Public ID of the file to delete */ + publicId: string; + /** @description Type of resource */ + resourceType: 'image' | 'video' | 'raw'; + }; + cookie?: never; }; - BountyDraftResponseDto: { - id: string; - /** - * @description Bounty lifecycle state (lowercase). - * @example draft - */ - status: string; - /** @description First incomplete step (1-based) */ - currentStep: number; - completedSteps: string[]; - /** @description Plain mode label derived from (entryType, claimType, winner count), e.g. "Open competition (multiple winners)". */ - modeLabel?: string | null; - data: components['schemas']['BountyDraftDataDto']; - prizeTiers: components['schemas']['BountyDraftPrizeTierDto'][]; - isValidForPublish: boolean; - /** @description Per-section validation messages, keyed by step */ - validationErrors: { - [key: string]: Record[]; + requestBody?: never; + responses: { + /** @description File deleted successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @example true */ + success?: boolean; + /** @example File deleted successfully */ + message?: string; + }; + }; + }; + /** @description File not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - /** Format: date-time */ - createdAt: string; - /** Format: date-time */ - updatedAt: string; }; - UpdateBountyDraftDto: { - scope?: components['schemas']['BountyScopeSectionDto']; - mode?: components['schemas']['BountyModeSectionDto']; - submission?: components['schemas']['BountySubmissionSectionDto']; - reward?: components['schemas']['BountyRewardSectionDto']; - /** @description Hint that this is an autosave (no completion side effects). */ - autoSave?: boolean; + }; + UploadController_getFileInfo: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Public ID of the file */ + publicId: string; + /** @description Type of resource */ + resourceType: 'image' | 'video' | 'raw'; + }; + cookie?: never; }; - BountyWinnerDistributionEntryDto: { - /** - * @description 1-indexed winner position. - * @example 1 - */ - position: number; - /** - * @description Percent of total_budget for this position. All entries sum to 100. - * @example 100 - */ - percent: number; + requestBody?: never; + responses: { + /** @description File information retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['FileInfoResponseDto']; + }; + }; + /** @description File not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - PublishBountyEscrowDto: { - /** - * @description Stellar G-address that will own and sign the create_event transaction. - * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ - */ - ownerAddress: string; - /** - * @description Whitelisted Stellar Asset Contract address the prize is in. - * @example CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA - */ - tokenAddress: string; - /** - * @description Total prize in token-native units (e.g. 500 = 500 USDC, NOT stroops). String is required when the value exceeds the JS safe-integer range. - * @example 500 - */ - budget: string; - /** - * @description Submission deadline as a Unix timestamp in seconds. Required for bounties that close at a specific time. Pass null only for always-open bounties (rare). - * @example 1804383600 - */ - submissionDeadline: number | null; - /** - * @description Credits required to apply. Defaults to 1; raise on high-value bounties to deter spam. Max 100 (enforced by the contract). - * @default 1 - * @example 1 - */ - applicationCreditCost: number; - /** @description Override for the winner distribution. Defaults to 100% to position 1. */ - winnerDistribution?: components['schemas']['BountyWinnerDistributionEntryDto'][]; - /** @description Override for the content URI stored on chain. Defaults to https://api.boundless.fi/bounties//content. */ - contentUri?: string; - /** - * @description Signing path. EXTERNAL (default) returns unsigned XDR for the wallet or multisig coordinator to sign. MANAGED has the backend sign and submit using the caller's platform-held wallet; the response is PENDING_CONFIRM with a txHash. - * @default EXTERNAL - * @example MANAGED - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + }; + UploadController_searchFiles: { + parameters: { + query?: { + /** @description Maximum number of results */ + maxResults?: number; + /** @description Resource type to filter by */ + resourceType?: 'image' | 'video' | 'raw'; + /** @description Folder to search in */ + folder?: unknown; + /** @description Tags to filter by */ + tags?: string[]; + }; + header?: never; + path?: never; + cookie?: never; }; - BountyEscrowOpResponseDto: { - /** @description Internal EscrowOp uuid. */ - id: string; - /** @description Hex-encoded 32-byte contract op_id. */ - opId: string; - /** @description Contract operation kind. */ - kind: string; - /** @description EscrowOp status. */ - status: string; - /** @description EntityKind (BOUNTY for this surface). */ - entityKind: string; - /** @description Bounty id. */ - entityId: string; - /** @description Unsigned XDR for the wallet to sign (PENDING_SIGN onward). */ - unsignedXdr?: string | null; - /** @description Stellar G-address expected to sign this op. */ - signerHint?: string | null; - /** @description Soroban tx hash (set once the op reaches PENDING_CONFIRM). */ - txHash?: string | null; - /** @description On-chain or platform-side error code when the op transitions to FAILED. */ - errorCode?: string | null; - /** Format: date-time */ - createdAt: string; - /** Format: date-time */ - updatedAt: string; + requestBody?: never; + responses: { + /** @description Files found successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['SearchFilesResponseDto']; + }; + }; + /** @description Search failed */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - CancelBountyEscrowDto: { - /** - * @description Organizer's Stellar G-address that signs cancel_event. Must match the bounty's on-chain owner. - * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ - */ - ownerAddress: string; - /** - * @description Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side with the caller's platform-held wallet and submits. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + }; + UploadController_generateOptimizedUrl: { + parameters: { + query?: { + /** @description Output format */ + format?: unknown; + /** @description Quality setting */ + quality?: unknown; + /** @description Crop mode */ + crop?: unknown; + /** @description Desired height */ + height?: number; + /** @description Desired width */ + width?: number; + }; + header?: never; + path: { + /** @description Public ID of the file */ + publicId: string; + }; + cookie?: never; }; - BountyWinnerSelectionDto: { - /** - * @description Stellar G-address of the applicant being declared winner. Must have an active submission anchor for this bounty. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description Winner position, 1-indexed. Must exist in the bounty's on-chain winner_distribution (the contract rejects unknown positions). - * @example 1 - */ - position: number; - /** - * @description Override the platform default credit_earn for this position. Defaults to 20/10/5 for positions 1/2/3 and 3 for the rest. Capped at 100 by the contract. - * @example 20 - */ - creditEarn?: number; - /** - * @description Override the platform default reputation_bump for this position. Defaults to 50/25/10 for positions 1/2/3 and 5 for the rest. - * @example 50 - */ - reputationBump?: number; + requestBody?: never; + responses: { + /** @description Optimized URL generated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['OptimizedUrlResponseDto']; + }; + }; + /** @description Failed to generate URL */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - SelectBountyWinnersDto: { - /** - * @description Organizer's Stellar G-address that signs select_winners. Must match the bounty's on-chain owner. - * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ - */ - ownerAddress: string; - /** @description Winners to declare. Each entry must reference an applicant with an active submission. Positions must be unique within the array. */ - selections: components['schemas']['BountyWinnerSelectionDto'][]; - /** - * @description Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side with the caller's platform-held wallet and submits. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + }; + UploadController_generateResponsiveUrls: { + parameters: { + query?: { + /** @description Output format */ + format?: unknown; + /** @description Quality setting */ + quality?: unknown; + /** @description Crop mode */ + crop?: unknown; + /** @description Base height for responsive breakpoints */ + height?: number; + /** @description Base width for responsive breakpoints */ + width?: number; + }; + header?: never; + path: { + /** @description Public ID of the file */ + publicId: string; + }; + cookie?: never; }; - BountySubmitSignedXdrDto: { - /** @description Fully-signed XDR returned by the wallet or coordinator. */ - signedXdr: string; + requestBody?: never; + responses: { + /** @description Responsive URLs generated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['ResponsiveUrlsResponseDto']; + }; + }; + /** @description Failed to generate responsive URLs */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - ApplyBountyDto: { - /** - * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + }; + UploadController_generateAvatarUrl: { + parameters: { + query?: { + /** @description Avatar size (square) */ + size?: number; + }; + header?: never; + path: { + /** @description Public ID of the image file */ + publicId: string; + }; + cookie?: never; }; - WithdrawApplicationDto: { - /** - * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + requestBody?: never; + responses: { + /** @description Avatar URL generated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['OptimizedUrlResponseDto']; + }; + }; + /** @description Failed to generate avatar URL */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - SubmitBountyDto: { - /** - * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; - /** - * @description URI of the participant's submission content. Stored on chain in the contract's submission anchor; off-chain content lives wherever the URI points (S3, IPFS, GitHub PR, etc.). - * @example https://github.com/me/boundless-fix/pull/1 - */ - contentUri: string; + }; + UploadController_generateLogoUrl: { + parameters: { + query?: { + /** @description Logo height */ + height?: number; + /** @description Logo width */ + width?: number; + }; + header?: never; + path: { + /** @description Public ID of the image file */ + publicId: string; + }; + cookie?: never; }; - WithdrawSubmissionDto: { - /** - * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + requestBody?: never; + responses: { + /** @description Logo URL generated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['OptimizedUrlResponseDto']; + }; + }; + /** @description Failed to generate logo URL */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - ContributeBountyDto: { - /** - * @description Caller's Stellar G-address. Must match the caller's linked wallet on the platform; the backend rejects mismatches up front so the wallet does not get a tx it cannot sign. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** - * @description EXTERNAL (default) returns unsigned XDR for the caller to sign. MANAGED signs server-side using the caller's platform-held wallet and submits immediately. Identical semantics to the publish flow. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; - /** - * @description Amount in token-native units (e.g. 30 = 30 USDC, NOT stroops). Pass a string when the value exceeds the JS safe-integer range. Must be >= 10 USDC (contract minimum). - * @example 30 - */ - amount: string; + }; + UploadController_generateBannerUrl: { + parameters: { + query?: { + /** @description Banner height */ + height?: number; + /** @description Banner width */ + width?: number; + }; + header?: never; + path: { + /** @description Public ID of the image file */ + publicId: string; + }; + cookie?: never; }; - CreateBountyApplicationDto: { - /** - * @description G-address that will receive payout if selected. - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; - /** @description Light proposal text (light application): 100 to 300 words. Required for APPLICATION_LIGHT mode. */ - proposalShort?: string; - /** @description Full proposal text (full application): 500 to 2000 words. Required for APPLICATION_FULL mode. */ - proposalFull?: string; - /** @description Portfolio links. APPLICATION_LIGHT: up to 3. APPLICATION_FULL: up to 6. */ - portfolioLinks?: string[]; - /** @description Estimated days to complete (APPLICATION_LIGHT). Required for APPLICATION_LIGHT mode. */ - estimatedDays?: number; - /** @description Qualifications text (APPLICATION_FULL). Required for APPLICATION_FULL mode. */ - qualifications?: string; - /** @description Optional video intro URL (APPLICATION_FULL). */ - videoIntroUrl?: string; + requestBody?: never; + responses: { + /** @description Banner URL generated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['OptimizedUrlResponseDto']; + }; + }; + /** @description Failed to generate banner URL */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - EditBountyApplicationDto: { - /** @description Light proposal text. */ - proposalShort?: string; - /** @description Full proposal text. */ - proposalFull?: string; - portfolioLinks?: string[]; - estimatedDays?: number; - qualifications?: string; - videoIntroUrl?: string; + }; + UploadController_getUsageStats: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - SelectForSingleClaimDto: { - /** @description Application id to select as the single winner. */ - applicationId: string; + requestBody?: never; + responses: { + /** @description Usage statistics retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['UsageStatsResponseDto']; + }; + }; + /** @description Failed to get usage stats */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - CreateShortlistDto: { - /** @description Application ids to include in the shortlist. */ - applicationIds: string[]; + }; + AuthController_register: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - DeclineApplicationDto: { - /** @description Reason for decline (surfaced to builder). */ - reason?: string; + requestBody: { + content: { + 'application/json': components['schemas']['RegisterDto']; + }; }; - JoinCompetitionDto: { - /** - * @description G-address that will receive payout if winning - * @example GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS - */ - applicantAddress: string; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - BountyPrizeTierPublicDto: { - position: number; - /** @description Tier amount in token-native units. */ - amount: string; - /** @description Optional minimum quality bar. */ - passMark?: number | null; + }; + AuthController_login: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - BountyOrganizationPublicDto: { - id: string; - name: string; - slug?: string | null; - logo?: string | null; + requestBody: { + content: { + 'application/json': components['schemas']['LoginDto']; + }; }; - BountyPublicDto: { - id: string; - title: string; - description: string; - /** @description Pillar lifecycle state (lowercase). */ - status: string; - type: string; - rewardAmount: number; - rewardCurrency: string; - /** @enum {string} */ - entryType?: 'OPEN' | 'APPLICATION_LIGHT' | 'APPLICATION_FULL'; - /** @enum {string} */ - claimType?: 'SINGLE_CLAIM' | 'COMPETITION'; - /** @enum {string} */ - submissionVisibility: 'ORGANIZER_ONLY' | 'HIDDEN_UNTIL_DEADLINE'; - /** Format: date-time */ - applicationWindowCloseAt?: string | null; - maxApplicants?: number | null; - shortlistSize?: number | null; - reputationMinimum?: number | null; - prizeTiers: components['schemas']['BountyPrizeTierPublicDto'][]; - organization: components['schemas']['BountyOrganizationPublicDto']; - /** @description On-chain event id once published; null while in draft. */ - escrowEventId?: string | null; - escrowTxHash?: string | null; - /** Format: date-time */ - createdAt: string; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - BountyPublicListDto: { - bounties: components['schemas']['BountyPublicDto'][]; - total: number; - page: number; - limit: number; + }; + AuthController_refreshToken: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - GrantWinnerDistributionEntryDto: { - /** - * @description 1-indexed winner position - * @example 1 - */ - position: number; - /** - * @description Percent of total_budget for this position. All sum to 100. - * @example 100 - */ - percent: number; + requestBody: { + content: { + 'application/json': components['schemas']['RefreshTokenDto']; + }; }; - PublishGrantEscrowDto: { - /** - * @description Organizer's Stellar G-address that signs the create_event transaction. - * @example GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ - */ - ownerAddress: string; - /** - * @description Whitelisted Stellar Asset Contract address. - * @example CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA - */ - tokenAddress: string; - /** - * @description Total budget in token-native units (NOT stroops). - * @example 500 - */ - budget: string; - /** - * @description Number of milestones (n) for the ReleaseKind::Multi(n) release_kind. Per-recipient amount is total_budget * winner_share% / 100 / n_milestones. - * @example 2 - */ - nMilestones: number; - /** - * @description Optional submission deadline (Unix seconds). - * @example 1804383600 - */ - submissionDeadline?: number; - /** @description Override the winner distribution. Defaults to 100% to position 1. */ - winnerDistribution?: components['schemas']['GrantWinnerDistributionEntryDto'][]; - /** @description Override the public content_uri. Defaults to /grants//content. */ - contentUri?: string; - /** - * @description Signing path. EXTERNAL (default) or MANAGED. - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - GrantEscrowOpResponseDto: { - id: string; - opId: string; - kind: string; - status: string; - entityKind: string; - entityId: string; - unsignedXdr?: string | null; - signerHint?: string | null; - txHash?: string | null; - errorCode?: string | null; - /** Format: date-time */ - createdAt: string; - /** Format: date-time */ - updatedAt: string; + }; + AuthController_logout: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - CancelGrantEscrowDto: { - /** @description Organizer's Stellar G-address. */ - ownerAddress: string; - /** - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - GrantWinnerSelectionDto: { - /** @description GrantApplication.id to declare as a winner. The application must already have applicantAddress set (the Stellar G-address receiving the grant). */ - grantApplicationId: string; - /** - * @description Winner position, 1-indexed. - * @example 1 - */ - position: number; - /** @example 20 */ - creditEarn?: number; - /** @example 50 */ - reputationBump?: number; + }; + AuthController_getProfile: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - SelectGrantWinnersDto: { - ownerAddress: string; - selections: components['schemas']['GrantWinnerSelectionDto'][]; - /** - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - ClaimGrantMilestoneDto: { - ownerAddress: string; - /** @description GrantMilestone.id to claim payment for. */ - grantMilestoneId: string; - /** - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + }; + AuthController_verifyStellarSignature: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - GrantSubmitSignedXdrDto: { - signedXdr: string; + requestBody: { + content: { + 'application/json': components['schemas']['VerifySignatureDto']; + }; }; - ContributeGrantDto: { - /** @description Contributor's Stellar G-address. Must match caller's wallet. */ - applicantAddress: string; - /** - * @description Amount in token-native units. Must be >= 10 USDC. - * @example 30 - */ - amount: string; - /** - * @default EXTERNAL - * @enum {string} - */ - fundingMode: 'EXTERNAL' | 'MANAGED'; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - GrantPublicListItemDto: { - /** - * @description Grant id. - * @example grant_123 - */ - id: string; - /** - * @description Underlying project title used as the card title. - * @example On-chain governance research - */ - title: string; - /** - * @description Short tagline/summary. Empty string when none is available. - * @example Funding research into delegated voting models. - */ - summary: string; - /** - * @description Banner or thumbnail image URL. - * @example https://cdn.boundless.dev/grants/abc.png - */ - coverImageUrl: string | null; - /** - * @description Lowercased grant status. - * @example open - */ - status: string; - /** - * @description Total program budget in USDC, stringified. - * @example 50000 - */ - totalBudgetUsdc: string | null; - /** - * @description Owning organization id, if any. - * @example org_123 - */ - organizationId: string | null; - /** - * @description Owning organization display name. - * @example Boundless Labs - */ - organizationName: string | null; - /** - * @description Owning organization logo URL. - * @example https://cdn.boundless.dev/orgs/boundless.png - */ - organizationLogoUrl: string | null; - /** - * @description Underlying project category, if any. - * @example governance - */ - category: string | null; - /** - * @description Total submitted applications count. - * @example 12 - */ - applicationCount: number; - /** - * @description When the grant was created. - * @example 2026-05-01T12:00:00.000Z - */ - createdAt: string; + }; + OAuthController_googleAuth: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - GrantPublicListResponseDto: { - items: components['schemas']['GrantPublicListItemDto'][]; - /** - * @description Total count of grants matching the filters. - * @example 84 - */ - total: number; - /** - * @description Current page (1-indexed). - * @example 1 - */ - page: number; - /** - * @description Items per page. - * @example 20 - */ - limit: number; + }; + OAuthController_googleAuthCallback: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - /** - * @description The pillar this opportunity belongs to. - * @enum {string} - */ - OpportunityType: 'BOUNTY' | 'HACKATHON' | 'GRANT' | 'CROWDFUNDING'; - OpportunityListItemDto: { - /** - * @description The pillar this opportunity belongs to. - * @example BOUNTY - */ - type: components['schemas']['OpportunityType']; - /** - * @description Pillar-local primary key. Globally unique within a type. - * @example ckxyz123 - */ - id: string; - /** - * @description Optional URL slug. Hackathons and crowdfunding campaigns expose one; bounties and grants do not. - * @example open-defi-hack - */ - slug: string | null; - /** - * @description Display title for the card. - * @example Build a DAO governance dashboard - */ - title: string; - /** - * @description Short blurb shown under the title. Empty string when the underlying pillar has no summary; never null. - * @example Ship a React dashboard that visualizes on-chain governance votes. - */ - summary: string; - /** - * @description Banner or hero image URL for the card. - * @example https://cdn.boundless.dev/banners/abc.png - */ - coverImageUrl: string | null; - /** - * @description Owning organization id. Null on crowdfunding or grants that lack an organization. - * @example org_123 - */ - organizationId: string | null; - /** - * @description Owning organization display name. - * @example Boundless Labs - */ - organizationName: string | null; - /** - * @description Owning organization logo URL. - * @example https://cdn.boundless.dev/orgs/boundless.png - */ - organizationLogoUrl: string | null; - /** - * @description Lowercased pillar-specific status (e.g. "open", "upcoming", "active"). - * @example open - */ - status: string; - /** - * @description Total advertised reward in USDC, stringified. Null when not applicable to the pillar. - * @example 5000.00 - */ - totalRewardUsdc: string | null; - /** - * @description Funded amount so far in USDC, crowdfunding only. Null elsewhere. - * @example 1234.56 - */ - fundedAmountUsdc: string | null; - /** - * @description When this opportunity went live. Falls back to createdAt when the pillar lacks publishedAt. - * @example 2026-05-01T12:00:00.000Z - */ - publishedAt: string; - /** - * @description When the opportunity window opens. - * @example 2026-05-15T00:00:00.000Z - */ - startsAt: string | null; - /** - * @description Application or submission deadline. Null for open-ended pillars (notably grants). - * @example 2026-06-30T23:59:59.000Z - */ - endsAt: string | null; - /** - * @description Approximate participant count. Null when the pillar has no relation to count from. - * @example 42 - */ - participantCount: number | null; - /** - * @description Pillar-defined tags. Empty array for pillars without a tag field; never null. - * @example [ - * "stellar", - * "defi" - * ] - */ - tags: string[]; - /** - * @description Path to the detail page on the frontend. - * @example /bounties/ckxyz123 - */ - detailUrl: string; - /** - * @description True when this opportunity is currently featured. Drives the page-1 boost in the marketplace. - * @example false - */ - isFeatured: boolean; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - OpportunityListResponseDto: { - /** @description Cards in the current page, post-merge. */ - items: components['schemas']['OpportunityListItemDto'][]; - /** - * @description Opaque cursor for the next page. Null when no more results are available. - * @example eyJzb3J0IjoibmV3ZXN0IiwicHJpbWFyeSI6IjIwMjYtMDUtMTVUMDA6MDA6MDAuMDAwWiIsImlkIjoiY2t4eXoxMjMifQ - */ - nextCursor: string | null; - /** - * @description Total rows matching the current filter combo (type, status, search, tags), summed across pillar adapters. Cursor-blind, so stable across paginated requests with the same filters. - * @example 137 - */ - total: number; + }; + OAuthController_githubAuth: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - SubscribeDto: { - /** - * @description Email address to subscribe - * @example user@example.com - */ - email: string; - /** - * @description Subscriber name - * @example John Doe - */ - name?: string; - /** - * @description Subscription source - * @example website - */ - source?: string; - /** - * @description Topic tags for subscription preferences - * @example [ - * "updates", - * "hackathons" - * ] - */ - tags?: string[]; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - UnsubscribeDto: { - /** - * @description Email address to unsubscribe - * @example user@example.com - */ - email: string; + }; + OAuthController_githubAuthCallback: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - UpdatePreferencesDto: { - /** - * @description Subscriber email address - * @example user@example.com - */ - email: string; - /** - * @description Topic tags to subscribe to. Valid: bounties, hackathons, grants, updates - * @example [ - * "updates", - * "hackathons" - * ] - */ - tags: string[]; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - CreateNewsletterCampaignDto: { - /** - * @description Campaign email subject line - * @example Boundless Weekly: New Hackathon Announced! - */ - subject: string; - /** - * @description Campaign HTML content. Supports {{name}} placeholder. - * @example

Hello {{name}}

Check out our latest hackathon!

- */ - content: string; - /** - * @description Preview text shown in email clients - * @example New hackathon with $10k in prizes - */ - previewText?: string; - /** - * @description Target subscriber tags — only subscribers with matching tags receive the campaign - * @example [ - * "hackathons", - * "updates" - * ] - */ - tags?: string[]; + }; + OAuthController_twitterAuth: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - User: { - id?: string; - name: string; - email: string; - /** @default false */ - readonly emailVerified: boolean; - image?: string; - /** - * Format: date-time - * @default Generated at runtime - */ - createdAt: string; - /** - * Format: date-time - * @default Generated at runtime - */ - updatedAt: string; - username?: string; - displayUsername?: string; - /** @default false */ - readonly twoFactorEnabled: boolean; - readonly lastLoginMethod?: string; - readonly role?: string; - /** @default false */ - readonly banned: boolean; - readonly banReason?: string; - /** Format: date-time */ - readonly banExpires?: string; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - Session: { - id?: string; - /** Format: date-time */ - expiresAt: string; - token: string; - /** - * Format: date-time - * @default Generated at runtime - */ - createdAt: string; - /** Format: date-time */ - updatedAt: string; - ipAddress?: string; - userAgent?: string; - userId: string; - activeOrganizationId?: string; - impersonatedBy?: string; + }; + OAuthController_twitterAuthCallback: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; }; - Account: { - id?: string; - accountId: string; - providerId: string; - userId: string; - accessToken?: string; - refreshToken?: string; - idToken?: string; - /** Format: date-time */ - accessTokenExpiresAt?: string; - /** Format: date-time */ - refreshTokenExpiresAt?: string; - scope?: string; - password?: string; - /** - * Format: date-time - * @default Generated at runtime - */ - createdAt: string; - /** Format: date-time */ - updatedAt: string; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - Verification: { - id?: string; - identifier: string; - value: string; - /** Format: date-time */ - expiresAt: string; - /** - * Format: date-time - * @default Generated at runtime - */ - createdAt: string; - /** - * Format: date-time - * @default Generated at runtime - */ - updatedAt: string; + }; + FollowsController_followEntity: { + parameters: { + query?: never; + header?: never; + path: { + entityType: string; + entityId: string; + }; + cookie?: never; }; - TwoFactor: { - id?: string; - secret: string; - backupCodes: string; - userId: string; + requestBody?: never; + responses: { + 201: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - Organization: { - id?: string; - name: string; - slug: string; - logo?: string; - /** Format: date-time */ - createdAt: string; - metadata?: string; + }; + FollowsController_unfollowEntity: { + parameters: { + query?: never; + header?: never; + path: { + entityType: string; + entityId: string; + }; + cookie?: never; }; - Member: { - id?: string; - organizationId: string; - userId: string; - /** @default member */ - role: string; - /** Format: date-time */ - createdAt: string; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; - Invitation: { - id?: string; - organizationId: string; - email: string; - role?: string; - /** @default pending */ - status: string; - /** Format: date-time */ - expiresAt: string; - /** - * Format: date-time - * @default Generated at runtime - */ - createdAt: string; - inviterId: string; + }; + FollowsController_getUserFollowing: { + parameters: { + query: { + entityType: string; + }; + header?: never; + path: { + userId: string; + }; + cookie?: never; }; - Passkey: { - id?: string; - name?: string; - publicKey: string; - userId: string; - credentialID: string; - counter: number; - deviceType: string; - backedUp: boolean; - transports?: string; - /** Format: date-time */ - createdAt?: string; - aaguid?: string; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + FollowsController_getEntityFollowers: { + parameters: { + query?: never; + header?: never; + path: { + entityType: string; + entityId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + FollowsController_getFollowStats: { + parameters: { + query?: never; + header?: never; + path: { + userId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + FollowsController_isFollowing: { + parameters: { + query?: never; + header?: never; + path: { + entityType: string; + entityId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; -} -export type $defs = Record; -export interface operations { - AppController_getHello: { + ChatController_getMessages: { parameters: { - query?: never; + query: { + roomId: string; + roomType: string; + cursor?: string; + limit?: number; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Returns list of messages. */ 200: { headers: { [name: string]: unknown; @@ -18868,15 +23382,19 @@ export interface operations { }; }; }; - NotificationsController_getNotifications: { + MessagesController_listConversations: { parameters: { - query?: never; + query?: { + limit?: number; + offset?: number; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Paginated list of conversations */ 200: { headers: { [name: string]: unknown; @@ -18885,15 +23403,20 @@ export interface operations { }; }; }; - NotificationsController_getUnreadCount: { + MessagesController_startOrGetConversation: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateConversationDto']; + }; + }; responses: { + /** @description Conversation (created or existing) */ 200: { headers: { [name: string]: unknown; @@ -18902,17 +23425,19 @@ export interface operations { }; }; }; - NotificationsController_markAsRead: { + MessagesController_getConversation: { parameters: { query?: never; header?: never; path: { + /** @description Conversation ID */ id: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Conversation details */ 200: { headers: { [name: string]: unknown; @@ -18921,15 +23446,23 @@ export interface operations { }; }; }; - NotificationsController_markAllAsRead: { + MessagesController_listMessages: { parameters: { - query?: never; + query?: { + limit?: number; + /** @description Cursor for older messages */ + before?: string; + }; header?: never; - path?: never; + path: { + /** @description Conversation ID */ + id: string; + }; cookie?: never; }; requestBody?: never; responses: { + /** @description Paginated messages */ 200: { headers: { [name: string]: unknown; @@ -18938,18 +23471,24 @@ export interface operations { }; }; }; - NotificationsController_deleteNotification: { + MessagesController_sendMessage: { parameters: { query?: never; header?: never; path: { + /** @description Conversation ID */ id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateMessageDto']; + }; + }; responses: { - 200: { + /** @description Message created */ + 201: { headers: { [name: string]: unknown; }; @@ -18957,15 +23496,19 @@ export interface operations { }; }; }; - NotificationsController_getPreferences: { + MessagesController_markConversationRead: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Conversation ID */ + id: string; + }; cookie?: never; }; requestBody?: never; responses: { + /** @description Marked as read */ 200: { headers: { [name: string]: unknown; @@ -18974,7 +23517,7 @@ export interface operations { }; }; }; - NotificationsController_updatePreferences: { + CampaignsController_validateCampaign: { parameters: { query?: never; header?: never; @@ -18983,28 +23526,41 @@ export interface operations { }; requestBody: { content: { - 'application/json': components['schemas']['NotificationPreferencesDto']; + 'application/json': components['schemas']['CreateCampaignDto']; }; }; responses: { + /** @description Campaign data is valid */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Invalid campaign data */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - NotificationsController_sendTestNotification: { + CampaignsController_createDraft: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateDraftDto']; + }; + }; responses: { - 200: { + /** @description Draft campaign created */ + 201: { headers: { [name: string]: unknown; }; @@ -19012,15 +23568,34 @@ export interface operations { }; }; }; - NotificationsController_triggerMarketingCron: { + CampaignsController_getCampaigns: { parameters: { - query?: never; + query: { + /** @description Category of the campaign */ + category?: string; + /** @description Status of the campaign */ + status?: 'active' | 'funded' | 'completed'; + minFundingGoal?: number; + /** @description Minimum funding goal of the campaign */ + maxFundingGoal?: number; + /** @description Maximum funding goal of the campaign */ + page?: number; + /** @description Limit of the campaign */ + limit?: number; + /** @description Sort by of the campaign */ + sortBy: string; + /** @description Sort order of the campaign */ + sortOrder: string; + /** @description Search of the campaign */ + search?: string; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Campaigns retrieved successfully */ 200: { headers: { [name: string]: unknown; @@ -19029,24 +23604,28 @@ export interface operations { }; }; }; - SettingsController_getSettings: { + CampaignsController_createCampaign: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateCampaignDto']; + }; + }; responses: { - /** @description Settings retrieved successfully */ - 200: { + /** @description Campaign and project created successfully */ + 201: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { + /** @description Invalid campaign data */ + 400: { headers: { [name: string]: unknown; }; @@ -19054,36 +23633,109 @@ export interface operations { }; }; }; - SettingsController_updateNotificationSettings: { + CampaignsController_triggerCron: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Notification settings object */ - requestBody: { - content: { - 'application/json': string; + requestBody?: never; + responses: { + /** @description Cron job triggered successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + CampaignsController_getMyCampaigns: { + parameters: { + query: { + /** @description Category of the campaign */ + category: string; + /** @description Status of the campaign */ + status: string; + minFundingGoal: number; + /** @description Minimum funding goal of the campaign */ + maxFundingGoal: number; + /** @description Maximum funding goal of the campaign */ + page?: number; + /** @description Limit of the campaign */ + limit?: number; + /** @description Sort by of the campaign */ + sortBy?: string; + /** @description Sort order of the campaign */ + sortOrder?: string; + /** @description Search of the campaign */ + search: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description User campaigns retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + CampaignsController_getCampaignBySlug: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Campaign URL slug */ + slug: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Notification settings updated successfully */ + /** @description Campaign details retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { + /** @description Campaign not found */ + 404: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { + }; + }; + CampaignsController_getCampaign: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Campaign details retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Campaign not found */ + 404: { headers: { [name: string]: unknown; }; @@ -19091,35 +23743,59 @@ export interface operations { }; }; }; - SettingsController_updatePrivacySettings: { + CampaignsController_updateCampaign: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdatePrivacySettingsDto']; + 'application/json': components['schemas']['UpdateCampaignDto']; }; }; responses: { - /** @description Privacy settings updated successfully */ + /** @description Campaign updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { + /** @description User does not own the campaign */ + 403: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { + }; + }; + CampaignsController_deleteCampaign: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Campaign deleted successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Cannot delete campaign with contributions, campaigns in funding phase, funded campaigns, completed campaigns, or user does not own the campaign */ + 403: { headers: { [name: string]: unknown; }; @@ -19127,35 +23803,81 @@ export interface operations { }; }; }; - SettingsController_updateAppearanceSettings: { + CampaignsController_getCampaignStatistics: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateAppearanceSettingsDto']; + requestBody?: never; + responses: { + /** @description Campaign statistics retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + CampaignsController_getInvitations: { + parameters: { + query?: never; + header?: never; + path: { + id: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Appearance settings updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { + }; + }; + CampaignsController_inviteTeamMember: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['InviteTeamMemberDto']; + }; + }; + responses: { + 201: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { + }; + }; + CampaignsController_acceptInvitation: { + parameters: { + query: { + token: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -19163,39 +23885,94 @@ export interface operations { }; }; }; - EarningsController_getEarningsPublic: { + ContributionsController_getCampaignContributions: { parameters: { - query: { - /** @description Max activities to return (default 100) */ + query?: { + page?: number; limit?: number; - /** @description Offset for activity pagination */ - offset?: number; - /** @description Username of the profile to fetch earnings for */ - username: string; }; header?: never; - path?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Public earnings retrieved successfully */ + /** @description Contributions retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['PublicEarningsResponseDto']; + content?: never; + }; + }; + }; + ContributionsController_getContributionStats: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Contribution statistics retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; }; + content?: never; }; - /** @description Missing or invalid username */ - 400: { + }; + }; + MilestonesController_getCampaignMilestones: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Milestones retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User not found */ + }; + }; + MilestonesController_getMilestone: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + /** @description Milestone ID */ + milestoneId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Milestone details retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Milestone not found */ 404: { headers: { [name: string]: unknown; @@ -19204,58 +23981,119 @@ export interface operations { }; }; }; - EarningsController_getEarnings: { + MilestonesController_updateMilestone: { parameters: { - query?: { - /** @description Max activities to return (default 100) */ - limit?: number; - /** @description Offset for activity pagination */ - offset?: number; + query?: never; + header?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + /** @description Milestone ID */ + milestoneId: string; }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateMilestoneDto']; + }; + }; + responses: { + /** @description Milestone submitted successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Validation failed - invalid proof of work data */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User does not own the campaign */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + }; + }; + MilestonesController_validateMilestoneSubmission: { + parameters: { + query?: never; header?: never; - path?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + /** @description Milestone ID */ + milestoneId: string; + }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ValidateMilestoneSubmissionDto']; + }; + }; responses: { - /** @description Earnings data retrieved successfully */ + /** @description Validation successful */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['EarningsResponseDto']; + 'application/json': { + /** @example true */ + validated?: boolean; + data?: { + /** @example submitted */ + status?: string; + /** @example Milestone completed - all deliverables ready for review. */ + evidence?: string; + /** + * @example [ + * "https://example.com/report.pdf" + * ] + */ + documents?: string[]; + }; + }; }; }; - /** @description Unauthorized */ - 401: { + /** @description Validation failed */ + 400: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': { + /** @example false */ + validated?: boolean; + /** @example Evidence must be at least 10 characters of meaningful content */ + error?: string; + }; + }; }; }; }; - UserController_getProfile: { + MilestonesController_getMilestoneStats: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Campaign ID or slug */ + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description User dashboard with profile, stats, chart data, activities graph, and recent activities retrieved successfully */ + /** @description Milestone statistics retrieved successfully */ 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['DashboardDto']; - }; - }; - /** @description Unauthorized */ - 401: { headers: { [name: string]: unknown; }; @@ -19263,16 +24101,17 @@ export interface operations { }; }; }; - UserController_getPublic: { + BuilderCrowdfundingV2Controller_submitForReview: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Public route accessed successfully */ 200: { headers: { [name: string]: unknown; @@ -19281,16 +24120,17 @@ export interface operations { }; }; }; - UserController_getOptional: { + BuilderCrowdfundingV2Controller_withdrawSubmission: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Optional auth route accessed successfully */ 200: { headers: { [name: string]: unknown; @@ -19299,358 +24139,261 @@ export interface operations { }; }; }; - UserController_getUserByUsername: { + BuilderCrowdfundingV2Controller_reviseAndResubmit: { parameters: { query?: never; header?: never; path: { - /** @description Username of the user to retrieve */ - username: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description User profile retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - UserController_getUserFollowers: { + BuilderCrowdfundingV2Controller_publish: { parameters: { - query?: { - /** @description Pagination offset */ - offset?: number; - /** @description Number of followers to return */ - limit?: number; - }; + query?: never; header?: never; path: { - /** @description Username of the user */ - username: string; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['PublishCrowdfundingEscrowDto']; + }; + }; responses: { - /** @description Followers retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - UserController_getUserFollowing: { + BuilderCrowdfundingV2Controller_cancel: { parameters: { - query?: { - /** @description Filter by entity type */ - entityType?: - | 'USER' - | 'PROJECT' - | 'ORGANIZATION' - | 'CROWDFUNDING_CAMPAIGN' - | 'BOUNTY' - | 'GRANT' - | 'HACKATHON'; - /** @description Pagination offset */ - offset?: number; - /** @description Number of following to return */ - limit?: number; - }; + query?: never; header?: never; path: { - /** @description Username of the user */ - username: string; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CancelCrowdfundingEscrowDto']; + }; + }; responses: { - /** @description Following list retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - ProfileController_getProfile: { + BackerCrowdfundingV2Controller_contribute: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ContributeCrowdfundingDto']; + }; + }; responses: { - /** @description Profile retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - ProfileController_updateProfile: { + BackerCrowdfundingV2Controller_submitSigned: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + opRowId: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdateProfileDto']; + 'application/json': components['schemas']['CrowdfundingSubmitSignedXdrDto']; }; }; responses: { - /** @description Profile updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - ProfileController_getProfileStats: { + BackerCrowdfundingV2Controller_getOp: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + opRowId: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Profile stats retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - ProfileController_getActivity: { + CommunityCrowdfundingV2Controller_getTally: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Activity retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - ProfileController_uploadAvatar: { + CommunityCrowdfundingV2Controller_castVote: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody: { content: { - 'multipart/form-data': { - /** - * Format: binary - * @description Avatar image file - */ - avatar?: string; - }; + 'application/json': components['schemas']['CastCrowdfundingVoteDto']; }; }; responses: { - /** @description Avatar uploaded successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - PreferencesController_getPreferences: { + CommunityCrowdfundingV2Controller_getMyVote: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Preferences retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - PreferencesController_updateLanguage: { + AdminCrowdfundingV2Controller_approve: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': { - /** @example en */ - language?: string; - }; + 'application/json': components['schemas']['ApproveCrowdfundingCampaignDto']; }; }; responses: { - /** @description Language preference updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - PreferencesController_updateTimezone: { + AdminCrowdfundingV2Controller_reject: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': { - /** @example America/New_York */ - timezone?: string; - }; + 'application/json': components['schemas']['RejectCrowdfundingCampaignDto']; }; }; responses: { - /** @description Timezone preference updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + AdminCrowdfundingV2Controller_extendFunding: { + parameters: { + query?: never; + header?: never; + path: { + id: string; }; - /** @description Unauthorized */ - 401: { + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ExtendCrowdfundingFundingDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -19658,43 +24401,41 @@ export interface operations { }; }; }; - PreferencesController_updateCategoryPreferences: { + AdminCrowdfundingV2Controller_pause: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': { - /** - * @example [ - * "tech", - * "design" - * ] - */ - categories?: string[]; - }; + 'application/json': components['schemas']['PauseCrowdfundingCampaignDto']; }; }; responses: { - /** @description Category preferences updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + AdminCrowdfundingV2Controller_unpause: { + parameters: { + query?: never; + header?: never; + path: { + id: string; }; - /** @description Unauthorized */ - 401: { + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -19702,43 +24443,47 @@ export interface operations { }; }; }; - PreferencesController_updateSkillPreferences: { + AdminCrowdfundingV2Controller_approveMilestone: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + milestoneId: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': { - /** - * @example [ - * "javascript", - * "react" - * ] - */ - skills?: string[]; - }; + 'application/json': components['schemas']['ApproveCrowdfundingMilestoneDto']; }; }; responses: { - /** @description Skill preferences updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + AdminCrowdfundingV2Controller_rejectMilestone: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + milestoneId: string; }; - /** @description Unauthorized */ - 401: { + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['RejectCrowdfundingMilestoneDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -19746,73 +24491,79 @@ export interface operations { }; }; }; - UsersController_getUsers: { + CrowdfundingDisputesController_file: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['FileDisputeDto']; + }; + }; responses: { - /** @description Users retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['DisputeResponseDto']; }; - content?: never; }; }; }; - UsersController_getUser: { + CrowdfundingDisputesController_mine: { parameters: { query?: never; header?: never; path: { - /** @description User ID */ id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description User retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Invalid user ID */ - 400: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['DisputeResponseDto'][]; }; - content?: never; }; - /** @description Unauthorized */ - 401: { + }; + }; + WalletController_getWallet: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User not found */ - 404: { + }; + }; + WalletController_getWalletDetails: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -19820,38 +24571,35 @@ export interface operations { }; }; }; - UsersController_updateUser: { + WalletController_getAddressBalance: { parameters: { query?: never; header?: never; path: { - /** @description User ID */ - id: string; + address: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateUserDto']; - }; - }; + requestBody?: never; responses: { - /** @description User updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description User not found */ - 404: { + }; + }; + WalletController_syncWallet: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 201: { headers: { [name: string]: unknown; }; @@ -19859,41 +24607,48 @@ export interface operations { }; }; }; - UsersController_deleteUser: { + WalletController_createWallet: { parameters: { query?: never; header?: never; - path: { - /** @description User ID */ - id: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description User deleted successfully */ - 200: { + 201: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Unauthorized */ - 401: { + }; + }; + WalletController_activate: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Wallet activated. Returns tx hash and added trustlines. */ + 201: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Forbidden - Admin access required */ - 403: { + /** @description Sponsorship not configured, or unexpected submit error. */ + 500: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User not found */ - 404: { + /** @description Sponsor account is out of available XLM. Operators have been alerted; retry later. */ + 503: { headers: { [name: string]: unknown; }; @@ -19901,27 +24656,28 @@ export interface operations { }; }; }; - UsersController_getUserProfile: { + WalletController_reclaimDormant: { parameters: { query?: never; header?: never; - path: { - /** @description User ID */ - id: string; - }; + path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ReclaimDormantDto']; + }; + }; responses: { - /** @description User profile retrieved successfully */ - 200: { + /** @description Reclaim summary: scanned, eligible, revoked, freedXlm, walletIds, errors */ + 201: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User not found */ - 404: { + /** @description Admin role required. */ + 403: { headers: { [name: string]: unknown; }; @@ -19929,63 +24685,17 @@ export interface operations { }; }; }; - UploadController_uploadSingle: { + WalletController_getSupportedTrustlines: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description File upload data */ - requestBody: { - content: { - 'multipart/form-data': { - /** - * Format: binary - * @description File to upload - */ - file?: string; - /** - * @description Folder to upload to - * @example boundless/projects/project123 - */ - folder?: string; - /** - * @description Tags for the file - * @example [ - * "project", - * "logo" - * ] - */ - tags?: string[]; - /** @description Image transformation options */ - transformation?: { - /** @example 400 */ - width?: number; - /** @example 400 */ - height?: number; - /** @example fit */ - crop?: string; - /** @example auto */ - quality?: string; - /** @example auto */ - format?: string; - }; - }; - }; - }; + requestBody?: never; responses: { - /** @description File uploaded successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['UploadResponseDto']; - }; - }; - /** @description Invalid file or upload failed */ - 400: { + /** @description List of supported trustline assets */ + 200: { headers: { [name: string]: unknown; }; @@ -19993,46 +24703,27 @@ export interface operations { }; }; }; - UploadController_uploadMultiple: { + WalletController_addTrustline: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - /** @description Multiple files upload data */ requestBody: { content: { - 'multipart/form-data': { - /** @description Files to upload */ - files?: string[]; - /** - * @description Folder to upload to - * @example boundless/projects/project123/gallery - */ - folder?: string; - /** - * @description Tags for the files - * @example [ - * "project", - * "gallery" - * ] - */ - tags?: string[]; - }; + 'application/json': components['schemas']['AddTrustlineDto']; }; }; responses: { - /** @description Files uploaded successfully */ + /** @description Trustline added or already exists */ 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['MultipleUploadResponseDto']; - }; + content?: never; }; - /** @description Invalid files or upload failed */ + /** @description Wallet not activated, insufficient XLM for fees, or unsupported asset */ 400: { headers: { [name: string]: unknown; @@ -20041,68 +24732,68 @@ export interface operations { }; }; }; - UploadController_deleteFile: { + WalletController_validateSendDestination: { parameters: { - query?: never; - header?: never; - path: { - /** @description Public ID of the file to delete */ - publicId: string; - /** @description Type of resource */ - resourceType: 'image' | 'video' | 'raw'; + query: { + /** @description Stellar public key (G...) */ + destinationPublicKey: string; + /** @description Asset code (e.g. USDC, XLM) */ + currency: string; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description File deleted successfully */ + /** @description Validation result (valid, isActivated, hasTrustlineForAsset, memoRequired) */ 200: { headers: { [name: string]: unknown; }; content: { 'application/json': { - /** @example true */ - success?: boolean; - /** @example File deleted successfully */ - message?: string; + valid?: boolean; + isValidPublicKey?: boolean; + isActivated?: boolean; + hasTrustlineForAsset?: boolean; + /** @description True if this destination requires a memo (e.g. exchange shared address) */ + memoRequired?: boolean; + message?: string | null; }; }; }; - /** @description File not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - UploadController_getFileInfo: { + WalletController_send: { parameters: { query?: never; header?: never; - path: { - /** @description Public ID of the file */ - publicId: string; - /** @description Type of resource */ - resourceType: 'image' | 'video' | 'raw'; - }; + path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UserSendDto']; + }; + }; responses: { - /** @description File information retrieved successfully */ - 200: { + /** @description Send submitted successfully */ + 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['FileInfoResponseDto']; + content?: never; + }; + /** @description Validation or business rule error (e.g. destination not activated, no trustline, memo required, insufficient balance) */ + 400: { + headers: { + [name: string]: unknown; }; + content?: never; }; - /** @description File not found */ - 404: { + /** @description Identity verification required. Complete KYC to send funds. */ + 403: { headers: { [name: string]: unknown; }; @@ -20110,76 +24801,35 @@ export interface operations { }; }; }; - UploadController_searchFiles: { + WalletPayoutController_sendPayout: { parameters: { - query?: { - /** @description Maximum number of results */ - maxResults?: number; - /** @description Resource type to filter by */ - resourceType?: 'image' | 'video' | 'raw'; - /** @description Folder to search in */ - folder?: unknown; - /** @description Tags to filter by */ - tags?: string[]; - }; + query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['SendPayoutDto']; + }; + }; responses: { - /** @description Files found successfully */ - 200: { + /** @description Payout submitted successfully */ + 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SearchFilesResponseDto']; - }; + content?: never; }; - /** @description Search failed */ + /** @description Validation or business rule error (e.g. destination not activated, no trustline, memo required) */ 400: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - UploadController_generateOptimizedUrl: { - parameters: { - query?: { - /** @description Output format */ - format?: unknown; - /** @description Quality setting */ - quality?: unknown; - /** @description Crop mode */ - crop?: unknown; - /** @description Desired height */ - height?: number; - /** @description Desired width */ - width?: number; - }; - header?: never; - path: { - /** @description Public ID of the file */ - publicId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Optimized URL generated successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['OptimizedUrlResponseDto']; - }; - }; - /** @description Failed to generate URL */ - 400: { + /** @description Forbidden – admin only */ + 403: { headers: { [name: string]: unknown; }; @@ -20187,40 +24837,48 @@ export interface operations { }; }; }; - UploadController_generateResponsiveUrls: { + CommentsController_listComments: { parameters: { query?: { - /** @description Output format */ - format?: unknown; - /** @description Quality setting */ - quality?: unknown; - /** @description Crop mode */ - crop?: unknown; - /** @description Base height for responsive breakpoints */ - height?: number; - /** @description Base width for responsive breakpoints */ - width?: number; + /** @description Entity type to filter comments */ + entityType?: + | 'PROJECT' + | 'BOUNTY' + | 'CROWDFUNDING_CAMPAIGN' + | 'GRANT' + | 'GRANT_APPLICATION' + | 'HACKATHON' + | 'HACKATHON_SUBMISSION' + | 'BLOG_POST'; + /** @description Entity ID to filter comments */ + entityId?: string; + /** @description Author ID to filter comments */ + authorId?: string; + /** @description Parent comment ID to filter replies */ + parentId?: string; + /** @description Comment status to filter */ + status?: 'ACTIVE' | 'HIDDEN' | 'DELETED' | 'PENDING_MODERATION'; + /** @description Include reaction data in response */ + includeReactions?: boolean; + /** @description Include report data in response (moderators only) */ + includeReports?: boolean; + /** @description Page number */ + page?: number; + /** @description Number of items per page */ + limit?: number; + /** @description Field to sort by */ + sortBy?: string; + /** @description Sort order */ + sortOrder?: 'asc' | 'desc'; }; header?: never; - path: { - /** @description Public ID of the file */ - publicId: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Responsive URLs generated successfully */ + /** @description Comments retrieved successfully */ 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['ResponsiveUrlsResponseDto']; - }; - }; - /** @description Failed to generate responsive URLs */ - 400: { headers: { [name: string]: unknown; }; @@ -20228,67 +24886,63 @@ export interface operations { }; }; }; - UploadController_generateAvatarUrl: { + CommentsController_createComment: { parameters: { - query?: { - /** @description Avatar size (square) */ - size?: number; - }; + query?: never; header?: never; - path: { - /** @description Public ID of the image file */ - publicId: string; - }; + path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateCommentDto']; + }; + }; responses: { - /** @description Avatar URL generated successfully */ - 200: { + /** @description Comment created successfully */ + 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['OptimizedUrlResponseDto']; - }; + content?: never; }; - /** @description Failed to generate avatar URL */ + /** @description Invalid input */ 400: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Rate limit exceeded */ + 429: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - UploadController_generateLogoUrl: { + CommentsController_getComment: { parameters: { - query?: { - /** @description Logo height */ - height?: number; - /** @description Logo width */ - width?: number; - }; + query?: never; header?: never; path: { - /** @description Public ID of the image file */ - publicId: string; + /** @description Comment ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Logo URL generated successfully */ + /** @description Comment retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['OptimizedUrlResponseDto']; - }; + content?: never; }; - /** @description Failed to generate logo URL */ - 400: { + /** @description Comment not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20296,34 +24950,38 @@ export interface operations { }; }; }; - UploadController_generateBannerUrl: { + CommentsController_updateComment: { parameters: { - query?: { - /** @description Banner height */ - height?: number; - /** @description Banner width */ - width?: number; - }; + query?: never; header?: never; path: { - /** @description Public ID of the image file */ - publicId: string; + /** @description Comment ID */ + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateCommentDto']; + }; + }; responses: { - /** @description Banner URL generated successfully */ + /** @description Comment updated successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['OptimizedUrlResponseDto']; + content?: never; + }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; }; + content?: never; }; - /** @description Failed to generate banner URL */ - 400: { + /** @description Comment not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20331,26 +24989,34 @@ export interface operations { }; }; }; - UploadController_getUsageStats: { + CommentsController_deleteComment: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Comment ID */ + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Usage statistics retrieved successfully */ - 200: { + /** @description Comment deleted successfully */ + 204: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['UsageStatsResponseDto']; + content?: never; + }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; }; + content?: never; }; - /** @description Failed to get usage stats */ - 400: { + /** @description Comment not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20358,20 +25024,24 @@ export interface operations { }; }; }; - AuthController_register: { + CommentsController_getCommentsByEntity: { parameters: { - query?: never; + query: { + includeNested: string; + }; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['RegisterDto']; + path: { + /** @description Entity type */ + entityType: string; + /** @description Entity ID */ + entityId: string; }; + cookie?: never; }; + requestBody?: never; responses: { - 201: { + /** @description Comments retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; @@ -20379,19 +25049,19 @@ export interface operations { }; }; }; - AuthController_login: { + CommentsController_getReactions: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['LoginDto']; + path: { + /** @description Comment ID */ + id: string; }; + cookie?: never; }; + requestBody?: never; responses: { + /** @description Reactions retrieved successfully */ 200: { headers: { [name: string]: unknown; @@ -20400,37 +25070,31 @@ export interface operations { }; }; }; - AuthController_refreshToken: { + CommentsController_addReaction: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Comment ID */ + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['RefreshTokenDto']; + 'application/json': components['schemas']['AddReactionDto']; }; }; responses: { - 200: { + /** @description Reaction added successfully */ + 201: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - AuthController_logout: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Rate limit exceeded */ + 429: { headers: { [name: string]: unknown; }; @@ -20438,16 +25102,22 @@ export interface operations { }; }; }; - AuthController_getProfile: { + CommentsController_removeReaction: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Comment ID */ + id: string; + /** @description Reaction type */ + reactionType: string; + }; cookie?: never; }; requestBody?: never; responses: { - 200: { + /** @description Reaction removed successfully */ + 204: { headers: { [name: string]: unknown; }; @@ -20455,37 +25125,31 @@ export interface operations { }; }; }; - AuthController_verifyStellarSignature: { + CommentsController_reportComment: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Comment ID */ + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['VerifySignatureDto']; + 'application/json': components['schemas']['ReportCommentDto']; }; }; responses: { + /** @description Comment reported successfully */ 201: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - OAuthController_googleAuth: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Rate limit exceeded */ + 429: { headers: { [name: string]: unknown; }; @@ -20493,33 +25157,27 @@ export interface operations { }; }; }; - OAuthController_googleAuthCallback: { + CommentModerationController_getModerationQueue: { parameters: { - query?: never; + query?: { + page?: number; + limit?: number; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Moderation queue retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - OAuthController_githubAuth: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Forbidden */ + 403: { headers: { [name: string]: unknown; }; @@ -20527,33 +25185,28 @@ export interface operations { }; }; }; - OAuthController_githubAuthCallback: { + CommentModerationController_getReports: { parameters: { - query?: never; + query?: { + status?: 'PENDING' | 'REVIEWED' | 'RESOLVED' | 'DISMISSED'; + page?: number; + limit?: number; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Reports retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - OAuthController_twitterAuth: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Forbidden */ + 403: { headers: { [name: string]: unknown; }; @@ -20561,36 +25214,38 @@ export interface operations { }; }; }; - OAuthController_twitterAuthCallback: { + CommentModerationController_resolveReport: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Report ID */ + id: string; + }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ResolveReportDto']; + }; + }; responses: { + /** @description Report resolved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - FollowsController_followEntity: { - parameters: { - query?: never; - header?: never; - path: { - entityType: string; - entityId: string; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - 201: { + /** @description Report not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20598,134 +25253,195 @@ export interface operations { }; }; }; - FollowsController_unfollowEntity: { + CommentModerationController_approveComment: { parameters: { query?: never; header?: never; path: { - entityType: string; - entityId: string; + /** @description Comment ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Comment approved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Comment not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - FollowsController_getUserFollowing: { + CommentModerationController_rejectComment: { parameters: { - query: { - entityType: string; - }; + query?: never; header?: never; path: { - userId: string; + /** @description Comment ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Comment rejected successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Comment not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - FollowsController_getEntityFollowers: { + CommentModerationController_hideComment: { parameters: { query?: never; header?: never; path: { - entityType: string; - entityId: string; + /** @description Comment ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Comment hidden successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Comment not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - FollowsController_getFollowStats: { + CommentModerationController_restoreComment: { parameters: { query?: never; header?: never; path: { - userId: string; + /** @description Comment ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Comment restored successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Comment not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - FollowsController_isFollowing: { + CommentModerationController_getModerationStats: { parameters: { query?: never; header?: never; - path: { - entityType: string; - entityId: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Moderation stats retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - ChatController_getMessages: { + HackathonsController_getHackathons: { parameters: { - query: { - roomId: string; - roomType: string; - cursor?: string; - limit?: number; - }; + query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Returns list of messages. */ + /** @description Hackathons retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['HackathonsListResponseDto']; + }; }; }; }; - MessagesController_listConversations: { + HackathonsController_getFeeEstimate: { parameters: { - query?: { - limit?: number; - offset?: number; + query: { + totalPool: string; }; header?: never; path?: never; @@ -20733,8 +25449,17 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Paginated list of conversations */ + /** @description Fee estimate */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['FeeEstimateResponseDto']; + }; + }; + /** @description totalPool is missing, invalid, or below minimum (5 USDC) */ + 400: { headers: { [name: string]: unknown; }; @@ -20742,21 +25467,36 @@ export interface operations { }; }; }; - MessagesController_startOrGetConversation: { + HackathonsController_getWinners: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateConversationDto']; + path: { + /** @description Hackathon ID or slug */ + idOrSlug: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Conversation (created or existing) */ + /** @description Winners retrieved successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['HackathonWinnersResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20764,20 +25504,36 @@ export interface operations { }; }; }; - MessagesController_getConversation: { + HackathonsController_getPublicResults: { parameters: { query?: never; header?: never; path: { - /** @description Conversation ID */ - id: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Conversation details */ + /** @description Results retrieved successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['PublicJudgingResultsResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20785,24 +25541,38 @@ export interface operations { }; }; }; - MessagesController_listMessages: { + HackathonsController_getHackathon: { parameters: { - query?: { - limit?: number; - /** @description Cursor for older messages */ - before?: string; + query: { + accessToken: string; }; header?: never; path: { - /** @description Conversation ID */ - id: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Paginated messages */ + /** @description Hackathon retrieved successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['HackathonResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20810,44 +25580,43 @@ export interface operations { }; }; }; - MessagesController_sendMessage: { + HackathonsController_verifyHackathonAccess: { parameters: { query?: never; header?: never; path: { - /** @description Conversation ID */ - id: string; + idOrSlug: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CreateMessageDto']; + 'application/json': components['schemas']['VerifyHackathonAccessDto']; }; }; responses: { - /** @description Message created */ - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['HackathonAccessTokenResponseDto']; + }; }; }; }; - MessagesController_markConversationRead: { + HackathonsController_getPublicContributors: { parameters: { query?: never; header?: never; path: { - /** @description Conversation ID */ - id: string; + slug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Marked as read */ + /** @description Contributors retrieved successfully */ 200: { headers: { [name: string]: unknown; @@ -20856,86 +25625,80 @@ export interface operations { }; }; }; - CampaignsController_validateCampaign: { + HackathonsController_followHackathon: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateCampaignDto']; + path: { + /** @description Hackathon ID or slug */ + idOrSlug: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Campaign data is valid */ + /** @description Follow status updated */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': { + /** @example true */ + following?: boolean; + }; + }; }; - /** @description Invalid campaign data */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - CampaignsController_createDraft: { + HackathonsController_joinHackathon: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Hackathon ID or slug */ + idOrSlug: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CreateDraftDto']; + 'application/json': components['schemas']['JoinHackathonDto']; }; }; responses: { - /** @description Draft campaign created */ - 201: { + /** @description Successfully joined hackathon */ + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ParticipationResponseDto']; + }; }; - }; - }; - CampaignsController_getCampaigns: { - parameters: { - query: { - /** @description Category of the campaign */ - category?: string; - /** @description Status of the campaign */ - status?: 'active' | 'funded' | 'completed'; - minFundingGoal?: number; - /** @description Minimum funding goal of the campaign */ - maxFundingGoal?: number; - /** @description Maximum funding goal of the campaign */ - page?: number; - /** @description Limit of the campaign */ - limit?: number; - /** @description Sort by of the campaign */ - sortBy: string; - /** @description Sort order of the campaign */ - sortOrder: string; - /** @description Search of the campaign */ - search?: string; + /** @description Registration closed or already participating */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Campaigns retrieved successfully */ - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20943,46 +25706,82 @@ export interface operations { }; }; }; - CampaignsController_createCampaign: { + HackathonsController_leaveHackathon: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateCampaignDto']; + path: { + /** @description Hackathon ID or slug */ + idOrSlug: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Campaign and project created successfully */ - 201: { + /** @description Successfully left hackathon */ + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ParticipationResponseDto']; + }; }; - /** @description Invalid campaign data */ + /** @description Not a participant or submission deadline passed */ 400: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - CampaignsController_triggerCron: { + HackathonsController_getHackathonParticipants: { parameters: { - query?: never; + query: { + /** @description Page number (1-based) */ + page?: number; + /** @description Items per page */ + limit?: number; + status: string; + skill: string; + type: string; + search: string; + }; header?: never; - path?: never; + path: { + /** @description Hackathon ID or slug */ + idOrSlug: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Cron job triggered successfully */ + /** @description Participants retrieved successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['HackathonParticipantsResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -20990,35 +25789,45 @@ export interface operations { }; }; }; - CampaignsController_getMyCampaigns: { + HackathonsSubmissionsController_getHackathonSubmissions: { parameters: { query: { - /** @description Category of the campaign */ - category: string; - /** @description Status of the campaign */ - status: string; - minFundingGoal: number; - /** @description Minimum funding goal of the campaign */ - maxFundingGoal: number; - /** @description Maximum funding goal of the campaign */ + /** @description Filter by submission status */ + status?: 'SUBMITTED' | 'SHORTLISTED' | 'DISQUALIFIED'; + /** @description Page number (1-based) */ page?: number; - /** @description Limit of the campaign */ + /** @description Items per page */ limit?: number; - /** @description Sort by of the campaign */ - sortBy?: string; - /** @description Sort order of the campaign */ - sortOrder?: string; - /** @description Search of the campaign */ search: string; + type: string; }; header?: never; - path?: never; + path: { + /** @description Hackathon ID or slug */ + idOrSlug: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description User campaigns retrieved successfully */ + /** @description Submissions retrieved successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['SubmissionResponseDto'][]; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21026,26 +25835,39 @@ export interface operations { }; }; }; - CampaignsController_getCampaignBySlug: { + HackathonsSubmissionsController_createSubmission: { parameters: { query?: never; header?: never; path: { - /** @description Campaign URL slug */ - slug: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateSubmissionDto']; + }; + }; responses: { - /** @description Campaign details retrieved successfully */ - 200: { + /** @description Submission created successfully */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['SubmissionResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Campaign not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -21054,26 +25876,35 @@ export interface operations { }; }; }; - CampaignsController_getCampaign: { + HackathonsSubmissionsController_exploreHackathonSubmissions: { parameters: { - query?: never; + query: { + /** @description Page number (1-based) */ + page?: number; + /** @description Items per page */ + limit?: number; + search: string; + type: string; + }; header?: never; path: { - /** @description Campaign ID or slug */ - id: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Campaign details retrieved successfully */ + /** @description Submissions retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['SubmissionResponseDto'][]; + }; }; - /** @description Campaign not found */ + /** @description Hackathon not found */ 404: { headers: { [name: string]: unknown; @@ -21082,31 +25913,36 @@ export interface operations { }; }; }; - CampaignsController_updateCampaign: { + HackathonsSubmissionsController_getMySubmission: { parameters: { query?: never; header?: never; path: { - /** @description Campaign ID or slug */ - id: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateCampaignDto']; - }; - }; + requestBody?: never; responses: { - /** @description Campaign updated successfully */ + /** @description Submission retrieved successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['SubmissionResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User does not own the campaign */ - 403: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21114,27 +25950,36 @@ export interface operations { }; }; }; - CampaignsController_deleteCampaign: { + HackathonsSubmissionsController_getSubmissionById: { parameters: { query?: never; header?: never; path: { - /** @description Campaign ID or slug */ - id: string; + /** @description Submission ID */ + submissionId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Campaign deleted successfully */ + /** @description Submission retrieved successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['SubmissionResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Cannot delete campaign with contributions, campaigns in funding phase, funded campaigns, completed campaigns, or user does not own the campaign */ - 403: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21142,39 +25987,39 @@ export interface operations { }; }; }; - CampaignsController_getCampaignStatistics: { + HackathonsSubmissionsController_deleteSubmission: { parameters: { query?: never; header?: never; path: { - /** @description Campaign ID or slug */ - id: string; + /** @description Submission ID */ + submissionId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Campaign statistics retrieved successfully */ + /** @description Submission withdrawn successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': { + /** @example Submission withdrawn successfully */ + message?: string; + }; + }; }; - }; - }; - CampaignsController_getInvitations: { - parameters: { - query?: never; - header?: never; - path: { - id: string; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21182,41 +26027,40 @@ export interface operations { }; }; }; - CampaignsController_inviteTeamMember: { + HackathonsSubmissionsController_updateSubmission: { parameters: { query?: never; header?: never; path: { - id: string; + /** @description Submission ID */ + submissionId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['InviteTeamMemberDto']; + 'application/json': components['schemas']['UpdateSubmissionDto']; }; }; responses: { - 201: { + /** @description Submission updated successfully */ + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['SubmissionResponseDto']; + }; }; - }; - }; - CampaignsController_acceptInvitation: { - parameters: { - query: { - token: string; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21224,44 +26068,44 @@ export interface operations { }; }; }; - ContributionsController_getCampaignContributions: { + HackathonsDiscussionsController_getHackathonDiscussions: { parameters: { query?: { + /** @description Page number (1-based) */ page?: number; + /** @description Items per page */ limit?: number; + /** @description Sort by field */ + sortBy?: 'createdAt' | 'updatedAt'; + /** @description Sort order */ + sortOrder?: 'asc' | 'desc'; }; header?: never; path: { - /** @description Campaign ID or slug */ id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Contributions retrieved successfully */ + /** @description Discussions retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - ContributionsController_getContributionStats: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Campaign ID or slug */ - id: string; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Contribution statistics retrieved successfully */ - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21269,20 +26113,50 @@ export interface operations { }; }; }; - MilestonesController_getCampaignMilestones: { + HackathonsDiscussionsController_createHackathonComment: { parameters: { query?: never; header?: never; path: { - /** @description Campaign ID or slug */ id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': { + /** + * @description Comment content + * @example This hackathon looks amazing! When does registration open? + */ + content: string; + /** + * @description Parent comment ID for replies + * @example comment_1234567890 + */ + parentId?: string; + }; + }; + }; responses: { - /** @description Milestones retrieved successfully */ - 200: { + /** @description Comment posted successfully */ + 201: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21290,28 +26164,38 @@ export interface operations { }; }; }; - MilestonesController_getMilestone: { + HackathonsDiscussionsController_deleteHackathonComment: { parameters: { query?: never; header?: never; path: { - /** @description Campaign ID or slug */ - id: string; - /** @description Milestone ID */ - milestoneId: string; + /** @description Comment ID */ + commentId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Milestone details retrieved successfully */ + /** @description Comment deleted successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @example Comment deleted successfully */ + message?: string; + }; + }; + }; + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Milestone not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -21320,40 +26204,44 @@ export interface operations { }; }; }; - MilestonesController_updateMilestone: { + HackathonsDiscussionsController_updateHackathonComment: { parameters: { query?: never; header?: never; path: { - /** @description Campaign ID or slug */ - id: string; - /** @description Milestone ID */ - milestoneId: string; + /** @description Comment ID */ + commentId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdateMilestoneDto']; + 'application/json': { + /** + * @description Updated comment content + * @example Updated: This hackathon looks amazing! + */ + content: string; + }; }; }; responses: { - /** @description Milestone submitted successfully */ + /** @description Comment updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Validation failed - invalid proof of work data */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description User does not own the campaign */ - 403: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21361,97 +26249,85 @@ export interface operations { }; }; }; - MilestonesController_validateMilestoneSubmission: { + HackathonsDiscussionsController_reactToComment: { parameters: { query?: never; header?: never; path: { - /** @description Campaign ID or slug */ - id: string; - /** @description Milestone ID */ - milestoneId: string; + /** @description Comment ID */ + commentId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['ValidateMilestoneSubmissionDto']; + 'application/json': { + /** + * @description Type of reaction + * @example LIKE + * @enum {string} + */ + reactionType: 'LIKE' | 'LOVE' | 'CELEBRATE' | 'INSIGHTFUL'; + }; }; }; responses: { - /** @description Validation successful */ + /** @description Reaction updated */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': { - /** @example true */ - validated?: boolean; - data?: { - /** @example submitted */ - status?: string; - /** @example Milestone completed - all deliverables ready for review. */ - evidence?: string; - /** - * @example [ - * "https://example.com/report.pdf" - * ] - */ - documents?: string[]; - }; - }; - }; + content?: never; }; - /** @description Validation failed */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; }; - content: { - 'application/json': { - /** @example false */ - validated?: boolean; - /** @example Evidence must be at least 10 characters of meaningful content */ - error?: string; - }; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - MilestonesController_getMilestoneStats: { + HackathonsDiscussionsController_getCommentReplies: { parameters: { - query?: never; + query?: { + /** @description Page number (1-based) */ + page?: number; + /** @description Items per page */ + limit?: number; + }; header?: never; path: { - /** @description Campaign ID or slug */ - id: string; + /** @description Comment ID */ + commentId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Milestone statistics retrieved successfully */ + /** @description Replies retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - BuilderCrowdfundingV2Controller_submitForReview: { - parameters: { - query?: never; - header?: never; - path: { - id: string; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21459,37 +26335,46 @@ export interface operations { }; }; }; - BuilderCrowdfundingV2Controller_withdrawSubmission: { + HackathonsTeamsController_getHackathonTeams: { parameters: { - query?: never; + query?: { + /** @description Search query */ + search?: string; + /** @description Filter by open teams only */ + openOnly?: boolean; + /** @description Page number */ + page?: number; + /** @description Items per page */ + limit?: number; + }; header?: never; path: { id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Teams retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['TeamListResponseDto']; + }; }; - }; - }; - BuilderCrowdfundingV2Controller_reviseAndResubmit: { - parameters: { - query?: never; - header?: never; - path: { - id: string; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21497,22 +26382,41 @@ export interface operations { }; }; }; - BuilderCrowdfundingV2Controller_publish: { + HackathonsTeamsController_createTeam: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['PublishCrowdfundingEscrowDto']; + 'application/json': components['schemas']['CreateTeamDto']; }; }; responses: { - 200: { + /** @description Team created successfully */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['TeamResponseDto']; + }; + }; + /** @description Not a participant, already in a team, or hackathon does not allow teams */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21520,22 +26424,39 @@ export interface operations { }; }; }; - BuilderCrowdfundingV2Controller_cancel: { + HackathonsTeamsController_getTeam: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['CancelCrowdfundingEscrowDto']; - }; - }; + requestBody?: never; responses: { + /** @description Team found */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['TeamResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21543,131 +26464,218 @@ export interface operations { }; }; }; - BuilderCrowdfundingV2Controller_claimMilestone: { + HackathonsTeamsController_disbandTeam: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['ClaimCrowdfundingMilestoneDto']; - }; - }; + requestBody?: never; responses: { + /** @description Team disbanded */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Team has an existing submission and cannot be disbanded */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Only the team leader can disband the team */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - BackerCrowdfundingV2Controller_contribute: { + HackathonsTeamsController_updateTeam: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['ContributeCrowdfundingDto']; + 'application/json': components['schemas']['UpdateTeamDto']; }; }; responses: { + /** @description Team updated */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Not team leader or invalid update */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - BackerCrowdfundingV2Controller_submitSigned: { + HackathonsTeamsController_joinTeam: { parameters: { query?: never; header?: never; path: { id: string; - opRowId: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CrowdfundingSubmitSignedXdrDto']; + 'application/json': { + /** + * @description Optional message to team leader + * @example I have 5 years of Rust development experience + */ + message?: string; + }; }; }; responses: { + /** @description Successfully joined team */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Team is closed, full, or user already in a team */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - BackerCrowdfundingV2Controller_getOp: { + HackathonsTeamsController_removeTeamMember: { parameters: { query?: never; header?: never; path: { id: string; - opRowId: string; + /** @description Team ID */ + teamId: string; + userId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Member removed from team */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Target user is not a member, or leader tried to remove themselves */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Only the team leader can remove members */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - CommunityCrowdfundingV2Controller_getTally: { + HackathonsTeamsController_leaveTeam: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Successfully left team */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - CommunityCrowdfundingV2Controller_castVote: { - parameters: { - query?: never; - header?: never; - path: { - id: string; - }; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['CastCrowdfundingVoteDto']; + /** @description Not a member or leader cannot leave with members */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - }; - responses: { - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21675,18 +26683,37 @@ export interface operations { }; }; }; - CommunityCrowdfundingV2Controller_getMyVote: { + HackathonsTeamsController_getMyTeam: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Team found or null if not in a team */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['TeamResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21694,22 +26721,43 @@ export interface operations { }; }; }; - AdminCrowdfundingV2Controller_approve: { + HackathonsTeamsController_inviteToTeam: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['ApproveCrowdfundingCampaignDto']; + 'application/json': components['schemas']['InviteToTeamDto']; }; }; responses: { - 200: { + /** @description Invitation sent successfully */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['TeamInvitationResponseDto']; + }; + }; + /** @description User already in team, team full, or pending invitation exists */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21717,45 +26765,66 @@ export interface operations { }; }; }; - AdminCrowdfundingV2Controller_reject: { + HackathonsTeamsController_getMyInvitations: { parameters: { - query?: never; + query?: { + /** @description Filter by invitation status */ + status?: 'pending' | 'accepted' | 'rejected' | 'expired'; + }; header?: never; path: { id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['RejectCrowdfundingCampaignDto']; - }; - }; + requestBody?: never; responses: { + /** @description List of invitations */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['TeamInvitationListResponseDto']; + }; }; }; }; - AdminCrowdfundingV2Controller_extendFunding: { + HackathonsTeamsController_acceptInvitation: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Invitation ID */ + inviteId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['ExtendCrowdfundingFundingDto']; - }; - }; + requestBody?: never; responses: { + /** @description Successfully accepted invitation and joined team */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['InvitationActionResponseDto']; + }; + }; + /** @description Invitation expired, already processed, or team full */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21763,22 +26832,39 @@ export interface operations { }; }; }; - AdminCrowdfundingV2Controller_pause: { + HackathonsTeamsController_rejectInvitation: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Invitation ID */ + inviteId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['PauseCrowdfundingCampaignDto']; - }; - }; + requestBody?: never; responses: { + /** @description Successfully rejected invitation */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['InvitationActionResponseDto']; + }; + }; + /** @description Invitation already processed */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21786,42 +26872,80 @@ export interface operations { }; }; }; - AdminCrowdfundingV2Controller_unpause: { + HackathonsTeamsController_cancelInvitation: { parameters: { query?: never; header?: never; path: { id: string; + /** @description Invitation ID */ + inviteId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Successfully cancelled invitation */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Not team leader or invitation already processed */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - AdminCrowdfundingV2Controller_approveMilestone: { + HackathonsTeamsController_getTeamInvitations: { parameters: { - query?: never; + query?: { + /** @description Filter by invitation status */ + status?: 'pending' | 'accepted' | 'rejected' | 'expired'; + }; header?: never; path: { id: string; - milestoneId: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['ApproveCrowdfundingMilestoneDto']; - }; - }; + requestBody?: never; responses: { + /** @description List of team invitations */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['TeamInvitationListResponseDto']; + }; + }; + /** @description Only team leader can view */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21829,57 +26953,41 @@ export interface operations { }; }; }; - AdminCrowdfundingV2Controller_rejectMilestone: { + HackathonsTeamsController_toggleRoleHiredStatus: { parameters: { query?: never; header?: never; path: { id: string; - milestoneId: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['RejectCrowdfundingMilestoneDto']; + 'application/json': components['schemas']['ToggleRoleHiredDto']; }; }; responses: { + /** @description Role status toggled successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - WalletController_getWallet: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Not team leader or invalid role */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - WalletController_getWalletDetails: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21887,52 +26995,50 @@ export interface operations { }; }; }; - WalletController_getAddressBalance: { + HackathonsTeamsController_transferLeadership: { parameters: { query?: never; header?: never; path: { - address: string; + id: string; + /** @description Team ID */ + teamId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['TransferLeadershipDto']; + }; + }; responses: { + /** @description Leadership successfully transferred */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['LeadershipTransferResponseDto']; + }; + }; + /** @description Not current leader, new leader not a member, or invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - WalletController_syncWallet: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 201: { + /** @description Only current team leader can transfer leadership */ + 403: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - WalletController_createWallet: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 201: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21940,31 +27046,38 @@ export interface operations { }; }; }; - WalletController_activate: { + OrganizationHackathonsDraftsController_getDraft: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon draft ID */ + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Wallet activated. Returns tx hash and added trustlines. */ - 201: { + /** @description Draft retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['HackathonDraftResponseDto']; + }; }; - /** @description Sponsorship not configured, or unexpected submit error. */ - 500: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Sponsor account is out of available XLM. Operators have been alerted; retry later. */ - 503: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -21972,46 +27085,36 @@ export interface operations { }; }; }; - WalletController_reclaimDormant: { + OrganizationHackathonsDraftsController_deleteDraft: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['ReclaimDormantDto']; + path: { + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon draft ID to delete */ + id: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Reclaim summary: scanned, eligible, revoked, freedXlm, walletIds, errors */ - 201: { + /** @description Draft deleted successfully */ + 204: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Admin role required. */ - 403: { + /** @description Draft not found or user not authorized */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - WalletController_getSupportedTrustlines: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description List of supported trustline assets */ - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22019,97 +27122,107 @@ export interface operations { }; }; }; - WalletController_addTrustline: { + OrganizationHackathonsDraftsController_updateDraft: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon draft ID */ + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AddTrustlineDto']; + 'application/json': components['schemas']['UpdateHackathonDraftDto']; }; }; responses: { - /** @description Trustline added or already exists */ - 201: { + /** @description Draft updated successfully */ + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['HackathonDraftResponseDto']; + }; }; - /** @description Wallet not activated, insufficient XLM for fees, or unsupported asset */ + /** @description Validation failed for one or more sections */ 400: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - WalletController_validateSendDestination: { + OrganizationHackathonsDraftsController_getOrganizationHackathons: { parameters: { query: { - /** @description Stellar public key (G...) */ - destinationPublicKey: string; - /** @description Asset code (e.g. USDC, XLM) */ - currency: string; + page: number; + limit: number; + /** @description Filter by hackathon status */ + status?: 'upcoming' | 'active' | 'ended'; }; header?: never; - path?: never; + path: { + /** @description Organization ID */ + organizationId: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Validation result (valid, isActivated, hasTrustlineForAsset, memoRequired) */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - valid?: boolean; - isValidPublicKey?: boolean; - isActivated?: boolean; - hasTrustlineForAsset?: boolean; - /** @description True if this destination requires a memo (e.g. exchange shared address) */ - memoRequired?: boolean; - message?: string | null; - }; + /** @description Hackathons retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['HackathonsListResponseDto']; }; }; }; }; - WalletController_send: { + OrganizationHackathonsDraftsController_createDraft: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['UserSendDto']; + path: { + /** @description Organization ID */ + organizationId: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Send submitted successfully */ + /** @description Draft created successfully */ 201: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['HackathonDraftResponseDto']; + }; }; - /** @description Validation or business rule error (e.g. destination not activated, no trustline, memo required, insufficient balance) */ + /** @description User is not a member of the organization */ 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Identity verification required. Complete KYC to send funds. */ - 403: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22117,83 +27230,42 @@ export interface operations { }; }; }; - WalletPayoutController_sendPayout: { + OrganizationHackathonsDraftsController_getOrganizationDrafts: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['SendPayoutDto']; + path: { + /** @description Organization ID */ + organizationId: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Payout submitted successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Validation or business rule error (e.g. destination not activated, no trustline, memo required) */ - 400: { + /** @description Drafts retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Forbidden – admin only */ - 403: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonDraftResponseDto'][]; }; - content?: never; }; }; }; - CommentsController_listComments: { + OrganizationHackathonsDraftsController_previewAnnouncementAudience: { parameters: { - query?: { - /** @description Entity type to filter comments */ - entityType?: - | 'PROJECT' - | 'BOUNTY' - | 'CROWDFUNDING_CAMPAIGN' - | 'GRANT' - | 'GRANT_APPLICATION' - | 'HACKATHON' - | 'HACKATHON_SUBMISSION' - | 'BLOG_POST'; - /** @description Entity ID to filter comments */ - entityId?: string; - /** @description Author ID to filter comments */ - authorId?: string; - /** @description Parent comment ID to filter replies */ - parentId?: string; - /** @description Comment status to filter */ - status?: 'ACTIVE' | 'HIDDEN' | 'DELETED' | 'PENDING_MODERATION'; - /** @description Include reaction data in response */ - includeReactions?: boolean; - /** @description Include report data in response (moderators only) */ - includeReports?: boolean; - /** @description Page number */ - page?: number; - /** @description Number of items per page */ - limit?: number; - /** @description Field to sort by */ - sortBy?: string; - /** @description Sort order */ - sortOrder?: 'asc' | 'desc'; - }; + query?: never; header?: never; - path?: never; + path: { + /** @description Hackathon (or draft) ID */ + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Comments retrieved successfully */ + /** @description Audience size preview */ 200: { headers: { [name: string]: unknown; @@ -22202,35 +27274,40 @@ export interface operations { }; }; }; - CommentsController_createComment: { + OrganizationHackathonsAiController_generateFromBrief: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Organization ID */ + organizationId: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CreateCommentDto']; + 'application/json': components['schemas']['GenerateDraftFromBriefDto']; }; }; responses: { - /** @description Comment created successfully */ + /** @description Draft generated and pre-filled. */ 201: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['GenerateDraftFromBriefResponseDto']; + }; }; - /** @description Invalid input */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Rate limit exceeded */ - 429: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22238,26 +27315,41 @@ export interface operations { }; }; }; - CommentsController_getComment: { + OrganizationHackathonsAiController_regenerateSection: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon draft ID */ id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['RegenerateDraftSectionDto']; + }; + }; responses: { - /** @description Comment retrieved successfully */ - 200: { + /** @description Regenerated section returned. */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['RegenerateDraftSectionResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Comment not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -22266,72 +27358,77 @@ export interface operations { }; }; }; - CommentsController_updateComment: { + OrganizationHackathonsSubmissionsController_updateVisibilitySettings: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdateCommentDto']; + 'application/json': components['schemas']['UpdateVisibilitySettingsDto']; }; }; responses: { - /** @description Comment updated successfully */ + /** @description Visibility settings updated successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Forbidden */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Comment not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonDraftResponseDto']; }; - content?: never; }; }; }; - CommentsController_deleteComment: { + OrganizationHackathonsSubmissionsController_reviewSubmission: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; + /** @description Organization ID */ + organizationId: string; + hackathonId: string; + /** @description Submission ID */ + submissionId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ReviewSubmissionDto']; + }; + }; responses: { - /** @description Comment deleted successfully */ - 204: { + /** @description Submission reviewed successfully */ + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': { + /** @example Submission reviewed successfully */ + message?: string; + submission?: Record; + }; + }; }; - /** @description Forbidden */ - 403: { + /** @description Invalid status or submission does not belong to hackathon */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Comment not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -22340,24 +27437,46 @@ export interface operations { }; }; }; - CommentsController_getCommentsByEntity: { + OrganizationHackathonsSubmissionsController_getOrganizationHackathonParticipants: { parameters: { query: { - includeNested: string; + /** @description Page number (1-based) */ + page?: number; + /** @description Items per page */ + limit?: number; + search: string; + status: string; + type: string; }; header?: never; path: { - /** @description Entity type */ - entityType: string; - /** @description Entity ID */ - entityId: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Comments retrieved successfully */ + /** @description Participants retrieved successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['OrganizationHackathonParticipantsResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22365,20 +27484,61 @@ export interface operations { }; }; }; - CommentsController_getReactions: { + OrganizationHackathonsSubmissionsController_scoreSubmissionOverride: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; + /** @description Organization ID */ + organizationId: string; + hackathonId: string; + /** @description Submission ID */ + submissionId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': { + /** + * @description Judge ID to credit with these scores (optional, defaults to organizer) + * @example user_1234567890 + */ + judgeId?: string; + /** @description Scores for each criterion */ + criteriaScores: unknown[]; + }; + }; + }; responses: { - /** @description Reactions retrieved successfully */ + /** @description Submission score override applied successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @example Submission scored successfully (organizer override) */ + message?: string; + judgingScore?: Record; + complianceChecks?: { + rubricValid?: boolean; + isOrganizerOverride?: boolean; + }; + }; + }; + }; + /** @description Invalid criteria scores or rubric validation failed */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22386,31 +27546,49 @@ export interface operations { }; }; }; - CommentsController_addReaction: { + OrganizationHackathonsSubmissionsController_disqualifySubmission: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; + /** @description Organization ID */ + organizationId: string; + hackathonId: string; + /** @description Submission ID */ + submissionId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AddReactionDto']; + 'application/json': components['schemas']['DisqualifySubmissionDto']; }; }; responses: { - /** @description Reaction added successfully */ - 201: { + /** @description Submission disqualified successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @example Submission disqualified successfully */ + message?: string; + submission?: Record; + }; + }; + }; + /** @description Submission does not belong to hackathon */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Rate limit exceeded */ - 429: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22418,22 +27596,43 @@ export interface operations { }; }; }; - CommentsController_removeReaction: { + OrganizationHackathonsSubmissionsController_bulkSubmissionAction: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; - /** @description Reaction type */ - reactionType: string; + /** @description Organization ID */ + organizationId: string; + hackathonId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['BulkSubmissionActionDto']; + }; + }; responses: { - /** @description Reaction removed successfully */ - 204: { + /** @description Bulk action completed successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @example Successfully updated 5 submission(s) */ + message?: string; + /** @example 5 */ + count?: number; + /** @example SHORTLISTED */ + action?: string; + }; + }; + }; + /** @description Invalid action or missing required fields */ + 400: { headers: { [name: string]: unknown; }; @@ -22441,31 +27640,52 @@ export interface operations { }; }; }; - CommentsController_reportComment: { + OrganizationHackathonsSubmissionsController_setSubmissionRank: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; + /** @description Organization ID */ + organizationId: string; + hackathonId: string; + /** @description Submission ID */ + submissionId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['ReportCommentDto']; + 'application/json': { + /** @example 1 */ + rank: number; + }; }; }; responses: { - /** @description Comment reported successfully */ - 201: { + /** @description Submission rank updated successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + /** @example Submission rank updated successfully */ + message?: string; + submission?: Record; + }; + }; + }; + /** @description Invalid rank or submission does not belong to hackathon */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Rate limit exceeded */ - 429: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22473,56 +27693,46 @@ export interface operations { }; }; }; - CommentModerationController_getModerationQueue: { + OrganizationHackathonsSubmissionsController_getAnalytics: { parameters: { - query?: { - page?: number; - limit?: number; - }; + query?: never; header?: never; - path?: never; + path: { + /** @description Organization ID */ + organizationId: string; + hackathonId: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Moderation queue retrieved successfully */ + /** @description Analytics retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['HackathonAnalyticsResponseDto']; + }; }; - /** @description Forbidden */ - 403: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - CommentModerationController_getReports: { - parameters: { - query?: { - status?: 'PENDING' | 'REVIEWED' | 'RESOLVED' | 'DISMISSED'; - page?: number; - limit?: number; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Reports retrieved successfully */ - 200: { + /** @description Forbidden - only organizers can access */ + 403: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Forbidden */ - 403: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22530,72 +27740,63 @@ export interface operations { }; }; }; - CommentModerationController_resolveReport: { + HackathonsAnnouncementsController_getAnnouncements: { parameters: { - query?: never; + query?: { + /** @description Page number (1-based) */ + page?: number; + /** @description Items per page */ + limit?: number; + }; header?: never; path: { - /** @description Report ID */ - id: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['ResolveReportDto']; - }; - }; + requestBody?: never; responses: { - /** @description Report resolved successfully */ + /** @description Announcements retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Forbidden */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Report not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AnnouncementResponseDto'][]; }; - content?: never; }; }; }; - CommentModerationController_approveComment: { + HackathonsAnnouncementsController_getAnnouncement: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; + /** @description Announcement ID */ + announcementId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Comment approved successfully */ + /** @description Announcement retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['AnnouncementResponseDto']; + }; }; - /** @description Forbidden */ - 403: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Comment not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -22604,33 +27805,41 @@ export interface operations { }; }; }; - CommentModerationController_rejectComment: { + OrganizationHackathonsAnnouncementsController_createAnnouncement: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateAnnouncementDto']; + }; + }; responses: { - /** @description Comment rejected successfully */ - 200: { + /** @description Announcement created successfully */ + 201: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['AnnouncementResponseDto']; + }; }; - /** @description Forbidden */ - 403: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Comment not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -22639,33 +27848,37 @@ export interface operations { }; }; }; - CommentModerationController_hideComment: { + OrganizationHackathonsAnnouncementsController_deleteAnnouncement: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; + /** @description Announcement ID */ + announcementId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Comment hidden successfully */ + /** @description Announcement deleted successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Forbidden */ - 403: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Comment not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -22674,33 +27887,43 @@ export interface operations { }; }; }; - CommentModerationController_restoreComment: { + OrganizationHackathonsAnnouncementsController_updateAnnouncement: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - id: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; + /** @description Announcement ID */ + announcementId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateAnnouncementDto']; + }; + }; responses: { - /** @description Comment restored successfully */ + /** @description Announcement updated successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['AnnouncementResponseDto']; + }; }; - /** @description Forbidden */ - 403: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Comment not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -22709,24 +27932,40 @@ export interface operations { }; }; }; - CommentModerationController_getModerationStats: { + OrganizationHackathonsAnnouncementsController_publishAnnouncement: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; + /** @description Announcement ID */ + announcementId: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Moderation stats retrieved successfully */ + /** @description Announcement published successfully */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['AnnouncementResponseDto']; + }; + }; + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Forbidden */ - 403: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22734,48 +27973,36 @@ export interface operations { }; }; }; - HackathonsController_getHackathons: { + HackathonsJudgingController_getCriteria: { parameters: { query?: never; header?: never; - path?: never; + path: { + /** @description Hackathon ID or Slug */ + idOrSlug: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Hackathons retrieved successfully */ + /** @description Criteria retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonsListResponseDto']; + 'application/json': components['schemas']['CriterionDto'][]; }; }; - }; - }; - HackathonsController_getFeeEstimate: { - parameters: { - query: { - totalPool: string; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Fee estimate */ - 200: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['FeeEstimateResponseDto']; - }; + content?: never; }; - /** @description totalPool is missing, invalid, or below minimum (5 USDC) */ - 400: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22783,28 +28010,41 @@ export interface operations { }; }; }; - HackathonsController_getWinners: { + HackathonsJudgingController_submitScore: { parameters: { query?: never; header?: never; - path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - }; + path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ScoreSubmissionDto']; + }; + }; responses: { - /** @description Winners retrieved successfully */ - 200: { + /** @description Score submitted successfully with compliance verification */ + 201: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonWinnersResponseDto']; + 'application/json': { + message?: string; + judgingScore?: { + id?: string; + totalScore?: number; + criteriaScores?: unknown[]; + }; + complianceChecks?: { + judgeAssigned?: boolean; + noConflictOfInterest?: boolean; + rubricValid?: boolean; + }; + }; }; }; - /** @description Invalid request */ + /** @description Judge not assigned, conflict of interest detected, or invalid scores */ 400: { headers: { [name: string]: unknown; @@ -22820,25 +28060,35 @@ export interface operations { }; }; }; - HackathonsController_getPublicResults: { + HackathonsJudgingController_getJudgingSubmissions: { parameters: { - query?: never; + query?: { + /** @description Page number (1-indexed) */ + page?: number; + /** @description Number of items per page */ + limit?: number; + /** @description Search term for project name, description, participant name or username */ + search?: string; + /** @description Sort field */ + sortBy?: 'date' | 'name' | 'score' | 'rank'; + /** @description Sort order */ + order?: 'asc' | 'desc'; + }; header?: never; path: { - /** @description Hackathon ID or slug */ + /** @description Hackathon ID or Slug */ idOrSlug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Results retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['PublicJudgingResultsResponseDto']; + 'application/json': components['schemas']['JudgingSubmissionsResponseDto']; }; }; /** @description Invalid request */ @@ -22857,13 +28107,13 @@ export interface operations { }; }; }; - HackathonsController_getHackathon: { + OrganizationHackathonsJudgingController_getJudges: { parameters: { - query: { - accessToken: string; - }; + query?: never; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; }; @@ -22871,13 +28121,13 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Hackathon retrieved successfully */ + /** @description Judges retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonResponseDto']; + 'application/json': components['schemas']['JudgeResponseDto'][]; }; }; /** @description Invalid request */ @@ -22896,44 +28146,42 @@ export interface operations { }; }; }; - HackathonsController_verifyHackathonAccess: { + OrganizationHackathonsJudgingController_addJudge: { parameters: { query?: never; header?: never; path: { + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ idOrSlug: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['VerifyHackathonAccessDto']; + 'application/json': components['schemas']['AddJudgeDto']; }; }; responses: { - 200: { + /** @description Judge added successfully */ + 201: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonAccessTokenResponseDto']; + 'application/json': components['schemas']['JudgeResponseDto']; }; }; - }; - }; - HackathonsController_getPublicContributors: { - parameters: { - query?: never; - header?: never; - path: { - slug: string; + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Contributors retrieved successfully */ - 200: { + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -22941,29 +28189,28 @@ export interface operations { }; }; }; - HackathonsController_followHackathon: { + OrganizationHackathonsJudgingController_removeJudge: { parameters: { query?: never; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; + /** @description User ID of the judge */ + userId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Follow status updated */ + /** @description Judge removed successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': { - /** @example true */ - following?: boolean; - }; - }; + content?: never; }; /** @description Invalid request */ 400: { @@ -22981,32 +28228,43 @@ export interface operations { }; }; }; - HackathonsController_joinHackathon: { + OrganizationHackathonsJudgingController_getResults: { parameters: { - query?: never; + query?: { + /** @description Page number (1-indexed) */ + page?: number; + /** @description Number of items per page */ + limit?: number; + /** @description Search term for project name, participant name or username */ + search?: string; + /** @description Sort field */ + sortBy?: 'score' | 'name' | 'rank' | 'date'; + /** @description Sort order */ + order?: 'asc' | 'desc'; + /** @description If true, only returns submissions that have been assigned a rank */ + onlyWinners?: boolean; + }; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['JoinHackathonDto']; - }; - }; + requestBody?: never; responses: { - /** @description Successfully joined hackathon */ + /** @description Results retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['ParticipationResponseDto']; + 'application/json': components['schemas']['JudgingResultsResponseDto']; }; }; - /** @description Registration closed or already participating */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -23022,28 +28280,31 @@ export interface operations { }; }; }; - HackathonsController_leaveHackathon: { + OrganizationHackathonsJudgingController_getIndividualScores: { parameters: { query?: never; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; + /** @description ID of the submission */ + submissionId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Successfully left hackathon */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['ParticipationResponseDto']; + 'application/json': components['schemas']['IndividualJudgingResultDto'][]; }; }; - /** @description Not a participant or submission deadline passed */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -23059,20 +28320,26 @@ export interface operations { }; }; }; - HackathonsController_getHackathonParticipants: { + OrganizationHackathonsJudgingController_getWinnerRanking: { parameters: { - query: { - /** @description Page number (1-based) */ + query?: { + /** @description Page number (1-indexed) */ page?: number; - /** @description Items per page */ + /** @description Number of items per page */ limit?: number; - status: string; - skill: string; - type: string; - search: string; + /** @description Search term for project name, participant name or username */ + search?: string; + /** @description Sort field */ + sortBy?: 'score' | 'name' | 'rank' | 'date'; + /** @description Sort order */ + order?: 'asc' | 'desc'; + /** @description If true, only returns submissions that have been assigned a rank */ + onlyWinners?: boolean; }; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; }; @@ -23080,13 +28347,12 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Participants retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonParticipantsResponseDto']; + 'application/json': components['schemas']['AggregatedJudgingResultDto'][]; }; }; /** @description Invalid request */ @@ -23105,20 +28371,13 @@ export interface operations { }; }; }; - HackathonsSubmissionsController_getHackathonSubmissions: { + OrganizationHackathonsJudgingController_judgingCoverage: { parameters: { - query: { - /** @description Filter by submission status */ - status?: 'SUBMITTED' | 'SHORTLISTED' | 'DISQUALIFIED'; - /** @description Page number (1-based) */ - page?: number; - /** @description Items per page */ - limit?: number; - search: string; - type: string; - }; + query?: never; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; }; @@ -23126,15 +28385,6 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Submissions retrieved successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['SubmissionResponseDto'][]; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -23151,31 +28401,20 @@ export interface operations { }; }; }; - HackathonsSubmissionsController_createSubmission: { + OrganizationHackathonsJudgingController_previewAllocation: { parameters: { query?: never; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateSubmissionDto']; - }; - }; + requestBody?: never; responses: { - /** @description Submission created successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['SubmissionResponseDto']; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -23192,18 +28431,13 @@ export interface operations { }; }; }; - HackathonsSubmissionsController_exploreHackathonSubmissions: { + OrganizationHackathonsJudgingController_allocationParity: { parameters: { - query: { - /** @description Page number (1-based) */ - page?: number; - /** @description Items per page */ - limit?: number; - search: string; - type: string; - }; + query?: never; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; }; @@ -23211,16 +28445,14 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Submissions retrieved successfully */ - 200: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SubmissionResponseDto'][]; - }; + content?: never; }; - /** @description Hackathon not found */ + /** @description Resource not found */ 404: { headers: { [name: string]: unknown; @@ -23229,11 +28461,13 @@ export interface operations { }; }; }; - HackathonsSubmissionsController_getMySubmission: { + OrganizationHackathonsJudgingController_judgingCompleteness: { parameters: { query?: never; header?: never; path: { + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; }; @@ -23241,15 +28475,6 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Submission retrieved successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['SubmissionResponseDto']; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -23266,26 +28491,26 @@ export interface operations { }; }; }; - HackathonsSubmissionsController_getSubmissionById: { + OrganizationHackathonsJudgingController_publishResults: { parameters: { query?: never; header?: never; path: { - /** @description Submission ID */ - submissionId: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Submission retrieved successfully */ + /** @description Results published successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SubmissionResponseDto']; - }; + content?: never; }; /** @description Invalid request */ 400: { @@ -23303,30 +28528,20 @@ export interface operations { }; }; }; - HackathonsSubmissionsController_deleteSubmission: { + OrganizationHackathonsJudgingController_winnersBoard: { parameters: { query?: never; header?: never; path: { - /** @description Submission ID */ - submissionId: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Submission withdrawn successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @example Submission withdrawn successfully */ - message?: string; - }; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -23343,31 +28558,26 @@ export interface operations { }; }; }; - HackathonsSubmissionsController_updateSubmission: { + OrganizationHackathonsJudgingController_setPlacementWinner: { parameters: { query?: never; header?: never; path: { - /** @description Submission ID */ - submissionId: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; + /** @description Prize placement id */ + placementId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdateSubmissionDto']; + 'application/json': components['schemas']['SetPlacementWinnerDto']; }; }; responses: { - /** @description Submission updated successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['SubmissionResponseDto']; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -23384,35 +28594,22 @@ export interface operations { }; }; }; - HackathonsDiscussionsController_getHackathonDiscussions: { + OrganizationHackathonsJudgingController_clearPlacementWinner: { parameters: { - query?: { - /** @description Page number (1-based) */ - page?: number; - /** @description Items per page */ - limit?: number; - /** @description Sort by field */ - sortBy?: 'createdAt' | 'updatedAt'; - /** @description Sort order */ - sortOrder?: 'asc' | 'desc'; - }; + query?: never; header?: never; path: { - id: string; + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Prize placement id */ + placementId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Discussions retrieved successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; /** @description Invalid request */ 400: { headers: { @@ -23429,41 +28626,22 @@ export interface operations { }; }; }; - HackathonsDiscussionsController_createHackathonComment: { + OrganizationHackathonsJudgingController_withholdPlacement: { parameters: { query?: never; header?: never; path: { - id: string; + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Prize placement id */ + placementId: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': { - /** - * @description Comment content - * @example This hackathon looks amazing! When does registration open? - */ - content: string; - /** - * @description Parent comment ID for replies - * @example comment_1234567890 - */ - parentId?: string; - }; - }; - }; + requestBody?: never; responses: { - /** @description Comment posted successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; /** @description Invalid request */ 400: { headers: { @@ -23480,30 +28658,20 @@ export interface operations { }; }; }; - HackathonsDiscussionsController_deleteHackathonComment: { + OrganizationHackathonsJudgingController_listInvitations: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - commentId: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Comment deleted successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @example Comment deleted successfully */ - message?: string; - }; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -23520,35 +28688,24 @@ export interface operations { }; }; }; - HackathonsDiscussionsController_updateHackathonComment: { + OrganizationHackathonsJudgingController_inviteJudge: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - commentId: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': { - /** - * @description Updated comment content - * @example Updated: This hackathon looks amazing! - */ - content: string; - }; + 'application/json': components['schemas']['InviteJudgeDto']; }; }; responses: { - /** @description Comment updated successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; /** @description Invalid request */ 400: { headers: { @@ -23565,35 +28722,31 @@ export interface operations { }; }; }; - HackathonsDiscussionsController_reactToComment: { + OrganizationHackathonsJudgingController_bulkInviteJudges: { parameters: { query?: never; header?: never; path: { - /** @description Comment ID */ - commentId: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': { - /** - * @description Type of reaction - * @example LIKE - * @enum {string} - */ - reactionType: 'LIKE' | 'LOVE' | 'CELEBRATE' | 'INSIGHTFUL'; - }; + 'application/json': components['schemas']['BulkInviteJudgesDto']; }; }; responses: { - /** @description Reaction updated */ - 200: { + 201: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['BulkInviteResultDto']; + }; }; /** @description Invalid request */ 400: { @@ -23611,30 +28764,22 @@ export interface operations { }; }; }; - HackathonsDiscussionsController_getCommentReplies: { + OrganizationHackathonsJudgingController_cancelInvitation: { parameters: { - query?: { - /** @description Page number (1-based) */ - page?: number; - /** @description Items per page */ - limit?: number; - }; + query?: never; header?: never; path: { - /** @description Comment ID */ - commentId: string; + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID or slug */ + idOrSlug: string; + /** @description Invitation ID */ + invitationId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Replies retrieved successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; /** @description Invalid request */ 400: { headers: { @@ -23651,37 +28796,22 @@ export interface operations { }; }; }; - HackathonsTeamsController_getHackathonTeams: { + OrganizationHackathonsJudgingController_resendInvitation: { parameters: { - query?: { - /** @description Search query */ - search?: string; - /** @description Filter by open teams only */ - openOnly?: boolean; - /** @description Page number */ - page?: number; - /** @description Items per page */ - limit?: number; - }; + query?: never; header?: never; path: { - id: string; + /** @description Organization ID */ + organizationId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Invitation ID */ + invitationId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Teams retrieved successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['TeamListResponseDto']; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -23698,33 +28828,29 @@ export interface operations { }; }; }; - HackathonsTeamsController_createTeam: { + OrganizationHackathonsJudgingController_listRecommendationThresholds: { parameters: { query?: never; header?: never; path: { - id: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Organization ID */ + organizationId: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateTeamDto']; - }; - }; + requestBody?: never; responses: { - /** @description Team created successfully */ - 201: { + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['TeamResponseDto']; + 'application/json': components['schemas']['RecommendationThresholdDto'][]; }; }; - /** @description Not a participant, already in a team, or hackathon does not allow teams */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -23740,28 +28866,30 @@ export interface operations { }; }; }; - HackathonsTeamsController_getTeam: { + OrganizationHackathonsJudgingController_setRecommendationThreshold: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Team ID */ - teamId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Organization ID */ + organizationId: unknown; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['SetRecommendationThresholdDto']; + }; + }; responses: { - /** @description Team found */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['TeamResponseDto']; + 'application/json': components['schemas']['RecommendationThresholdDto']; }; }; /** @description Invalid request */ @@ -23780,42 +28908,29 @@ export interface operations { }; }; }; - HackathonsTeamsController_disbandTeam: { + OrganizationHackathonsJudgingController_deleteRecommendationThreshold: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Team ID */ - teamId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Threshold ID */ + thresholdId: string; + /** @description Organization ID */ + organizationId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Team disbanded */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Team has an existing submission and cannot be disbanded */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Only the team leader can disband the team */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; /** @description Resource not found */ 404: { headers: { @@ -23825,33 +28940,29 @@ export interface operations { }; }; }; - HackathonsTeamsController_updateTeam: { + OrganizationHackathonsJudgingController_computeRecommendations: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Team ID */ - teamId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Organization ID */ + organizationId: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateTeamDto']; - }; - }; + requestBody?: never; responses: { - /** @description Team updated */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['RecommendationComputeResultDto']; + }; }; - /** @description Not team leader or invalid update */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -23867,39 +28978,25 @@ export interface operations { }; }; }; - HackathonsTeamsController_joinTeam: { + OrganizationHackathonsJudgingController_aiScoreSubmission: { parameters: { - query?: never; + query?: { + prizeId?: unknown; + }; header?: never; path: { - id: string; - /** @description Team ID */ - teamId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Submission ID */ + submissionId: string; + /** @description Organization ID */ + organizationId: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': { - /** - * @description Optional message to team leader - * @example I have 5 years of Rust development experience - */ - message?: string; - }; - }; - }; + requestBody?: never; responses: { - /** @description Successfully joined team */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Team is closed, full, or user already in a team */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -23915,43 +29012,27 @@ export interface operations { }; }; }; - HackathonsTeamsController_removeTeamMember: { + OrganizationHackathonsJudgingController_aiScorecards: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Team ID */ - teamId: string; - userId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Organization ID */ + organizationId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Member removed from team */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Target user is not a member, or leader tried to remove themselves */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Only the team leader can remove members */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; /** @description Resource not found */ 404: { headers: { @@ -23961,29 +29042,23 @@ export interface operations { }; }; }; - HackathonsTeamsController_leaveTeam: { + OrganizationHackathonsJudgingController_promoteAiScore: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Team ID */ - teamId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Submission ID */ + submissionId: string; + /** @description Organization ID */ + organizationId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Successfully left team */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Not a member or leader cannot leave with members */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -23999,28 +29074,22 @@ export interface operations { }; }; }; - HackathonsTeamsController_getMyTeam: { + OrganizationHackathonsJudgingController_unpromoteAiScore: { parameters: { query?: never; header?: never; path: { - id: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + idOrSlug: string; + /** @description Submission ID */ + submissionId: string; + /** @description Organization ID */ + organizationId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Team found or null if not in a team */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['TeamResponseDto']; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -24037,35 +29106,16 @@ export interface operations { }; }; }; - HackathonsTeamsController_inviteToTeam: { + JudgeController_myInvitations: { parameters: { query?: never; header?: never; - path: { - id: string; - /** @description Team ID */ - teamId: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; - }; + path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['InviteToTeamDto']; - }; - }; + requestBody?: never; responses: { - /** @description Invitation sent successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['TeamInvitationResponseDto']; - }; - }; - /** @description User already in team, team full, or pending invitation exists */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24081,58 +29131,19 @@ export interface operations { }; }; }; - HackathonsTeamsController_getMyInvitations: { - parameters: { - query?: { - /** @description Filter by invitation status */ - status?: 'pending' | 'accepted' | 'rejected' | 'expired'; - }; - header?: never; - path: { - id: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description List of invitations */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['TeamInvitationListResponseDto']; - }; - }; - }; - }; - HackathonsTeamsController_acceptInvitation: { + JudgeController_previewInvitation: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Invitation ID */ - inviteId: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; + /** @description Opaque invitation token */ + token: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Successfully accepted invitation and joined team */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['InvitationActionResponseDto']; - }; - }; - /** @description Invitation expired, already processed, or team full */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24148,31 +29159,23 @@ export interface operations { }; }; }; - HackathonsTeamsController_rejectInvitation: { + JudgeController_acceptInvitation: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Invitation ID */ - inviteId: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; + /** @description Opaque invitation token */ + token: string; }; cookie?: never; }; - requestBody?: never; - responses: { - /** @description Successfully rejected invitation */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['InvitationActionResponseDto']; - }; + requestBody: { + content: { + 'application/json': components['schemas']['AcceptJudgeInvitationDto']; }; - /** @description Invitation already processed */ + }; + responses: { + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24188,29 +29191,19 @@ export interface operations { }; }; }; - HackathonsTeamsController_cancelInvitation: { + JudgeController_declineInvitation: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Invitation ID */ - inviteId: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; + /** @description Opaque invitation token */ + token: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Successfully cancelled invitation */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Not team leader or invitation already processed */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24226,34 +29219,23 @@ export interface operations { }; }; }; - HackathonsTeamsController_getTeamInvitations: { + JudgeController_myHackathons: { parameters: { - query?: { - /** @description Filter by invitation status */ - status?: 'pending' | 'accepted' | 'rejected' | 'expired'; - }; + query?: never; header?: never; - path: { - id: string; - /** @description Team ID */ - teamId: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description List of team invitations */ + /** @description Assigned hackathons */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TeamInvitationListResponseDto']; - }; + content?: never; }; - /** @description Only team leader can view */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24269,33 +29251,26 @@ export interface operations { }; }; }; - HackathonsTeamsController_toggleRoleHiredStatus: { + JudgeController_overview: { parameters: { query?: never; header?: never; path: { - id: string; - /** @description Team ID */ - teamId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + hackathonId: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['ToggleRoleHiredDto']; - }; - }; + requestBody?: never; responses: { - /** @description Role status toggled successfully */ + /** @description Hackathon overview */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Not team leader or invalid role */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24311,48 +29286,44 @@ export interface operations { }; }; }; - HackathonsTeamsController_transferLeadership: { + JudgeController_submissions: { parameters: { - query?: never; + query?: { + /** @description Page number (1-indexed) */ + page?: number; + /** @description Number of items per page */ + limit?: number; + /** @description Search term for project name, description, participant name or username */ + search?: string; + /** @description Sort field */ + sortBy?: 'date' | 'name' | 'score' | 'rank'; + /** @description Sort order */ + order?: 'asc' | 'desc'; + }; header?: never; path: { - id: string; - /** @description Team ID */ - teamId: string; /** @description Hackathon ID or slug */ - idOrSlug: unknown; + hackathonId: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['TransferLeadershipDto']; - }; - }; + requestBody?: never; responses: { - /** @description Leadership successfully transferred */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['LeadershipTransferResponseDto']; + 'application/json': components['schemas']['JudgingSubmissionsResponseDto']; }; }; - /** @description Not current leader, new leader not a member, or invalid request */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Only current team leader can transfer leadership */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; /** @description Resource not found */ 404: { headers: { @@ -24362,29 +29333,20 @@ export interface operations { }; }; }; - OrganizationHackathonsDraftsController_getDraft: { + JudgeController_submission: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon draft ID */ - id: string; + /** @description Submission ID */ + submissionId: string; + /** @description Hackathon ID or slug */ + hackathonId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Draft retrieved successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['HackathonDraftResponseDto']; - }; - }; /** @description Invalid request */ 400: { headers: { @@ -24401,28 +29363,21 @@ export interface operations { }; }; }; - OrganizationHackathonsDraftsController_deleteDraft: { + JudgeController_neighbors: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon draft ID to delete */ - id: string; + /** @description Submission ID */ + submissionId: string; + /** @description Hackathon ID or slug */ + hackathonId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Draft deleted successfully */ - 204: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Draft not found or user not authorized */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24438,34 +29393,19 @@ export interface operations { }; }; }; - OrganizationHackathonsDraftsController_updateDraft: { + JudgeController_criteria: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon draft ID */ - id: string; + /** @description Hackathon ID or slug */ + hackathonId: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateHackathonDraftDto']; - }; - }; + requestBody?: never; responses: { - /** @description Draft updated successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['HackathonDraftResponseDto']; - }; - }; - /** @description Validation failed for one or more sections */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24481,56 +29421,49 @@ export interface operations { }; }; }; - OrganizationHackathonsDraftsController_getOrganizationHackathons: { + JudgeController_results: { parameters: { - query: { - page: number; - limit: number; - /** @description Filter by hackathon status */ - status?: 'upcoming' | 'active' | 'ended'; - }; + query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; + /** @description Hackathon ID or slug */ + hackathonId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Hackathons retrieved successfully */ - 200: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonsListResponseDto']; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationHackathonsDraftsController_createDraft: { + JudgeController_score: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; + /** @description Submission ID */ + submissionId: string; + /** @description Hackathon ID or slug */ + hackathonId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Draft created successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['HackathonDraftResponseDto']; - }; - }; - /** @description User is not a member of the organization */ + /** @description Invalid request */ 400: { headers: { [name: string]: unknown; @@ -24546,43 +29479,59 @@ export interface operations { }; }; }; - OrganizationHackathonsDraftsController_getOrganizationDrafts: { + JudgeController_aiScorecard: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; + /** @description Hackathon ID or slug */ + hackathonId: string; + /** @description Submission ID */ + submissionId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Drafts retrieved successfully */ - 200: { + /** @description Invalid request */ + 400: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonDraftResponseDto'][]; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationHackathonsDraftsController_previewAnnouncementAudience: { + JudgeController_runAiScore: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon (or draft) ID */ - id: string; + /** @description Hackathon ID or slug */ + hackathonId: string; + /** @description Submission ID */ + submissionId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Audience size preview */ - 200: { + /** @description Invalid request */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Resource not found */ + 404: { headers: { [name: string]: unknown; }; @@ -24590,29 +29539,40 @@ export interface operations { }; }; }; - OrganizationHackathonsAiController_generateFromBrief: { + OrganizationHackathonsUpdatesController_getHackathonStatistics: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; + id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['GenerateDraftFromBriefDto']; - }; - }; + requestBody?: never; responses: { - /** @description Draft generated and pre-filled. */ - 201: { + /** @description Statistics retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['GenerateDraftFromBriefResponseDto']; + 'application/json': { + /** @example 45 */ + totalSubmissions?: number; + /** @example 120 */ + activeParticipants?: number; + /** @example 340 */ + totalFollowers?: number; + /** @example 50000 */ + prizePool?: number; + categories?: string[]; + /** @example active */ + status?: string; + }; }; }; /** @description Invalid request */ @@ -24631,34 +29591,35 @@ export interface operations { }; }; }; - OrganizationHackathonsAiController_regenerateSection: { + OrganizationHackathonsUpdatesController_updatePublishedContent: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; - /** @description Hackathon draft ID */ id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['RegenerateDraftSectionDto']; + 'application/json': components['schemas']['UpdatePublishedHackathonContentDto']; }; }; responses: { - /** @description Regenerated section returned. */ - 201: { + /** @description Published hackathon content updated successfully */ + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['RegenerateDraftSectionResponseDto']; + 'application/json': components['schemas']['HackathonResponseDto']; }; }; - /** @description Invalid request */ + /** @description Invalid payload or hackathon state */ 400: { headers: { [name: string]: unknown; @@ -24674,45 +29635,58 @@ export interface operations { }; }; }; - OrganizationHackathonsSubmissionsController_updateVisibilitySettings: { + OrganizationHackathonsUpdatesController_updatePublishedSchedule: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ id: string; + /** @description Hackathon ID or slug */ + idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdateVisibilitySettingsDto']; + 'application/json': components['schemas']['UpdatePublishedHackathonScheduleDto']; }; }; responses: { - /** @description Visibility settings updated successfully */ + /** @description Published hackathon schedule updated successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonDraftResponseDto']; + 'application/json': components['schemas']['HackathonResponseDto']; + }; + }; + /** @description Invalid payload or schedule changes are no longer allowed */ + 400: { + headers: { + [name: string]: unknown; }; + content?: never; + }; + /** @description Resource not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; }; }; }; - OrganizationHackathonsSubmissionsController_reviewSubmission: { + OrganizationHackathonsUpdatesController_updatePublishedFinancial: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; - hackathonId: string; - /** @description Submission ID */ - submissionId: string; + id: string; /** @description Hackathon ID or slug */ idOrSlug: unknown; }; @@ -24720,24 +29694,20 @@ export interface operations { }; requestBody: { content: { - 'application/json': components['schemas']['ReviewSubmissionDto']; + 'application/json': components['schemas']['UpdatePublishedHackathonFinancialDto']; }; }; responses: { - /** @description Submission reviewed successfully */ + /** @description Published hackathon financial settings updated successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': { - /** @example Submission reviewed successfully */ - message?: string; - submission?: Record; - }; + 'application/json': components['schemas']['HackathonResponseDto']; }; }; - /** @description Invalid status or submission does not belong to hackathon */ + /** @description Invalid payload or escrow-restricted financial change */ 400: { headers: { [name: string]: unknown; @@ -24753,38 +29723,66 @@ export interface operations { }; }; }; - OrganizationHackathonsSubmissionsController_getOrganizationHackathonParticipants: { + OrganizationHackathonsUpdatesController_previewPublishedFinancial: { parameters: { - query: { - /** @description Page number (1-based) */ - page?: number; - /** @description Items per page */ - limit?: number; - search: string; - status: string; - type: string; - }; + query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; + id: string; /** @description Hackathon ID or slug */ - idOrSlug: string; + idOrSlug: unknown; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UpdatePublishedHackathonFinancialDto']; + }; + }; responses: { - /** @description Participants retrieved successfully */ + /** @description Cost preview computed successfully (no changes made) */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['OrganizationHackathonParticipantsResponseDto']; + 'application/json': { + /** @example 180 */ + currentPrizePool?: number; + /** @example 250 */ + newPrizePool?: number; + /** @example 8.5 */ + currentPlatformFee?: number; + /** @example 11.8 */ + newPlatformFee?: number; + /** @example 188.5 */ + currentTotalRequired?: number; + /** @example 261.8 */ + newTotalRequired?: number; + /** @example 73.3 */ + additionalFundingRequired?: number; + /** @example 78.8 */ + walletBalance?: number | null; + /** @example true */ + sufficient?: boolean; + /** @example 0 */ + shortfall?: number; + breakdown?: { + /** @example 1st Place */ + place?: string; + /** @example 50 */ + amount?: number; + /** @example 2.25 */ + fee?: number; + /** @example 52.25 */ + total?: number; + }[]; + }; }; }; - /** @description Invalid request */ + /** @description Invalid payload or hackathon state */ 400: { headers: { [name: string]: unknown; @@ -24800,16 +29798,14 @@ export interface operations { }; }; }; - OrganizationHackathonsSubmissionsController_scoreSubmissionOverride: { + OrganizationHackathonsUpdatesController_updatePublishedAdvancedSettings: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; - hackathonId: string; - /** @description Submission ID */ - submissionId: string; + id: string; /** @description Hackathon ID or slug */ idOrSlug: unknown; }; @@ -24817,36 +29813,20 @@ export interface operations { }; requestBody: { content: { - 'application/json': { - /** - * @description Judge ID to credit with these scores (optional, defaults to organizer) - * @example user_1234567890 - */ - judgeId?: string; - /** @description Scores for each criterion */ - criteriaScores: unknown[]; - }; + 'application/json': components['schemas']['UpdatePublishedHackathonAdvancedSettingsDto']; }; }; responses: { - /** @description Submission score override applied successfully */ + /** @description Published hackathon advanced settings updated successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': { - /** @example Submission scored successfully (organizer override) */ - message?: string; - judgingScore?: Record; - complianceChecks?: { - rubricValid?: boolean; - isOrganizerOverride?: boolean; - }; - }; + 'application/json': components['schemas']['HackathonResponseDto']; }; }; - /** @description Invalid criteria scores or rubric validation failed */ + /** @description Invalid payload or unsupported hackathon state */ 400: { headers: { [name: string]: unknown; @@ -24862,16 +29842,14 @@ export interface operations { }; }; }; - OrganizationHackathonsSubmissionsController_disqualifySubmission: { + OrganizationHackathonsUpdatesController_setHackathonAccess: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; - hackathonId: string; - /** @description Submission ID */ - submissionId: string; + id: string; /** @description Hackathon ID or slug */ idOrSlug: unknown; }; @@ -24879,24 +29857,19 @@ export interface operations { }; requestBody: { content: { - 'application/json': components['schemas']['DisqualifySubmissionDto']; + 'application/json': components['schemas']['SetHackathonAccessDto']; }; }; responses: { - /** @description Submission disqualified successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': { - /** @example Submission disqualified successfully */ - message?: string; - submission?: Record; - }; + 'application/json': components['schemas']['HackathonResponseDto']; }; }; - /** @description Submission does not belong to hackathon */ + /** @description Missing password for private access */ 400: { headers: { [name: string]: unknown; @@ -24912,96 +29885,112 @@ export interface operations { }; }; }; - OrganizationHackathonsSubmissionsController_bulkSubmissionAction: { + OrganizationHackathonsExportController_exportHackathon: { parameters: { - query?: never; + query: { + /** @description Output format */ + format: 'csv' | 'pdf'; + /** @description Dataset scope. Defaults to "full" (all sections). */ + dataset?: + | 'overview' + | 'participants' + | 'submissions' + | 'prize_tiers' + | 'winners' + | 'judging' + | 'full'; + }; header?: never; path: { - /** @description Organization ID */ + /** @description ID of the organization that owns the hackathon */ organizationId: string; - hackathonId: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; + /** @description ID or slug of the hackathon */ + id: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['BulkSubmissionActionDto']; - }; - }; + requestBody?: never; responses: { - /** @description Bulk action completed successfully */ + /** @description Binary file stream (CSV or PDF) */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': { - /** @example Successfully updated 5 submission(s) */ - message?: string; - /** @example 5 */ - count?: number; - /** @example SHORTLISTED */ - action?: string; - }; + 'text/csv': string; + 'application/pdf': string; }; }; - /** @description Invalid action or missing required fields */ + /** @description Unsupported format or dataset */ 400: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Not an organizer of this hackathon */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Hackathon not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - OrganizationHackathonsSubmissionsController_setSubmissionRank: { + OrganizationHackathonsPartnersController_invite: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; + /** @description Hackathon ID */ hackathonId: string; - /** @description Submission ID */ - submissionId: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': { - /** @example 1 */ - rank: number; - }; + 'application/json': components['schemas']['InvitePartnerDto']; }; }; responses: { - /** @description Submission rank updated successfully */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @example Submission rank updated successfully */ - message?: string; - submission?: Record; - }; - }; - }; - /** @description Invalid rank or submission does not belong to hackathon */ - 400: { + /** @description Invitation created and email sent */ + 201: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + OrganizationHackathonsPartnersController_list: { + parameters: { + query?: { + status?: 'PENDING' | 'CONFIRMED' | 'FAILED' | 'REFUNDED' | 'CANCELLED'; + page?: number; + limit?: number; + }; + header?: never; + path: { + /** @description Organization ID */ + organizationId: string; + /** @description Hackathon ID */ + hackathonId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Contributions retrieved */ + 200: { headers: { [name: string]: unknown; }; @@ -25009,46 +29998,93 @@ export interface operations { }; }; }; - OrganizationHackathonsSubmissionsController_getAnalytics: { + OrganizationHackathonsPartnersController_cancel: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ organizationId: string; + /** @description Hackathon ID */ hackathonId: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; + /** @description Contribution ID */ + contributionId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Analytics retrieved successfully */ + /** @description Invitation cancelled */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonAnalyticsResponseDto']; - }; + content?: never; }; - /** @description Invalid request */ - 400: { + }; + }; + OrganizationHackathonsPartnersController_getAllocations: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; + hackathonId: string; + contributionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Allocation summary */ + 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Forbidden - only organizers can access */ - 403: { + }; + }; + OrganizationHackathonsPartnersController_allocate: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; + hackathonId: string; + contributionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['AllocateContributionDto']; + }; + }; + responses: { + /** @description Contribution allocated */ + 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + OrganizationHackathonsPartnersController_prizes: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; + hackathonId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Prizes with placements */ + 200: { headers: { [name: string]: unknown; }; @@ -25056,64 +30092,42 @@ export interface operations { }; }; }; - HackathonsAnnouncementsController_getAnnouncements: { + OrganizationHackathonsPartnersController_undoAllocation: { parameters: { - query?: { - /** @description Page number (1-based) */ - page?: number; - /** @description Items per page */ - limit?: number; - }; + query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; + organizationId: string; + hackathonId: string; + allocationId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Announcements retrieved successfully */ + /** @description Allocation undone */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['AnnouncementResponseDto'][]; - }; + content?: never; }; }; }; - HackathonsAnnouncementsController_getAnnouncement: { + PartnersContributeController_getByToken: { parameters: { query?: never; header?: never; path: { - /** @description Announcement ID */ - announcementId: string; + /** @description Hex-encoded invite token */ + token: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Announcement retrieved successfully */ + /** @description Invitation details */ 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['AnnouncementResponseDto']; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { headers: { [name: string]: unknown; }; @@ -25121,42 +30135,24 @@ export interface operations { }; }; }; - OrganizationHackathonsAnnouncementsController_createAnnouncement: { + PartnersContributeController_prepareFundTx: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hex-encoded invite token */ + token: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CreateAnnouncementDto']; + 'application/json': components['schemas']['PrepareFundTransactionDto']; }; }; responses: { - /** @description Announcement created successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['AnnouncementResponseDto']; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + /** @description Unsigned transaction prepared */ + 200: { headers: { [name: string]: unknown; }; @@ -25164,72 +30160,52 @@ export interface operations { }; }; }; - OrganizationHackathonsAnnouncementsController_deleteAnnouncement: { + PartnersContributeController_submitTx: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Announcement ID */ - announcementId: string; + /** @description Hex-encoded invite token */ + token: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['SubmitSignedTransactionDto']; + }; + }; responses: { - /** @description Announcement deleted successfully */ + /** @description Contribution confirmed */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - OrganizationHackathonsAnnouncementsController_updateAnnouncement: { + HackathonsTracksController_listTracks: { parameters: { - query?: never; + query?: { + /** @description Set true to include archived tracks. */ + includeArchived?: boolean; + }; header?: never; path: { - /** @description Organization ID */ - organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; - /** @description Announcement ID */ - announcementId: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateAnnouncementDto']; - }; - }; + requestBody?: never; responses: { - /** @description Announcement updated successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['AnnouncementResponseDto']; + 'application/json': components['schemas']['TrackResponseDto'][]; }; }; /** @description Invalid request */ @@ -25248,29 +30224,26 @@ export interface operations { }; }; }; - OrganizationHackathonsAnnouncementsController_publishAnnouncement: { + HackathonsCustomQuestionsController_list: { parameters: { - query?: never; + query?: { + scope?: 'REGISTRATION' | 'SUBMISSION'; + }; header?: never; path: { - /** @description Organization ID */ - organizationId: string; /** @description Hackathon ID or slug */ idOrSlug: string; - /** @description Announcement ID */ - announcementId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Announcement published successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['AnnouncementResponseDto']; + 'application/json': components['schemas']['CustomQuestionResponseDto'][]; }; }; /** @description Invalid request */ @@ -25289,86 +30262,92 @@ export interface operations { }; }; }; - HackathonsJudgingController_getCriteria: { + OrganizationHackathonsTracksController_list: { parameters: { - query?: never; + query?: { + includeArchived?: boolean; + }; header?: never; path: { - /** @description Hackathon ID or Slug */ - idOrSlug: string; + /** @description Hackathon ID or slug */ + id: string; + organizationId: unknown; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Criteria retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['CriterionDto'][]; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['TrackResponseDto'][]; }; - content?: never; }; }; }; - HackathonsJudgingController_submitScore: { + OrganizationHackathonsTracksController_create: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['ScoreSubmissionDto']; + 'application/json': components['schemas']['CreateTrackDto']; }; }; responses: { - /** @description Score submitted successfully with compliance verification */ 201: { headers: { [name: string]: unknown; }; content: { - 'application/json': { - message?: string; - judgingScore?: { - id?: string; - totalScore?: number; - criteriaScores?: unknown[]; - }; - complianceChecks?: { - judgeAssigned?: boolean; - noConflictOfInterest?: boolean; - rubricValid?: boolean; - }; - }; + 'application/json': components['schemas']['TrackResponseDto']; }; }; - /** @description Judge not assigned, conflict of interest detected, or invalid scores */ - 400: { + }; + }; + OrganizationHackathonsTracksController_updateConfig: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateTracksConfigDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + OrganizationHackathonsTracksController_remove: { + parameters: { + query?: never; + header?: never; + path: { + trackId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Deleted or archived */ + 204: { headers: { [name: string]: unknown; }; @@ -25376,430 +30355,319 @@ export interface operations { }; }; }; - HackathonsJudgingController_getJudgingSubmissions: { + OrganizationHackathonsTracksController_update: { parameters: { - query?: { - /** @description Page number (1-indexed) */ - page?: number; - /** @description Number of items per page */ - limit?: number; - /** @description Search term for project name, description, participant name or username */ - search?: string; - /** @description Sort field */ - sortBy?: 'date' | 'name' | 'score' | 'rank'; - /** @description Sort order */ - order?: 'asc' | 'desc'; - }; + query?: never; header?: never; path: { - /** @description Hackathon ID or Slug */ - idOrSlug: string; + trackId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateTrackDto']; + }; + }; responses: { 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['JudgingSubmissionsResponseDto']; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['TrackResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_getJudges: { + OrganizationHackathonsTracksController_bulkOptIn: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + trackId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Judges retrieved successfully */ + /** @description Bulk opt-in complete; returns counts. */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['JudgeResponseDto'][]; + 'application/json': { + trackName?: string; + added?: number; + alreadyOptedIn?: number; + skippedDisqualified?: number; + totalSubmissions?: number; + newCap?: number | null; + }; }; }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationHackathonsCustomQuestionsController_list: { + parameters: { + query?: { + scope?: 'REGISTRATION' | 'SUBMISSION'; }; - /** @description Resource not found */ - 404: { + header?: never; + path: { + /** @description Hackathon ID or slug */ + id: string; + organizationId: unknown; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['CustomQuestionResponseDto'][]; + }; }; }; }; - OrganizationHackathonsJudgingController_addJudge: { + OrganizationHackathonsCustomQuestionsController_replace: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AddJudgeDto']; + 'application/json': components['schemas']['UpsertCustomQuestionsDto']; }; }; responses: { - /** @description Judge added successfully */ - 201: { + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['JudgeResponseDto']; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['CustomQuestionResponseDto'][]; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_removeJudge: { + OrganizationHackathonsEscrowController_requestFundingOtp: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description User ID of the judge */ - userId: string; + /** @description Hackathon id */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Judge removed successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['RequestFundingOtpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_getResults: { + OrganizationHackathonsEscrowController_verifyFundingOtp: { parameters: { - query?: { - /** @description Page number (1-indexed) */ - page?: number; - /** @description Number of items per page */ - limit?: number; - /** @description Search term for project name, participant name or username */ - search?: string; - /** @description Sort field */ - sortBy?: 'score' | 'name' | 'rank' | 'date'; - /** @description Sort order */ - order?: 'asc' | 'desc'; - /** @description If true, only returns submissions that have been assigned a rank */ - onlyWinners?: boolean; - }; + query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hackathon id */ + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['VerifyFundingOtpDto']; + }; + }; responses: { - /** @description Results retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['JudgingResultsResponseDto']; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['VerifyFundingOtpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_getIndividualScores: { + OrganizationHackathonsEscrowController_publish: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description ID of the submission */ - submissionId: string; + /** @description Hackathon draft id */ + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['PublishHackathonEscrowDto']; + }; + }; responses: { + /** @description Escrow op created; unsigned XDR ready for wallet signing. Hackathon transitioned to DRAFT_AWAITING_FUNDING. */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['IndividualJudgingResultDto'][]; + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; }; - /** @description Invalid request */ + /** @description Validation error or hackathon not in DRAFT status */ 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - OrganizationHackathonsJudgingController_getWinnerRanking: { + OrganizationHackathonsEscrowController_cancel: { parameters: { - query?: { - /** @description Page number (1-indexed) */ - page?: number; - /** @description Number of items per page */ - limit?: number; - /** @description Search term for project name, participant name or username */ - search?: string; - /** @description Sort field */ - sortBy?: 'score' | 'name' | 'rank' | 'date'; - /** @description Sort order */ - order?: 'asc' | 'desc'; - /** @description If true, only returns submissions that have been assigned a rank */ - onlyWinners?: boolean; - }; + query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hackathon id */ + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CancelHackathonEscrowDto']; + }; + }; responses: { 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['AggregatedJudgingResultDto'][]; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_judgingCoverage: { + OrganizationHackathonsEscrowController_selectWinners: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hackathon id */ + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['SelectHackathonWinnersDto']; + }; + }; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_previewAllocation: { + OrganizationHackathonsEscrowController_submitSigned: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hackathon id */ + id: string; + /** @description EscrowOp uuid returned by the publish call */ + opRowId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['HackathonSubmitSignedXdrDto']; + }; + }; responses: { - /** @description Invalid request */ - 400: { + /** @description Signed XDR submitted; op is now PENDING_CONFIRM. */ + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_allocationParity: { + OrganizationHackathonsEscrowController_getOp: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hackathon id */ + id: string; + /** @description EscrowOp uuid */ + opRowId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_judgingCompleteness: { + OrganizationHackathonsEscrowController_resetToDraft: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hackathon id */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + /** @description Hackathon reset to DRAFT. */ + 200: { headers: { [name: string]: unknown; }; @@ -25807,196 +30675,150 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_publishResults: { + HackathonParticipantEscrowController_submit: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hackathon id */ + id: string; + /** @description HackathonSubmission uuid */ + submissionId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['SubmitHackathonDto']; + }; + }; responses: { - /** @description Results published successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_winnersBoard: { + HackathonParticipantEscrowController_withdrawSubmission: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; + /** @description Hackathon id */ + id: string; + /** @description HackathonSubmission uuid */ + submissionId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['WithdrawHackathonSubmissionDto']; + }; + }; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_setPlacementWinner: { + HackathonParticipantEscrowController_contribute: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Prize placement id */ - placementId: string; + /** @description Hackathon id */ + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['SetPlacementWinnerDto']; + 'application/json': components['schemas']['ContributeHackathonDto']; }; }; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_clearPlacementWinner: { + HackathonParticipantEscrowController_submitSigned: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Prize placement id */ - placementId: string; + /** @description Hackathon id */ + id: string; + /** @description EscrowOp uuid */ + opRowId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['HackathonSubmitSignedXdrDto']; + }; + }; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_withholdPlacement: { + HackathonParticipantEscrowController_getOp: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Prize placement id */ - placementId: string; + /** @description Hackathon id */ + id: string; + /** @description EscrowOp uuid */ + opRowId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsJudgingController_listInvitations: { + OrganizationsController_getOrganizations: { parameters: { query?: never; header?: never; - path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + 200: { headers: { [name: string]: unknown; }; @@ -26004,33 +30826,37 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_inviteJudge: { + OrganizationsController_createOrganization: { parameters: { query?: never; header?: never; - path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['InviteJudgeDto']; + 'application/json': components['schemas']['CreateOrganizationDto']; }; }; responses: { - /** @description Invalid request */ - 400: { + 201: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + OrganizationsController_getMyOrganizations: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -26038,41 +30864,55 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_bulkInviteJudges: { + OrganizationsController_getOrganizationProfile: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ + /** @description Organization ID or slug */ idOrSlug: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['BulkInviteJudgesDto']; - }; - }; + requestBody?: never; responses: { - 201: { + /** @description Organization profile retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['BulkInviteResultDto']; + 'application/json': components['schemas']['OrganizationProfileDto']; }; }; - /** @description Invalid request */ - 400: { + /** @description Organization not found */ + 404: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + OrganizationsController_searchOrganizations: { + parameters: { + query?: { + /** @description Search term (name, slug, tagline) */ + q?: string; + isProfileComplete?: 'true' | 'false'; + hasHackathons?: 'true' | 'false'; + hasGrants?: 'true' | 'false'; + /** @description Max results (default 10) */ + limit?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Paginated organizations */ + 200: { headers: { [name: string]: unknown; }; @@ -26080,30 +30920,140 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_cancelInvitation: { + OrganizationsController_getOrganization: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Invitation ID */ - invitationId: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + /** @description Organization retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': { + /** @example org_1234567890 */ + id?: string; + /** @example Tech Innovators */ + name?: string; + /** @example https://example.com/logo.png */ + logo?: string; + /** @example Building the future of technology */ + tagline?: string; + /** @example We are a community of developers... */ + about?: string; + links?: { + /** @example https://techinnovators.com */ + website?: string; + /** @example https://twitter.com/techinnovators */ + x?: string; + /** @example https://github.com/techinnovators */ + github?: string; + /** @example https://linkedin.com/company/techinnovators */ + others?: string; + }; + /** + * @example [ + * "user_123", + * "user_456" + * ] + */ + members?: string[]; + /** + * @example [ + * "user_123" + * ] + */ + admins?: string[]; + /** @example user_123 */ + owner?: string; + /** @example [] */ + hackathons?: string[]; + /** @example [] */ + grants?: string[]; + /** @example true */ + isProfileComplete?: boolean; + /** + * @example [ + * "invite_123" + * ] + */ + pendingInvites?: string[]; + /** @example better_auth_org_123 */ + betterAuthOrgId?: string; + /** @example false */ + isArchived?: boolean; + /** @example null */ + archivedBy?: string; + /** @example null */ + archivedAt?: string; + /** @example 2024-01-15T10:30:00.000Z */ + createdAt?: string; + /** @example 2024-01-15T10:30:00.000Z */ + updatedAt?: string; + analytics?: { + trends?: { + members?: { + /** @example 25 */ + current?: number; + /** @example 22 */ + previous?: number; + /** @example 3 */ + change?: number; + /** @example 13.64 */ + changePercentage?: number; + /** @example true */ + isPositive?: boolean; + }; + hackathons?: { + /** @example 5 */ + current?: number; + /** @example 4 */ + previous?: number; + /** @example 1 */ + change?: number; + /** @example 25 */ + changePercentage?: number; + /** @example true */ + isPositive?: boolean; + }; + grants?: { + /** @example 0 */ + current?: number; + /** @example 0 */ + previous?: number; + /** @example 0 */ + change?: number; + /** @example 0 */ + changePercentage?: number; + /** @example true */ + isPositive?: boolean; + }; + }; + timeSeries?: { + hackathons?: { + /** @example January */ + month?: string; + /** @example 2024 */ + year?: number; + /** @example 2 */ + count?: number; + /** @example 2024-01-01T00:00:00.000Z */ + timestamp?: string; + }[]; + }; + }; + }; + }; }; - /** @description Resource not found */ + /** @description Organization not found */ 404: { headers: { [name: string]: unknown; @@ -26112,31 +31062,22 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_resendInvitation: { + OrganizationsController_updateOrganization: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - organizationId: string; - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Invitation ID */ - invitationId: string; + id: string; }; cookie?: never; }; - requestBody?: never; - responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateOrganizationDto']; }; - /** @description Resource not found */ - 404: { + }; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -26144,37 +31085,18 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_listRecommendationThresholds: { + OrganizationsController_deleteOrganization: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Organization ID */ - organizationId: unknown; + id: string; }; cookie?: never; }; requestBody?: never; responses: { 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['RecommendationThresholdDto'][]; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { headers: { [name: string]: unknown; }; @@ -26182,41 +31104,37 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_setRecommendationThreshold: { + OrganizationsController_getOrganizationMembers: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Organization ID */ - organizationId: unknown; + id: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['SetRecommendationThresholdDto']; - }; - }; + requestBody?: never; responses: { 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['RecommendationThresholdDto']; - }; - }; - /** @description Invalid request */ - 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + OrganizationsController_getOrganizationPermissions: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -26224,31 +31142,18 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_deleteRecommendationThreshold: { + OrganizationsController_updateOrganizationPermissions: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Threshold ID */ - thresholdId: string; - /** @description Organization ID */ - organizationId: unknown; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + 200: { headers: { [name: string]: unknown; }; @@ -26256,37 +31161,18 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_computeRecommendations: { + OrganizationsController_resetOrganizationPermissions: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Organization ID */ - organizationId: unknown; + id: string; }; cookie?: never; }; requestBody?: never; responses: { 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['RecommendationComputeResultDto']; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { headers: { [name: string]: unknown; }; @@ -26294,33 +31180,18 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_aiScoreSubmission: { + OrganizationsController_getOrganizationStats: { parameters: { - query?: { - prizeId?: unknown; - }; + query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Submission ID */ - submissionId: string; - /** @description Organization ID */ - organizationId: unknown; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + 200: { headers: { [name: string]: unknown; }; @@ -26328,29 +31199,18 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_aiScorecards: { + MembersController_getMembers: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Organization ID */ - organizationId: unknown; + organizationId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + 200: { headers: { [name: string]: unknown; }; @@ -26358,31 +31218,19 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_promoteAiScore: { + MembersController_addMember: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Submission ID */ - submissionId: string; - /** @description Organization ID */ - organizationId: unknown; + organizationId: string; + userId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + 200: { headers: { [name: string]: unknown; }; @@ -26390,31 +31238,43 @@ export interface operations { }; }; }; - OrganizationHackathonsJudgingController_unpromoteAiScore: { + MembersController_removeMember: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; - /** @description Submission ID */ - submissionId: string; - /** @description Organization ID */ - organizationId: unknown; + organizationId: string; + userId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + MembersController_updateMemberRole: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; + userId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateMemberRoleDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -26422,24 +31282,18 @@ export interface operations { }; }; }; - JudgeController_myInvitations: { + MembersController_getMyMembership: { parameters: { query?: never; header?: never; - path?: never; + path: { + organizationId: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + 200: { headers: { [name: string]: unknown; }; @@ -26447,27 +31301,18 @@ export interface operations { }; }; }; - JudgeController_previewInvitation: { + InvitationsController_getInvitations: { parameters: { query?: never; header?: never; path: { - /** @description Opaque invitation token */ - token: string; + organizationId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { + 200: { headers: { [name: string]: unknown; }; @@ -26475,31 +31320,41 @@ export interface operations { }; }; }; - JudgeController_acceptInvitation: { + InvitationsController_inviteMember: { parameters: { query?: never; header?: never; path: { - /** @description Opaque invitation token */ - token: string; + organizationId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AcceptJudgeInvitationDto']; + 'application/json': components['schemas']['InviteMemberDto']; }; }; responses: { - /** @description Invalid request */ - 400: { + 201: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + InvitationsController_acceptInvitation: { + parameters: { + query?: never; + header?: never; + path: { + invitationId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -26507,27 +31362,38 @@ export interface operations { }; }; }; - JudgeController_declineInvitation: { + InvitationsController_rejectInvitation: { parameters: { query?: never; header?: never; path: { - /** @description Opaque invitation token */ - token: string; + invitationId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + InvitationsController_cancelInvitation: { + parameters: { + query?: never; + header?: never; + path: { + invitationId: string; + organizationId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; @@ -26535,7 +31401,7 @@ export interface operations { }; }; }; - JudgeController_myHackathons: { + InvitationsController_getMyInvitations: { parameters: { query?: never; header?: never; @@ -26544,82 +31410,62 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Assigned hackathons */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationTreasuryController_listWallets: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; }; - /** @description Resource not found */ - 404: { + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['TreasuryWalletResponseDto'][]; + }; }; }; }; - JudgeController_overview: { + OrganizationTreasuryController_listArchivedWallets: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - hackathonId: unknown; + organizationId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Hackathon overview */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['TreasuryWalletResponseDto'][]; }; - content?: never; }; }; }; - JudgeController_submissions: { + OrganizationTreasuryController_getDefaultWallet: { parameters: { - query?: { - /** @description Page number (1-indexed) */ - page?: number; - /** @description Number of items per page */ - limit?: number; - /** @description Search term for project name, description, participant name or username */ - search?: string; - /** @description Sort field */ - sortBy?: 'date' | 'name' | 'score' | 'rank'; - /** @description Sort order */ - order?: 'asc' | 'desc'; - }; + query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - hackathonId: unknown; + organizationId: string; }; cookie?: never; }; @@ -26630,550 +31476,424 @@ export interface operations { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['JudgingSubmissionsResponseDto']; + 'application/json': components['schemas']['TreasuryWalletResponseDto']; }; }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationTreasuryController_createManagedWallet: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; }; - /** @description Resource not found */ - 404: { + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['CreateManagedWalletDto']; + }; + }; + responses: { + 201: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['TreasuryWalletResponseDto']; + }; }; }; }; - JudgeController_submission: { + OrganizationTreasuryController_registerConnectedWallet: { parameters: { query?: never; header?: never; path: { - /** @description Submission ID */ - submissionId: string; - /** @description Hackathon ID or slug */ - hackathonId: unknown; + organizationId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['RegisterConnectedWalletDto']; + }; + }; responses: { - /** @description Invalid request */ - 400: { + 201: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['TreasuryWalletResponseDto']; }; - content?: never; }; }; }; - JudgeController_neighbors: { + OrganizationTreasuryController_refreshSigners: { parameters: { query?: never; header?: never; path: { - /** @description Submission ID */ - submissionId: string; - /** @description Hackathon ID or slug */ - hackathonId: unknown; + organizationId: string; + walletId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['TreasuryWalletResponseDto']; }; - content?: never; }; }; }; - JudgeController_criteria: { + OrganizationTreasuryController_updateWallet: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - hackathonId: unknown; + organizationId: string; + walletId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateTreasuryWalletDto']; + }; + }; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['TreasuryWalletResponseDto']; }; - content?: never; }; }; }; - JudgeController_results: { + OrganizationTreasuryController_archiveWallet: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - hackathonId: unknown; + organizationId: string; + walletId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['TreasuryWalletResponseDto']; }; - content?: never; }; }; }; - JudgeController_score: { + OrganizationTreasuryController_restoreWallet: { parameters: { query?: never; header?: never; path: { - /** @description Submission ID */ - submissionId: string; - /** @description Hackathon ID or slug */ - hackathonId: unknown; + organizationId: string; + walletId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['TreasuryWalletResponseDto']; }; - content?: never; }; }; }; - JudgeController_aiScorecard: { + OrganizationTreasuryController_walletBalance: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - hackathonId: string; - /** @description Submission ID */ - submissionId: string; + organizationId: string; + walletId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['WalletBalanceResponseDto']; }; - content?: never; }; }; }; - JudgeController_runAiScore: { + OrganizationTreasuryController_getPolicy: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - hackathonId: string; - /** @description Submission ID */ - submissionId: string; + organizationId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invalid request */ - 400: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['TreasuryPolicyResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsUpdatesController_getHackathonStatistics: { + OrganizationTreasuryController_updatePolicy: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - id: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateTreasuryPolicyDto']; + }; + }; responses: { - /** @description Statistics retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': { - /** @example 45 */ - totalSubmissions?: number; - /** @example 120 */ - activeParticipants?: number; - /** @example 340 */ - totalFollowers?: number; - /** @example 50000 */ - prizePool?: number; - categories?: string[]; - /** @example active */ - status?: string; - }; + 'application/json': components['schemas']['TreasuryPolicyResponseDto']; }; }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationTreasuryController_listSpend: { + parameters: { + query?: { + status?: string; }; - /** @description Resource not found */ - 404: { + header?: never; + path: { + organizationId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['SpendRequestResponseDto'][]; + }; }; }; }; - OrganizationHackathonsUpdatesController_updatePublishedContent: { + OrganizationTreasuryController_initiateSpend: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - id: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdatePublishedHackathonContentDto']; + 'application/json': components['schemas']['InitiateSpendDto']; }; }; responses: { - /** @description Published hackathon content updated successfully */ - 200: { + 201: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonResponseDto']; + 'application/json': components['schemas']['SpendRequestResponseDto']; }; }; - /** @description Invalid payload or hackathon state */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationTreasuryController_requestSendOtp: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; }; - /** @description Resource not found */ - 404: { + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['RequestFundingOtpResponseDto']; + }; }; }; }; - OrganizationHackathonsUpdatesController_updatePublishedSchedule: { + OrganizationTreasuryController_verifySendOtp: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - id: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdatePublishedHackathonScheduleDto']; + 'application/json': components['schemas']['VerifyFundingOtpDto']; }; }; responses: { - /** @description Published hackathon schedule updated successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonResponseDto']; - }; - }; - /** @description Invalid payload or schedule changes are no longer allowed */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['VerifyFundingOtpResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsUpdatesController_updatePublishedFinancial: { + OrganizationTreasuryController_sendFunds: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - id: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdatePublishedHackathonFinancialDto']; + 'application/json': components['schemas']['SendTreasuryFundsDto']; }; }; responses: { - /** @description Published hackathon financial settings updated successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonResponseDto']; + 'application/json': components['schemas']['SpendRequestResponseDto']; }; }; - /** @description Invalid payload or escrow-restricted financial change */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationTreasuryController_checkSendDestination: { + parameters: { + query: { + address: string; }; - /** @description Resource not found */ - 404: { + header?: never; + path: { + organizationId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['SendDestinationReadinessDto']; + }; }; }; }; - OrganizationHackathonsUpdatesController_previewPublishedFinancial: { + OrganizationTreasuryController_getSpend: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - id: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; + requestId: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdatePublishedHackathonFinancialDto']; - }; - }; + requestBody?: never; responses: { - /** @description Cost preview computed successfully (no changes made) */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': { - /** @example 180 */ - currentPrizePool?: number; - /** @example 250 */ - newPrizePool?: number; - /** @example 8.5 */ - currentPlatformFee?: number; - /** @example 11.8 */ - newPlatformFee?: number; - /** @example 188.5 */ - currentTotalRequired?: number; - /** @example 261.8 */ - newTotalRequired?: number; - /** @example 73.3 */ - additionalFundingRequired?: number; - /** @example 78.8 */ - walletBalance?: number | null; - /** @example true */ - sufficient?: boolean; - /** @example 0 */ - shortfall?: number; - breakdown?: { - /** @example 1st Place */ - place?: string; - /** @example 50 */ - amount?: number; - /** @example 2.25 */ - fee?: number; - /** @example 52.25 */ - total?: number; - }[]; - }; - }; - }; - /** @description Invalid payload or hackathon state */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['SpendRequestResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsUpdatesController_updatePublishedAdvancedSettings: { + OrganizationTreasuryController_approveSpend: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - id: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; + requestId: string; }; cookie?: never; }; - requestBody: { + requestBody?: { content: { - 'application/json': components['schemas']['UpdatePublishedHackathonAdvancedSettingsDto']; + 'application/json': components['schemas']['SpendDecisionDto']; }; }; responses: { - /** @description Published hackathon advanced settings updated successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonResponseDto']; - }; - }; - /** @description Invalid payload or unsupported hackathon state */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['SpendRequestResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsUpdatesController_setHackathonAccess: { + OrganizationTreasuryController_rejectSpend: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - id: string; - /** @description Hackathon ID or slug */ - idOrSlug: unknown; + requestId: string; }; cookie?: never; }; - requestBody: { + requestBody?: { content: { - 'application/json': components['schemas']['SetHackathonAccessDto']; + 'application/json': components['schemas']['SpendDecisionDto']; }; }; responses: { @@ -27182,203 +31902,192 @@ export interface operations { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonResponseDto']; + 'application/json': components['schemas']['SpendRequestResponseDto']; }; }; - /** @description Missing password for private access */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationTreasuryController_cancelSpend: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; + requestId: string; }; - /** @description Resource not found */ - 404: { + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['SpendRequestResponseDto']; + }; }; }; }; - OrganizationHackathonsExportController_exportHackathon: { + OrganizationTreasuryController_executeSpend: { parameters: { - query: { - /** @description Output format */ - format: 'csv' | 'pdf'; - /** @description Dataset scope. Defaults to "full" (all sections). */ - dataset?: - | 'overview' - | 'participants' - | 'submissions' - | 'prize_tiers' - | 'winners' - | 'judging' - | 'full'; - }; + query?: never; header?: never; path: { - /** @description ID of the organization that owns the hackathon */ organizationId: string; - /** @description ID or slug of the hackathon */ - id: string; + requestId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Binary file stream (CSV or PDF) */ 200: { headers: { [name: string]: unknown; }; content: { - 'text/csv': string; - 'application/pdf': string; + 'application/json': components['schemas']['SpendRequestResponseDto']; }; }; - /** @description Unsupported format or dataset */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationTreasuryController_buildSpendXdr: { + parameters: { + query?: never; + header?: never; + path: { + organizationId: string; + requestId: string; }; - /** @description Not an organizer of this hackathon */ - 403: { + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Hackathon not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['BuildSpendXdrResponseDto']; }; - content?: never; }; }; }; - OrganizationHackathonsPartnersController_invite: { + OrganizationTreasuryController_submitSpendSignedXdr: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID */ - hackathonId: string; + requestId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['InvitePartnerDto']; + 'application/json': components['schemas']['SubmitSpendSignedXdrDto']; }; }; responses: { - /** @description Invitation created and email sent */ - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['SpendRequestResponseDto']; + }; }; }; }; - OrganizationHackathonsPartnersController_list: { + OrganizationTreasuryController_auditLog: { parameters: { query?: { - status?: 'PENDING' | 'CONFIRMED' | 'FAILED' | 'REFUNDED' | 'CANCELLED'; - page?: number; - limit?: number; + page?: string; + limit?: string; }; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID */ - hackathonId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Contributions retrieved */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['TreasuryAuditLogResponseDto']; + }; }; }; }; - OrganizationHackathonsPartnersController_cancel: { + OrganizationReceiptsController_list: { parameters: { - query?: never; + query?: { + page?: string; + limit?: string; + type?: string; + referenceType?: string; + referenceId?: string; + }; header?: never; path: { - /** @description Organization ID */ organizationId: string; - /** @description Hackathon ID */ - hackathonId: string; - /** @description Contribution ID */ - contributionId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Invitation cancelled */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ReceiptListResponseDto']; + }; }; }; }; - OrganizationHackathonsPartnersController_getAllocations: { + OrganizationReceiptsController_getOne: { parameters: { query?: never; header?: never; path: { organizationId: string; - hackathonId: string; - contributionId: string; + receiptId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Allocation summary */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ReceiptResponseDto']; + }; }; }; }; - OrganizationHackathonsPartnersController_allocate: { + OrganizationReceiptsController_send: { parameters: { query?: never; header?: never; path: { organizationId: string; - hackathonId: string; - contributionId: string; + receiptId: string; }; cookie?: never; }; - requestBody: { + requestBody?: { content: { - 'application/json': components['schemas']['AllocateContributionDto']; + 'application/json': components['schemas']['SendReceiptDto']; }; }; responses: { - /** @description Contribution allocated */ 200: { headers: { [name: string]: unknown; @@ -27387,41 +32096,54 @@ export interface operations { }; }; }; - OrganizationHackathonsPartnersController_prizes: { + OrganizationReceiptsController_void: { parameters: { query?: never; header?: never; path: { organizationId: string; - hackathonId: string; + receiptId: string; }; cookie?: never; }; - requestBody?: never; + requestBody?: { + content: { + 'application/json': components['schemas']['VoidReceiptDto']; + }; + }; responses: { - /** @description Prizes with placements */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ReceiptResponseDto']; + }; }; }; }; - OrganizationHackathonsPartnersController_undoAllocation: { + VotesController_getVotes: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; - hackathonId: string; - allocationId: string; + query: { + /** @description Project ID */ + projectId?: string; + /** @description Entity Type */ + entityType?: string; + /** @description Vote Type */ + voteType: string; + /** @description User ID */ + userId: string; + /** @description Limit */ + limit: number; + /** @description Offset */ + offset: number; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Allocation undone */ 200: { headers: { [name: string]: unknown; @@ -27430,20 +32152,20 @@ export interface operations { }; }; }; - PartnersContributeController_getByToken: { + VotesController_createVote: { parameters: { query?: never; header?: never; - path: { - /** @description Hex-encoded invite token */ - token: string; - }; + path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateVoteDto']; + }; + }; responses: { - /** @description Invitation details */ - 200: { + 201: { headers: { [name: string]: unknown; }; @@ -27451,23 +32173,18 @@ export interface operations { }; }; }; - PartnersContributeController_prepareFundTx: { + VotesController_removeVote: { parameters: { query?: never; header?: never; path: { - /** @description Hex-encoded invite token */ - token: string; + projectId: string; + entityType: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['PrepareFundTransactionDto']; - }; - }; + requestBody?: never; responses: { - /** @description Unsigned transaction prepared */ 200: { headers: { [name: string]: unknown; @@ -27476,23 +32193,18 @@ export interface operations { }; }; }; - PartnersContributeController_submitTx: { + VotesController_getVoteCounts: { parameters: { query?: never; header?: never; path: { - /** @description Hex-encoded invite token */ - token: string; + projectId: string; + entityType: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['SubmitSignedTransactionDto']; - }; - }; + requestBody?: never; responses: { - /** @description Contribution confirmed */ 200: { headers: { [name: string]: unknown; @@ -27501,38 +32213,19 @@ export interface operations { }; }; }; - HackathonsTracksController_listTracks: { + VotesController_getUserVote: { parameters: { - query?: { - /** @description Set true to include archived tracks. */ - includeArchived?: boolean; - }; + query?: never; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; + projectId: string; + entityType: string; }; cookie?: never; }; requestBody?: never; responses: { 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['TrackResponseDto'][]; - }; - }; - /** @description Invalid request */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Resource not found */ - 404: { headers: { [name: string]: unknown; }; @@ -27540,37 +32233,56 @@ export interface operations { }; }; }; - HackathonsCustomQuestionsController_list: { + VotesController_getProjectVotes: { parameters: { query?: { - scope?: 'REGISTRATION' | 'SUBMISSION'; + entityType?: + | 'PROJECT' + | 'CROWDFUNDING_CAMPAIGN' + | 'HACKATHON_SUBMISSION' + | 'GRANT'; + voteType?: 'UPVOTE' | 'DOWNVOTE'; + limit?: number; + offset?: number; + /** @description Include voter list and vote counts in response */ + includeVoters?: boolean; }; header?: never; path: { - /** @description Hackathon ID or slug */ - idOrSlug: string; + projectId: string; }; cookie?: never; }; requestBody?: never; responses: { 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['CustomQuestionResponseDto'][]; - }; - }; - /** @description Invalid request */ - 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Resource not found */ - 404: { + }; + }; + LeaderboardController_getLeaderboard: { + parameters: { + query?: { + /** @description Filter by reputation tier */ + tier?: 'NEWCOMER' | 'CONTRIBUTOR' | 'ESTABLISHED' | 'EXPERT' | 'LEGEND'; + /** @description Time window for score aggregation */ + timeframe?: 'ALL_TIME' | 'THIS_MONTH' | 'THIS_WEEK' | 'THIS_DAY'; + /** @description Items per page, max 50 (default: 20) */ + limit?: number; + /** @description Page number (default: 1) */ + page?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Leaderboard retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; @@ -27578,72 +32290,88 @@ export interface operations { }; }; }; - OrganizationHackathonsTracksController_list: { + BlogPostsController_listBlogPosts: { parameters: { query?: { - includeArchived?: boolean; + /** @description Author ID to filter posts */ + authorId?: string; + /** @description Post status to filter */ + status?: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED' | 'SCHEDULED'; + /** @description Search query for post title/content */ + search?: string; + /** @description Filter by tags (comma-separated) */ + tags?: string; + /** @description Filter by categories (comma-separated) */ + categories?: string; + /** @description Include only featured posts */ + isFeatured?: boolean; + /** @description Include pinned posts first */ + includePinned?: boolean; + /** @description Page number */ + page?: number; + /** @description Number of items per page */ + limit?: number; + /** @description Sort field */ + sortBy?: + | 'createdAt' + | 'updatedAt' + | 'publishedAt' + | 'viewCount' + | 'title'; + /** @description Sort order */ + sortOrder?: 'asc' | 'desc'; }; header?: never; - path: { - /** @description Hackathon ID or slug */ - id: string; - organizationId: unknown; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Blog posts retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TrackResponseDto'][]; - }; + content?: never; }; }; }; - OrganizationHackathonsTracksController_create: { + BlogPostsController_createBlogPost: { parameters: { query?: never; header?: never; - path: { - id: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CreateTrackDto']; + 'application/json': components['schemas']['CreateBlogPostDto']; }; }; responses: { + /** @description Blog post created successfully */ 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TrackResponseDto']; - }; + content?: never; }; - }; - }; - OrganizationHackathonsTracksController_updateConfig: { - parameters: { - query?: never; - header?: never; - path: { - id: string; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateTracksConfigDto']; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - }; - responses: { - 200: { + /** @description Rate limit exceeded */ + 429: { headers: { [name: string]: unknown; }; @@ -27651,208 +32379,221 @@ export interface operations { }; }; }; - OrganizationHackathonsTracksController_remove: { + BlogPostsController_getBlogPostById: { parameters: { query?: never; header?: never; path: { - trackId: string; + /** @description Blog post ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Deleted or archived */ - 204: { + /** @description Blog post retrieved successfully */ + 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - OrganizationHackathonsTracksController_update: { - parameters: { - query?: never; - header?: never; - path: { - trackId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateTrackDto']; - }; - }; - responses: { - 200: { + /** @description Post is not published */ + 403: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TrackResponseDto']; + content?: never; + }; + /** @description Blog post not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationHackathonsTracksController_bulkOptIn: { + BlogPostsController_getBlogPostBySlug: { parameters: { query?: never; header?: never; path: { - trackId: string; + /** @description Blog post slug */ + slug: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Bulk opt-in complete; returns counts. */ + /** @description Blog post retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': { - trackName?: string; - added?: number; - alreadyOptedIn?: number; - skippedDisqualified?: number; - totalSubmissions?: number; - newCap?: number | null; - }; + content?: never; + }; + /** @description Post is not published */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Blog post not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationHackathonsCustomQuestionsController_list: { + BlogPostsController_getRelatedPosts: { parameters: { - query?: { - scope?: 'REGISTRATION' | 'SUBMISSION'; + query: { + limit: string; }; header?: never; path: { - /** @description Hackathon ID or slug */ + /** @description Blog post ID */ id: string; - organizationId: unknown; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Related posts retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['CustomQuestionResponseDto'][]; + content?: never; + }; + /** @description Blog post not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationHackathonsCustomQuestionsController_replace: { + BlogPostsController_updateBlogPost: { parameters: { query?: never; header?: never; path: { + /** @description Blog post ID */ id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpsertCustomQuestionsDto']; + 'application/json': components['schemas']['UpdateBlogPostDto']; }; }; responses: { + /** @description Blog post updated successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['CustomQuestionResponseDto'][]; + content?: never; + }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Blog post not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationHackathonsEscrowController_requestFundingOtp: { + BlogPostsController_deleteBlogPost: { parameters: { query?: never; header?: never; path: { - organizationId: string; - /** @description Hackathon id */ + /** @description Blog post ID */ id: string; }; cookie?: never; }; requestBody?: never; responses: { - 200: { + /** @description Blog post deleted successfully */ + 204: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['RequestFundingOtpResponseDto']; + content?: never; + }; + /** @description Forbidden */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Blog post not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationHackathonsEscrowController_verifyFundingOtp: { + AiController_generateExcerpt: { parameters: { query?: never; header?: never; - path: { - organizationId: string; - /** @description Hackathon id */ - id: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['VerifyFundingOtpDto']; + 'application/json': { + content: string; + }; }; }; responses: { + /** @description Excerpt generated successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['VerifyFundingOtpResponseDto']; - }; + content?: never; }; }; }; - OrganizationHackathonsEscrowController_publish: { + AiController_generateReadingTime: { parameters: { query?: never; header?: never; - path: { - organizationId: string; - /** @description Hackathon draft id */ - id: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['PublishHackathonEscrowDto']; + 'application/json': { + content: string; + }; }; }; responses: { - /** @description Escrow op created; unsigned XDR ready for wallet signing. Hackathon transitioned to DRAFT_AWAITING_FUNDING. */ + /** @description Reading time generated successfully */ 200: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; - }; - }; - /** @description Validation error or hackathon not in DRAFT status */ - 400: { headers: { [name: string]: unknown; }; @@ -27860,130 +32601,115 @@ export interface operations { }; }; }; - OrganizationHackathonsEscrowController_cancel: { + AiController_generateSEO: { parameters: { query?: never; header?: never; - path: { - organizationId: string; - /** @description Hackathon id */ - id: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CancelHackathonEscrowDto']; + 'application/json': { + content: string; + }; }; }; responses: { + /** @description SEO settings generated successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; - }; + content?: never; }; }; }; - OrganizationHackathonsEscrowController_selectWinners: { + AiController_generateTags: { parameters: { query?: never; header?: never; - path: { - organizationId: string; - /** @description Hackathon id */ - id: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['SelectHackathonWinnersDto']; + 'application/json': { + content: string; + }; }; }; responses: { + /** @description Tags generated successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; - }; + content?: never; }; }; }; - OrganizationHackathonsEscrowController_submitSigned: { + AiController_generateCategory: { parameters: { query?: never; header?: never; - path: { - organizationId: string; - /** @description Hackathon id */ - id: string; - /** @description EscrowOp uuid returned by the publish call */ - opRowId: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['HackathonSubmitSignedXdrDto']; + 'application/json': { + content: string; + }; }; }; responses: { - /** @description Signed XDR submitted; op is now PENDING_CONFIRM. */ + /** @description Category generated successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; - }; + content?: never; }; }; }; - OrganizationHackathonsEscrowController_getOp: { + AdminController_getOverview: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; - /** @description Hackathon id */ - id: string; - /** @description EscrowOp uuid */ - opRowId: string; + query?: { + /** @description Time range for the overview data */ + timeRange?: '7d' | '30d' | '90d'; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Overview data retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; + 'application/json': components['schemas']['AdminOverviewResponseDto']; }; }; - }; - }; - OrganizationHackathonsEscrowController_resetToDraft: { - parameters: { - query?: never; - header?: never; - path: { - organizationId: string; - /** @description Hackathon id */ - id: string; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Hackathon reset to DRAFT. */ - 200: { + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Internal server error */ + 500: { headers: { [name: string]: unknown; }; @@ -27991,188 +32717,205 @@ export interface operations { }; }; }; - HackathonParticipantEscrowController_submit: { + AdminController_getUsers: { parameters: { - query?: never; - header?: never; - path: { - /** @description Hackathon id */ - id: string; - /** @description HackathonSubmission uuid */ - submissionId: string; + query?: { + /** @description Page number */ + page?: number; + /** @description Items per page */ + limit?: number; + /** @description Search by name, email, or username */ + search?: string; + /** @description Filter by user role */ + role?: string; + /** @description Filter by active status (not banned) */ + isActive?: boolean; }; + header?: never; + path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['SubmitHackathonDto']; - }; - }; + requestBody?: never; responses: { + /** @description Users retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; + content?: never; + }; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - HackathonParticipantEscrowController_withdrawSubmission: { + AdminController_exportUsers: { parameters: { query?: never; header?: never; - path: { - /** @description Hackathon id */ - id: string; - /** @description HackathonSubmission uuid */ - submissionId: string; - }; + path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['WithdrawHackathonSubmissionDto']; - }; - }; + requestBody?: never; responses: { + /** @description CSV file download */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; + content?: never; + }; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - HackathonParticipantEscrowController_contribute: { + AdminController_getUserDetails: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon id */ - id: string; + /** @description User username or ID */ + usernameOrId: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['ContributeHackathonDto']; - }; - }; + requestBody?: never; responses: { + /** @description User details retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; + content?: never; + }; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - HackathonParticipantEscrowController_submitSigned: { + AdminController_getUserStats: { parameters: { query?: never; header?: never; path: { - /** @description Hackathon id */ - id: string; - /** @description EscrowOp uuid */ - opRowId: string; + /** @description User username or ID */ + usernameOrId: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['HackathonSubmitSignedXdrDto']; - }; - }; + requestBody?: never; responses: { + /** @description User statistics retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; + content?: never; + }; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - HackathonParticipantEscrowController_getOp: { + AdminController_getUserActivity: { parameters: { - query?: never; + query?: { + /** @description Page number */ + page?: number; + /** @description Items per page */ + limit?: number; + }; header?: never; path: { - /** @description Hackathon id */ - id: string; - /** @description EscrowOp uuid */ - opRowId: string; + /** @description User username or ID */ + usernameOrId: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description User activity retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['HackathonEscrowOpResponseDto']; - }; + content?: never; }; - }; - }; - OrganizationsController_getOrganizations: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Unauthorized - Authentication required */ + 401: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - OrganizationsController_createOrganization: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateOrganizationDto']; - }; - }; - responses: { - 201: { + /** @description Forbidden - Admin access required */ + 403: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - OrganizationsController_getMyOrganizations: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description User not found */ + 404: { headers: { [name: string]: unknown; }; @@ -28180,28 +32923,49 @@ export interface operations { }; }; }; - OrganizationsController_getOrganizationProfile: { + AdminController_getUserProjects: { parameters: { - query?: never; + query?: { + /** @description Page number */ + page?: number; + /** @description Items per page */ + limit?: number; + /** @description Filter by project status */ + status?: string; + /** @description Filter by project category */ + category?: string; + }; header?: never; path: { - /** @description Organization ID or slug */ - idOrSlug: string; + /** @description User username or ID */ + usernameOrId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Organization profile retrieved successfully */ + /** @description User projects retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['OrganizationProfileDto']; + content?: never; + }; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; }; + content?: never; }; - /** @description Organization not found */ + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ 404: { headers: { [name: string]: unknown; @@ -28210,16 +32974,15 @@ export interface operations { }; }; }; - OrganizationsController_searchOrganizations: { + AdminController_getOrganizations: { parameters: { query?: { - /** @description Search term (name, slug, tagline) */ - q?: string; - isProfileComplete?: 'true' | 'false'; - hasHackathons?: 'true' | 'false'; - hasGrants?: 'true' | 'false'; - /** @description Max results (default 10) */ + /** @description Page number */ + page?: number; + /** @description Items per page */ limit?: number; + /** @description Search by organization name or slug */ + search?: string; }; header?: never; path?: never; @@ -28227,147 +32990,61 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Paginated organizations */ + /** @description Organizations retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - OrganizationsController_getOrganization: { + AdminController_getOrganizationDetails: { parameters: { query?: never; header?: never; path: { /** @description Organization ID */ - id: string; + orgId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Organization retrieved successfully */ + /** @description Organization details retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': { - /** @example org_1234567890 */ - id?: string; - /** @example Tech Innovators */ - name?: string; - /** @example https://example.com/logo.png */ - logo?: string; - /** @example Building the future of technology */ - tagline?: string; - /** @example We are a community of developers... */ - about?: string; - links?: { - /** @example https://techinnovators.com */ - website?: string; - /** @example https://twitter.com/techinnovators */ - x?: string; - /** @example https://github.com/techinnovators */ - github?: string; - /** @example https://linkedin.com/company/techinnovators */ - others?: string; - }; - /** - * @example [ - * "user_123", - * "user_456" - * ] - */ - members?: string[]; - /** - * @example [ - * "user_123" - * ] - */ - admins?: string[]; - /** @example user_123 */ - owner?: string; - /** @example [] */ - hackathons?: string[]; - /** @example [] */ - grants?: string[]; - /** @example true */ - isProfileComplete?: boolean; - /** - * @example [ - * "invite_123" - * ] - */ - pendingInvites?: string[]; - /** @example better_auth_org_123 */ - betterAuthOrgId?: string; - /** @example false */ - isArchived?: boolean; - /** @example null */ - archivedBy?: string; - /** @example null */ - archivedAt?: string; - /** @example 2024-01-15T10:30:00.000Z */ - createdAt?: string; - /** @example 2024-01-15T10:30:00.000Z */ - updatedAt?: string; - analytics?: { - trends?: { - members?: { - /** @example 25 */ - current?: number; - /** @example 22 */ - previous?: number; - /** @example 3 */ - change?: number; - /** @example 13.64 */ - changePercentage?: number; - /** @example true */ - isPositive?: boolean; - }; - hackathons?: { - /** @example 5 */ - current?: number; - /** @example 4 */ - previous?: number; - /** @example 1 */ - change?: number; - /** @example 25 */ - changePercentage?: number; - /** @example true */ - isPositive?: boolean; - }; - grants?: { - /** @example 0 */ - current?: number; - /** @example 0 */ - previous?: number; - /** @example 0 */ - change?: number; - /** @example 0 */ - changePercentage?: number; - /** @example true */ - isPositive?: boolean; - }; - }; - timeSeries?: { - hackathons?: { - /** @example January */ - month?: string; - /** @example 2024 */ - year?: number; - /** @example 2 */ - count?: number; - /** @example 2024-01-01T00:00:00.000Z */ - timestamp?: string; - }[]; - }; - }; - }; + content?: never; + }; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; }; + content?: never; }; /** @description Organization not found */ 404: { @@ -28378,41 +33055,41 @@ export interface operations { }; }; }; - OrganizationsController_updateOrganization: { + AdminController_getUserOrganizations: { parameters: { query?: never; header?: never; path: { - id: string; + /** @description User username or ID */ + usernameOrId: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateOrganizationDto']; - }; - }; + requestBody?: never; responses: { + /** @description User organizations retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - OrganizationsController_deleteOrganization: { - parameters: { - query?: never; - header?: never; - path: { - id: string; + /** @description Unauthorized - Authentication required */ + 401: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description User not found */ + 404: { headers: { [name: string]: unknown; }; @@ -28420,17 +33097,44 @@ export interface operations { }; }; }; - OrganizationsController_getOrganizationMembers: { + AdminBlogsController_listAllBlogPosts: { parameters: { - query?: never; - header?: never; - path: { - id: string; + query?: { + /** @description Author ID to filter posts */ + authorId?: string; + /** @description Post status to filter */ + status?: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED' | 'SCHEDULED'; + /** @description Search query for post title/content */ + search?: string; + /** @description Filter by tags (comma-separated) */ + tags?: string; + /** @description Filter by categories (comma-separated) */ + categories?: string; + /** @description Include only featured posts */ + isFeatured?: boolean; + /** @description Include pinned posts first */ + includePinned?: boolean; + /** @description Page number */ + page?: number; + /** @description Number of items per page */ + limit?: number; + /** @description Sort field */ + sortBy?: + | 'createdAt' + | 'updatedAt' + | 'publishedAt' + | 'viewCount' + | 'title'; + /** @description Sort order */ + sortOrder?: 'asc' | 'desc'; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Blog posts retrieved successfully */ 200: { headers: { [name: string]: unknown; @@ -28439,37 +33143,42 @@ export interface operations { }; }; }; - OrganizationsController_getOrganizationPermissions: { + AdminBlogsController_createBlogPost: { parameters: { query?: never; header?: never; - path: { - id: string; - }; + path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateBlogPostDto']; + }; + }; responses: { - 200: { + /** @description Blog post created successfully */ + 201: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - OrganizationsController_updateOrganizationPermissions: { - parameters: { - query?: never; - header?: never; - path: { - id: string; + /** @description Invalid input */ + 400: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Rate limit exceeded */ + 429: { headers: { [name: string]: unknown; }; @@ -28477,56 +33186,66 @@ export interface operations { }; }; }; - OrganizationsController_resetOrganizationPermissions: { + AdminBlogsController_getBlogPostById: { parameters: { query?: never; header?: never; path: { + /** @description Blog post ID */ id: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Blog post retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Blog post not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - OrganizationsController_getOrganizationStats: { + AdminBlogsController_updateBlogPost: { parameters: { query?: never; header?: never; path: { + /** @description Blog post ID */ id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateBlogPostDto']; + }; + }; responses: { + /** @description Blog post updated successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - MembersController_getMembers: { - parameters: { - query?: never; - header?: never; - path: { - organizationId: string; + /** @description Forbidden - Admin access required */ + 403: { + headers: { + [name: string]: unknown; + }; + content?: never; }; - cookie?: never; - }; - requestBody?: never; - responses: { - 200: { + /** @description Blog post not found */ + 404: { headers: { [name: string]: unknown; }; @@ -28534,19 +33253,27 @@ export interface operations { }; }; }; - MembersController_addMember: { + AdminBlogsController_deleteBlogPost: { parameters: { query?: never; header?: never; path: { - organizationId: string; - userId: string; + /** @description Blog post ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { - 200: { + /** @description Blog post deleted successfully */ + 204: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Blog post not found */ + 404: { headers: { [name: string]: unknown; }; @@ -28554,43 +33281,27 @@ export interface operations { }; }; }; - MembersController_removeMember: { + AdminBlogsController_permanentlyDeleteBlogPost: { parameters: { query?: never; header?: never; path: { - organizationId: string; - userId: string; + /** @description Blog post ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { - 200: { + /** @description Blog post permanently deleted successfully */ + 204: { headers: { [name: string]: unknown; }; content?: never; }; - }; - }; - MembersController_updateMemberRole: { - parameters: { - query?: never; - header?: never; - path: { - organizationId: string; - userId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateMemberRoleDto']; - }; - }; - responses: { - 200: { + /** @description Blog post not found */ + 404: { headers: { [name: string]: unknown; }; @@ -28598,36 +33309,46 @@ export interface operations { }; }; }; - MembersController_getMyMembership: { + AdminBlogsController_restoreBlogPost: { parameters: { query?: never; header?: never; path: { - organizationId: string; + /** @description Blog post ID */ + id: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Blog post restored successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description Blog post not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - InvitationsController_getInvitations: { + AdminBlogsController_getAllTags: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; + query: { + limit: string; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Tags retrieved successfully */ 200: { headers: { [name: string]: unknown; @@ -28636,22 +33357,27 @@ export interface operations { }; }; }; - InvitationsController_inviteMember: { + AdminBlogsController_getTagBySlug: { parameters: { query?: never; header?: never; path: { - organizationId: string; + /** @description Tag slug */ + slug: string; }; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['InviteMemberDto']; - }; - }; + requestBody?: never; responses: { - 201: { + /** @description Tag retrieved successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Tag not found */ + 404: { headers: { [name: string]: unknown; }; @@ -28659,17 +33385,16 @@ export interface operations { }; }; }; - InvitationsController_acceptInvitation: { + AdminBlogsController_deleteUnusedTags: { parameters: { query?: never; header?: never; - path: { - invitationId: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Unused tags deleted successfully */ 200: { headers: { [name: string]: unknown; @@ -28678,17 +33403,16 @@ export interface operations { }; }; }; - InvitationsController_rejectInvitation: { + AdminBlogsController_publishScheduledPosts: { parameters: { query?: never; header?: never; - path: { - invitationId: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description Scheduled posts published successfully */ 200: { headers: { [name: string]: unknown; @@ -28697,18 +33421,19 @@ export interface operations { }; }; }; - InvitationsController_cancelInvitation: { + AdminCrowdfundingController_list: { parameters: { - query?: never; - header?: never; - path: { - invitationId: string; - organizationId: string; + query?: { + limit?: unknown; + page?: unknown; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description List of campaigns */ 200: { headers: { [name: string]: unknown; @@ -28717,542 +33442,702 @@ export interface operations { }; }; }; - InvitationsController_getMyInvitations: { + AdminCrowdfundingController_listByUser: { parameters: { - query?: never; + query?: { + limit?: unknown; + page?: unknown; + }; header?: never; - path?: never; + path: { + /** @description Username or User ID */ + usernameOrId: string; + }; cookie?: never; }; requestBody?: never; responses: { + /** @description List of campaigns by user */ 200: { headers: { [name: string]: unknown; }; content?: never; }; + /** @description User not found */ + 404: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; }; }; - OrganizationTreasuryController_listWallets: { + AdminCrowdfundingController_getCampaign: { parameters: { query?: never; header?: never; path: { - organizationId: string; + /** @description Campaign ID */ + campaignId: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Campaign details */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto'][]; + content?: never; + }; + /** @description Campaign not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_listArchivedWallets: { + AdminCrowdfundingController_listPending: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; + query?: { + limit?: unknown; + page?: unknown; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description List of pending campaigns */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto'][]; - }; + content?: never; }; }; }; - OrganizationTreasuryController_getDefaultWallet: { + AdminCrowdfundingController_approve: { parameters: { query?: never; header?: never; path: { - organizationId: string; + campaignId: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Campaign approved */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto']; - }; + content?: never; }; }; }; - OrganizationTreasuryController_createManagedWallet: { + AdminCrowdfundingController_reject: { parameters: { query?: never; header?: never; path: { - organizationId: string; + campaignId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CreateManagedWalletDto']; + 'application/json': components['schemas']['AdminCrowdfundingRejectDto']; }; }; responses: { - 201: { + /** @description Campaign rejected */ + 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto']; - }; + content?: never; }; }; }; - OrganizationTreasuryController_registerConnectedWallet: { + AdminCrowdfundingController_requestRevision: { parameters: { query?: never; header?: never; path: { - organizationId: string; + campaignId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['RegisterConnectedWalletDto']; + 'application/json': components['schemas']['AdminCrowdfundingRequestRevisionDto']; }; }; responses: { - 201: { + /** @description Revision request created */ + 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto']; + content?: never; + }; + /** @description Campaign not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_refreshSigners: { + AdminCrowdfundingController_addReviewNote: { parameters: { query?: never; header?: never; path: { - organizationId: string; - walletId: string; + campaignId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['AdminCrowdfundingNoteDto']; + }; + }; responses: { + /** @description Review note added */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto']; + content?: never; + }; + /** @description Campaign not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_updateWallet: { + AdminCrowdfundingController_assignReviewer: { parameters: { query?: never; header?: never; path: { - organizationId: string; - walletId: string; + campaignId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdateTreasuryWalletDto']; + 'application/json': components['schemas']['AdminCrowdfundingAssignDto']; }; }; responses: { + /** @description Reviewer assigned */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto']; + content?: never; + }; + /** @description Campaign not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_archiveWallet: { + AdminMilestonesController_listAllMilestonesByCampaign: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; - walletId: string; + query?: { + /** @description Page number */ + page?: number; + /** @description Items per page */ + limit?: number; + /** @description Filter by review status */ + status?: + | 'PENDING' + | 'SUBMITTED' + | 'UNDER_REVIEW' + | 'APPROVED' + | 'REJECTED' + | 'RESUBMISSION_REQUIRED'; + /** @description Sort by field */ + sortBy?: + | 'submittedAt' + | 'campaignSize' + | 'creatorReputation' + | 'createdAt'; + /** @description Filter by campaign ID */ + campaignId?: string; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description List of campaigns with their milestones */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto']; - }; + content?: never; }; }; }; - OrganizationTreasuryController_restoreWallet: { + AdminMilestonesController_listPendingMilestones: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; - walletId: string; + query?: { + /** @description Page number */ + page?: number; + /** @description Items per page */ + limit?: number; + /** @description Filter by review status */ + status?: + | 'PENDING' + | 'SUBMITTED' + | 'UNDER_REVIEW' + | 'APPROVED' + | 'REJECTED' + | 'RESUBMISSION_REQUIRED'; + /** @description Sort by field */ + sortBy?: + | 'submittedAt' + | 'campaignSize' + | 'creatorReputation' + | 'createdAt'; + /** @description Filter by campaign ID */ + campaignId?: string; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { + /** @description List of pending milestones */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryWalletResponseDto']; - }; + content?: never; }; }; }; - OrganizationTreasuryController_walletBalance: { + AdminMilestonesController_getMilestoneForReview: { parameters: { query?: never; header?: never; path: { - organizationId: string; - walletId: string; + milestoneId: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Milestone details */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['WalletBalanceResponseDto']; + content?: never; + }; + /** @description Milestone not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_getPolicy: { + AdminMilestonesController_approveMilestone: { parameters: { query?: never; header?: never; path: { - organizationId: string; + milestoneId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ApproveMilestoneDto']; + }; + }; responses: { + /** @description Milestone approved */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryPolicyResponseDto']; + content?: never; + }; + /** @description Milestone not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_updatePolicy: { + AdminMilestonesController_rejectMilestone: { parameters: { query?: never; header?: never; path: { - organizationId: string; + milestoneId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdateTreasuryPolicyDto']; + 'application/json': components['schemas']['RejectMilestoneDto']; }; }; responses: { + /** @description Milestone rejected */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryPolicyResponseDto']; + content?: never; + }; + /** @description Milestone not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_listSpend: { + AdminMilestonesController_requestResubmission: { parameters: { - query?: { - status?: string; - }; + query?: never; header?: never; path: { - organizationId: string; + milestoneId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['RequestMilestoneResubmissionDto']; + }; + }; responses: { + /** @description Resubmission requested */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto'][]; + content?: never; + }; + /** @description Milestone not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_initiateSpend: { + AdminMilestonesController_addReviewNote: { parameters: { query?: never; header?: never; path: { - organizationId: string; + milestoneId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['InitiateSpendDto']; + 'application/json': components['schemas']['AddMilestoneReviewNoteDto']; }; }; responses: { + /** @description Review note added */ 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto']; + content?: never; + }; + /** @description Milestone not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_requestSendOtp: { + AdminEscrowController_getEscrowInfo: { parameters: { query?: never; header?: never; path: { - organizationId: string; + campaignId: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Escrow information */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['RequestFundingOtpResponseDto']; + content?: never; + }; + /** @description Campaign not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_verifySendOtp: { + AdminEscrowController_executeEscrowAction: { parameters: { query?: never; header?: never; path: { - organizationId: string; + campaignId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['VerifyFundingOtpDto']; + 'application/json': components['schemas']['ManualEscrowActionDto']; }; }; responses: { + /** @description Escrow action executed */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['VerifyFundingOtpResponseDto']; + content?: never; + }; + /** @description Campaign not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_sendFunds: { + AdminDisputesController_listDisputes: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; + query?: { + /** @description Page number */ + page?: number; + /** @description Items per page */ + limit?: number; + /** @description Filter by dispute status */ + status?: + | 'OPEN' + | 'UNDER_REVIEW' + | 'AWAITING_RESPONSE' + | 'RESOLVED' + | 'ESCALATED' + | 'CLOSED'; + /** @description Filter by campaign ID */ + campaignId?: string; }; + header?: never; + path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['SendTreasuryFundsDto']; - }; - }; + requestBody?: never; responses: { + /** @description List of disputes */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto']; - }; + content?: never; }; }; }; - OrganizationTreasuryController_checkSendDestination: { + AdminDisputesController_getDisputeDetail: { parameters: { - query: { - address: string; - }; + query?: never; header?: never; path: { - organizationId: string; + disputeId: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Dispute details */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SendDestinationReadinessDto']; + content?: never; + }; + /** @description Dispute not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_getSpend: { + AdminDisputesController_assignDispute: { parameters: { query?: never; header?: never; path: { - organizationId: string; - requestId: string; + disputeId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['AssignDisputeDto']; + }; + }; responses: { + /** @description Dispute assigned */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto']; + content?: never; + }; + /** @description Dispute not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_approveSpend: { + AdminDisputesController_addDisputeNote: { parameters: { query?: never; header?: never; path: { - organizationId: string; - requestId: string; + disputeId: string; }; cookie?: never; }; - requestBody?: { + requestBody: { content: { - 'application/json': components['schemas']['SpendDecisionDto']; + 'application/json': components['schemas']['AddDisputeNoteDto']; }; }; responses: { - 200: { + /** @description Note added */ + 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto']; + content?: never; + }; + /** @description Dispute not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_rejectSpend: { + AdminDisputesController_resolveDispute: { parameters: { query?: never; header?: never; path: { - organizationId: string; - requestId: string; + disputeId: string; }; cookie?: never; }; - requestBody?: { + requestBody: { content: { - 'application/json': components['schemas']['SpendDecisionDto']; + 'application/json': components['schemas']['ResolveDisputeDto']; }; }; responses: { + /** @description Dispute resolved */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto']; + content?: never; + }; + /** @description Dispute not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_cancelSpend: { + AdminDisputesController_escalateDispute: { parameters: { query?: never; header?: never; path: { - organizationId: string; - requestId: string; + disputeId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['EscalateDisputeDto']; + }; + }; responses: { + /** @description Dispute escalated */ 200: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto']; + content?: never; + }; + /** @description Dispute not found */ + 404: { + headers: { + [name: string]: unknown; }; + content?: never; }; }; }; - OrganizationTreasuryController_executeSpend: { + AdminManualProjectsController_listPendingManualProjects: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; - requestId: string; + query?: { + page?: number; + limit?: number; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; @@ -29261,97 +34146,86 @@ export interface operations { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto']; - }; + content?: never; }; }; }; - OrganizationTreasuryController_buildSpendXdr: { + AdminManualProjectsController_approveManualProject: { parameters: { query?: never; header?: never; path: { - organizationId: string; - requestId: string; + /** @description Project ID */ + projectId: string; }; cookie?: never; }; requestBody?: never; responses: { - 200: { + 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['BuildSpendXdrResponseDto']; - }; + content?: never; }; }; }; - OrganizationTreasuryController_submitSpendSignedXdr: { + AdminManualProjectsController_rejectManualProject: { parameters: { query?: never; header?: never; path: { - organizationId: string; - requestId: string; + /** @description Project ID */ + projectId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['SubmitSpendSignedXdrDto']; + 'application/json': components['schemas']['RejectManualProjectDto']; }; }; responses: { - 200: { + 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['SpendRequestResponseDto']; - }; + content?: never; }; }; }; - OrganizationTreasuryController_auditLog: { + AdminManualProjectsController_requestChanges: { parameters: { - query?: { - page?: string; - limit?: string; - }; + query?: never; header?: never; path: { - organizationId: string; + /** @description Project ID */ + projectId: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['RequestManualProjectChangesDto']; + }; + }; responses: { - 200: { + 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['TreasuryAuditLogResponseDto']; - }; + content?: never; }; }; }; - OrganizationReceiptsController_list: { + AdminProjectEditsController_listPendingProjectEdits: { parameters: { query?: { - page?: string; - limit?: string; - type?: string; - referenceType?: string; - referenceId?: string; + page?: number; + limit?: number; }; header?: never; - path: { - organizationId: string; - }; + path?: never; cookie?: never; }; requestBody?: never; @@ -29360,51 +34234,47 @@ export interface operations { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['ReceiptListResponseDto']; - }; + content?: never; }; }; }; - OrganizationReceiptsController_getOne: { + AdminProjectEditsController_approveProjectEdit: { parameters: { query?: never; header?: never; path: { - organizationId: string; - receiptId: string; + /** @description ProjectEdit ID */ + editId: string; }; cookie?: never; }; requestBody?: never; responses: { - 200: { + 201: { headers: { [name: string]: unknown; }; - content: { - 'application/json': components['schemas']['ReceiptResponseDto']; - }; + content?: never; }; }; }; - OrganizationReceiptsController_send: { + AdminProjectEditsController_rejectProjectEdit: { parameters: { query?: never; header?: never; path: { - organizationId: string; - receiptId: string; + /** @description ProjectEdit ID */ + editId: string; }; cookie?: never; }; - requestBody?: { + requestBody: { content: { - 'application/json': components['schemas']['SendReceiptDto']; + 'application/json': components['schemas']['RejectProjectEditDto']; }; }; responses: { - 200: { + 201: { headers: { [name: string]: unknown; }; @@ -29412,47 +34282,33 @@ export interface operations { }; }; }; - OrganizationReceiptsController_void: { + AdminWalletsController_getStats: { parameters: { - query?: never; - header?: never; - path: { - organizationId: string; - receiptId: string; + query?: { + timeRange?: '7d' | '30d' | '90d'; }; + header?: never; + path?: never; cookie?: never; }; - requestBody?: { - content: { - 'application/json': components['schemas']['VoidReceiptDto']; - }; - }; + requestBody?: never; responses: { - 200: { + default: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['ReceiptResponseDto']; + 'application/json': components['schemas']['AdminWalletStatsDto']; }; }; }; }; - VotesController_getVotes: { + AdminWalletsController_listWallets: { parameters: { - query: { - /** @description Project ID */ - projectId?: string; - /** @description Entity Type */ - entityType?: string; - /** @description Vote Type */ - voteType: string; - /** @description User ID */ - userId: string; - /** @description Limit */ - limit: number; - /** @description Offset */ - offset: number; + query?: { + search?: string; + limit?: number; + page?: number; }; header?: never; path?: never; @@ -29460,67 +34316,70 @@ export interface operations { }; requestBody?: never; responses: { - 200: { + default: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['AdminWalletListResponseDto']; + }; }; }; }; - VotesController_createVote: { + AdminWalletsController_getByUserId: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateVoteDto']; + path: { + userId: string; }; + cookie?: never; }; + requestBody?: never; responses: { - 201: { + default: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['AdminWalletListItemDto'][]; + }; }; }; }; - VotesController_removeVote: { + AdminWalletsController_getDetails: { parameters: { query?: never; header?: never; path: { - projectId: string; - entityType: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - 200: { + default: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['AdminWalletDetailsDto']; + }; }; }; }; - VotesController_getVoteCounts: { + AdminWalletsController_activateWallet: { parameters: { query?: never; header?: never; path: { - projectId: string; - entityType: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { + /** @description Wallet activated successfully */ 200: { headers: { [name: string]: unknown; @@ -29529,19 +34388,19 @@ export interface operations { }; }; }; - VotesController_getUserVote: { + AdminWalletsController_sponsorActivateUser: { parameters: { query?: never; header?: never; path: { - projectId: string; - entityType: string; + userId: string; }; cookie?: never; }; requestBody?: never; responses: { - 200: { + /** @description Returns activation result for the user (activated, alreadyActivated, addedTrustlines, hash). */ + 201: { headers: { [name: string]: unknown; }; @@ -29549,29 +34408,19 @@ export interface operations { }; }; }; - VotesController_getProjectVotes: { + AdminWalletsController_sponsorActivateHackathon: { parameters: { - query?: { - entityType?: - | 'PROJECT' - | 'CROWDFUNDING_CAMPAIGN' - | 'HACKATHON_SUBMISSION' - | 'GRANT'; - voteType?: 'UPVOTE' | 'DOWNVOTE'; - limit?: number; - offset?: number; - /** @description Include voter list and vote counts in response */ - includeVoters?: boolean; - }; + query?: never; header?: never; path: { - projectId: string; + hackathonId: string; }; cookie?: never; }; requestBody?: never; responses: { - 200: { + /** @description Job enqueued. Returns { jobId, hackathonId, estimatedParticipants, statusUrl }. */ + 201: { headers: { [name: string]: unknown; }; @@ -29579,25 +34428,17 @@ export interface operations { }; }; }; - LeaderboardController_getLeaderboard: { + AdminWalletsController_getSponsorActivationJobStatus: { parameters: { - query?: { - /** @description Filter by reputation tier */ - tier?: 'NEWCOMER' | 'CONTRIBUTOR' | 'ESTABLISHED' | 'EXPERT' | 'LEGEND'; - /** @description Time window for score aggregation */ - timeframe?: 'ALL_TIME' | 'THIS_MONTH' | 'THIS_WEEK' | 'THIS_DAY'; - /** @description Items per page, max 50 (default: 20) */ - limit?: number; - /** @description Page number (default: 1) */ - page?: number; - }; + query?: never; header?: never; - path?: never; + path: { + jobId: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description Leaderboard retrieved successfully */ 200: { headers: { [name: string]: unknown; @@ -29606,44 +34447,15 @@ export interface operations { }; }; }; - BlogPostsController_listBlogPosts: { + HealthController_liveness: { parameters: { - query?: { - /** @description Author ID to filter posts */ - authorId?: string; - /** @description Post status to filter */ - status?: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED' | 'SCHEDULED'; - /** @description Search query for post title/content */ - search?: string; - /** @description Filter by tags (comma-separated) */ - tags?: string; - /** @description Filter by categories (comma-separated) */ - categories?: string; - /** @description Include only featured posts */ - isFeatured?: boolean; - /** @description Include pinned posts first */ - includePinned?: boolean; - /** @description Page number */ - page?: number; - /** @description Number of items per page */ - limit?: number; - /** @description Sort field */ - sortBy?: - | 'createdAt' - | 'updatedAt' - | 'publishedAt' - | 'viewCount' - | 'title'; - /** @description Sort order */ - sortOrder?: 'asc' | 'desc'; - }; + query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Blog posts retrieved successfully */ 200: { headers: { [name: string]: unknown; @@ -29652,142 +34464,187 @@ export interface operations { }; }; }; - BlogPostsController_createBlogPost: { + HealthController_readiness: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateBlogPostDto']; - }; - }; + requestBody?: never; responses: { - /** @description Blog post created successfully */ - 201: { + /** @description The Health Check is successful */ + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Invalid input */ - 400: { - headers: { - [name: string]: unknown; + content: { + 'application/json': { + /** @example ok */ + status?: string; + /** + * @example { + * "database": { + * "status": "up" + * } + * } + */ + info?: { + [key: string]: { + status: string; + } & { + [key: string]: unknown; + }; + } | null; + /** @example {} */ + error?: { + [key: string]: { + status: string; + } & { + [key: string]: unknown; + }; + } | null; + /** + * @example { + * "database": { + * "status": "up" + * } + * } + */ + details?: { + [key: string]: { + status: string; + } & { + [key: string]: unknown; + }; + }; + }; }; - content?: never; }; - /** @description Forbidden */ - 403: { + /** @description The Health Check is not successful */ + 503: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Rate limit exceeded */ - 429: { - headers: { - [name: string]: unknown; + content: { + 'application/json': { + /** @example error */ + status?: string; + /** + * @example { + * "database": { + * "status": "up" + * } + * } + */ + info?: { + [key: string]: { + status: string; + } & { + [key: string]: unknown; + }; + } | null; + /** + * @example { + * "redis": { + * "status": "down", + * "message": "Could not connect" + * } + * } + */ + error?: { + [key: string]: { + status: string; + } & { + [key: string]: unknown; + }; + } | null; + /** + * @example { + * "database": { + * "status": "up" + * }, + * "redis": { + * "status": "down", + * "message": "Could not connect" + * } + * } + */ + details?: { + [key: string]: { + status: string; + } & { + [key: string]: unknown; + }; + }; + }; }; - content?: never; }; }; }; - BlogPostsController_getBlogPostById: { + DiditController_getStatus: { parameters: { query?: never; header?: never; - path: { - /** @description Blog post ID */ - id: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Blog post retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Post is not published */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Blog post not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['VerificationStatusDto']; }; - content?: never; }; }; }; - BlogPostsController_getBlogPostBySlug: { + DiditController_callback: { parameters: { query?: never; header?: never; - path: { - /** @description Blog post slug */ - slug: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Blog post retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Post is not published */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Blog post not found */ - 404: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; }; }; - BlogPostsController_getRelatedPosts: { + DiditController_createSession: { parameters: { - query: { - limit: string; - }; + query?: never; header?: never; - path: { - /** @description Blog post ID */ - id: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Related posts retrieved successfully */ + /** @description Session created */ 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': unknown; + }; + }; + /** @description Missing DIDIT_API_KEY or DIDIT_WORKFLOW_ID */ + 400: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Blog post not found */ - 404: { + /** @description Unauthorized */ + 401: { headers: { [name: string]: unknown; }; @@ -29795,38 +34652,24 @@ export interface operations { }; }; }; - BlogPostsController_updateBlogPost: { + DiditController_webhook: { parameters: { query?: never; header?: never; - path: { - /** @description Blog post ID */ - id: string; - }; + path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['UpdateBlogPostDto']; - }; - }; + requestBody?: never; responses: { - /** @description Blog post updated successfully */ + /** @description Webhook accepted */ 200: { headers: { [name: string]: unknown; }; content?: never; }; - /** @description Forbidden */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Blog post not found */ - 404: { + /** @description Invalid or missing signature */ + 400: { headers: { [name: string]: unknown; }; @@ -29834,57 +34677,43 @@ export interface operations { }; }; }; - BlogPostsController_deleteBlogPost: { + PricingController_preview: { parameters: { - query?: never; - header?: never; - path: { - /** @description Blog post ID */ - id: string; + query: { + pillar: 'Hackathon' | 'Bounty' | 'Grant' | 'Crowdfunding'; + organizationId: string; + /** @description Budget in stroops (7-decimal). String to preserve precision. */ + budgetStroops: string; + /** @description Override fee bps from a sales authority. 0 = waiver. */ + salesOverrideBps?: number; + /** @description Free-text reason for the audit log. */ + salesOverrideReason?: string; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Blog post deleted successfully */ - 204: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden */ - 403: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Blog post not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['PricingPreviewResponseDto']; }; - content?: never; }; }; }; - AiController_generateExcerpt: { + AdminOpsController_pause: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': { - content: string; - }; - }; + path?: never; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Excerpt generated successfully */ 200: { headers: { [name: string]: unknown; @@ -29893,22 +34722,15 @@ export interface operations { }; }; }; - AiController_generateReadingTime: { + AdminOpsController_unpause: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': { - content: string; - }; - }; - }; + requestBody?: never; responses: { - /** @description Reading time generated successfully */ 200: { headers: { [name: string]: unknown; @@ -29917,22 +34739,15 @@ export interface operations { }; }; }; - AiController_generateSEO: { + AdminOpsController_setFeeBps: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': { - content: string; - }; - }; - }; + requestBody?: never; responses: { - /** @description SEO settings generated successfully */ 200: { headers: { [name: string]: unknown; @@ -29941,46 +34756,34 @@ export interface operations { }; }; }; - AiController_generateTags: { + AccessController_me: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': { - content: string; - }; - }; - }; + requestBody?: never; responses: { - /** @description Tags generated successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['MeResponseDto']; + }; }; }; }; - AiController_generateCategory: { + AccessController_roles: { parameters: { query?: never; header?: never; path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': { - content: string; - }; - }; - }; + requestBody?: never; responses: { - /** @description Category generated successfully */ 200: { headers: { [name: string]: unknown; @@ -29989,63 +34792,54 @@ export interface operations { }; }; }; - AdminController_getOverview: { + AnalyticsController_get: { parameters: { - query?: { - /** @description Time range for the overview data */ - timeRange?: '7d' | '30d' | '90d'; - }; + query?: never; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Overview data retrieved successfully */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['AdminOverviewResponseDto']; - }; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['AnalyticsDto']; }; - content?: never; }; - /** @description Forbidden - Admin access required */ - 403: { + }; + }; + OverviewController_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['OverviewDto']; }; - content?: never; }; }; }; - AdminController_getUsers: { + UsersController_list: { parameters: { query?: { - /** @description Page number */ + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; page?: number; - /** @description Items per page */ limit?: number; - /** @description Search by name, email, or username */ + /** @description Match against name, email, or username */ search?: string; - /** @description Filter by user role */ - role?: string; - /** @description Filter by active status (not banned) */ - isActive?: boolean; }; header?: never; path?: never; @@ -30053,251 +34847,134 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Users retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['PaginatedUsersDto']; }; - content?: never; }; }; }; - AdminController_exportUsers: { + UsersController_getById: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody?: never; responses: { - /** @description CSV file download */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AdminUserDetailDto']; }; - content?: never; }; }; }; - AdminController_getUserDetails: { + UsersController_getEarnings: { parameters: { query?: never; header?: never; path: { - /** @description User username or ID */ - usernameOrId: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description User details retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description User not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['EarningsResponseDto']; }; - content?: never; }; }; }; - AdminController_getUserStats: { + UsersController_getOrganizations: { parameters: { query?: never; header?: never; path: { - /** @description User username or ID */ - usernameOrId: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description User statistics retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description User not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AdminUserOrganizationDto'][]; }; - content?: never; }; }; }; - AdminController_getUserActivity: { + UsersController_getWallet: { parameters: { - query?: { - /** @description Page number */ - page?: number; - /** @description Items per page */ - limit?: number; - }; + query?: never; header?: never; path: { - /** @description User username or ID */ - usernameOrId: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description User activity retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description User not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AdminUserWalletDto']; }; - content?: never; }; }; }; - AdminController_getUserProjects: { + UsersController_setBanned: { parameters: { - query?: { - /** @description Page number */ - page?: number; - /** @description Items per page */ - limit?: number; - /** @description Filter by project status */ - status?: string; - /** @description Filter by project category */ - category?: string; - }; + query?: never; header?: never; path: { - /** @description User username or ID */ - usernameOrId: string; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['BanUserDto']; + }; + }; responses: { - /** @description User projects retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description User not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['BanUserResponseDto']; }; - content?: never; }; }; }; - AdminController_getOrganizations: { + OrganizationsController_list: { parameters: { query?: { - /** @description Page number */ + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; page?: number; - /** @description Items per page */ limit?: number; - /** @description Search by organization name or slug */ + /** @description Match against name or slug */ search?: string; }; header?: never; @@ -30306,143 +34983,124 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Organizations retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['PaginatedOrganizationsDto']; }; - content?: never; }; }; }; - AdminController_getOrganizationDetails: { + OrganizationsController_getById: { parameters: { query?: never; header?: never; path: { - /** @description Organization ID */ - orgId: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Organization details retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AdminOrgDetailDto']; }; - content?: never; }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationsController_update: { + parameters: { + query?: never; + header?: never; + path: { + id: string; }; - /** @description Organization not found */ - 404: { + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['UpdateOrgDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['OrgActionResponseDto']; + }; }; }; }; - AdminController_getUserOrganizations: { + OrganizationsController_suspend: { parameters: { query?: never; header?: never; path: { - /** @description User username or ID */ - usernameOrId: string; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['SuspendOrgDto']; + }; + }; responses: { - /** @description User organizations retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Unauthorized - Authentication required */ - 401: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['OrgSuspensionResponseDto']; }; - content?: never; }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; - }; - content?: never; + }; + }; + OrganizationsController_reinstate: { + parameters: { + query?: never; + header?: never; + path: { + id: string; }; - /** @description User not found */ - 404: { + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ReinstateOrgDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['OrgSuspensionResponseDto']; + }; }; }; }; - AdminBlogsController_listAllBlogPosts: { + ProgramsController_list: { parameters: { query?: { - /** @description Author ID to filter posts */ - authorId?: string; - /** @description Post status to filter */ - status?: 'DRAFT' | 'PUBLISHED' | 'ARCHIVED' | 'SCHEDULED'; - /** @description Search query for post title/content */ - search?: string; - /** @description Filter by tags (comma-separated) */ - tags?: string; - /** @description Filter by categories (comma-separated) */ - categories?: string; - /** @description Include only featured posts */ - isFeatured?: boolean; - /** @description Include pinned posts first */ - includePinned?: boolean; - /** @description Page number */ + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; + /** @description Which pillar to list. Defaults to hackathons. */ + type?: 'hackathon' | 'bounty' | 'grant' | 'crowdfunding'; page?: number; - /** @description Number of items per page */ limit?: number; - /** @description Sort field */ - sortBy?: - | 'createdAt' - | 'updatedAt' - | 'publishedAt' - | 'viewCount' - | 'title'; - /** @description Sort order */ - sortOrder?: 'asc' | 'desc'; + /** @description Match against the program title */ + search?: string; }; header?: never; path?: never; @@ -30450,378 +35108,370 @@ export interface operations { }; requestBody?: never; responses: { - /** @description Blog posts retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedProgramsDto']; + }; }; }; }; - AdminBlogsController_createBlogPost: { + ProgramsController_getById: { parameters: { - query?: never; + query: { + /** @description Which pillar the id belongs to */ + type: 'hackathon' | 'bounty' | 'grant' | 'crowdfunding'; + }; header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - 'application/json': components['schemas']['CreateBlogPostDto']; + path: { + id: string; }; + cookie?: never; }; + requestBody?: never; responses: { - /** @description Blog post created successfully */ - 201: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Invalid input */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Rate limit exceeded */ - 429: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AdminProgramDetailDto']; }; - content?: never; }; }; }; - AdminBlogsController_getBlogPostById: { + ProgramsController_setFeatured: { parameters: { query?: never; header?: never; path: { - /** @description Blog post ID */ id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['SetFeaturedDto']; + }; + }; responses: { - /** @description Blog post retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Blog post not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['ProgramActionResponseDto']; }; - content?: never; }; }; }; - AdminBlogsController_updateBlogPost: { + ProgramsController_setStatus: { parameters: { query?: never; header?: never; path: { - /** @description Blog post ID */ id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['UpdateBlogPostDto']; + 'application/json': components['schemas']['SetProgramStatusDto']; }; }; responses: { - /** @description Blog post updated successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Forbidden - Admin access required */ - 403: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['ProgramActionResponseDto']; }; - content?: never; }; - /** @description Blog post not found */ - 404: { + }; + }; + DisputesController_list: { + parameters: { + query?: { + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; + page?: number; + limit?: number; + /** @description Match against the dispute description or campaign title */ + search?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedDisputesDto']; + }; }; }; }; - AdminBlogsController_deleteBlogPost: { + DisputesController_getById: { parameters: { query?: never; header?: never; path: { - /** @description Blog post ID */ id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Blog post deleted successfully */ - 204: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Blog post not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AdminDisputeDetailDto']; }; - content?: never; }; }; }; - AdminBlogsController_permanentlyDeleteBlogPost: { + DisputesController_assign: { parameters: { query?: never; header?: never; path: { - /** @description Blog post ID */ id: string; }; cookie?: never; }; - requestBody?: never; - responses: { - /** @description Blog post permanently deleted successfully */ - 204: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Blog post not found */ - 404: { + requestBody: { + content: { + 'application/json': components['schemas']['AssignDisputeDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['DisputeAssignmentResponseDto']; + }; }; }; }; - AdminBlogsController_restoreBlogPost: { + DisputesController_note: { parameters: { query?: never; header?: never; path: { - /** @description Blog post ID */ id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['NoteDisputeDto']; + }; + }; responses: { - /** @description Blog post restored successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Blog post not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['DisputeNoteResponseDto']; }; - content?: never; }; }; }; - AdminBlogsController_getAllTags: { + DisputesController_resolve: { parameters: { - query: { - limit: string; - }; + query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ResolveDisputeDto']; + }; + }; responses: { - /** @description Tags retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['DisputeActionResponseDto']; + }; }; }; }; - AdminBlogsController_getTagBySlug: { + DisputesController_escalate: { parameters: { query?: never; header?: never; path: { - /** @description Tag slug */ - slug: string; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['EscalateDisputeDto']; + }; + }; responses: { - /** @description Tag retrieved successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Tag not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['DisputeActionResponseDto']; }; - content?: never; }; }; }; - AdminBlogsController_deleteUnusedTags: { + EscrowController_list: { parameters: { - query?: never; + query?: { + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; + page?: number; + limit?: number; + /** @description Match against the on-chain reference (hash or address) */ + search?: string; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Unused tags deleted successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedMoneyDto']; + }; }; }; }; - AdminBlogsController_publishScheduledPosts: { + EscrowController_listRequests: { parameters: { - query?: never; + query?: { + /** @description Filter to a single request status */ + status?: 'PROPOSED' | 'APPROVED' | 'REJECTED' | 'EXECUTED'; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Scheduled posts published successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['EscrowRequestListResponseDto']; + }; }; }; }; - AdminCrowdfundingController_list: { + EscrowController_propose: { parameters: { - query?: { - limit?: unknown; - page?: unknown; - }; + query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ProposeEscrowRequestDto']; + }; + }; responses: { - /** @description List of campaigns */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['EscrowRequestDto']; + }; }; }; }; - AdminCrowdfundingController_listByUser: { + EscrowController_decide: { parameters: { - query?: { - limit?: unknown; - page?: unknown; - }; + query?: never; header?: never; path: { - /** @description Username or User ID */ - usernameOrId: string; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['DecideEscrowRequestDto']; + }; + }; responses: { - /** @description List of campaigns by user */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description User not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['EscrowRequestDto']; }; - content?: never; }; }; }; - AdminCrowdfundingController_getCampaign: { + EscrowController_execute: { parameters: { query?: never; header?: never; path: { - /** @description Campaign ID */ - campaignId: string; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ExecuteEscrowRequestDto']; + }; + }; responses: { - /** @description Campaign details */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Campaign not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['EscrowRequestDto']; }; - content?: never; }; }; }; - AdminCrowdfundingController_listPending: { + PayoutsController_list: { parameters: { query?: { - limit?: unknown; - page?: unknown; + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; + page?: number; + limit?: number; + /** @description Match against the on-chain reference (hash or address) */ + search?: string; }; header?: never; path?: never; @@ -30829,175 +35479,174 @@ export interface operations { }; requestBody?: never; responses: { - /** @description List of pending campaigns */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedMoneyDto']; + }; }; }; }; - AdminCrowdfundingController_approve: { + PayoutsController_listRequests: { parameters: { - query?: never; - header?: never; - path: { - campaignId: string; + query?: { + /** @description Filter to a single request status */ + status?: + | 'PROPOSED' + | 'APPROVED' + | 'AWAITING_SIGNATURE' + | 'REJECTED' + | 'EXECUTED'; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Campaign approved */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PayoutRequestListResponseDto']; + }; }; }; }; - AdminCrowdfundingController_reject: { + PayoutsController_propose: { parameters: { query?: never; header?: never; - path: { - campaignId: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AdminCrowdfundingRejectDto']; + 'application/json': components['schemas']['ProposePayoutRequestDto']; }; }; responses: { - /** @description Campaign rejected */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PayoutRequestDto']; + }; }; }; }; - AdminCrowdfundingController_requestRevision: { + PayoutsController_decide: { parameters: { query?: never; header?: never; path: { - campaignId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AdminCrowdfundingRequestRevisionDto']; + 'application/json': components['schemas']['DecidePayoutRequestDto']; }; }; responses: { - /** @description Revision request created */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PayoutRequestDto']; + }; }; - /** @description Campaign not found */ - 404: { + }; + }; + PayoutsController_buildXdr: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['BuildXdrResponseDto']; + }; }; }; }; - AdminCrowdfundingController_addReviewNote: { + PayoutsController_submitSigned: { parameters: { query?: never; header?: never; path: { - campaignId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AdminCrowdfundingNoteDto']; + 'application/json': components['schemas']['SubmitPayoutSignedXdrDto']; }; }; responses: { - /** @description Review note added */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Campaign not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['PayoutRequestDto']; }; - content?: never; }; }; }; - AdminCrowdfundingController_assignReviewer: { + PayoutsController_execute: { parameters: { query?: never; header?: never; path: { - campaignId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AdminCrowdfundingAssignDto']; + 'application/json': components['schemas']['ExecutePayoutRequestDto']; }; }; responses: { - /** @description Reviewer assigned */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Campaign not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['PayoutRequestDto']; }; - content?: never; }; }; }; - AdminMilestonesController_listAllMilestonesByCampaign: { + ContentController_list: { parameters: { query?: { - /** @description Page number */ + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; page?: number; - /** @description Items per page */ limit?: number; - /** @description Filter by review status */ - status?: - | 'PENDING' - | 'SUBMITTED' - | 'UNDER_REVIEW' - | 'APPROVED' - | 'REJECTED' - | 'RESUBMISSION_REQUIRED'; - /** @description Sort by field */ - sortBy?: - | 'submittedAt' - | 'campaignSize' - | 'creatorReputation' - | 'createdAt'; - /** @description Filter by campaign ID */ - campaignId?: string; + /** @description Match against the post title or slug */ + search?: string; + /** @description Show archived (soft-deleted) posts instead of active ones. */ + archived?: boolean; }; header?: never; path?: never; @@ -31005,225 +35654,233 @@ export interface operations { }; requestBody?: never; responses: { - /** @description List of campaigns with their milestones */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedContentDto']; + }; }; }; }; - AdminMilestonesController_listPendingMilestones: { + ContentController_create: { parameters: { - query?: { - /** @description Page number */ - page?: number; - /** @description Items per page */ - limit?: number; - /** @description Filter by review status */ - status?: - | 'PENDING' - | 'SUBMITTED' - | 'UNDER_REVIEW' - | 'APPROVED' - | 'REJECTED' - | 'RESUBMISSION_REQUIRED'; - /** @description Sort by field */ - sortBy?: - | 'submittedAt' - | 'campaignSize' - | 'creatorReputation' - | 'createdAt'; - /** @description Filter by campaign ID */ - campaignId?: string; - }; + query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateBlogPostDto']; + }; + }; responses: { - /** @description List of pending milestones */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ContentMutationResponseDto']; + }; }; }; }; - AdminMilestonesController_getMilestoneForReview: { + ContentController_getById: { parameters: { query?: never; header?: never; path: { - milestoneId: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Milestone details */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Milestone not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AdminContentDetailDto']; }; - content?: never; }; }; }; - AdminMilestonesController_approveMilestone: { + ContentController_update: { parameters: { query?: never; header?: never; path: { - milestoneId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['ApproveMilestoneDto']; + 'application/json': components['schemas']['UpdateContentDto']; }; }; responses: { - /** @description Milestone approved */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Milestone not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['ContentMutationResponseDto']; }; - content?: never; }; }; }; - AdminMilestonesController_rejectMilestone: { + ContentController_setPublished: { parameters: { query?: never; header?: never; path: { - milestoneId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['RejectMilestoneDto']; + 'application/json': components['schemas']['SetPublishedDto']; }; }; responses: { - /** @description Milestone rejected */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Milestone not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['ContentActionResponseDto']; }; - content?: never; }; }; }; - AdminMilestonesController_requestResubmission: { + ContentController_archive: { parameters: { query?: never; header?: never; path: { - milestoneId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['RequestMilestoneResubmissionDto']; + 'application/json': components['schemas']['ArchiveContentDto']; }; }; responses: { - /** @description Resubmission requested */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ContentActionResponseDto']; + }; }; - /** @description Milestone not found */ - 404: { + }; + }; + ContentController_restore: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ContentActionResponseDto']; + }; }; }; }; - AdminMilestonesController_addReviewNote: { + CrowdfundingChecklistController_list: { parameters: { query?: never; header?: never; - path: { - milestoneId: string; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['ChecklistItemDto'][]; + }; }; + }; + }; + CrowdfundingChecklistController_create: { + parameters: { + query?: never; + header?: never; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AddMilestoneReviewNoteDto']; + 'application/json': components['schemas']['CreateChecklistItemDto']; }; }; responses: { - /** @description Review note added */ - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ChecklistItemDto']; + }; }; - /** @description Milestone not found */ - 404: { + }; + }; + CrowdfundingChecklistController_reorder: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['ReorderChecklistDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['ChecklistItemDto'][]; + }; }; }; }; - AdminEscrowController_getEscrowInfo: { + CrowdfundingChecklistController_archive: { parameters: { query?: never; header?: never; path: { - campaignId: string; + itemId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Escrow information */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Campaign not found */ - 404: { + 204: { headers: { [name: string]: unknown; }; @@ -31231,54 +35888,56 @@ export interface operations { }; }; }; - AdminEscrowController_executeEscrowAction: { + CrowdfundingChecklistController_update: { parameters: { query?: never; header?: never; path: { - campaignId: string; + itemId: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['ManualEscrowActionDto']; + 'application/json': components['schemas']['UpdateChecklistItemDto']; }; }; responses: { - /** @description Escrow action executed */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Campaign not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['ChecklistItemDto']; }; - content?: never; }; }; }; - AdminDisputesController_listDisputes: { + CrowdfundingController_list: { parameters: { query?: { - /** @description Page number */ + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; page?: number; - /** @description Items per page */ limit?: number; - /** @description Filter by dispute status */ + /** @description Match against the project title */ + search?: string; + /** @description v2Status filter. Omit to list the full lifecycle (all statuses). */ status?: - | 'OPEN' - | 'UNDER_REVIEW' - | 'AWAITING_RESPONSE' - | 'RESOLVED' - | 'ESCALATED' - | 'CLOSED'; - /** @description Filter by campaign ID */ - campaignId?: string; + | 'DRAFT' + | 'SUBMITTED_FOR_REVIEW' + | 'REVIEW_REJECTED' + | 'REVIEW_APPROVED' + | 'VOTING' + | 'VOTE_FAILED' + | 'VOTE_PASSED' + | 'PUBLISHING' + | 'FUNDING' + | 'COMPLETED' + | 'CANCELLED' + | 'PAUSED' + | 'FAILED'; }; header?: never; path?: never; @@ -31286,171 +35945,187 @@ export interface operations { }; requestBody?: never; responses: { - /** @description List of disputes */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedCrowdfundingDto']; + }; }; }; }; - AdminDisputesController_getDisputeDetail: { + CrowdfundingController_getById: { parameters: { query?: never; header?: never; path: { - disputeId: string; + id: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Dispute details */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Dispute not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['AdminCrowdfundingDetailDto']; }; - content?: never; }; }; }; - AdminDisputesController_assignDispute: { + CrowdfundingController_approve: { parameters: { query?: never; header?: never; path: { - disputeId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AssignDisputeDto']; + 'application/json': components['schemas']['ApproveCampaignDto']; }; }; responses: { - /** @description Dispute assigned */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Dispute not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['CrowdfundingActionResponseDto']; }; - content?: never; }; }; }; - AdminDisputesController_addDisputeNote: { + CrowdfundingController_reject: { parameters: { query?: never; header?: never; path: { - disputeId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['AddDisputeNoteDto']; + 'application/json': components['schemas']['RejectCampaignDto']; }; }; responses: { - /** @description Note added */ - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Dispute not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['CrowdfundingActionResponseDto']; }; - content?: never; }; }; }; - AdminDisputesController_resolveDispute: { + CrowdfundingController_requestRevision: { parameters: { query?: never; header?: never; path: { - disputeId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['ResolveDisputeDto']; + 'application/json': components['schemas']['RequestRevisionDto']; }; }; responses: { - /** @description Dispute resolved */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['CrowdfundingActionResponseDto']; + }; }; - /** @description Dispute not found */ - 404: { + }; + }; + SecurityController_enroll: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['TotpEnrollResponseDto']; + }; + }; + }; + }; + SecurityController_activate: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['TotpCodeDto']; + }; + }; + responses: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['OkResponseDto']; + }; }; }; }; - AdminDisputesController_escalateDispute: { + SecurityController_stepUp: { parameters: { query?: never; header?: never; - path: { - disputeId: string; - }; + path?: never; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['EscalateDisputeDto']; + 'application/json': components['schemas']['TotpCodeDto']; }; }; responses: { - /** @description Dispute escalated */ 200: { headers: { [name: string]: unknown; }; - content?: never; - }; - /** @description Dispute not found */ - 404: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['OkResponseDto']; }; - content?: never; }; }; }; - AdminManualProjectsController_listPendingManualProjects: { + AuditController_list: { parameters: { query?: { + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; page?: number; limit?: number; + /** @description Match against the actor email, action, or target id */ + search?: string; }; header?: never; path?: never; @@ -31462,23 +36137,22 @@ export interface operations { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedAuditDto']; + }; }; }; }; - AdminManualProjectsController_approveManualProject: { + AuditController_stream: { parameters: { query?: never; header?: never; - path: { - /** @description Project ID */ - projectId: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - 201: { + 200: { headers: { [name: string]: unknown; }; @@ -31486,60 +36160,53 @@ export interface operations { }; }; }; - AdminManualProjectsController_rejectManualProject: { + FeatureFlagsController_list: { parameters: { query?: never; header?: never; - path: { - /** @description Project ID */ - projectId: string; - }; + path?: never; cookie?: never; }; - requestBody: { - content: { - 'application/json': components['schemas']['RejectManualProjectDto']; - }; - }; + requestBody?: never; responses: { - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['FeatureFlagsResponseDto']; + }; }; }; }; - AdminManualProjectsController_requestChanges: { + FeatureFlagsController_toggle: { parameters: { query?: never; header?: never; path: { - /** @description Project ID */ - projectId: string; + key: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['RequestManualProjectChangesDto']; + 'application/json': components['schemas']['ToggleFeatureFlagDto']; }; }; responses: { - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['FeatureFlagDto']; + }; }; }; }; - AdminProjectEditsController_listPendingProjectEdits: { + StaffController_list: { parameters: { - query?: { - page?: number; - limit?: number; - }; + query?: never; header?: never; path?: never; cookie?: never; @@ -31550,58 +36217,42 @@ export interface operations { headers: { [name: string]: unknown; }; - content?: never; - }; - }; - }; - AdminProjectEditsController_approveProjectEdit: { - parameters: { - query?: never; - header?: never; - path: { - /** @description ProjectEdit ID */ - editId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - 201: { - headers: { - [name: string]: unknown; + content: { + 'application/json': components['schemas']['StaffListResponseDto']; }; - content?: never; }; }; }; - AdminProjectEditsController_rejectProjectEdit: { + StaffController_setRole: { parameters: { query?: never; header?: never; path: { - /** @description ProjectEdit ID */ - editId: string; + id: string; }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['RejectProjectEditDto']; + 'application/json': components['schemas']['SetRoleDto']; }; }; responses: { - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['StaffListItemDto']; + }; }; }; }; - AdminWalletsController_getStats: { + GovernanceController_list: { parameters: { query?: { - timeRange?: '7d' | '30d' | '90d'; + /** @description Filter to a single proposal status */ + status?: 'PROPOSED' | 'APPROVED' | 'REJECTED' | 'EXECUTED'; }; header?: never; path?: never; @@ -31609,61 +36260,65 @@ export interface operations { }; requestBody?: never; responses: { - default: { + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['AdminWalletStatsDto']; + 'application/json': components['schemas']['GovernanceListResponseDto']; }; }; }; }; - AdminWalletsController_listWallets: { + GovernanceController_propose: { parameters: { - query?: { - search?: string; - limit?: number; - page?: number; - }; + query?: never; header?: never; path?: never; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['CreateProposalDto']; + }; + }; responses: { - default: { + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['AdminWalletListResponseDto']; + 'application/json': components['schemas']['GovernanceProposalDto']; }; }; }; }; - AdminWalletsController_getByUserId: { + GovernanceController_decide: { parameters: { query?: never; header?: never; path: { - userId: string; + id: string; }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['DecideProposalDto']; + }; + }; responses: { - default: { + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['AdminWalletListItemDto'][]; + 'application/json': components['schemas']['GovernanceProposalDto']; }; }; }; }; - AdminWalletsController_getDetails: { + GovernanceController_execute: { parameters: { query?: never; header?: never; @@ -31672,84 +36327,97 @@ export interface operations { }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['ExecuteProposalDto']; + }; + }; responses: { - default: { + 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['AdminWalletDetailsDto']; + 'application/json': components['schemas']['GovernanceProposalDto']; }; }; }; }; - AdminWalletsController_activateWallet: { + KycController_list: { parameters: { - query?: never; - header?: never; - path: { - id: string; + query?: { + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; + /** @description Filter to one KYC state. Omit for all KYC-engaged users. */ + status?: 'in_review' | 'approved' | 'declined'; + page?: number; + limit?: number; + /** @description Match against the user name or email */ + search?: string; }; + header?: never; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Wallet activated successfully */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedKycDto']; + }; }; }; }; - AdminWalletsController_sponsorActivateUser: { + KycController_connection: { parameters: { query?: never; header?: never; - path: { - userId: string; - }; + path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description Returns activation result for the user (activated, alreadyActivated, addedTrustlines, hash). */ - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['DiditConnectionDto']; + }; }; }; }; - AdminWalletsController_sponsorActivateHackathon: { + KycController_sync: { parameters: { query?: never; header?: never; path: { - hackathonId: string; + userId: string; }; cookie?: never; }; requestBody?: never; responses: { - /** @description Job enqueued. Returns { jobId, hackathonId, estimatedParticipants, statusUrl }. */ - 201: { + 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['KycSyncResponseDto']; + }; }; }; }; - AdminWalletsController_getSponsorActivationJobStatus: { + KycController_retrigger: { parameters: { query?: never; header?: never; path: { - jobId: string; + userId: string; }; cookie?: never; }; @@ -31759,150 +36427,73 @@ export interface operations { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['KycRetriggerResponseDto']; + }; }; }; }; - HealthController_liveness: { + KycController_override: { parameters: { query?: never; header?: never; - path?: never; + path: { + userId: string; + }; cookie?: never; }; - requestBody?: never; + requestBody: { + content: { + 'application/json': components['schemas']['KycOverrideDto']; + }; + }; responses: { 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['KycOverrideResponseDto']; + }; }; }; }; - HealthController_readiness: { + MilestonesController_list: { parameters: { - query?: never; + query?: { + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; + /** @description Which pillar to list. Defaults to crowdfunding. */ + type?: 'crowdfunding' | 'grant'; + page?: number; + limit?: number; + /** @description Match against milestone or program title */ + search?: string; + }; header?: never; path?: never; cookie?: never; }; requestBody?: never; responses: { - /** @description The Health Check is successful */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': { - /** @example ok */ - status?: string; - /** - * @example { - * "database": { - * "status": "up" - * } - * } - */ - info?: { - [key: string]: { - status: string; - } & { - [key: string]: unknown; - }; - } | null; - /** @example {} */ - error?: { - [key: string]: { - status: string; - } & { - [key: string]: unknown; - }; - } | null; - /** - * @example { - * "database": { - * "status": "up" - * } - * } - */ - details?: { - [key: string]: { - status: string; - } & { - [key: string]: unknown; - }; - }; - }; - }; - }; - /** @description The Health Check is not successful */ - 503: { - headers: { - [name: string]: unknown; - }; - content: { - 'application/json': { - /** @example error */ - status?: string; - /** - * @example { - * "database": { - * "status": "up" - * } - * } - */ - info?: { - [key: string]: { - status: string; - } & { - [key: string]: unknown; - }; - } | null; - /** - * @example { - * "redis": { - * "status": "down", - * "message": "Could not connect" - * } - * } - */ - error?: { - [key: string]: { - status: string; - } & { - [key: string]: unknown; - }; - } | null; - /** - * @example { - * "database": { - * "status": "up" - * }, - * "redis": { - * "status": "down", - * "message": "Could not connect" - * } - * } - */ - details?: { - [key: string]: { - status: string; - } & { - [key: string]: unknown; - }; - }; - }; + 'application/json': components['schemas']['PaginatedMilestonesDto']; }; }; }; }; - DiditController_getStatus: { + MilestonesController_findOne: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody?: never; @@ -31912,16 +36503,18 @@ export interface operations { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['VerificationStatusDto']; + 'application/json': components['schemas']['AdminMilestoneDetailDto']; }; }; }; }; - DiditController_callback: { + MilestonesController_approve: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody?: never; @@ -31930,87 +36523,44 @@ export interface operations { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['MilestoneActionResponseDto']; + }; }; }; }; - DiditController_createSession: { + MilestonesController_reject: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; requestBody: { content: { - 'application/json': components['schemas']['CreateDiditSessionDto']; + 'application/json': components['schemas']['RejectMilestoneDto']; }; }; responses: { - /** @description Session created */ 200: { headers: { [name: string]: unknown; }; content: { - 'application/json': unknown; - }; - }; - /** @description Missing DIDIT_API_KEY or DIDIT_WORKFLOW_ID */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; + 'application/json': components['schemas']['MilestoneActionResponseDto']; }; - content?: never; }; }; }; - DiditController_webhook: { + MilestonesController_buildReleaseXdr: { parameters: { query?: never; header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Webhook accepted */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Invalid signature */ - 400: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - }; - }; - PricingController_preview: { - parameters: { - query: { - pillar: 'Hackathon' | 'Bounty' | 'Grant' | 'Crowdfunding'; - organizationId: string; - /** @description Budget in stroops (7-decimal). String to preserve precision. */ - budgetStroops: string; - /** @description Override fee bps from a sales authority. 0 = waiver. */ - salesOverrideBps?: number; - /** @description Free-text reason for the audit log. */ - salesOverrideReason?: string; + path: { + id: string; }; - header?: never; - path?: never; cookie?: never; }; requestBody?: never; @@ -32020,48 +36570,47 @@ export interface operations { [name: string]: unknown; }; content: { - 'application/json': components['schemas']['PricingPreviewResponseDto']; + 'application/json': components['schemas']['MilestoneReleaseXdrDto']; }; }; }; }; - AdminOpsController_pause: { + MilestonesController_submitReleaseSigned: { parameters: { query?: never; header?: never; - path?: never; + path: { + id: string; + }; cookie?: never; }; - requestBody?: never; - responses: { - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; + requestBody: { + content: { + 'application/json': components['schemas']['SubmitMilestoneReleaseDto']; }; }; - }; - AdminOpsController_unpause: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; responses: { 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['MilestoneReleaseResultDto']; + }; }; }; }; - AdminOpsController_setFeeBps: { + WalletsController_list: { parameters: { - query?: never; + query?: { + /** @description Field to sort by (whitelisted per resource; ignored otherwise) */ + sort?: string; + dir?: 'asc' | 'desc'; + page?: number; + limit?: number; + /** @description Match against the public key (G-address) */ + search?: string; + }; header?: never; path?: never; cookie?: never; @@ -32072,7 +36621,9 @@ export interface operations { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['PaginatedWalletsDto']; + }; }; }; }; @@ -32891,11 +37442,14 @@ export interface operations { }; requestBody?: never; responses: { + /** @description The caller's application, or null when they have not applied. */ 200: { headers: { [name: string]: unknown; }; - content?: never; + content: { + 'application/json': components['schemas']['BountyApplicationResponseDto']; + }; }; }; }; @@ -33086,6 +37640,121 @@ export interface operations { }; }; }; + BountyParticipantDashboardController_myApplications: { + parameters: { + query?: { + page?: number; + limit?: number; + status?: + | 'SUBMITTED' + | 'SHORTLISTED' + | 'SELECTED' + | 'DECLINED' + | 'WITHDRAWN'; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['MyBountyApplicationListDto']; + }; + }; + }; + }; + BountyParticipantDashboardController_mySubmissions: { + parameters: { + query?: { + page?: number; + limit?: number; + status?: unknown; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['MyBountySubmissionListDto']; + }; + }; + }; + }; + BountyParticipantDashboardController_mySubmissionForBounty: { + parameters: { + query?: never; + header?: never; + path: { + bountyId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description The caller's submission, or null when they have not submitted. */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['MyBountySubmissionRowDto']; + }; + }; + }; + }; + BountyResultsController_getResults: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['BountyResultsDto']; + }; + }; + }; + }; + BountyResultsController_getSubmissions: { + parameters: { + query?: never; + header?: never; + path: { + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['BountySubmissionListDto']; + }; + }; + }; + }; BountyPublicController_list: { parameters: { query?: { diff --git a/openapi.snapshot.json b/openapi.snapshot.json index 3c549d40..f1446109 100644 --- a/openapi.snapshot.json +++ b/openapi.snapshot.json @@ -3358,43 +3358,6 @@ "tags": ["Crowdfunding v2 - Builder"] } }, - "/api/crowdfunding/campaigns/{id}/v2/escrow/claim-milestone": { - "post": { - "operationId": "BuilderCrowdfundingV2Controller_claimMilestone", - "parameters": [ - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ClaimCrowdfundingMilestoneDto" - } - } - } - }, - "responses": { - "200": { - "description": "" - } - }, - "security": [ - { - "bearer": [] - } - ], - "summary": "Claim a milestone payout (reviewStatus must be APPROVED)", - "tags": ["Crowdfunding v2 - Builder"] - } - }, "/api/crowdfunding/campaigns/{id}/v2/escrow/contribute": { "post": { "operationId": "BackerCrowdfundingV2Controller_contribute", @@ -3866,6 +3829,87 @@ "tags": ["Crowdfunding v2 - Admin"] } }, + "/api/crowdfunding/campaigns/{id}/v2/disputes": { + "post": { + "operationId": "CrowdfundingDisputesController_file", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FileDisputeDto" + } + } + } + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DisputeResponseDto" + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Open a dispute on a campaign (backers only)", + "tags": ["Crowdfunding v2 - Backer"] + } + }, + "/api/crowdfunding/campaigns/{id}/v2/disputes/mine": { + "get": { + "operationId": "CrowdfundingDisputesController_mine", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DisputeResponseDto" + } + } + } + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List the caller’s disputes on a campaign", + "tags": ["Crowdfunding v2 - Backer"] + } + }, "/api/wallet": { "get": { "operationId": "WalletController_getWallet", @@ -18799,19 +18843,9 @@ }, "/api/didit/create-session": { "post": { - "description": "Creates a Didit verification session. Returns session_token and verification_url for the frontend SDK. Authenticated user id is sent as vendor_data unless user_id is provided.", + "description": "Creates a Didit verification session for the authenticated user. Returns session_token and verification_url for the frontend SDK.", "operationId": "DiditController_createSession", "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateDiditSessionDto" - } - } - } - }, "responses": { "200": { "description": "Session created", @@ -18846,7 +18880,7 @@ }, "/api/didit/webhook": { "post": { - "description": "Receives verification completion events from Didit. Verifies X-Signature-V2 when DIDIT_WEBHOOK_SECRET is set. Updates user verification status and DiditVerificationSession.", + "description": "Receives verification completion events from Didit. The signature is verified by DiditWebhookGuard. Updates user verification status and DiditVerificationSession.", "operationId": "DiditController_webhook", "parameters": [], "responses": { @@ -18854,7 +18888,7 @@ "description": "Webhook accepted" }, "400": { - "description": "Invalid signature" + "description": "Invalid or missing signature" } }, "summary": "Didit webhook", @@ -18964,261 +18998,321 @@ "tags": ["AdminOps"] } }, - "/api/prices": { + "/api/admin/v2/access/me": { "get": { - "description": "Returns per-unit USD prices for XLM, USDC, EURC and USDGLO. Resolved from the Reflector on-chain oracle, with CoinGecko and stablecoin-peg fallbacks. Cached for 5 minutes (matches Reflector update cadence).", - "operationId": "PricesController_getAll", + "operationId": "AccessController_me", "parameters": [], "responses": { "200": { - "description": "Map of asset symbol → USD price as a decimal string (6 dp).", + "description": "", "content": { "application/json": { "schema": { - "example": { - "XLM": "0.117800", - "USDC": "1.000000", - "EURC": "1.080000", - "USDGLO": "1.000000" - } + "$ref": "#/components/schemas/MeResponseDto" } } } } }, - "summary": "Get USD prices for all supported assets", - "tags": ["prices"] + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "The current staff principal and role", + "tags": ["Admin v2 - Access"] } }, - "/api/prices/debug": { + "/api/admin/v2/access/roles": { "get": { - "description": "Bypasses the cache and pings Reflector + CoinGecko for every supported asset. Returns what each provider returned alongside which one the resolution chain would have picked. Use to verify both price paths are live.", - "operationId": "PricesController_getDebug", + "operationId": "AccessController_roles", "parameters": [], "responses": { "200": { - "description": "Per-asset debug info. `source` is which provider won the resolution chain.", + "description": "" + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "The role and permission matrix (Super Admin only)", + "tags": ["Admin v2 - Access"] + } + }, + "/api/admin/v2/analytics": { + "get": { + "operationId": "AnalyticsController_get", + "parameters": [], + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "example": { - "XLM": { - "resolved": "0.117800", - "source": "reflector", - "providers": { - "reflector": "0.117800", - "coingecko": "0.117850", - "stablecoinFallback": null - } - }, - "USDC": { - "resolved": "1.000000", - "source": "reflector", - "providers": { - "reflector": "1.000000", - "coingecko": "1.000000", - "stablecoinFallback": "1.0000" - } - } - } + "$ref": "#/components/schemas/AnalyticsDto" } } } } }, - "summary": "Per-provider price resolution (diagnostic)", - "tags": ["prices"] + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Platform analytics (growth, breakdowns, trend)", + "tags": ["Admin v2 - Analytics"] } }, - "/api/prices/{symbol}": { + "/api/admin/v2/overview": { "get": { - "description": "Convenience lookup — internally reads from the same cached map as the list endpoint.", - "operationId": "PricesController_getOne", + "operationId": "OverviewController_get", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OverviewDto" + } + } + } + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Platform overview counts", + "tags": ["Admin v2 - Overview"] + } + }, + "/api/admin/v2/users": { + "get": { + "operationId": "UsersController_list", "parameters": [ { - "name": "symbol", + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", + "schema": { + "type": "string" + } + }, + { + "name": "dir", + "required": false, + "in": "query", + "schema": { + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, + "type": "number" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Match against name, email, or username", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedUsersDto" + } + } + } + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "List users (paginated, searchable)", + "tags": ["Admin v2 - Users"] + } + }, + "/api/admin/v2/users/{id}": { + "get": { + "operationId": "UsersController_getById", + "parameters": [ + { + "name": "id", "required": true, "in": "path", - "description": "Asset ticker (case-insensitive).", "schema": { - "enum": ["XLM", "USDC", "EURC", "USDGLO"], "type": "string" } } ], "responses": { "200": { - "description": "USD price as a decimal string (6 dp).", + "description": "", "content": { "application/json": { "schema": { - "example": "0.117800" + "$ref": "#/components/schemas/AdminUserDetailDto" } } } } }, - "summary": "Get USD price for a single asset", - "tags": ["prices"] + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Get one user", + "tags": ["Admin v2 - Users"] } }, - "/api/projects/drafts": { - "post": { - "operationId": "ProjectsController_createDraft", - "parameters": [], - "requestBody": { - "required": true, - "description": "Full payload for the stepped draft creation", - "content": { - "application/json": { - "schema": { - "type": "object" - }, - "examples": { - "campaign": { - "value": { - "title": "DeFi Lending Protocol", - "tagline": "Scalable liquidity", - "category": "DeFi", - "description": "A Stellar-native DeFi lending protocol that enables users to deposit assets and earn interest with transparent on-chain accounting.", - "summary": "Lending with transparent on-chain accounting", - "vision": "We aim to make lending safer and more scalable by improving collateral efficiency and risk modeling.", - "details": "Full technical and product details (markdown supported).", - "banner": "https://example.com/banner.png", - "logo": "https://example.com/logo.png", - "githubUrl": "https://github.com/example/defi-lending", - "gitlabUrl": "https://gitlab.com/example/defi-lending", - "bitbucketUrl": "https://bitbucket.org/example/defi-lending", - "projectWebsite": "https://defi-lending.example.com", - "demoVideo": "https://example.com/demo.mp4", - "whitepaperUrl": "https://example.com/whitepaper.pdf", - "pitchVideoUrl": "https://example.com/pitch.mp4", - "socialLinks": { - "twitter": "https://twitter.com/example", - "discord": "https://discord.gg/example" - }, - "contact": { - "primary": "@alex123", - "backup": "alex_doe#1234" - }, - "tags": ["Soroban", "TypeScript", "DeFi"], - "draftData": { - "isCampaign": true, - "campaign": { - "title": "DeFi Lending Protocol Campaign", - "logo": "https://example.com/logo.png", - "vision": "Build, ship, and deliver measurable milestones.", - "banner": "https://example.com/banner.png", - "category": "DeFi", - "details": "Funding request and milestone plan for the lending protocol.", - "fundingAmount": 15000, - "githubUrl": "https://github.com/example/defi-lending", - "gitlabUrl": "https://gitlab.com/example/defi-lending", - "bitbucketUrl": "https://bitbucket.org/example/defi-lending", - "projectWebsite": "https://defi-lending.example.com", - "demoVideo": "https://example.com/demo.mp4", - "milestones": [ - { - "title": "Milestone 1", - "description": "Core lending vault + basic UI.", - "deliverable": "Deploy vault contracts + initial product UI.", - "fundingPercentage": 50, - "amount": 7500, - "expectedDeliveryDate": "2026-04-01T00:00:00.000Z", - "successCriteria": "Contracts deployed and UI shipped.", - "orderIndex": 0 - }, - { - "title": "Milestone 2", - "description": "Risk modeling improvements + analytics.", - "deliverable": "Add risk model and dashboard metrics.", - "fundingPercentage": 50, - "amount": 7500, - "expectedDeliveryDate": "2026-05-01T00:00:00.000Z", - "successCriteria": "Risk model live and dashboards updated.", - "orderIndex": 1 - } - ], - "team": [ - { - "name": "John Doe", - "role": "Lead Developer", - "email": "john@example.com", - "linkedin": "https://linkedin.com/in/johndoe", - "twitter": "https://twitter.com/johndoe" - } - ], - "contact": { - "primary": "@alex123", - "backup": "alex_doe#1234" - }, - "socialLinks": [ - { - "platform": "twitter", - "url": "https://twitter.com/example" - }, - { - "platform": "discord", - "url": "https://discord.gg/example" - } - ] - } - } - } - }, - "nonCampaign": { - "value": { - "title": "NFT Marketplace", - "tagline": "Creator focused", - "category": "NFT", - "description": "A creator-first NFT marketplace for Stellar projects with curated discovery and transparent royalties.", - "summary": "Marketplace for creators", - "vision": "Make discovery and royalties simple.", - "details": "Markdown project details here.", - "banner": "https://example.com/banner.png", - "logo": "https://example.com/logo.png", - "githubUrl": "https://github.com/example/nft-marketplace", - "projectWebsite": "https://nft-marketplace.example.com", - "demoVideo": "https://example.com/demo.mp4", - "socialLinks": { - "twitter": "https://twitter.com/example" - }, - "contact": { - "primary": "@alex123" - }, - "tags": ["NFT", "React"], - "draftData": { - "isCampaign": false - } + "/api/admin/v2/users/{id}/earnings": { + "get": { + "operationId": "UsersController_getEarnings", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EarningsResponseDto" + } + } + } + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Get a user's earnings (summary, breakdown, activity)", + "tags": ["Admin v2 - Users"] + } + }, + "/api/admin/v2/users/{id}/organizations": { + "get": { + "operationId": "UsersController_getOrganizations", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminUserOrganizationDto" } } } } } }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Get a user's organizations", + "tags": ["Admin v2 - Users"] + } + }, + "/api/admin/v2/users/{id}/wallet": { + "get": { + "operationId": "UsersController_getWallet", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], "responses": { - "201": { - "description": "Draft created successfully" + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminUserWalletDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Create a project draft (stepped form)", - "tags": ["projects"] + "summary": "Get a user's wallet and live balances", + "tags": ["Admin v2 - Users"] } }, - "/api/projects/{id}/draft": { + "/api/admin/v2/users/{id}/ban": { "patch": { - "operationId": "ProjectsController_saveDraft", + "operationId": "UsersController_setBanned", "parameters": [ { "name": "id", "required": true, "in": "path", - "description": "Project ID", "schema": { "type": "string" } @@ -19226,169 +19320,84 @@ ], "requestBody": { "required": true, - "description": "Full payload for stepped draft autosave", "content": { "application/json": { "schema": { - "type": "object" - }, - "examples": { - "campaign": { - "value": { - "title": "DeFi Lending Protocol", - "tagline": "Scalable liquidity", - "category": "DeFi", - "description": "A Stellar-native DeFi lending protocol that enables users to deposit assets and earn interest with transparent on-chain accounting.", - "summary": "Lending with transparent on-chain accounting", - "vision": "We aim to make lending safer and more scalable by improving collateral efficiency and risk modeling.", - "details": "Full technical and product details (markdown supported).", - "banner": "https://example.com/banner.png", - "logo": "https://example.com/logo.png", - "githubUrl": "https://github.com/example/defi-lending", - "gitlabUrl": "https://gitlab.com/example/defi-lending", - "bitbucketUrl": "https://bitbucket.org/example/defi-lending", - "projectWebsite": "https://defi-lending.example.com", - "demoVideo": "https://example.com/demo.mp4", - "whitepaperUrl": "https://example.com/whitepaper.pdf", - "pitchVideoUrl": "https://example.com/pitch.mp4", - "socialLinks": { - "twitter": "https://twitter.com/example", - "discord": "https://discord.gg/example" - }, - "contact": { - "primary": "@alex123", - "backup": "alex_doe#1234" - }, - "tags": ["Soroban", "TypeScript", "DeFi"], - "draftData": { - "isCampaign": true, - "campaign": { - "title": "DeFi Lending Protocol Campaign", - "logo": "https://example.com/logo.png", - "vision": "Build, ship, and deliver measurable milestones.", - "banner": "https://example.com/banner.png", - "category": "DeFi", - "details": "Funding request and milestone plan for the lending protocol.", - "fundingAmount": 15000, - "githubUrl": "https://github.com/example/defi-lending", - "gitlabUrl": "https://gitlab.com/example/defi-lending", - "bitbucketUrl": "https://bitbucket.org/example/defi-lending", - "projectWebsite": "https://defi-lending.example.com", - "demoVideo": "https://example.com/demo.mp4", - "milestones": [ - { - "title": "Milestone 1", - "description": "Core lending vault + basic UI.", - "deliverable": "Deploy vault contracts + initial product UI.", - "fundingPercentage": 50, - "amount": 7500, - "expectedDeliveryDate": "2026-04-01T00:00:00.000Z", - "successCriteria": "Contracts deployed and UI shipped.", - "orderIndex": 0 - }, - { - "title": "Milestone 2", - "description": "Risk modeling improvements + analytics.", - "deliverable": "Add risk model and dashboard metrics.", - "fundingPercentage": 50, - "amount": 7500, - "expectedDeliveryDate": "2026-05-01T00:00:00.000Z", - "successCriteria": "Risk model live and dashboards updated.", - "orderIndex": 1 - } - ], - "team": [ - { - "name": "John Doe", - "role": "Lead Developer", - "email": "john@example.com", - "linkedin": "https://linkedin.com/in/johndoe", - "twitter": "https://twitter.com/johndoe" - } - ], - "contact": { - "primary": "@alex123", - "backup": "alex_doe#1234" - }, - "socialLinks": [ - { - "platform": "twitter", - "url": "https://twitter.com/example" - }, - { - "platform": "discord", - "url": "https://discord.gg/example" - } - ] - } - } - } - }, - "nonCampaign": { - "value": { - "title": "NFT Marketplace", - "tagline": "Creator focused", - "category": "NFT", - "description": "A creator-first NFT marketplace for Stellar projects with curated discovery and transparent royalties.", - "summary": "Marketplace for creators", - "vision": "Make discovery and royalties simple.", - "details": "Markdown project details here.", - "banner": "https://example.com/banner.png", - "logo": "https://example.com/logo.png", - "githubUrl": "https://github.com/example/nft-marketplace", - "projectWebsite": "https://nft-marketplace.example.com", - "demoVideo": "https://example.com/demo.mp4", - "socialLinks": { - "twitter": "https://twitter.com/example" - }, - "contact": { - "primary": "@alex123" - }, - "tags": ["NFT", "React"], - "draftData": { - "isCampaign": false - } - } - } + "$ref": "#/components/schemas/BanUserDto" } } } }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BanUserResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Update a project draft (stepped form autosave)", - "tags": ["projects"] - } - }, - "/api/projects": { - "get": { - "operationId": "ProjectsController_listPublicProjects", - "parameters": [], - "responses": { - "200": { - "description": "" - } - }, - "summary": "List public projects (PRD products directory)", - "tags": ["projects"] + "summary": "Ban or unban a user (Tier 2: requires step-up)", + "tags": ["Admin v2 - Users"] } }, - "/api/projects/search": { + "/api/admin/v2/organizations": { "get": { - "operationId": "ProjectsController_searchPublicProjects", + "operationId": "OrganizationsController_list", "parameters": [ + { + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", + "schema": { + "type": "string" + } + }, + { + "name": "dir", + "required": false, + "in": "query", + "schema": { + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, + "type": "number" + } + }, { "name": "search", "required": false, "in": "query", + "description": "Match against name or slug", "schema": { "type": "string" } @@ -19396,29 +19405,60 @@ ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedOrganizationsDto" + } + } + } } }, - "summary": "Search public projects", - "tags": ["projects"] + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "List organizations (paginated, searchable)", + "tags": ["Admin v2 - Organizations"] } }, - "/api/projects/featured": { + "/api/admin/v2/organizations/{id}": { "get": { - "operationId": "ProjectsController_listFeaturedProjects", - "parameters": [], + "operationId": "OrganizationsController_getById", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminOrgDetailDto" + } + } + } } }, - "summary": "List featured projects", - "tags": ["projects"] - } - }, - "/api/projects/{id}/edits": { - "post": { - "operationId": "ProjectsController_submitProjectEdit", + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Get one organization", + "tags": ["Admin v2 - Organizations"] + }, + "patch": { + "operationId": "OrganizationsController_update", "parameters": [ { "name": "id", @@ -19434,26 +19474,36 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Function" + "$ref": "#/components/schemas/UpdateOrgDto" } } } }, "responses": { - "201": { - "description": "" + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OrgActionResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Submit a major/minor edit for your project", - "tags": ["projects"] - }, - "get": { - "operationId": "ProjectsController_listProjectEdits", + "summary": "Update organization details (Tier 2: requires step-up)", + "tags": ["Admin v2 - Organizations"] + } + }, + "/api/admin/v2/organizations/{id}/suspend": { + "post": { + "description": "Freezes member-initiated mutations (treasury, member management, owner config). Reversible via reinstate.", + "operationId": "OrganizationsController_suspend", "parameters": [ { "name": "id", @@ -19464,29 +19514,45 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SuspendOrgDto" + } + } + } + }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OrgSuspensionResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "List edit history for your project", - "tags": ["projects"] + "summary": "Suspend an organization (Tier 2: requires step-up)", + "tags": ["Admin v2 - Organizations"] } }, - "/api/projects/{id}/publish": { + "/api/admin/v2/organizations/{id}/reinstate": { "post": { - "operationId": "ProjectsController_publishProject", + "operationId": "OrganizationsController_reinstate", "parameters": [ { "name": "id", "required": true, "in": "path", - "description": "Project ID", "schema": { "type": "string" } @@ -19494,71 +19560,95 @@ ], "requestBody": { "required": true, - "description": "Publish/submit action (Review & Submit)", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "isCampaign": { - "type": "boolean", - "example": true - } - } - }, - "examples": { - "publishCampaign": { - "value": { - "isCampaign": true - } - }, - "publishNonCampaign": { - "value": { - "isCampaign": false - } - } + "$ref": "#/components/schemas/ReinstateOrgDto" } } } }, "responses": { - "201": { - "description": "" + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OrgSuspensionResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Publish/submit a project draft (Review & Submit)", - "tags": ["projects"] + "summary": "Reinstate a suspended organization (Tier 2: requires step-up)", + "tags": ["Admin v2 - Organizations"] } }, - "/api/projects/me": { + "/api/admin/v2/programs": { "get": { - "operationId": "ProjectsController_getMyProjects", + "operationId": "ProgramsController_list", "parameters": [ { - "name": "limit", + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", + "schema": { + "type": "string" + } + }, + { + "name": "dir", + "required": false, + "in": "query", + "schema": { + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] + } + }, + { + "name": "type", + "required": false, + "in": "query", + "description": "Which pillar to list. Defaults to hackathons.", + "schema": { + "default": "hackathon", + "type": "string", + "enum": ["hackathon", "bounty", "grant", "crowdfunding"] + } + }, + { + "name": "page", "required": false, "in": "query", "schema": { + "minimum": 1, + "default": 1, "type": "number" } }, { - "name": "offset", + "name": "limit", "required": false, "in": "query", "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, "type": "number" } }, { - "name": "status", - "required": true, + "name": "search", + "required": false, "in": "query", + "description": "Match against the program title", "schema": { "type": "string" } @@ -19566,135 +19656,122 @@ ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedProgramsDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "List my projects", - "tags": ["projects"] + "summary": "List programs across a pillar (paginated, searchable)", + "tags": ["Admin v2 - Programs"] } }, - "/api/projects/{slug}": { + "/api/admin/v2/programs/{id}": { "get": { - "operationId": "ProjectsController_getPublicProjectBySlug", + "operationId": "ProgramsController_getById", "parameters": [ { - "name": "slug", + "name": "id", "required": true, "in": "path", - "description": "Project slug", "schema": { "type": "string" } - } - ], - "responses": { - "200": { - "description": "" - } - }, - "security": [ - { - "bearer": [] - } - ], - "summary": "Get public project by slug", - "tags": ["projects"] - } - }, - "/api/projects/me/{id}": { - "get": { - "operationId": "ProjectsController_getProject", - "parameters": [ + }, { - "name": "id", + "name": "type", "required": true, - "in": "path", - "description": "Project ID", + "in": "query", + "description": "Which pillar the id belongs to", "schema": { - "type": "string" + "type": "string", + "enum": ["hackathon", "bounty", "grant", "crowdfunding"] } } ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminProgramDetailDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Get my project by ID", - "tags": ["projects"] + "summary": "Get one program (type selects the pillar)", + "tags": ["Admin v2 - Programs"] } }, - "/api/organizations/{organizationId}/bounties/draft/{id}": { - "delete": { - "description": "Deletes an unpublished bounty (draft / draft_awaiting_funding).", - "operationId": "OrganizationBountiesDraftsController_deleteDraft", + "/api/admin/v2/programs/{id}/feature": { + "patch": { + "operationId": "ProgramsController_setFeatured", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "example": "org_1234567890", - "type": "string" - } - }, { "name": "id", "required": true, "in": "path", - "description": "Bounty draft id", "schema": { - "example": "bnt_123", "type": "string" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetFeaturedDto" + } + } + } + }, "responses": { - "204": { - "description": "Draft deleted" - }, - "400": { - "description": "Draft not found, not authorized, or not an unpublished draft" + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProgramActionResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Delete a bounty draft", - "tags": ["Organization Bounties - Drafts"] - }, + "summary": "Feature or unfeature a program (Tier 1; hackathons & bounties)", + "tags": ["Admin v2 - Programs"] + } + }, + "/api/admin/v2/programs/{id}/status": { "patch": { - "description": "Applies any subset of wizard sections in a single PATCH. Send one section for a per-step \"Continue\", or several for \"Save draft\". Each present section is validated and transformed independently, then merged into one write. The reward section replaces the prize tiers.", - "operationId": "OrganizationBountiesDraftsController_updateDraft", + "operationId": "ProgramsController_setStatus", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "example": "org_1234567890", - "type": "string" - } - }, { "name": "id", "required": true, "in": "path", - "description": "Bounty draft id", "schema": { - "example": "bnt_123", "type": "string" } } @@ -19704,226 +19781,127 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateBountyDraftDto" - }, - "examples": { - "singleSection": { - "summary": "Update one section (per-step Continue)", - "value": { - "scope": { - "title": "Build a Soroban faucet bot", - "description": "A Discord bot that drips testnet tokens on request." - } - } - }, - "multipleSections": { - "summary": "Update several sections (Save draft)", - "value": { - "mode": { - "claimType": "COMPETITION", - "entryType": "APPLICATION_LIGHT" - }, - "submission": { - "submissionDeadline": "2026-12-01T00:00:00Z", - "applicationWindowCloseAt": "2026-11-01T00:00:00Z", - "shortlistSize": 3 - }, - "reward": { - "rewardCurrency": "USDC", - "prizeTiers": [ - { - "position": 1, - "amount": "500" - }, - { - "position": 2, - "amount": "250" - } - ] - } - } - } + "$ref": "#/components/schemas/SetProgramStatusDto" } } } }, "responses": { "200": { - "description": "Draft updated", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyDraftResponseDto" + "$ref": "#/components/schemas/ProgramActionResponseDto" } } } - }, - "400": { - "description": "Validation failed for one or more sections" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Update one or more sections of a bounty draft", - "tags": ["Organization Bounties - Drafts"] - }, + "summary": "Set an admin lifecycle status (Tier 2: requires step-up)", + "tags": ["Admin v2 - Programs"] + } + }, + "/api/admin/v2/disputes": { "get": { - "description": "Returns the current section-keyed state of a bounty draft.", - "operationId": "OrganizationBountiesDraftsController_getDraft", + "operationId": "DisputesController_list", "parameters": [ { - "name": "organizationId", - "required": true, - "in": "path", + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", "schema": { - "example": "org_1234567890", "type": "string" } }, { - "name": "id", - "required": true, - "in": "path", - "description": "Bounty draft id", - "schema": { - "example": "bnt_123", - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Draft retrieved", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BountyDraftResponseDto" - } - } - } - } - }, - "security": [ - { - "bearer": [] - } - ], - "summary": "Get a bounty draft for resume", - "tags": ["Organization Bounties - Drafts"] - } - }, - "/api/organizations/{organizationId}/bounties": { - "get": { - "description": "Lists bounties for an organization, newest first.", - "operationId": "OrganizationBountiesDraftsController_getOrganizationBounties", - "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", + "name": "dir", + "required": false, + "in": "query", "schema": { - "example": "org_1234567890", - "type": "string" + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] } }, { "name": "page", - "required": true, + "required": false, "in": "query", "schema": { + "minimum": 1, + "default": 1, "type": "number" } }, { "name": "limit", - "required": true, + "required": false, "in": "query", "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, "type": "number" } - } - ], - "responses": { - "200": { - "description": "Bounties retrieved" - } - }, - "security": [ - { - "bearer": [] - } - ], - "summary": "Get an organization's published bounties", - "tags": ["Organization Bounties - Drafts"] - } - }, - "/api/organizations/{organizationId}/bounties/draft": { - "post": { - "description": "Creates an empty bounty in draft status that organization members can edit section by section through the Configure wizard.", - "operationId": "OrganizationBountiesDraftsController_createDraft", - "parameters": [ + }, { - "name": "organizationId", - "required": true, - "in": "path", + "name": "search", + "required": false, + "in": "query", + "description": "Match against the dispute description or campaign title", "schema": { - "example": "org_1234567890", "type": "string" } } ], "responses": { - "201": { - "description": "Draft created", + "200": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyDraftResponseDto" + "$ref": "#/components/schemas/PaginatedDisputesDto" } } } - }, - "400": { - "description": "User is not a member of the organization" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Create a new bounty draft for an organization", - "tags": ["Organization Bounties - Drafts"] + "summary": "List disputes (paginated, searchable)", + "tags": ["Admin v2 - Disputes"] } }, - "/api/organizations/{organizationId}/bounties/drafts": { + "/api/admin/v2/disputes/{id}": { "get": { - "description": "Lists draft and draft_awaiting_funding bounties for an organization.", - "operationId": "OrganizationBountiesDraftsController_getOrganizationDrafts", + "operationId": "DisputesController_getById", "parameters": [ { - "name": "organizationId", + "name": "id", "required": true, "in": "path", "schema": { - "example": "org_1234567890", "type": "string" } } ], "responses": { "200": { - "description": "Drafts retrieved", + "description": "", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BountyDraftResponseDto" - } + "$ref": "#/components/schemas/AdminDisputeDetailDto" } } } @@ -19931,34 +19909,22 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Get an organization's bounty drafts", - "tags": ["Organization Bounties - Drafts"] + "summary": "Get one dispute", + "tags": ["Admin v2 - Disputes"] } }, - "/api/organizations/{organizationId}/bounties/{id}/escrow/publish": { + "/api/admin/v2/disputes/{id}/assign": { "post": { - "description": "Validates the draft, transitions it to draft_awaiting_funding, and returns an unsigned XDR (EXTERNAL) or the op in PENDING_CONFIRM (MANAGED). Reconciliation transitions the bounty to OPEN on success.", - "operationId": "OrganizationBountiesEscrowController_publish", + "operationId": "DisputesController_assign", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "example": "org_1234567890", - "type": "string" - } - }, { "name": "id", "required": true, "in": "path", - "description": "Bounty draft id", "schema": { - "example": "bnt_1234567890", "type": "string" } } @@ -19968,7 +19934,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PublishBountyEscrowDto" + "$ref": "#/components/schemas/AssignDisputeDto" } } } @@ -19979,43 +19945,29 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/DisputeAssignmentResponseDto" } } } - }, - "400": { - "description": "Validation failed or bounty not in draft status" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Publish a bounty draft to the events contract", - "tags": ["Organization Bounties - Escrow (v2)"] + "summary": "Assign a dispute to a staff handler, or unassign (Tier 1)", + "tags": ["Admin v2 - Disputes"] } }, - "/api/organizations/{organizationId}/bounties/{id}/escrow/cancel": { + "/api/admin/v2/disputes/{id}/note": { "post": { - "description": "Builds a cancel_event contract op. The contract refunds partner contributions first (in full), then the owner residual; or pro-rates partners if escrow is short. On settle, BountyEscrowSubscriber moves the bounty to CANCELLED and stamps the cancel audit columns.", - "operationId": "OrganizationBountiesEscrowController_cancel", + "operationId": "DisputesController_note", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "example": "org_1234567890", - "type": "string" - } - }, { "name": "id", "required": true, "in": "path", - "description": "Bounty id", "schema": { "type": "string" } @@ -20026,7 +19978,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CancelBountyEscrowDto" + "$ref": "#/components/schemas/NoteDisputeDto" } } } @@ -20037,7 +19989,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/DisputeNoteResponseDto" } } } @@ -20045,32 +19997,21 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Cancel an active bounty", - "tags": ["Organization Bounties - Escrow (v2)"] + "summary": "Add an internal note to a dispute (Tier 1)", + "tags": ["Admin v2 - Disputes"] } }, - "/api/organizations/{organizationId}/bounties/{id}/escrow/select-winners": { + "/api/admin/v2/disputes/{id}/resolve": { "post": { - "description": "Builds a select_winners contract op that pays out per the on-chain winner_distribution and bumps each winner's profile credits / reputation / earnings. On settle, BountyEscrowSubscriber moves the bounty to COMPLETED and marks the winning BountySubmission rows accepted with the reward tx hash.", - "operationId": "OrganizationBountiesEscrowController_selectWinners", + "operationId": "DisputesController_resolve", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "example": "org_1234567890", - "type": "string" - } - }, { "name": "id", "required": true, "in": "path", - "description": "Bounty id", "schema": { "type": "string" } @@ -20081,7 +20022,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SelectBountyWinnersDto" + "$ref": "#/components/schemas/ResolveDisputeDto" } } } @@ -20092,7 +20033,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/DisputeActionResponseDto" } } } @@ -20100,39 +20041,21 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Select winners for a bounty", - "tags": ["Organization Bounties - Escrow (v2)"] + "summary": "Resolve a dispute with an outcome (Tier 2: requires step-up)", + "tags": ["Admin v2 - Disputes"] } }, - "/api/organizations/{organizationId}/bounties/{id}/escrow/ops/{opRowId}/submit-signed": { + "/api/admin/v2/disputes/{id}/escalate": { "post": { - "operationId": "OrganizationBountiesEscrowController_submitSigned", + "operationId": "DisputesController_escalate", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - }, { "name": "id", "required": true, "in": "path", - "description": "Bounty id", - "schema": { - "type": "string" - } - }, - { - "name": "opRowId", - "required": true, - "in": "path", - "description": "EscrowOp uuid", "schema": { "type": "string" } @@ -20143,7 +20066,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountySubmitSignedXdrDto" + "$ref": "#/components/schemas/EscalateDisputeDto" } } } @@ -20154,7 +20077,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/DisputeActionResponseDto" } } } @@ -20162,39 +20085,62 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Submit signed XDR for a previously-built bounty escrow op", - "tags": ["Organization Bounties - Escrow (v2)"] + "summary": "Escalate a dispute to arbitration (Tier 2: requires step-up)", + "tags": ["Admin v2 - Disputes"] } }, - "/api/organizations/{organizationId}/bounties/{id}/escrow/ops/{opRowId}": { + "/api/admin/v2/escrow": { "get": { - "operationId": "OrganizationBountiesEscrowController_getOp", + "operationId": "EscrowController_list", "parameters": [ { - "name": "organizationId", - "required": true, - "in": "path", + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", "schema": { "type": "string" } }, { - "name": "id", - "required": true, - "in": "path", - "description": "Bounty id", + "name": "dir", + "required": false, + "in": "query", "schema": { - "type": "string" + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] } }, { - "name": "opRowId", - "required": true, - "in": "path", - "description": "EscrowOp uuid", + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, + "type": "number" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Match against the on-chain reference (hash or address)", "schema": { "type": "string" } @@ -20206,7 +20152,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/PaginatedMoneyDto" } } } @@ -20214,34 +20160,57 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Read the current state of a bounty escrow op", - "tags": ["Organization Bounties - Escrow (v2)"] + "summary": "List escrow transactions (paginated, searchable)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{id}/escrow/apply": { - "post": { - "description": "Builds an apply_to_bounty contract op. EXTERNAL returns unsigned XDR; MANAGED signs and submits. The contract charges the bounty's application_credit_cost via the profile contract on settle.", - "operationId": "BountyParticipantEscrowController_apply", + "/api/admin/v2/escrow/requests": { + "get": { + "operationId": "EscrowController_listRequests", "parameters": [ { - "name": "id", - "required": true, - "in": "path", - "description": "Bounty id", + "name": "status", + "required": false, + "in": "query", + "description": "Filter to a single request status", "schema": { - "type": "string" + "type": "string", + "enum": ["PROPOSED", "APPROVED", "REJECTED", "EXECUTED"] + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EscrowRequestListResponseDto" + } + } } } + }, + "security": [ + { + "JWT-auth": [] + } ], + "summary": "List escrow release/refund requests (maker-checker)", + "tags": ["Admin v2 - Money"] + }, + "post": { + "operationId": "EscrowController_propose", + "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ApplyBountyDto" + "$ref": "#/components/schemas/ProposeEscrowRequestDto" } } } @@ -20252,7 +20221,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/EscrowRequestDto" } } } @@ -20260,23 +20229,21 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Apply to a bounty", - "tags": ["Bounties - Participant Escrow (v2)"] + "summary": "Propose an escrow release/refund (Tier 3: step-up)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{id}/escrow/withdraw-application": { + "/api/admin/v2/escrow/requests/{id}/decision": { "post": { - "description": "Builds a withdraw_application contract op. Contract refunds half the application_credit_cost via the profile contract on settle.", - "operationId": "BountyParticipantEscrowController_withdrawApplication", + "operationId": "EscrowController_decide", "parameters": [ { "name": "id", "required": true, "in": "path", - "description": "Bounty id", "schema": { "type": "string" } @@ -20287,7 +20254,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WithdrawApplicationDto" + "$ref": "#/components/schemas/DecideEscrowRequestDto" } } } @@ -20298,7 +20265,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/EscrowRequestDto" } } } @@ -20306,23 +20273,21 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Withdraw a bounty application", - "tags": ["Bounties - Participant Escrow (v2)"] + "summary": "Approve or reject a request (Tier 3: step-up, maker-checker)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{id}/escrow/submit": { + "/api/admin/v2/escrow/requests/{id}/execute": { "post": { - "description": "Builds a submit contract op. Requires the applicant's prior apply_to_bounty to be in active status (contract enforces; the service pre-checks for a cleaner 4xx).", - "operationId": "BountyParticipantEscrowController_submit", + "operationId": "EscrowController_execute", "parameters": [ { "name": "id", "required": true, "in": "path", - "description": "Bounty id", "schema": { "type": "string" } @@ -20333,7 +20298,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubmitBountyDto" + "$ref": "#/components/schemas/ExecuteEscrowRequestDto" } } } @@ -20344,7 +20309,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/EscrowRequestDto" } } } @@ -20352,44 +20317,74 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Submit work for a bounty", - "tags": ["Bounties - Participant Escrow (v2)"] + "summary": "Record an approved request as executed (Tier 3: step-up)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{id}/escrow/withdraw-submission": { - "post": { - "operationId": "BountyParticipantEscrowController_withdrawSubmission", + "/api/admin/v2/payouts": { + "get": { + "operationId": "PayoutsController_list", "parameters": [ { - "name": "id", - "required": true, - "in": "path", - "description": "Bounty id", + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", "schema": { "type": "string" } - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WithdrawSubmissionDto" - } + }, + { + "name": "dir", + "required": false, + "in": "query", + "schema": { + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, + "type": "number" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Match against the on-chain reference (hash or address)", + "schema": { + "type": "string" } } - }, + ], "responses": { "200": { "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/PaginatedMoneyDto" } } } @@ -20397,34 +20392,63 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Withdraw a bounty submission anchor", - "tags": ["Bounties - Participant Escrow (v2)"] + "summary": "List platform payouts (paginated, searchable)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{id}/escrow/contribute": { - "post": { - "description": "Builds an add_funds contract op signed by the caller. Contract enforces a 10 USDC minimum. Anyone with a funded wallet can contribute; this v1 surface requires Boundless auth, so multiple top-ups from the same wallet are allowed (one row per attempt).", - "operationId": "BountyParticipantEscrowController_contribute", + "/api/admin/v2/payouts/requests": { + "get": { + "operationId": "PayoutsController_listRequests", "parameters": [ { - "name": "id", - "required": true, - "in": "path", - "description": "Bounty id", + "name": "status", + "required": false, + "in": "query", + "description": "Filter to a single request status", "schema": { - "type": "string" + "type": "string", + "enum": [ + "PROPOSED", + "APPROVED", + "AWAITING_SIGNATURE", + "REJECTED", + "EXECUTED" + ] + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayoutRequestListResponseDto" + } + } } } + }, + "security": [ + { + "JWT-auth": [] + } ], + "summary": "List payout requests (maker-checker)", + "tags": ["Admin v2 - Money"] + }, + "post": { + "operationId": "PayoutsController_propose", + "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContributeBountyDto" + "$ref": "#/components/schemas/ProposePayoutRequestDto" } } } @@ -20435,7 +20459,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/PayoutRequestDto" } } } @@ -20443,31 +20467,21 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Contribute funds to a bounty pool", - "tags": ["Bounties - Participant Escrow (v2)"] + "summary": "Propose a payout (Tier 3: step-up)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{id}/escrow/ops/{opRowId}/submit-signed": { + "/api/admin/v2/payouts/requests/{id}/decision": { "post": { - "operationId": "BountyParticipantEscrowController_submitSigned", + "operationId": "PayoutsController_decide", "parameters": [ { "name": "id", "required": true, "in": "path", - "description": "Bounty id", - "schema": { - "type": "string" - } - }, - { - "name": "opRowId", - "required": true, - "in": "path", - "description": "EscrowOp uuid", "schema": { "type": "string" } @@ -20478,7 +20492,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountySubmitSignedXdrDto" + "$ref": "#/components/schemas/DecidePayoutRequestDto" } } } @@ -20489,7 +20503,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/PayoutRequestDto" } } } @@ -20497,31 +20511,21 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Submit signed XDR for a previously-built participant op", - "tags": ["Bounties - Participant Escrow (v2)"] + "summary": "Approve or reject a payout request (Tier 3: step-up, maker-checker)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{id}/escrow/ops/{opRowId}": { - "get": { - "operationId": "BountyParticipantEscrowController_getOp", + "/api/admin/v2/payouts/requests/{id}/build-xdr": { + "post": { + "operationId": "PayoutsController_buildXdr", "parameters": [ { "name": "id", "required": true, "in": "path", - "description": "Bounty id", - "schema": { - "type": "string" - } - }, - { - "name": "opRowId", - "required": true, - "in": "path", - "description": "EscrowOp uuid", "schema": { "type": "string" } @@ -20533,7 +20537,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyEscrowOpResponseDto" + "$ref": "#/components/schemas/BuildXdrResponseDto" } } } @@ -20541,19 +20545,19 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Read the state of a participant op", - "tags": ["Bounties - Participant Escrow (v2)"] + "summary": "Build the unsigned payout XDR for offline signing (Tier 3: step-up)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{bountyId}/v2/applications": { + "/api/admin/v2/payouts/requests/{id}/submit-signed": { "post": { - "operationId": "BountyApplicationController_create", + "operationId": "PayoutsController_submitSigned", "parameters": [ { - "name": "bountyId", + "name": "id", "required": true, "in": "path", "schema": { @@ -20566,31 +20570,38 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateBountyApplicationDto" + "$ref": "#/components/schemas/SubmitPayoutSignedXdrDto" } } } }, "responses": { - "201": { - "description": "" + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayoutRequestDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Submit an application for a application bounty", - "tags": ["Bounty v2 - Applications"] + "summary": "Submit the offline-signed payout XDR; verifies + broadcasts (Tier 3: step-up)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{bountyId}/v2/applications/me": { - "get": { - "operationId": "BountyApplicationController_getMine", + "/api/admin/v2/payouts/requests/{id}/execute": { + "post": { + "operationId": "PayoutsController_execute", "parameters": [ { - "name": "bountyId", + "name": "id", "required": true, "in": "path", "schema": { @@ -20598,77 +20609,161 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutePayoutRequestDto" + } + } + } + }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PayoutRequestDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Read the caller's application for this bounty", - "tags": ["Bounty v2 - Applications"] + "summary": "Fallback: record a payout signed + broadcast off-platform (Tier 3: step-up)", + "tags": ["Admin v2 - Money"] } }, - "/api/bounties/{bountyId}/v2/applications/{appId}": { - "patch": { - "operationId": "BountyApplicationController_edit", + "/api/admin/v2/content": { + "get": { + "operationId": "ContentController_list", "parameters": [ { - "name": "bountyId", - "required": true, - "in": "path", + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", "schema": { "type": "string" } }, { - "name": "appId", - "required": true, - "in": "path", - "schema": { + "name": "dir", + "required": false, + "in": "query", + "schema": { + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, + "type": "number" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Match against the post title or slug", + "schema": { "type": "string" } + }, + { + "name": "archived", + "required": false, + "in": "query", + "description": "Show archived (soft-deleted) posts instead of active ones.", + "schema": { + "default": false, + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedContentDto" + } + } + } + } + }, + "security": [ + { + "JWT-auth": [] } ], + "summary": "List blog posts (paginated, searchable; archived via ?archived)", + "tags": ["Admin v2 - Content"] + }, + "post": { + "operationId": "ContentController_create", + "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EditBountyApplicationDto" + "$ref": "#/components/schemas/CreateBlogPostDto" } } } }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContentMutationResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Edit a SUBMITTED application (before shortlist)", - "tags": ["Bounty v2 - Applications"] - }, - "delete": { - "operationId": "BountyApplicationController_withdraw", + "summary": "Create a blog post (MDX body) (Tier 1)", + "tags": ["Admin v2 - Content"] + } + }, + "/api/admin/v2/content/{id}": { + "get": { + "operationId": "ContentController_getById", "parameters": [ { - "name": "bountyId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - }, - { - "name": "appId", + "name": "id", "required": true, "in": "path", "schema": { @@ -20678,73 +20773,73 @@ ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminContentDetailDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Withdraw a SUBMITTED application", - "tags": ["Bounty v2 - Applications"] - } - }, - "/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications": { - "get": { - "operationId": "OrganizationBountyShortlistController_list", + "summary": "Get one post (full body + metadata, for editing)", + "tags": ["Admin v2 - Content"] + }, + "patch": { + "operationId": "ContentController_update", "parameters": [ { - "name": "bountyId", + "name": "id", "required": true, "in": "path", "schema": { "type": "string" } - }, - { - "name": "status", - "required": false, - "in": "query", - "description": "Filter by application status", - "schema": { - "enum": [ - "SUBMITTED", - "SHORTLISTED", - "SELECTED", - "DECLINED", - "WITHDRAWN" - ], - "type": "string" - } - }, - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": {} } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateContentDto" + } + } + } + }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContentMutationResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "List applications on a bounty", - "tags": ["Bounty v2 - Organizer Shortlist"] + "summary": "Update a blog post (Tier 1)", + "tags": ["Admin v2 - Content"] } }, - "/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/select": { - "post": { - "operationId": "OrganizationBountyShortlistController_selectForSingleClaim", + "/api/admin/v2/content/{id}/publish": { + "patch": { + "operationId": "ContentController_setPublished", "parameters": [ { - "name": "bountyId", + "name": "id", "required": true, "in": "path", "schema": { @@ -20757,31 +20852,38 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SelectForSingleClaimDto" + "$ref": "#/components/schemas/SetPublishedDto" } } } }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContentActionResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Select a single application (application (light) single claim / application (full) single claim)", - "tags": ["Bounty v2 - Organizer Shortlist"] + "summary": "Publish or unpublish a post (Tier 1)", + "tags": ["Admin v2 - Content"] } }, - "/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/shortlist": { + "/api/admin/v2/content/{id}/archive": { "post": { - "operationId": "OrganizationBountyShortlistController_createShortlist", + "operationId": "ContentController_archive", "parameters": [ { - "name": "bountyId", + "name": "id", "required": true, "in": "path", "schema": { @@ -20794,31 +20896,38 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateShortlistDto" + "$ref": "#/components/schemas/ArchiveContentDto" } } } }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContentActionResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Approve a shortlist (application (light) competition / application (full) competition)", - "tags": ["Bounty v2 - Organizer Shortlist"] + "summary": "Archive (soft-delete) a post (Tier 2: requires step-up)", + "tags": ["Admin v2 - Content"] } }, - "/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/{appId}/decline": { + "/api/admin/v2/content/{id}/restore": { "post": { - "operationId": "OrganizationBountyShortlistController_decline", + "operationId": "ContentController_restore", "parameters": [ { - "name": "appId", + "name": "id", "required": true, "in": "path", "schema": { @@ -20826,36 +20935,132 @@ } } ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContentActionResponseDto" + } + } + } + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Restore an archived post (Tier 1)", + "tags": ["Admin v2 - Content"] + } + }, + "/api/admin/v2/crowdfunding/review-checklist": { + "get": { + "operationId": "CrowdfundingChecklistController_list", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChecklistItemDto" + } + } + } + } + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "List active review checklist items (display order)", + "tags": ["Admin v2 - Crowdfunding Review Checklist"] + }, + "post": { + "operationId": "CrowdfundingChecklistController_create", + "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeclineApplicationDto" + "$ref": "#/components/schemas/CreateChecklistItemDto" } } } }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChecklistItemDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Decline an application with optional reason", - "tags": ["Bounty v2 - Organizer Shortlist"] + "summary": "Add a checklist item (super_admin / operations)", + "tags": ["Admin v2 - Crowdfunding Review Checklist"] } }, - "/api/bounties/{bountyId}/v2/competition/join": { + "/api/admin/v2/crowdfunding/review-checklist/reorder": { "post": { - "operationId": "BountyCompetitionJoinController_join", + "operationId": "CrowdfundingChecklistController_reorder", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReorderChecklistDto" + } + } + } + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChecklistItemDto" + } + } + } + } + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Reorder checklist items (super_admin / operations)", + "tags": ["Admin v2 - Crowdfunding Review Checklist"] + } + }, + "/api/admin/v2/crowdfunding/review-checklist/{itemId}": { + "patch": { + "operationId": "CrowdfundingChecklistController_update", "parameters": [ { - "name": "bountyId", + "name": "itemId", "required": true, "in": "path", "schema": { @@ -20868,29 +21073,36 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/JoinCompetitionDto" + "$ref": "#/components/schemas/UpdateChecklistItemDto" } } } }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChecklistItemDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Join an open competition bounty", - "tags": ["Bounty v2 - open competition"] + "summary": "Edit a checklist item (super_admin / operations)", + "tags": ["Admin v2 - Crowdfunding Review Checklist"] }, "delete": { - "operationId": "BountyCompetitionJoinController_leave", + "operationId": "CrowdfundingChecklistController_archive", "parameters": [ { - "name": "bountyId", + "name": "itemId", "required": true, "in": "path", "schema": { @@ -20898,39 +21110,50 @@ } } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/JoinCompetitionDto" - } - } - } - }, "responses": { - "200": { + "204": { "description": "" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Leave an open competition before submitting", - "tags": ["Bounty v2 - open competition"] + "summary": "Archive a checklist item (super_admin / operations)", + "tags": ["Admin v2 - Crowdfunding Review Checklist"] } }, - "/api/bounties": { + "/api/admin/v2/crowdfunding": { "get": { - "operationId": "BountyPublicController_list", + "operationId": "CrowdfundingController_list", "parameters": [ + { + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", + "schema": { + "type": "string" + } + }, + { + "name": "dir", + "required": false, + "in": "query", + "schema": { + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] + } + }, { "name": "page", "required": false, "in": "query", "schema": { + "minimum": 1, + "default": 1, "type": "number" } }, @@ -20939,6 +21162,9 @@ "required": false, "in": "query", "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, "type": "number" } }, @@ -20946,19 +21172,34 @@ "name": "search", "required": false, "in": "query", - "schema": {} + "description": "Match against the project title", + "schema": { + "type": "string" + } }, { "name": "status", "required": false, "in": "query", - "schema": {} - }, - { - "name": "organizationId", - "required": false, - "in": "query", - "schema": {} + "description": "v2Status filter. Omit to list the full lifecycle (all statuses).", + "schema": { + "type": "string", + "enum": [ + "DRAFT", + "SUBMITTED_FOR_REVIEW", + "REVIEW_REJECTED", + "REVIEW_APPROVED", + "VOTING", + "VOTE_FAILED", + "VOTE_PASSED", + "PUBLISHING", + "FUNDING", + "COMPLETED", + "CANCELLED", + "PAUSED", + "FAILED" + ] + } } ], "responses": { @@ -20967,19 +21208,24 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyPublicListDto" + "$ref": "#/components/schemas/PaginatedCrowdfundingDto" } } } } }, - "summary": "Public bounty marketplace list", - "tags": ["bounties"] + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "List crowdfunding campaigns (defaults to the review queue)", + "tags": ["Admin v2 - Crowdfunding"] } }, - "/api/bounties/{id}": { + "/api/admin/v2/crowdfunding/{id}": { "get": { - "operationId": "BountyPublicController_findOne", + "operationId": "CrowdfundingController_getById", "parameters": [ { "name": "id", @@ -20996,35 +21242,29 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/BountyPublicDto" + "$ref": "#/components/schemas/AdminCrowdfundingDetailDto" } } } } }, - "summary": "Public bounty detail", - "tags": ["bounties"] + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Get one campaign with its review history", + "tags": ["Admin v2 - Crowdfunding"] } }, - "/api/organizations/{organizationId}/grants/{id}/escrow/publish": { + "/api/admin/v2/crowdfunding/{id}/approve": { "post": { - "description": "Validates the draft, transitions to DRAFT_AWAITING_FUNDING, and returns an unsigned XDR (EXTERNAL) or the op in PENDING_CONFIRM (MANAGED). Reconciliation transitions the grant to OPEN on success.", - "operationId": "OrganizationGrantsEscrowController_publish", + "operationId": "CrowdfundingController_approve", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "example": "org_1234567890", - "type": "string" - } - }, { "name": "id", "required": true, "in": "path", - "description": "Grant id", "schema": { "type": "string" } @@ -21035,7 +21275,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PublishGrantEscrowDto" + "$ref": "#/components/schemas/ApproveCampaignDto" } } } @@ -21046,36 +21286,25 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantEscrowOpResponseDto" + "$ref": "#/components/schemas/CrowdfundingActionResponseDto" } } } - }, - "400": { - "description": "Draft not in DRAFT status" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Publish a grant draft to the events contract", - "tags": ["Organization Grants - Escrow (v2)"] + "summary": "Approve a submitted campaign; assigns a reviewer (Tier 2: step-up)", + "tags": ["Admin v2 - Crowdfunding"] } }, - "/api/organizations/{organizationId}/grants/{id}/escrow/cancel": { + "/api/admin/v2/crowdfunding/{id}/reject": { "post": { - "operationId": "OrganizationGrantsEscrowController_cancel", + "operationId": "CrowdfundingController_reject", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - }, { "name": "id", "required": true, @@ -21090,7 +21319,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CancelGrantEscrowDto" + "$ref": "#/components/schemas/RejectCampaignDto" } } } @@ -21101,7 +21330,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantEscrowOpResponseDto" + "$ref": "#/components/schemas/CrowdfundingActionResponseDto" } } } @@ -21109,26 +21338,17 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Cancel an active grant", - "tags": ["Organization Grants - Escrow (v2)"] + "summary": "Reject a submitted campaign (Tier 2: step-up)", + "tags": ["Admin v2 - Crowdfunding"] } }, - "/api/organizations/{organizationId}/grants/{id}/escrow/select-winners": { + "/api/admin/v2/crowdfunding/{id}/request-revision": { "post": { - "description": "For Multi release_kind, select_winners records recipients with amount=0 — payouts happen per-milestone via claim_milestone.", - "operationId": "OrganizationGrantsEscrowController_selectWinners", + "operationId": "CrowdfundingController_requestRevision", "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - }, { "name": "id", "required": true, @@ -21143,7 +21363,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SelectGrantWinnersDto" + "$ref": "#/components/schemas/RequestRevisionDto" } } } @@ -21154,7 +21374,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantEscrowOpResponseDto" + "$ref": "#/components/schemas/CrowdfundingActionResponseDto" } } } @@ -21162,41 +21382,48 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Select grant recipients", - "tags": ["Organization Grants - Escrow (v2)"] + "summary": "Send a submitted campaign back for revisions (Tier 1)", + "tags": ["Admin v2 - Crowdfunding"] } }, - "/api/organizations/{organizationId}/grants/{id}/escrow/claim-milestone": { + "/api/admin/v2/access/totp/enroll": { "post": { - "description": "Builds a claim_milestone contract op. Contract pays the per-milestone amount to the recipient and bumps profile credits / reputation / earnings.", - "operationId": "OrganizationGrantsEscrowController_claimMilestone", - "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "type": "string" + "operationId": "SecurityController_enroll", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TotpEnrollResponseDto" + } + } } - }, + } + }, + "security": [ { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } + "JWT-auth": [] } ], + "summary": "Begin TOTP enrollment (returns secret + QR URI)", + "tags": ["Admin v2 - Access"] + } + }, + "/api/admin/v2/access/totp/activate": { + "post": { + "operationId": "SecurityController_activate", + "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ClaimGrantMilestoneDto" + "$ref": "#/components/schemas/TotpCodeDto" } } } @@ -21207,7 +21434,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantEscrowOpResponseDto" + "$ref": "#/components/schemas/OkResponseDto" } } } @@ -21215,48 +21442,23 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Pay out a specific milestone for a recipient", - "tags": ["Organization Grants - Escrow (v2)"] + "summary": "Confirm TOTP enrollment with a code", + "tags": ["Admin v2 - Access"] } }, - "/api/organizations/{organizationId}/grants/{id}/escrow/ops/{opRowId}/submit-signed": { + "/api/admin/v2/access/step-up": { "post": { - "operationId": "OrganizationGrantsEscrowController_submitSigned", - "parameters": [ - { - "name": "organizationId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - }, - { - "name": "id", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - }, - { - "name": "opRowId", - "required": true, - "in": "path", - "schema": { - "type": "string" - } - } - ], + "operationId": "SecurityController_stepUp", + "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantSubmitSignedXdrDto" + "$ref": "#/components/schemas/TotpCodeDto" } } } @@ -21267,7 +21469,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantEscrowOpResponseDto" + "$ref": "#/components/schemas/OkResponseDto" } } } @@ -21275,37 +21477,62 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Submit signed XDR for a grant op", - "tags": ["Organization Grants - Escrow (v2)"] + "summary": "Step up: verify a fresh TOTP code for sensitive actions", + "tags": ["Admin v2 - Access"] } }, - "/api/organizations/{organizationId}/grants/{id}/escrow/ops/{opRowId}": { + "/api/admin/v2/audit": { "get": { - "operationId": "OrganizationGrantsEscrowController_getOp", + "operationId": "AuditController_list", "parameters": [ { - "name": "organizationId", - "required": true, - "in": "path", + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", "schema": { "type": "string" } }, { - "name": "id", - "required": true, - "in": "path", + "name": "dir", + "required": false, + "in": "query", "schema": { - "type": "string" + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] } }, { - "name": "opRowId", - "required": true, - "in": "path", + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, + "type": "number" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Match against the actor email, action, or target id", "schema": { "type": "string" } @@ -21317,7 +21544,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantEscrowOpResponseDto" + "$ref": "#/components/schemas/PaginatedAuditDto" } } } @@ -21325,23 +21552,64 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Read the state of a grant op", - "tags": ["Organization Grants - Escrow (v2)"] + "summary": "List admin audit log entries (paginated, searchable)", + "tags": ["Admin v2 - Audit"] } }, - "/api/grants/{id}/escrow/contribute": { - "post": { - "description": "Open add_funds op. Contract enforces a 10 USDC minimum. Anyone authenticated can contribute; multiple top-ups from the same wallet are allowed (one row per attempt).", - "operationId": "GrantContributeEscrowController_contribute", + "/api/admin/v2/audit/stream": { + "get": { + "operationId": "AuditController_stream", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Live stream of new audit entries (Server-Sent Events)", + "tags": ["Admin v2 - Audit"] + } + }, + "/api/admin/v2/feature-flags": { + "get": { + "operationId": "FeatureFlagsController_list", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FeatureFlagsResponseDto" + } + } + } + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "List feature flags", + "tags": ["Admin v2 - Feature flags"] + } + }, + "/api/admin/v2/feature-flags/{key}": { + "patch": { + "operationId": "FeatureFlagsController_toggle", "parameters": [ { - "name": "id", + "name": "key", "required": true, "in": "path", - "description": "Grant id", "schema": { "type": "string" } @@ -21352,7 +21620,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ContributeGrantDto" + "$ref": "#/components/schemas/ToggleFeatureFlagDto" } } } @@ -21363,7 +21631,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantEscrowOpResponseDto" + "$ref": "#/components/schemas/FeatureFlagDto" } } } @@ -21371,620 +21639,391 @@ }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Contribute funds to a grant pool", - "tags": ["Grants - Contribute (v2)"] + "summary": "Toggle a feature flag (Tier 2: requires step-up)", + "tags": ["Admin v2 - Feature flags"] } }, - "/api/grants": { + "/api/admin/v2/staff": { "get": { - "description": "Public, page-based list of grant programs. Parallel to /bounties and /hackathons. For a multi-pillar feed (Bounty, Hackathon, Grant, Crowdfunding), use /opportunities instead.", - "operationId": "GrantsPublicController_list", - "parameters": [ - { - "name": "status", - "required": false, - "in": "query", - "description": "Pillar-specific status filter (open, closed, in_progress).", - "schema": { - "example": "open", - "type": "string" + "operationId": "StaffController_list", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StaffListResponseDto" + } + } } - }, + } + }, + "security": [ { - "name": "search", - "required": false, - "in": "query", - "description": "Case-insensitive substring match against project title and summary.", - "schema": { - "example": "governance", - "type": "string" - } - }, + "JWT-auth": [] + } + ], + "summary": "List staff members and their roles", + "tags": ["Admin v2 - Access"] + } + }, + "/api/admin/v2/staff/{id}/role": { + "patch": { + "operationId": "StaffController_setRole", + "parameters": [ { - "name": "category", - "required": false, - "in": "query", - "description": "Filter by the underlying project category.", + "name": "id", + "required": true, + "in": "path", "schema": { - "example": "defi", "type": "string" } - }, - { - "name": "page", - "required": false, - "in": "query", - "description": "Page number (1-indexed).", - "schema": { - "minimum": 1, - "default": 1, - "example": 1, - "type": "number" - } - }, - { - "name": "limit", - "required": false, - "in": "query", - "description": "Items per page.", - "schema": { - "minimum": 1, - "maximum": 50, - "default": 20, - "example": 20, - "type": "number" - } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SetRoleDto" + } + } + } + }, "responses": { "200": { - "description": "Grants page", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GrantPublicListResponseDto" + "$ref": "#/components/schemas/StaffListItemDto" } } } } }, - "summary": "List published grants", - "tags": ["Grants"] + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Assign a staff role (Tier 2: requires step-up)", + "tags": ["Admin v2 - Access"] } }, - "/api/opportunities": { + "/api/admin/v2/governance": { "get": { - "description": "Returns a unified, cursor-paginated feed across Bounty, Hackathon, Grant, and Crowdfunding. Pass type= to restrict to one. The cursor is opaque; pass it back as-is to fetch the next page.", - "operationId": "OpportunitiesController_list", + "operationId": "GovernanceController_list", "parameters": [ - { - "name": "type", - "required": false, - "in": "query", - "description": "Which pillar to query. \"all\" fans out across the four adapters; the others restrict to a single adapter.", - "schema": { - "default": "all", - "example": "all", - "type": "string", - "enum": ["all", "bounty", "hackathon", "grant", "crowdfunding"] - } - }, { "name": "status", "required": false, "in": "query", - "description": "Pillar-specific status filter. Adapters match case-insensitively against their own enum and return [] when no value matches.", - "schema": { - "example": "open", - "type": "string" - } - }, - { - "name": "search", - "required": false, - "in": "query", - "description": "Case-insensitive substring match against title and summary across adapters.", - "schema": { - "example": "governance", - "type": "string" - } - }, - { - "name": "tags", - "required": false, - "in": "query", - "description": "Comma-separated tag list. Pillar-aware: bounty has no tag field and returns [] for any tags filter.", - "schema": { - "example": "stellar,defi", - "type": "string" - } - }, - { - "name": "sort", - "required": false, - "in": "query", - "description": "Sort mode. \"deadline\" sorts ascending by the next deadline (NULLS LAST); \"prize_desc\" sorts by reward descending.", + "description": "Filter to a single proposal status", "schema": { - "default": "newest", - "example": "newest", "type": "string", - "enum": ["newest", "deadline", "prize_desc"] - } - }, - { - "name": "cursor", - "required": false, - "in": "query", - "description": "Opaque pagination cursor returned by the previous response. Omit to start from page 1.", - "schema": { - "example": "eyJzb3J0IjoibmV3ZXN0IiwicHJpbWFyeSI6IjIwMjYtMDUtMTVUMDA6MDA6MDAuMDAwWiIsImlkIjoiY2t4eXoxMjMifQ", - "type": "string" - } - }, - { - "name": "limit", - "required": false, - "in": "query", - "description": "Items per page. Capped at 50.", - "schema": { - "minimum": 1, - "maximum": 50, - "default": 12, - "example": 12, - "type": "number" + "enum": ["PROPOSED", "APPROVED", "REJECTED", "EXECUTED"] } } ], "responses": { "200": { - "description": "Opportunities page", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/OpportunityListResponseDto" + "$ref": "#/components/schemas/GovernanceListResponseDto" } } } } }, - "summary": "List opportunities across all pillars", - "tags": ["Opportunities"] - } - }, - "/api/newsletter/subscribe": { + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "List governance proposals (optionally by status)", + "tags": ["Admin v2 - Governance"] + }, "post": { - "description": "Subscribe an email address to the newsletter. Sends a confirmation email (double opt-in). Rate limited to 5 requests per minute.", - "operationId": "NewsletterController_subscribe", + "operationId": "GovernanceController_propose", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubscribeDto" + "$ref": "#/components/schemas/CreateProposalDto" } } } }, "responses": { - "201": { - "description": "Confirmation email sent successfully", + "200": { + "description": "", "content": { "application/json": { "schema": { - "example": { - "message": "Confirmation email sent. Please check your inbox.", - "id": "clx1234567890" - } + "$ref": "#/components/schemas/GovernanceProposalDto" } } } - }, - "400": { - "description": "Invalid tags provided" - }, - "409": { - "description": "Email is already subscribed" - }, - "429": { - "description": "Too many requests — rate limited" } }, - "summary": "Subscribe to the newsletter", - "tags": ["Newsletter"] - } - }, - "/api/newsletter/confirm/{token}": { - "get": { - "description": "Confirm a newsletter subscription via the token sent in the confirmation email. Redirects to the frontend on success.", - "operationId": "NewsletterController_confirmSubscription", - "parameters": [ + "security": [ { - "name": "token", - "required": true, - "in": "path", - "description": "Confirmation token received via email", - "schema": { - "type": "string" - } + "JWT-auth": [] } ], - "responses": { - "302": { - "description": "Redirects to frontend confirmation page" - }, - "400": { - "description": "Confirmation token has expired" - }, - "404": { - "description": "Invalid or expired confirmation token" - } - }, - "summary": "Confirm newsletter subscription", - "tags": ["Newsletter"] + "summary": "Propose a governance action (Tier 4: step-up)", + "tags": ["Admin v2 - Governance"] } }, - "/api/newsletter/unsubscribe/{token}": { - "get": { - "description": "Unsubscribe from the newsletter using the one-click unsubscribe token from emails. Redirects to the frontend.", - "operationId": "NewsletterController_unsubscribeByToken", + "/api/admin/v2/governance/{id}/decision": { + "post": { + "operationId": "GovernanceController_decide", "parameters": [ { - "name": "token", + "name": "id", "required": true, "in": "path", - "description": "Unsubscribe token from the email footer", "schema": { "type": "string" } } ], - "responses": { - "302": { - "description": "Redirects to frontend unsubscribe confirmation page" - }, - "404": { - "description": "Invalid unsubscribe link" - } - }, - "summary": "Unsubscribe by token", - "tags": ["Newsletter"] - } - }, - "/api/newsletter/unsubscribe": { - "post": { - "description": "Legacy unsubscribe endpoint. Unsubscribe a subscriber by their email address.", - "operationId": "NewsletterController_unsubscribe", - "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UnsubscribeDto" + "$ref": "#/components/schemas/DecideProposalDto" } } } }, "responses": { "200": { - "description": "Successfully unsubscribed" - }, - "404": { - "description": "Subscriber not found" - } - }, - "summary": "Unsubscribe by email", - "tags": ["Newsletter"] - } - }, - "/api/newsletter/preferences": { - "patch": { - "description": "Update topic tag preferences for a subscriber. Valid tags: bounties, hackathons, grants, updates.", - "operationId": "NewsletterController_updatePreferences", - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdatePreferencesDto" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GovernanceProposalDto" + } } } } }, - "responses": { - "200": { - "description": "Preferences updated successfully" - }, - "400": { - "description": "Invalid tags provided" - }, - "404": { - "description": "Subscriber not found" + "security": [ + { + "JWT-auth": [] } - }, - "summary": "Update subscription preferences", - "tags": ["Newsletter"] + ], + "summary": "Approve or reject a proposal (Tier 3: step-up, maker-checker)", + "tags": ["Admin v2 - Governance"] } }, - "/api/newsletter/tracking/open/{campaignId}/{subscriberId}": { - "get": { - "description": "Open tracking pixel endpoint. Returns a 1x1 transparent GIF and records the open event. Used in campaign emails.", - "operationId": "NewsletterController_trackOpen", + "/api/admin/v2/governance/{id}/execute": { + "post": { + "operationId": "GovernanceController_execute", "parameters": [ { - "name": "campaignId", - "required": true, - "in": "path", - "description": "Campaign ID", - "schema": { - "type": "string" - } - }, - { - "name": "subscriberId", + "name": "id", "required": true, "in": "path", - "description": "Subscriber ID", "schema": { "type": "string" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecuteProposalDto" + } + } + } + }, "responses": { "200": { - "description": "Returns 1x1 transparent GIF" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GovernanceProposalDto" + } + } + } } }, - "summary": "Track email open", - "tags": ["Newsletter"] - } - }, - "/api/newsletter/tracking/click/{campaignId}/{subscriberId}": { - "get": { - "description": "Click tracking endpoint. Records the click event and redirects the subscriber to the target URL.", - "operationId": "NewsletterController_trackClick", - "parameters": [ - { - "name": "campaignId", - "required": true, - "in": "path", - "description": "Campaign ID", - "schema": { - "type": "string" - } - }, - { - "name": "subscriberId", - "required": true, - "in": "path", - "description": "Subscriber ID", - "schema": { - "type": "string" - } - }, + "security": [ { - "name": "url", - "required": true, - "in": "query", - "description": "Target URL to redirect to after tracking", - "schema": { - "example": "https://www.boundlessfi.xyz/hackathons", - "type": "string" - } + "JWT-auth": [] } ], - "responses": { - "302": { - "description": "Redirects to the target URL" - } - }, - "summary": "Track email link click", - "tags": ["Newsletter"] + "summary": "Record an approved proposal as executed (Tier 4: step-up)", + "tags": ["Admin v2 - Governance"] } }, - "/api/newsletter/subscribers": { + "/api/admin/v2/kyc": { "get": { - "description": "Get a paginated list of newsletter subscribers with optional filters by status, source, tags, and search.", - "operationId": "NewsletterController_getSubscribers", + "operationId": "KycController_list", "parameters": [ { - "name": "status", + "name": "sort", "required": false, "in": "query", - "description": "Filter by status", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", "schema": { - "enum": ["active", "pending", "unsubscribed", "bounced"], "type": "string" } }, { - "name": "source", + "name": "dir", "required": false, "in": "query", - "description": "Filter by source", "schema": { - "example": "website", - "type": "string" + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] } }, { - "name": "tags", + "name": "status", "required": false, "in": "query", - "description": "Filter by tags (comma-separated)", + "description": "Filter to one KYC state. Omit for all KYC-engaged users.", "schema": { - "example": "updates,hackathons", - "type": "string" + "type": "string", + "enum": ["in_review", "approved", "declined"] } }, { - "name": "search", + "name": "page", "required": false, "in": "query", - "description": "Search by email or name", "schema": { - "example": "john", - "type": "string" + "minimum": 1, + "default": 1, + "type": "number" } }, { - "name": "page", + "name": "limit", "required": false, "in": "query", - "description": "Page number (default: 1)", "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, "type": "number" } }, { - "name": "limit", + "name": "search", "required": false, "in": "query", - "description": "Items per page (default: 50)", + "description": "Match against the user name or email", "schema": { - "type": "number" + "type": "string" } } ], "responses": { "200": { - "description": "Subscribers retrieved successfully", + "description": "", "content": { "application/json": { "schema": { - "example": { - "subscribers": [], - "total": 0, - "page": 1, - "limit": 50 - } + "$ref": "#/components/schemas/PaginatedKycDto" } } } - }, - "401": { - "description": "Unauthorized" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "List newsletter subscribers", - "tags": ["Newsletter"] + "summary": "List identity-verification (KYC) records (paginated, filterable)", + "tags": ["Admin v2 - KYC"] } }, - "/api/newsletter/stats": { + "/api/admin/v2/kyc/connection": { "get": { - "description": "Get subscriber counts by status, subscription sources, and campaign statistics (sent, opens, clicks).", - "operationId": "NewsletterController_getStats", + "operationId": "KycController_connection", "parameters": [], "responses": { "200": { - "description": "Statistics retrieved successfully", + "description": "", "content": { "application/json": { "schema": { - "example": { - "subscribers": { - "total": 100, - "active": 80, - "pending": 10, - "unsubscribed": 8, - "bounced": 2 - }, - "bySource": [ - { - "source": "website", - "count": 60 - } - ], - "campaigns": { - "total": 5, - "totalSent": 400, - "totalOpens": 200, - "totalClicks": 50 - } - } + "$ref": "#/components/schemas/DiditConnectionDto" } } } - }, - "401": { - "description": "Unauthorized" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Get newsletter statistics", - "tags": ["Newsletter"] + "summary": "Live Didit integration status (config presence)", + "tags": ["Admin v2 - KYC"] } }, - "/api/newsletter/export": { - "get": { - "description": "Download a CSV file of subscribers with optional status and tag filters.", - "operationId": "NewsletterController_exportSubscribers", + "/api/admin/v2/kyc/{userId}/sync": { + "post": { + "operationId": "KycController_sync", "parameters": [ { - "name": "status", - "required": false, - "in": "query", - "description": "Filter by subscriber status", - "schema": { - "enum": ["active", "pending", "unsubscribed", "bounced"], - "type": "string" - } - }, - { - "name": "tags", - "required": false, - "in": "query", - "description": "Filter by tags (comma-separated)", + "name": "userId", + "required": true, + "in": "path", "schema": { - "example": "updates,hackathons", "type": "string" } } ], "responses": { "200": { - "description": "CSV file downloaded", + "description": "", "content": { - "text/csv": {} + "application/json": { + "schema": { + "$ref": "#/components/schemas/KycSyncResponseDto" + } + } } - }, - "401": { - "description": "Unauthorized" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Export subscribers as CSV", - "tags": ["Newsletter"] + "summary": "Pull the latest decision live from Didit and reconcile (Tier 1)", + "tags": ["Admin v2 - KYC"] } }, - "/api/newsletter/subscribers/{id}": { - "delete": { - "description": "Permanently delete a newsletter subscriber by ID.", - "operationId": "NewsletterController_deleteSubscriber", + "/api/admin/v2/kyc/{userId}/retrigger": { + "post": { + "operationId": "KycController_retrigger", "parameters": [ { - "name": "id", + "name": "userId", "required": true, "in": "path", - "description": "Subscriber ID", "schema": { "type": "string" } @@ -21992,77 +22031,110 @@ ], "responses": { "200": { - "description": "Subscriber deleted successfully", + "description": "", "content": { "application/json": { "schema": { - "example": { - "success": true - } + "$ref": "#/components/schemas/KycRetriggerResponseDto" } } } - }, - "401": { - "description": "Unauthorized" - }, - "404": { - "description": "Subscriber not found" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Delete a subscriber", - "tags": ["Newsletter"] + "summary": "Create a fresh Didit verification session for the user (Tier 1)", + "tags": ["Admin v2 - KYC"] } }, - "/api/newsletter/campaigns": { + "/api/admin/v2/kyc/{userId}/override": { "post": { - "description": "Create a new newsletter campaign draft. Use {{name}} placeholder in content for personalization. Target specific subscribers using tags.", - "operationId": "NewsletterController_createCampaign", - "parameters": [], + "operationId": "KycController_override", + "parameters": [ + { + "name": "userId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateNewsletterCampaignDto" + "$ref": "#/components/schemas/KycOverrideDto" } } } }, "responses": { - "201": { - "description": "Campaign created successfully" - }, - "400": { - "description": "Invalid tags provided" - }, - "401": { - "description": "Unauthorized" + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KycOverrideResponseDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Create a new campaign", - "tags": ["Newsletter"] - }, + "summary": "Manually force a KYC decision, overriding Didit (Tier 2: step-up)", + "tags": ["Admin v2 - KYC"] + } + }, + "/api/admin/v2/milestones": { "get": { - "description": "Get a paginated list of newsletter campaigns, ordered by most recent first.", - "operationId": "NewsletterController_getCampaigns", + "operationId": "MilestonesController_list", "parameters": [ + { + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", + "schema": { + "type": "string" + } + }, + { + "name": "dir", + "required": false, + "in": "query", + "schema": { + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] + } + }, + { + "name": "type", + "required": false, + "in": "query", + "description": "Which pillar to list. Defaults to crowdfunding.", + "schema": { + "default": "crowdfunding", + "type": "string", + "enum": ["crowdfunding", "grant"] + } + }, { "name": "page", "required": false, "in": "query", - "description": "Page number (default: 1)", "schema": { + "minimum": 1, + "default": 1, "type": "number" } }, @@ -22070,51 +22142,52 @@ "name": "limit", "required": false, "in": "query", - "description": "Items per page (default: 20)", "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, "type": "number" } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Match against milestone or program title", + "schema": { + "type": "string" + } } ], "responses": { "200": { - "description": "Campaigns retrieved successfully", + "description": "", "content": { "application/json": { "schema": { - "example": { - "campaigns": [], - "total": 0, - "page": 1, - "limit": 20 - } + "$ref": "#/components/schemas/PaginatedMilestonesDto" } } } - }, - "401": { - "description": "Unauthorized" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "List newsletter campaigns", - "tags": ["Newsletter"] + "summary": "List deliverable milestones across a pillar (paginated)", + "tags": ["Admin v2 - Milestones"] } }, - "/api/newsletter/campaigns/{id}": { + "/api/admin/v2/milestones/{id}": { "get": { - "description": "Get detailed information about a specific campaign, including the most recent 100 send logs.", - "operationId": "NewsletterController_getCampaign", + "operationId": "MilestonesController_findOne", "parameters": [ { "name": "id", "required": true, "in": "path", - "description": "Campaign ID", "schema": { "type": "string" } @@ -22122,34 +22195,33 @@ ], "responses": { "200": { - "description": "Campaign details retrieved successfully" - }, - "401": { - "description": "Unauthorized" - }, - "404": { - "description": "Campaign not found" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminMilestoneDetailDto" + } + } + } } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Get campaign details", - "tags": ["Newsletter"] + "summary": "Get full milestone detail for admin review", + "tags": ["Admin v2 - Milestones"] } }, - "/api/newsletter/campaigns/{id}/send": { + "/api/admin/v2/milestones/{id}/approve": { "post": { - "description": "Send a campaign to all matching subscribers. Delivers in batches of 10 with 1-second delays. Cannot re-send an already sent campaign.", - "operationId": "NewsletterController_sendCampaign", + "operationId": "MilestonesController_approve", "parameters": [ { "name": "id", "required": true, "in": "path", - "description": "Campaign ID to send", "schema": { "type": "string" } @@ -22157,45 +22229,58 @@ ], "responses": { "200": { - "description": "Campaign sent successfully", + "description": "", "content": { "application/json": { "schema": { - "example": { - "sentCount": 80, - "failedCount": 2, - "total": 82 - } + "$ref": "#/components/schemas/MilestoneActionResponseDto" } } } - }, - "400": { - "description": "Campaign already sent or currently sending" - }, - "401": { - "description": "Unauthorized" - }, - "404": { - "description": "Campaign not found" } }, "security": [ { - "bearer": [] + "JWT-auth": [] } ], - "summary": "Send a campaign", - "tags": ["Newsletter"] + "summary": "Approve a submitted crowdfunding milestone (Tier 3: step-up)", + "tags": ["Admin v2 - Milestones"] } }, - "/api/admin/queues/dlq/depth": { - "get": { - "operationId": "DlqAdminController_getDepth", - "parameters": [], + "/api/admin/v2/milestones/{id}/reject": { + "post": { + "operationId": "MilestonesController_reject", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RejectMilestoneDto" + } + } + } + }, "responses": { "200": { - "description": "Total parked jobs" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MilestoneActionResponseDto" + } + } + } } }, "security": [ @@ -22203,19 +22288,18 @@ "JWT-auth": [] } ], - "summary": "Current DLQ depth (admin only)", - "tags": ["Admin / Queues"] + "summary": "Reject a submitted crowdfunding milestone (Tier 2: step-up)", + "tags": ["Admin v2 - Milestones"] } }, - "/api/admin/queues/dlq": { - "get": { - "operationId": "DlqAdminController_list", + "/api/admin/v2/milestones/{id}/release/build-xdr": { + "post": { + "operationId": "MilestonesController_buildReleaseXdr", "parameters": [ { - "name": "limit", - "required": false, - "in": "query", - "description": "Max entries to return (1 to 200, default 50)", + "name": "id", + "required": true, + "in": "path", "schema": { "type": "string" } @@ -22223,7 +22307,14 @@ ], "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MilestoneReleaseXdrDto" + } + } + } } }, "security": [ @@ -22231,16 +22322,16 @@ "JWT-auth": [] } ], - "summary": "List parked DLQ entries (admin only)", - "tags": ["Admin / Queues"] + "summary": "Build the unsigned release transaction for an APPROVED milestone (admin signs the envelope offline at the Lab). Tier 3: step-up.", + "tags": ["Admin v2 - Milestones"] } }, - "/api/admin/queues/dlq/{jobId}": { - "get": { - "operationId": "DlqAdminController_getOne", + "/api/admin/v2/milestones/{id}/release/submit-signed": { + "post": { + "operationId": "MilestonesController_submitReleaseSigned", "parameters": [ { - "name": "jobId", + "name": "id", "required": true, "in": "path", "schema": { @@ -22248,9 +22339,26 @@ } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubmitMilestoneReleaseDto" + } + } + } + }, "responses": { "200": { - "description": "" + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MilestoneReleaseResultDto" + } + } + } } }, "security": [ @@ -22258,27 +22366,74 @@ "JWT-auth": [] } ], - "summary": "Fetch a single parked DLQ entry (admin only)", - "tags": ["Admin / Queues"] + "summary": "Submit the admin-signed release transaction for a milestone (verified against the built XDR). Tier 3: step-up.", + "tags": ["Admin v2 - Milestones"] } }, - "/api/admin/queues/dlq/{jobId}/replay": { - "post": { - "description": "The DLQ row is removed on success. Replay uses the original queue's normal retry budget, so a job that died after 3 retries gets another 3 retries on replay.", - "operationId": "DlqAdminController_replay", + "/api/admin/v2/wallets": { + "get": { + "operationId": "WalletsController_list", "parameters": [ { - "name": "jobId", - "required": true, - "in": "path", + "name": "sort", + "required": false, + "in": "query", + "description": "Field to sort by (whitelisted per resource; ignored otherwise)", + "schema": { + "type": "string" + } + }, + { + "name": "dir", + "required": false, + "in": "query", + "schema": { + "default": "desc", + "type": "string", + "enum": ["asc", "desc"] + } + }, + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "default": 1, + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "minimum": 1, + "maximum": 100, + "default": 25, + "type": "number" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Match against the public key (G-address)", "schema": { "type": "string" } } ], "responses": { - "201": { - "description": "" + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaginatedWalletsDto" + } + } + } } }, "security": [ @@ -22286,1171 +22441,1241 @@ "JWT-auth": [] } ], - "summary": "Re-enqueue a parked DLQ entry on its original queue", - "tags": ["Admin / Queues"] + "summary": "List abstracted wallets (paginated, searchable)", + "tags": ["Admin v2 - Wallets"] } }, - "/api/auth/sign-in/social": { - "post": { - "tags": ["Default"], - "description": "Sign in with a social provider", - "operationId": "socialSignIn", - "security": [ - { - "bearerAuth": [] - } - ], + "/api/prices": { + "get": { + "description": "Returns per-unit USD prices for XLM, USDC, EURC and USDGLO. Resolved from the Reflector on-chain oracle, with CoinGecko and stablecoin-peg fallbacks. Cached for 5 minutes (matches Reflector update cadence).", + "operationId": "PricesController_getAll", "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "callbackURL": { - "type": ["string", "null"], - "description": "Callback URL to redirect to after the user has signed in" - }, - "newUserCallbackURL": { - "type": ["string", "null"] - }, - "errorCallbackURL": { - "type": ["string", "null"], - "description": "Callback URL to redirect to if an error happens" - }, - "provider": { - "type": "string" - }, - "disableRedirect": { - "type": ["boolean", "null"], - "description": "Disable automatic redirection to the provider. Useful for handling the redirection yourself" - }, - "idToken": { - "type": ["object", "null"], - "properties": { - "token": { - "type": "string", - "description": "ID token from the provider" - }, - "nonce": { - "type": ["string", "null"], - "description": "Nonce used to generate the token" - }, - "accessToken": { - "type": ["string", "null"], - "description": "Access token from the provider" - }, - "refreshToken": { - "type": ["string", "null"], - "description": "Refresh token from the provider" - }, - "expiresAt": { - "type": ["number", "null"], - "description": "Expiry date of the token" - } - }, - "required": ["token"] - }, - "scopes": { - "type": ["array", "null"], - "description": "Array of scopes to request from the provider. This will override the default scopes passed." - }, - "requestSignUp": { - "type": ["boolean", "null"], - "description": "Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider" - }, - "loginHint": { - "type": ["string", "null"], - "description": "The login hint to use for the authorization code request" - }, - "additionalData": { - "type": ["string", "null"] + "responses": { + "200": { + "description": "Map of asset symbol → USD price as a decimal string (6 dp).", + "content": { + "application/json": { + "schema": { + "example": { + "XLM": "0.117800", + "USDC": "1.000000", + "EURC": "1.080000", + "USDGLO": "1.000000" } - }, - "required": ["provider"] + } } } } }, + "summary": "Get USD prices for all supported assets", + "tags": ["prices"] + } + }, + "/api/prices/debug": { + "get": { + "description": "Bypasses the cache and pings Reflector + CoinGecko for every supported asset. Returns what each provider returned alongside which one the resolution chain would have picked. Use to verify both price paths are live.", + "operationId": "PricesController_getDebug", + "parameters": [], "responses": { "200": { - "description": "Success - Returns either session details or redirect URL", + "description": "Per-asset debug info. `source` is which provider won the resolution chain.", "content": { "application/json": { "schema": { - "type": "object", - "description": "Session response when idToken is provided", - "properties": { - "token": { - "type": "string" - }, - "user": { - "type": "object", - "$ref": "#/components/schemas/User" - }, - "url": { - "type": "string" + "example": { + "XLM": { + "resolved": "0.117800", + "source": "reflector", + "providers": { + "reflector": "0.117800", + "coingecko": "0.117850", + "stablecoinFallback": null + } }, - "redirect": { - "type": "boolean", - "enum": [false] - } - }, - "required": ["redirect", "token", "user"] - } - } - } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" + "USDC": { + "resolved": "1.000000", + "source": "reflector", + "providers": { + "reflector": "1.000000", + "coingecko": "1.000000", + "stablecoinFallback": "1.0000" + } } } } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "summary": "Per-provider price resolution (diagnostic)", + "tags": ["prices"] } }, - "/api/auth/get-session": { + "/api/prices/{symbol}": { "get": { - "tags": ["Default"], - "description": "Get the current session", - "operationId": "getSession", - "security": [ + "description": "Convenience lookup — internally reads from the same cached map as the list endpoint.", + "operationId": "PricesController_getOne", + "parameters": [ { - "bearerAuth": [] + "name": "symbol", + "required": true, + "in": "path", + "description": "Asset ticker (case-insensitive).", + "schema": { + "enum": ["XLM", "USDC", "EURC", "USDGLO"], + "type": "string" + } } ], - "parameters": [], "responses": { "200": { - "description": "Success", + "description": "USD price as a decimal string (6 dp).", "content": { "application/json": { "schema": { - "type": "object", - "nullable": true, - "properties": { - "session": { - "$ref": "#/components/schemas/Session" - }, - "user": { - "$ref": "#/components/schemas/User" - } - }, - "required": ["session", "user"] + "example": "0.117800" } } } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." } - } + }, + "summary": "Get USD price for a single asset", + "tags": ["prices"] } }, - "/api/auth/sign-out": { + "/api/projects/drafts": { "post": { - "tags": ["Default"], - "description": "Sign out the current user", - "operationId": "signOut", - "security": [ - { - "bearerAuth": [] - } - ], + "operationId": "ProjectsController_createDraft", "parameters": [], "requestBody": { + "required": true, + "description": "Full payload for the stepped draft creation", "content": { "application/json": { "schema": { - "type": "object", - "properties": {} - } - } - } - }, - "responses": { - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - } - } - } - } - } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" + "type": "object" + }, + "examples": { + "campaign": { + "value": { + "title": "DeFi Lending Protocol", + "tagline": "Scalable liquidity", + "category": "DeFi", + "description": "A Stellar-native DeFi lending protocol that enables users to deposit assets and earn interest with transparent on-chain accounting.", + "summary": "Lending with transparent on-chain accounting", + "vision": "We aim to make lending safer and more scalable by improving collateral efficiency and risk modeling.", + "details": "Full technical and product details (markdown supported).", + "banner": "https://example.com/banner.png", + "logo": "https://example.com/logo.png", + "githubUrl": "https://github.com/example/defi-lending", + "gitlabUrl": "https://gitlab.com/example/defi-lending", + "bitbucketUrl": "https://bitbucket.org/example/defi-lending", + "projectWebsite": "https://defi-lending.example.com", + "demoVideo": "https://example.com/demo.mp4", + "whitepaperUrl": "https://example.com/whitepaper.pdf", + "pitchVideoUrl": "https://example.com/pitch.mp4", + "socialLinks": { + "twitter": "https://twitter.com/example", + "discord": "https://discord.gg/example" + }, + "contact": { + "primary": "@alex123", + "backup": "alex_doe#1234" + }, + "tags": ["Soroban", "TypeScript", "DeFi"], + "draftData": { + "isCampaign": true, + "campaign": { + "title": "DeFi Lending Protocol Campaign", + "logo": "https://example.com/logo.png", + "vision": "Build, ship, and deliver measurable milestones.", + "banner": "https://example.com/banner.png", + "category": "DeFi", + "details": "Funding request and milestone plan for the lending protocol.", + "fundingAmount": 15000, + "githubUrl": "https://github.com/example/defi-lending", + "gitlabUrl": "https://gitlab.com/example/defi-lending", + "bitbucketUrl": "https://bitbucket.org/example/defi-lending", + "projectWebsite": "https://defi-lending.example.com", + "demoVideo": "https://example.com/demo.mp4", + "milestones": [ + { + "title": "Milestone 1", + "description": "Core lending vault + basic UI.", + "deliverable": "Deploy vault contracts + initial product UI.", + "fundingPercentage": 50, + "amount": 7500, + "expectedDeliveryDate": "2026-04-01T00:00:00.000Z", + "successCriteria": "Contracts deployed and UI shipped.", + "orderIndex": 0 + }, + { + "title": "Milestone 2", + "description": "Risk modeling improvements + analytics.", + "deliverable": "Add risk model and dashboard metrics.", + "fundingPercentage": 50, + "amount": 7500, + "expectedDeliveryDate": "2026-05-01T00:00:00.000Z", + "successCriteria": "Risk model live and dashboards updated.", + "orderIndex": 1 + } + ], + "team": [ + { + "name": "John Doe", + "role": "Lead Developer", + "email": "john@example.com", + "linkedin": "https://linkedin.com/in/johndoe", + "twitter": "https://twitter.com/johndoe" + } + ], + "contact": { + "primary": "@alex123", + "backup": "alex_doe#1234" + }, + "socialLinks": [ + { + "platform": "twitter", + "url": "https://twitter.com/example" + }, + { + "platform": "discord", + "url": "https://discord.gg/example" + } + ] + } } } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" + }, + "nonCampaign": { + "value": { + "title": "NFT Marketplace", + "tagline": "Creator focused", + "category": "NFT", + "description": "A creator-first NFT marketplace for Stellar projects with curated discovery and transparent royalties.", + "summary": "Marketplace for creators", + "vision": "Make discovery and royalties simple.", + "details": "Markdown project details here.", + "banner": "https://example.com/banner.png", + "logo": "https://example.com/logo.png", + "githubUrl": "https://github.com/example/nft-marketplace", + "projectWebsite": "https://nft-marketplace.example.com", + "demoVideo": "https://example.com/demo.mp4", + "socialLinks": { + "twitter": "https://twitter.com/example" + }, + "contact": { + "primary": "@alex123" + }, + "tags": ["NFT", "React"], + "draftData": { + "isCampaign": false } } } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "responses": { + "201": { + "description": "Draft created successfully" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Create a project draft (stepped form)", + "tags": ["projects"] } }, - "/api/auth/sign-up/email": { - "post": { - "tags": ["Default"], - "description": "Sign up a user using email and password", - "operationId": "signUpWithEmailAndPassword", - "security": [ + "/api/projects/{id}/draft": { + "patch": { + "operationId": "ProjectsController_saveDraft", + "parameters": [ { - "bearerAuth": [] + "name": "id", + "required": true, + "in": "path", + "description": "Project ID", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { + "required": true, + "description": "Full payload for stepped draft autosave", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the user" - }, - "email": { - "type": "string", - "description": "The email of the user" - }, - "password": { - "type": "string", - "description": "The password of the user" - }, - "image": { - "type": "string", - "description": "The profile image URL of the user" - }, - "callbackURL": { - "type": "string", - "description": "The URL to use for email verification callback" - }, - "rememberMe": { - "type": "boolean", - "description": "If this is false, the session will not be remembered. Default is `true`." + "type": "object" + }, + "examples": { + "campaign": { + "value": { + "title": "DeFi Lending Protocol", + "tagline": "Scalable liquidity", + "category": "DeFi", + "description": "A Stellar-native DeFi lending protocol that enables users to deposit assets and earn interest with transparent on-chain accounting.", + "summary": "Lending with transparent on-chain accounting", + "vision": "We aim to make lending safer and more scalable by improving collateral efficiency and risk modeling.", + "details": "Full technical and product details (markdown supported).", + "banner": "https://example.com/banner.png", + "logo": "https://example.com/logo.png", + "githubUrl": "https://github.com/example/defi-lending", + "gitlabUrl": "https://gitlab.com/example/defi-lending", + "bitbucketUrl": "https://bitbucket.org/example/defi-lending", + "projectWebsite": "https://defi-lending.example.com", + "demoVideo": "https://example.com/demo.mp4", + "whitepaperUrl": "https://example.com/whitepaper.pdf", + "pitchVideoUrl": "https://example.com/pitch.mp4", + "socialLinks": { + "twitter": "https://twitter.com/example", + "discord": "https://discord.gg/example" + }, + "contact": { + "primary": "@alex123", + "backup": "alex_doe#1234" + }, + "tags": ["Soroban", "TypeScript", "DeFi"], + "draftData": { + "isCampaign": true, + "campaign": { + "title": "DeFi Lending Protocol Campaign", + "logo": "https://example.com/logo.png", + "vision": "Build, ship, and deliver measurable milestones.", + "banner": "https://example.com/banner.png", + "category": "DeFi", + "details": "Funding request and milestone plan for the lending protocol.", + "fundingAmount": 15000, + "githubUrl": "https://github.com/example/defi-lending", + "gitlabUrl": "https://gitlab.com/example/defi-lending", + "bitbucketUrl": "https://bitbucket.org/example/defi-lending", + "projectWebsite": "https://defi-lending.example.com", + "demoVideo": "https://example.com/demo.mp4", + "milestones": [ + { + "title": "Milestone 1", + "description": "Core lending vault + basic UI.", + "deliverable": "Deploy vault contracts + initial product UI.", + "fundingPercentage": 50, + "amount": 7500, + "expectedDeliveryDate": "2026-04-01T00:00:00.000Z", + "successCriteria": "Contracts deployed and UI shipped.", + "orderIndex": 0 + }, + { + "title": "Milestone 2", + "description": "Risk modeling improvements + analytics.", + "deliverable": "Add risk model and dashboard metrics.", + "fundingPercentage": 50, + "amount": 7500, + "expectedDeliveryDate": "2026-05-01T00:00:00.000Z", + "successCriteria": "Risk model live and dashboards updated.", + "orderIndex": 1 + } + ], + "team": [ + { + "name": "John Doe", + "role": "Lead Developer", + "email": "john@example.com", + "linkedin": "https://linkedin.com/in/johndoe", + "twitter": "https://twitter.com/johndoe" + } + ], + "contact": { + "primary": "@alex123", + "backup": "alex_doe#1234" + }, + "socialLinks": [ + { + "platform": "twitter", + "url": "https://twitter.com/example" + }, + { + "platform": "discord", + "url": "https://discord.gg/example" + } + ] + } + } } }, - "required": ["name", "email", "password"] + "nonCampaign": { + "value": { + "title": "NFT Marketplace", + "tagline": "Creator focused", + "category": "NFT", + "description": "A creator-first NFT marketplace for Stellar projects with curated discovery and transparent royalties.", + "summary": "Marketplace for creators", + "vision": "Make discovery and royalties simple.", + "details": "Markdown project details here.", + "banner": "https://example.com/banner.png", + "logo": "https://example.com/logo.png", + "githubUrl": "https://github.com/example/nft-marketplace", + "projectWebsite": "https://nft-marketplace.example.com", + "demoVideo": "https://example.com/demo.mp4", + "socialLinks": { + "twitter": "https://twitter.com/example" + }, + "contact": { + "primary": "@alex123" + }, + "tags": ["NFT", "React"], + "draftData": { + "isCampaign": false + } + } + } } } } }, "responses": { "200": { - "description": "Successfully created user", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "token": { - "type": "string", - "nullable": true, - "description": "Authentication token for the session" - }, - "user": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "The unique identifier of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "The email address of the user" - }, - "name": { - "type": "string", - "description": "The name of the user" - }, - "image": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The profile image URL of the user" - }, - "emailVerified": { - "type": "boolean", - "description": "Whether the email has been verified" - }, - "createdAt": { - "type": "string", - "format": "date-time", - "description": "When the user was created" - }, - "updatedAt": { - "type": "string", - "format": "date-time", - "description": "When the user was last updated" - } - }, - "required": [ - "id", - "email", - "name", - "emailVerified", - "createdAt", - "updatedAt" - ] - } - }, - "required": ["user"] - } - } + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Update a project draft (stepped form autosave)", + "tags": ["projects"] + } + }, + "/api/projects": { + "get": { + "operationId": "ProjectsController_listPublicProjects", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "summary": "List public projects (PRD products directory)", + "tags": ["projects"] + } + }, + "/api/projects/search": { + "get": { + "operationId": "ProjectsController_searchPublicProjects", + "parameters": [ + { + "name": "search", + "required": false, + "in": "query", + "schema": { + "type": "string" } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "422": { - "description": "Unprocessable Entity. User already exists or failed to create user.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "summary": "Search public projects", + "tags": ["projects"] + } + }, + "/api/projects/featured": { + "get": { + "operationId": "ProjectsController_listFeaturedProjects", + "parameters": [], + "responses": { + "200": { + "description": "" + } + }, + "summary": "List featured projects", + "tags": ["projects"] + } + }, + "/api/projects/{id}/edits": { + "post": { + "operationId": "ProjectsController_submitProjectEdit", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" } - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Function" } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "responses": { + "201": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Submit a major/minor edit for your project", + "tags": ["projects"] + }, + "get": { + "operationId": "ProjectsController_listProjectEdits", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List edit history for your project", + "tags": ["projects"] } }, - "/api/auth/sign-in/email": { + "/api/projects/{id}/publish": { "post": { - "tags": ["Default"], - "description": "Sign in with email and password", - "operationId": "signInEmail", - "security": [ + "operationId": "ProjectsController_publishProject", + "parameters": [ { - "bearerAuth": [] + "name": "id", + "required": true, + "in": "path", + "description": "Project ID", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { "required": true, + "description": "Publish/submit action (Review & Submit)", "content": { "application/json": { "schema": { "type": "object", "properties": { - "email": { - "type": "string", - "description": "Email of the user" - }, - "password": { - "type": "string", - "description": "Password of the user" - }, - "callbackURL": { - "type": ["string", "null"], - "description": "Callback URL to use as a redirect for email verification" - }, - "rememberMe": { - "type": ["boolean", "null"], - "description": "If this is false, the session will not be remembered. Default is `true`.", - "default": true + "isCampaign": { + "type": "boolean", + "example": true + } + } + }, + "examples": { + "publishCampaign": { + "value": { + "isCampaign": true } }, - "required": ["email", "password"] + "publishNonCampaign": { + "value": { + "isCampaign": false + } + } } } } }, + "responses": { + "201": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Publish/submit a project draft (Review & Submit)", + "tags": ["projects"] + } + }, + "/api/projects/me": { + "get": { + "operationId": "ProjectsController_getMyProjects", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "type": "number" + } + }, + { + "name": "offset", + "required": false, + "in": "query", + "schema": { + "type": "number" + } + }, + { + "name": "status", + "required": true, + "in": "query", + "schema": { + "type": "string" + } + } + ], "responses": { "200": { - "description": "Success - Returns either session details or redirect URL", - "content": { - "application/json": { - "schema": { - "type": "object", - "description": "Session response when idToken is provided", - "properties": { - "redirect": { - "type": "boolean", - "enum": [false] - }, - "token": { - "type": "string", - "description": "Session token" + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List my projects", + "tags": ["projects"] + } + }, + "/api/projects/{slug}": { + "get": { + "operationId": "ProjectsController_getPublicProjectBySlug", + "parameters": [ + { + "name": "slug", + "required": true, + "in": "path", + "description": "Project slug", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Get public project by slug", + "tags": ["projects"] + } + }, + "/api/projects/me/{id}": { + "get": { + "operationId": "ProjectsController_getProject", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Project ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Get my project by ID", + "tags": ["projects"] + } + }, + "/api/organizations/{organizationId}/bounties/draft/{id}": { + "delete": { + "description": "Deletes an unpublished bounty (draft / draft_awaiting_funding).", + "operationId": "OrganizationBountiesDraftsController_deleteDraft", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty draft id", + "schema": { + "example": "bnt_123", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Draft deleted" + }, + "400": { + "description": "Draft not found, not authorized, or not an unpublished draft" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Delete a bounty draft", + "tags": ["Organization Bounties - Drafts"] + }, + "patch": { + "description": "Applies any subset of wizard sections in a single PATCH. Send one section for a per-step \"Continue\", or several for \"Save draft\". Each present section is validated and transformed independently, then merged into one write. The reward section replaces the prize tiers.", + "operationId": "OrganizationBountiesDraftsController_updateDraft", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty draft id", + "schema": { + "example": "bnt_123", + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBountyDraftDto" + }, + "examples": { + "singleSection": { + "summary": "Update one section (per-step Continue)", + "value": { + "scope": { + "title": "Build a Soroban faucet bot", + "description": "A Discord bot that drips testnet tokens on request." + } + } + }, + "multipleSections": { + "summary": "Update several sections (Save draft)", + "value": { + "mode": { + "claimType": "COMPETITION", + "entryType": "APPLICATION_LIGHT" }, - "url": { - "type": "string", - "nullable": true + "submission": { + "submissionDeadline": "2026-12-01T00:00:00Z", + "applicationWindowCloseAt": "2026-11-01T00:00:00Z", + "shortlistSize": 3 }, - "user": { - "type": "object", - "$ref": "#/components/schemas/User" + "reward": { + "rewardCurrency": "USDC", + "prizeTiers": [ + { + "position": 1, + "amount": "500" + }, + { + "position": 2, + "amount": "250" + } + ] } - }, - "required": ["redirect", "token", "user"] + } } } } - }, - "400": { + } + }, + "responses": { + "200": { + "description": "Draft updated", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] + "$ref": "#/components/schemas/BountyDraftResponseDto" } } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + } }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." + "400": { + "description": "Validation failed for one or more sections" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Update one or more sections of a bounty draft", + "tags": ["Organization Bounties - Drafts"] + }, + "get": { + "description": "Returns the current section-keyed state of a bounty draft.", + "operationId": "OrganizationBountiesDraftsController_getDraft", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } }, - "403": { + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty draft id", + "schema": { + "example": "bnt_123", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Draft retrieved", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyDraftResponseDto" } } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Get a bounty draft for resume", + "tags": ["Organization Bounties - Drafts"] + } + }, + "/api/organizations/{organizationId}/bounties": { + "get": { + "description": "Lists bounties for an organization, newest first.", + "operationId": "OrganizationBountiesDraftsController_getOrganizationBounties", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." + { + "name": "page", + "required": true, + "in": "query", + "schema": { + "type": "number" + } }, - "429": { + { + "name": "limit", + "required": true, + "in": "query", + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Bounties retrieved" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Get an organization's published bounties", + "tags": ["Organization Bounties - Drafts"] + } + }, + "/api/organizations/{organizationId}/bounties/draft": { + "post": { + "description": "Creates an empty bounty in draft status that organization members can edit section by section through the Configure wizard.", + "operationId": "OrganizationBountiesDraftsController_createDraft", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "Draft created", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyDraftResponseDto" } } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + } }, - "500": { + "400": { + "description": "User is not a member of the organization" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Create a new bounty draft for an organization", + "tags": ["Organization Bounties - Drafts"] + } + }, + "/api/organizations/{organizationId}/bounties/drafts": { + "get": { + "description": "Lists draft and draft_awaiting_funding bounties for an organization.", + "operationId": "OrganizationBountiesDraftsController_getOrganizationDrafts", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Drafts retrieved", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } + "type": "array", + "items": { + "$ref": "#/components/schemas/BountyDraftResponseDto" } } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Get an organization's bounty drafts", + "tags": ["Organization Bounties - Drafts"] } }, - "/api/auth/reset-password": { + "/api/organizations/{organizationId}/bounties/{id}/escrow/publish": { "post": { - "tags": ["Default"], - "description": "Reset the password for a user", - "operationId": "resetPassword", - "security": [ + "description": "Validates the draft, transitions it to draft_awaiting_funding, and returns an unsigned XDR (EXTERNAL) or the op in PENDING_CONFIRM (MANAGED). Reconciliation transitions the bounty to OPEN on success.", + "operationId": "OrganizationBountiesEscrowController_publish", + "parameters": [ { - "bearerAuth": [] + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty draft id", + "schema": { + "example": "bnt_1234567890", + "type": "string" + } } ], - "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "newPassword": { - "type": "string", - "description": "The new password to set" - }, - "token": { - "type": ["string", "null"], - "description": "The token to reset the password" - } - }, - "required": ["newPassword"] + "$ref": "#/components/schemas/PublishBountyEscrowDto" } } } }, "responses": { "200": { - "description": "Success", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "status": { - "type": "boolean" - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } } }, "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + "description": "Validation failed or bounty not in draft status" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Publish a bounty draft to the events contract", + "tags": ["Organization Bounties - Escrow (v2)"] + } + }, + "/api/organizations/{organizationId}/bounties/{id}/escrow/cancel": { + "post": { + "description": "Builds a cancel_event contract op. The contract refunds partner contributions first (in full), then the owner residual; or pro-rates partners if escrow is short. On settle, BountyEscrowSubscriber moves the bounty to CANCELLED and stamps the cancel audit columns.", + "operationId": "OrganizationBountiesEscrowController_cancel", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CancelBountyEscrowDto" } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { + } + } + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Cancel an active bounty", + "tags": ["Organization Bounties - Escrow (v2)"] } }, - "/api/auth/verify-password": { + "/api/organizations/{organizationId}/bounties/{id}/escrow/select-winners": { "post": { - "tags": ["Default"], - "description": "Verify the current user's password", - "operationId": "verifyPassword", - "security": [ + "description": "Builds a select_winners contract op that pays out per the on-chain winner_distribution and bumps each winner's profile credits / reputation / earnings. On settle, BountyEscrowSubscriber moves the bounty to COMPLETED and marks the winning BountySubmission rows accepted with the reward tx hash.", + "operationId": "OrganizationBountiesEscrowController_selectWinners", + "parameters": [ { - "bearerAuth": [] + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "example": "org_1234567890", + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "password": { - "type": "string", - "description": "The password to verify" - } - }, - "required": ["password"] + "$ref": "#/components/schemas/SelectBountyWinnersDto" } } } }, "responses": { "200": { - "description": "Success", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "status": { - "type": "boolean" - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Select winners for a bounty", + "tags": ["Organization Bounties - Escrow (v2)"] + } + }, + "/api/organizations/{organizationId}/bounties/{id}/escrow/ops/{opRowId}/submit-signed": { + "post": { + "operationId": "OrganizationBountiesEscrowController_submitSigned", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + { + "name": "opRowId", + "required": true, + "in": "path", + "description": "EscrowOp uuid", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BountySubmitSignedXdrDto" } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { + } + } + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } - } - }, - "/api/auth/verify-email": { - "get": { - "tags": ["Default"], - "description": "Verify the email of the user", + }, "security": [ { - "bearerAuth": [] + "bearer": [] } ], + "summary": "Submit signed XDR for a previously-built bounty escrow op", + "tags": ["Organization Bounties - Escrow (v2)"] + } + }, + "/api/organizations/{organizationId}/bounties/{id}/escrow/ops/{opRowId}": { + "get": { + "operationId": "OrganizationBountiesEscrowController_getOp", "parameters": [ { - "name": "token", - "in": "query", - "description": "The token to verify the email", + "name": "organizationId", "required": true, + "in": "path", "schema": { "type": "string" } }, { - "name": "callbackURL", - "in": "query", - "description": "The URL to redirect to after email verification", - "required": false, + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } + }, + { + "name": "opRowId", + "required": true, + "in": "path", + "description": "EscrowOp uuid", "schema": { "type": "string" } @@ -23458,2149 +23683,2431 @@ ], "responses": { "200": { - "description": "Success", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "user": { - "type": "object", - "$ref": "#/components/schemas/User" - }, - "status": { - "type": "boolean", - "description": "Indicates if the email was verified successfully" - } - }, - "required": ["user", "status"] + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Read the current state of a bounty escrow op", + "tags": ["Organization Bounties - Escrow (v2)"] + } + }, + "/api/bounties/{id}/escrow/apply": { + "post": { + "description": "Builds an apply_to_bounty contract op. EXTERNAL returns unsigned XDR; MANAGED signs and submits. The contract charges the bounty's application_credit_cost via the profile contract on settle.", + "operationId": "BountyParticipantEscrowController_apply", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApplyBountyDto" } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { + } + } + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Apply to a bounty", + "tags": ["Bounties - Participant Escrow (v2)"] } }, - "/api/auth/send-verification-email": { + "/api/bounties/{id}/escrow/withdraw-application": { "post": { - "tags": ["Default"], - "description": "Send a verification email to the user", - "operationId": "sendVerificationEmail", - "security": [ + "description": "Builds a withdraw_application contract op. Contract refunds half the application_credit_cost via the profile contract on settle.", + "operationId": "BountyParticipantEscrowController_withdrawApplication", + "parameters": [ { - "bearerAuth": [] + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { + "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "description": "The email to send the verification email to", - "example": "user@example.com" - }, - "callbackURL": { - "type": "string", - "description": "The URL to use for email verification callback", - "example": "https://example.com/callback", - "nullable": true - } - }, - "required": ["email"] + "$ref": "#/components/schemas/WithdrawApplicationDto" } } } }, "responses": { "200": { - "description": "Success", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "status": { - "type": "boolean", - "description": "Indicates if the email was sent successfully", - "example": true - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string", - "description": "Error message", - "example": "Verification email isn't enabled" - } - } - } - } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Withdraw a bounty application", + "tags": ["Bounties - Participant Escrow (v2)"] + } + }, + "/api/bounties/{id}/escrow/submit": { + "post": { + "description": "Builds a submit contract op. Requires the applicant's prior apply_to_bounty to be in active status (contract enforces; the service pre-checks for a cleaner 4xx).", + "operationId": "BountyParticipantEscrowController_submit", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" } - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubmitBountyDto" } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { + } + } + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Submit work for a bounty", + "tags": ["Bounties - Participant Escrow (v2)"] } }, - "/api/auth/change-email": { + "/api/bounties/{id}/escrow/withdraw-submission": { "post": { - "tags": ["Default"], - "operationId": "changeEmail", - "security": [ + "operationId": "BountyParticipantEscrowController_withdrawSubmission", + "parameters": [ { - "bearerAuth": [] + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "newEmail": { - "type": "string", - "description": "The new email address to set must be a valid email address" - }, - "callbackURL": { - "type": ["string", "null"], - "description": "The URL to redirect to after email verification" - } - }, - "required": ["newEmail"] + "$ref": "#/components/schemas/WithdrawSubmissionDto" } } } }, "responses": { "200": { - "description": "Email change request processed successfully", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "user": { - "type": "object", - "$ref": "#/components/schemas/User" - }, - "status": { - "type": "boolean", - "description": "Indicates if the request was successful" - }, - "message": { - "type": "string", - "enum": ["Email updated", "Verification email sent"], - "description": "Status message of the email change process", - "nullable": true - } - }, - "required": ["status"] + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Withdraw a bounty submission anchor", + "tags": ["Bounties - Participant Escrow (v2)"] + } + }, + "/api/bounties/{id}/escrow/contribute": { + "post": { + "description": "Builds an add_funds contract op signed by the caller. Contract enforces a 10 USDC minimum. Anyone with a funded wallet can contribute; this v1 surface requires Boundless auth, so multiple top-ups from the same wallet are allowed (one row per attempt).", + "operationId": "BountyParticipantEscrowController_contribute", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ContributeBountyDto" } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { + } + } + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } - }, - "description": "Unauthorized. Due to missing or invalid authentication." + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Contribute funds to a bounty pool", + "tags": ["Bounties - Participant Escrow (v2)"] + } + }, + "/api/bounties/{id}/escrow/ops/{opRowId}/submit-signed": { + "post": { + "operationId": "BountyParticipantEscrowController_submitSigned", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + { + "name": "opRowId", + "required": true, + "in": "path", + "description": "EscrowOp uuid", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BountySubmitSignedXdrDto" } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { + } + } + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } - }, - "description": "Not Found. The requested resource was not found." + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Submit signed XDR for a previously-built participant op", + "tags": ["Bounties - Participant Escrow (v2)"] + } + }, + "/api/bounties/{id}/escrow/ops/{opRowId}": { + "get": { + "operationId": "BountyParticipantEscrowController_getOp", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Bounty id", + "schema": { + "type": "string" + } }, - "422": { - "description": "Unprocessable Entity. Email already exists", + { + "name": "opRowId", + "required": true, + "in": "path", + "description": "EscrowOp uuid", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyEscrowOpResponseDto" } } } - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Read the state of a participant op", + "tags": ["Bounties - Participant Escrow (v2)"] + } + }, + "/api/bounties/{bountyId}/v2/applications": { + "post": { + "operationId": "BountyApplicationController_create", + "parameters": [ + { + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBountyApplicationDto" } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { + } + } + }, + "responses": { + "201": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Submit an application for a application bounty", + "tags": ["Bounty v2 - Applications"] + } + }, + "/api/bounties/{bountyId}/v2/applications/me": { + "get": { + "operationId": "BountyApplicationController_getMine", + "parameters": [ + { + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "The caller's application, or null when they have not applied.", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyApplicationResponseDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Read the caller's application for this bounty", + "tags": ["Bounty v2 - Applications"] } }, - "/api/auth/change-password": { - "post": { - "tags": ["Default"], - "description": "Change the password of the user", - "operationId": "changePassword", - "security": [ + "/api/bounties/{bountyId}/v2/applications/{appId}": { + "patch": { + "operationId": "BountyApplicationController_edit", + "parameters": [ { - "bearerAuth": [] + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "appId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "newPassword": { - "type": "string", - "description": "The new password to set" - }, - "currentPassword": { - "type": "string", - "description": "The current password is required" - }, - "revokeOtherSessions": { - "type": ["boolean", "null"], - "description": "Must be a boolean value" - } - }, - "required": ["newPassword", "currentPassword"] + "$ref": "#/components/schemas/EditBountyApplicationDto" } } } }, "responses": { "200": { - "description": "Password successfully changed", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "token": { - "type": "string", - "nullable": true, - "description": "New session token if other sessions were revoked" - }, - "user": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "The unique identifier of the user" - }, - "email": { - "type": "string", - "format": "email", - "description": "The email address of the user" - }, - "name": { - "type": "string", - "description": "The name of the user" - }, - "image": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "The profile image URL of the user" - }, - "emailVerified": { - "type": "boolean", - "description": "Whether the email has been verified" - }, - "createdAt": { - "type": "string", - "format": "date-time", - "description": "When the user was created" - }, - "updatedAt": { - "type": "string", - "format": "date-time", - "description": "When the user was last updated" - } - }, - "required": [ - "id", - "email", - "name", - "emailVerified", - "createdAt", - "updatedAt" - ] - } - }, - "required": ["user"] - } - } + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Edit a SUBMITTED application (before shortlist)", + "tags": ["Bounty v2 - Applications"] + }, + "delete": { + "operationId": "BountyApplicationController_withdraw", + "parameters": [ + { + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" } }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." + { + "name": "appId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Withdraw a SUBMITTED application", + "tags": ["Bounty v2 - Applications"] + } + }, + "/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications": { + "get": { + "operationId": "OrganizationBountyShortlistController_list", + "parameters": [ + { + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + { + "name": "status", + "required": false, + "in": "query", + "description": "Filter by application status", + "schema": { + "enum": [ + "SUBMITTED", + "SHORTLISTED", + "SELECTED", + "DECLINED", + "WITHDRAWN" + ], + "type": "string" + } }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": {} } - } + ], + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List applications on a bounty", + "tags": ["Bounty v2 - Organizer Shortlist"] } }, - "/api/auth/update-user": { + "/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/select": { "post": { - "tags": ["Default"], - "description": "Update the current user", - "operationId": "updateUser", - "security": [ + "operationId": "OrganizationBountyShortlistController_selectForSingleClaim", + "parameters": [ { - "bearerAuth": [] + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { + "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the user" - }, - "image": { - "type": "string", - "description": "The image of the user", - "nullable": true - } - } + "$ref": "#/components/schemas/SelectForSingleClaimDto" } } } }, "responses": { "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "user": { - "type": "object", - "$ref": "#/components/schemas/User" - } - } - } - } + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Select a single application (application (light) single claim / application (full) single claim)", + "tags": ["Bounty v2 - Organizer Shortlist"] + } + }, + "/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/shortlist": { + "post": { + "operationId": "OrganizationBountyShortlistController_createShortlist", + "parameters": [ + { + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateShortlistDto" } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Approve a shortlist (application (light) competition / application (full) competition)", + "tags": ["Bounty v2 - Organizer Shortlist"] } }, - "/api/auth/delete-user": { + "/api/organizations/{organizationId}/bounties/{bountyId}/v2/applications/{appId}/decline": { "post": { - "tags": ["Default"], - "description": "Delete the user", - "operationId": "deleteUser", - "security": [ + "operationId": "OrganizationBountyShortlistController_decline", + "parameters": [ { - "bearerAuth": [] + "name": "appId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { + "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "callbackURL": { - "type": "string", - "description": "The callback URL to redirect to after the user is deleted" - }, - "password": { - "type": "string", - "description": "The user's password. Required if session is not fresh" - }, - "token": { - "type": "string", - "description": "The deletion verification token" - } - } + "$ref": "#/components/schemas/DeclineApplicationDto" } } } }, "responses": { "200": { - "description": "User deletion processed successfully", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "description": "Indicates if the operation was successful" - }, - "message": { - "type": "string", - "enum": ["User deleted", "Verification email sent"], - "description": "Status message of the deletion process" - } - }, - "required": ["success", "message"] - } - } + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Decline an application with optional reason", + "tags": ["Bounty v2 - Organizer Shortlist"] + } + }, + "/api/bounties/{bountyId}/v2/competition/join": { + "post": { + "operationId": "BountyCompetitionJoinController_join", + "parameters": [ + { + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JoinCompetitionDto" } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } - } - }, - "/api/auth/request-password-reset": { - "post": { - "tags": ["Default"], - "description": "Send a password reset email to the user", - "operationId": "requestPasswordReset", + }, + "responses": { + "200": { + "description": "" + } + }, "security": [ { - "bearerAuth": [] + "bearer": [] + } + ], + "summary": "Join an open competition bounty", + "tags": ["Bounty v2 - open competition"] + }, + "delete": { + "operationId": "BountyCompetitionJoinController_leave", + "parameters": [ + { + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "description": "The email address of the user to send a password reset email to" - }, - "redirectTo": { - "type": ["string", "null"], - "description": "The URL to redirect the user to reset their password. If the token isn't valid or expired, it'll be redirected with a query parameter `?error=INVALID_TOKEN`. If the token is valid, it'll be redirected with a query parameter `?token=VALID_TOKEN" - } - }, - "required": ["email"] + "$ref": "#/components/schemas/JoinCompetitionDto" } } } }, "responses": { "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "status": { - "type": "boolean" - }, - "message": { - "type": "string" - } - } - } - } + "description": "" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Leave an open competition before submitting", + "tags": ["Bounty v2 - open competition"] + } + }, + "/api/bounties/me/applications": { + "get": { + "operationId": "BountyParticipantDashboardController_myApplications", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "type": "number" } }, - "400": { + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "type": "number" + } + }, + { + "name": "status", + "required": false, + "in": "query", + "schema": { + "enum": [ + "SUBMITTED", + "SHORTLISTED", + "SELECTED", + "DECLINED", + "WITHDRAWN" + ], + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] + "$ref": "#/components/schemas/MyBountyApplicationListDto" } } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List the caller's applications across all bounties", + "tags": ["Bounty v2 - Participant dashboard"] + } + }, + "/api/bounties/me/submissions": { + "get": { + "operationId": "BountyParticipantDashboardController_mySubmissions", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "type": "number" + } }, - "401": { + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "type": "number" + } + }, + { + "name": "status", + "required": false, + "in": "query", + "schema": {} + } + ], + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] + "$ref": "#/components/schemas/MyBountySubmissionListDto" } } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List the caller's submissions across all bounties", + "tags": ["Bounty v2 - Participant dashboard"] + } + }, + "/api/bounties/me/submissions/{bountyId}": { + "get": { + "operationId": "BountyParticipantDashboardController_mySubmissionForBounty", + "parameters": [ + { + "name": "bountyId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "The caller's submission, or null when they have not submitted.", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/MyBountySubmissionRowDto" } } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Read the caller's submission for one bounty", + "tags": ["Bounty v2 - Participant dashboard"] + } + }, + "/api/bounties/{id}/results": { + "get": { + "operationId": "BountyResultsController_getResults", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyResultsDto" } } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Public results / leaderboard (winners by tier)", + "tags": ["Bounty v2 - Results"] + } + }, + "/api/bounties/{id}/submissions": { + "get": { + "operationId": "BountyResultsController_getSubmissions", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountySubmissionListDto" } } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Submissions the caller may see (respects submissionVisibility)", + "tags": ["Bounty v2 - Results"] + } + }, + "/api/bounties": { + "get": { + "operationId": "BountyPublicController_list", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "schema": { + "type": "number" + } }, - "500": { + { + "name": "limit", + "required": false, + "in": "query", + "schema": { + "type": "number" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "schema": {} + }, + { + "name": "status", + "required": false, + "in": "query", + "schema": {} + }, + { + "name": "organizationId", + "required": false, + "in": "query", + "schema": {} + } + ], + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/BountyPublicListDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "summary": "Public bounty marketplace list", + "tags": ["bounties"] } }, - "/api/auth/reset-password/{token}": { + "/api/bounties/{id}": { "get": { - "tags": ["Default"], - "description": "Redirects the user to the callback URL with the token", - "operationId": "resetPasswordCallback", - "security": [ + "operationId": "BountyPublicController_findOne", + "parameters": [ { - "bearerAuth": [] + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } } ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BountyPublicDto" + } + } + } + } + }, + "summary": "Public bounty detail", + "tags": ["bounties"] + } + }, + "/api/organizations/{organizationId}/grants/{id}/escrow/publish": { + "post": { + "description": "Validates the draft, transitions to DRAFT_AWAITING_FUNDING, and returns an unsigned XDR (EXTERNAL) or the op in PENDING_CONFIRM (MANAGED). Reconciliation transitions the grant to OPEN on success.", + "operationId": "OrganizationGrantsEscrowController_publish", "parameters": [ { - "name": "token", - "in": "path", + "name": "organizationId", "required": true, - "description": "The token to reset the password", + "in": "path", "schema": { + "example": "org_1234567890", "type": "string" } }, { - "name": "callbackURL", - "in": "query", + "name": "id", "required": true, - "description": "The URL to redirect the user to reset their password", + "in": "path", + "description": "Grant id", "schema": { "type": "string" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishGrantEscrowDto" + } + } + } + }, "responses": { "200": { - "description": "Success", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "token": { - "type": "string" - } - } + "$ref": "#/components/schemas/GrantEscrowOpResponseDto" } } } }, "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + "description": "Draft not in DRAFT status" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Publish a grant draft to the events contract", + "tags": ["Organization Grants - Escrow (v2)"] + } + }, + "/api/organizations/{organizationId}/grants/{id}/escrow/cancel": { + "post": { + "operationId": "OrganizationGrantsEscrowController_cancel", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CancelGrantEscrowDto" } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { + } + } + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/GrantEscrowOpResponseDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Cancel an active grant", + "tags": ["Organization Grants - Escrow (v2)"] } }, - "/api/auth/list-sessions": { - "get": { - "tags": ["Default"], - "description": "List all active sessions for the user", - "operationId": "listUserSessions", - "security": [ + "/api/organizations/{organizationId}/grants/{id}/escrow/select-winners": { + "post": { + "description": "For Multi release_kind, select_winners records recipients with amount=0 — payouts happen per-milestone via claim_milestone.", + "operationId": "OrganizationGrantsEscrowController_selectWinners", + "parameters": [ { - "bearerAuth": [] + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } } ], - "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SelectGrantWinnersDto" + } + } + } + }, "responses": { "200": { - "description": "Success", + "description": "", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Session" - } + "$ref": "#/components/schemas/GrantEscrowOpResponseDto" } } } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." } - } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Select grant recipients", + "tags": ["Organization Grants - Escrow (v2)"] } }, - "/api/auth/revoke-session": { + "/api/organizations/{organizationId}/grants/{id}/escrow/claim-milestone": { "post": { - "tags": ["Default"], - "description": "Revoke a single session", - "security": [ + "description": "Builds a claim_milestone contract op. Contract pays the per-milestone amount to the recipient and bumps profile credits / reputation / earnings.", + "operationId": "OrganizationGrantsEscrowController_claimMilestone", + "parameters": [ { - "bearerAuth": [] + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { + "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "token": { - "type": "string", - "description": "The token to revoke" - } - }, - "required": ["token"] + "$ref": "#/components/schemas/ClaimGrantMilestoneDto" } } } }, "responses": { "200": { - "description": "Success", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "status": { - "type": "boolean", - "description": "Indicates if the session was revoked successfully" - } - }, - "required": ["status"] + "$ref": "#/components/schemas/GrantEscrowOpResponseDto" } } } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Pay out a specific milestone for a recipient", + "tags": ["Organization Grants - Escrow (v2)"] + } + }, + "/api/organizations/{organizationId}/grants/{id}/escrow/ops/{opRowId}/submit-signed": { + "post": { + "operationId": "OrganizationGrantsEscrowController_submitSigned", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + { + "name": "opRowId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GrantSubmitSignedXdrDto" } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { + } + } + }, + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/GrantEscrowOpResponseDto" } } - }, - "description": "Not Found. The requested resource was not found." + } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Submit signed XDR for a grant op", + "tags": ["Organization Grants - Escrow (v2)"] + } + }, + "/api/organizations/{organizationId}/grants/{id}/escrow/ops/{opRowId}": { + "get": { + "operationId": "OrganizationGrantsEscrowController_getOp", + "parameters": [ + { + "name": "organizationId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + { + "name": "id", + "required": true, + "in": "path", + "schema": { + "type": "string" + } }, - "500": { + { + "name": "opRowId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/GrantEscrowOpResponseDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Read the state of a grant op", + "tags": ["Organization Grants - Escrow (v2)"] } }, - "/api/auth/revoke-sessions": { + "/api/grants/{id}/escrow/contribute": { "post": { - "tags": ["Default"], - "description": "Revoke all sessions for the user", - "security": [ + "description": "Open add_funds op. Contract enforces a 10 USDC minimum. Anyone authenticated can contribute; multiple top-ups from the same wallet are allowed (one row per attempt).", + "operationId": "GrantContributeEscrowController_contribute", + "parameters": [ { - "bearerAuth": [] + "name": "id", + "required": true, + "in": "path", + "description": "Grant id", + "schema": { + "type": "string" + } } ], - "parameters": [], "requestBody": { + "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": {} + "$ref": "#/components/schemas/ContributeGrantDto" } } } }, "responses": { "200": { - "description": "Success", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "status": { - "type": "boolean", - "description": "Indicates if all sessions were revoked successfully" - } - }, - "required": ["status"] + "$ref": "#/components/schemas/GrantEscrowOpResponseDto" } } } + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Contribute funds to a grant pool", + "tags": ["Grants - Contribute (v2)"] + } + }, + "/api/grants": { + "get": { + "description": "Public, page-based list of grant programs. Parallel to /bounties and /hackathons. For a multi-pillar feed (Bounty, Hackathon, Grant, Crowdfunding), use /opportunities instead.", + "operationId": "GrantsPublicController_list", + "parameters": [ + { + "name": "status", + "required": false, + "in": "query", + "description": "Pillar-specific status filter (open, closed, in_progress).", + "schema": { + "example": "open", + "type": "string" + } }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." + { + "name": "search", + "required": false, + "in": "query", + "description": "Case-insensitive substring match against project title and summary.", + "schema": { + "example": "governance", + "type": "string" + } }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." + { + "name": "category", + "required": false, + "in": "query", + "description": "Filter by the underlying project category.", + "schema": { + "example": "defi", + "type": "string" + } }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." + { + "name": "page", + "required": false, + "in": "query", + "description": "Page number (1-indexed).", + "schema": { + "minimum": 1, + "default": 1, + "example": 1, + "type": "number" + } }, - "429": { + { + "name": "limit", + "required": false, + "in": "query", + "description": "Items per page.", + "schema": { + "minimum": 1, + "maximum": 50, + "default": 20, + "example": 20, + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Grants page", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/GrantPublicListResponseDto" } } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + } + } + }, + "summary": "List published grants", + "tags": ["Grants"] + } + }, + "/api/opportunities": { + "get": { + "description": "Returns a unified, cursor-paginated feed across Bounty, Hackathon, Grant, and Crowdfunding. Pass type= to restrict to one. The cursor is opaque; pass it back as-is to fetch the next page.", + "operationId": "OpportunitiesController_list", + "parameters": [ + { + "name": "type", + "required": false, + "in": "query", + "description": "Which pillar to query. \"all\" fans out across the four adapters; the others restrict to a single adapter.", + "schema": { + "default": "all", + "example": "all", + "type": "string", + "enum": ["all", "bounty", "hackathon", "grant", "crowdfunding"] + } }, - "500": { + { + "name": "status", + "required": false, + "in": "query", + "description": "Pillar-specific status filter. Adapters match case-insensitively against their own enum and return [] when no value matches.", + "schema": { + "example": "open", + "type": "string" + } + }, + { + "name": "search", + "required": false, + "in": "query", + "description": "Case-insensitive substring match against title and summary across adapters.", + "schema": { + "example": "governance", + "type": "string" + } + }, + { + "name": "tags", + "required": false, + "in": "query", + "description": "Comma-separated tag list. Pillar-aware: bounty has no tag field and returns [] for any tags filter.", + "schema": { + "example": "stellar,defi", + "type": "string" + } + }, + { + "name": "sort", + "required": false, + "in": "query", + "description": "Sort mode. \"deadline\" sorts ascending by the next deadline (NULLS LAST); \"prize_desc\" sorts by reward descending.", + "schema": { + "default": "newest", + "example": "newest", + "type": "string", + "enum": ["newest", "deadline", "prize_desc"] + } + }, + { + "name": "cursor", + "required": false, + "in": "query", + "description": "Opaque pagination cursor returned by the previous response. Omit to start from page 1.", + "schema": { + "example": "eyJzb3J0IjoibmV3ZXN0IiwicHJpbWFyeSI6IjIwMjYtMDUtMTVUMDA6MDA6MDAuMDAwWiIsImlkIjoiY2t4eXoxMjMifQ", + "type": "string" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "description": "Items per page. Capped at 50.", + "schema": { + "minimum": 1, + "maximum": 50, + "default": 12, + "example": 12, + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Opportunities page", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } + "$ref": "#/components/schemas/OpportunityListResponseDto" } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } } - } + }, + "summary": "List opportunities across all pillars", + "tags": ["Opportunities"] } }, - "/api/auth/revoke-other-sessions": { + "/api/newsletter/subscribe": { "post": { - "tags": ["Default"], - "description": "Revoke all other sessions for the user except the current one", - "security": [ - { - "bearerAuth": [] - } - ], + "description": "Subscribe an email address to the newsletter. Sends a confirmation email (double opt-in). Rate limited to 5 requests per minute.", + "operationId": "NewsletterController_subscribe", "parameters": [], "requestBody": { + "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": {} + "$ref": "#/components/schemas/SubscribeDto" } } } }, "responses": { - "200": { - "description": "Success", + "201": { + "description": "Confirmation email sent successfully", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "status": { - "type": "boolean", - "description": "Indicates if all other sessions were revoked successfully" - } - }, - "required": ["status"] + "example": { + "message": "Confirmation email sent. Please check your inbox.", + "id": "clx1234567890" + } } } } }, "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." + "description": "Invalid tags provided" }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." + "409": { + "description": "Email is already subscribed" }, "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + "description": "Too many requests — rate limited" + } + }, + "summary": "Subscribe to the newsletter", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/confirm/{token}": { + "get": { + "description": "Confirm a newsletter subscription via the token sent in the confirmation email. Redirects to the frontend on success.", + "operationId": "NewsletterController_confirmSubscription", + "parameters": [ + { + "name": "token", + "required": true, + "in": "path", + "description": "Confirmation token received via email", + "schema": { + "type": "string" + } + } + ], + "responses": { + "302": { + "description": "Redirects to frontend confirmation page" }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + "400": { + "description": "Confirmation token has expired" + }, + "404": { + "description": "Invalid or expired confirmation token" } - } + }, + "summary": "Confirm newsletter subscription", + "tags": ["Newsletter"] } }, - "/api/auth/link-social": { - "post": { - "tags": ["Default"], - "description": "Link a social account to the user", - "operationId": "linkSocialAccount", - "security": [ + "/api/newsletter/unsubscribe/{token}": { + "get": { + "description": "Unsubscribe from the newsletter using the one-click unsubscribe token from emails. Redirects to the frontend.", + "operationId": "NewsletterController_unsubscribeByToken", + "parameters": [ { - "bearerAuth": [] + "name": "token", + "required": true, + "in": "path", + "description": "Unsubscribe token from the email footer", + "schema": { + "type": "string" + } } ], + "responses": { + "302": { + "description": "Redirects to frontend unsubscribe confirmation page" + }, + "404": { + "description": "Invalid unsubscribe link" + } + }, + "summary": "Unsubscribe by token", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/unsubscribe": { + "post": { + "description": "Legacy unsubscribe endpoint. Unsubscribe a subscriber by their email address.", + "operationId": "NewsletterController_unsubscribe", "parameters": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "callbackURL": { - "type": ["string", "null"], - "description": "The URL to redirect to after the user has signed in" - }, - "provider": { - "type": "string" - }, - "idToken": { - "type": ["object", "null"], - "properties": { - "token": { - "type": "string" - }, - "nonce": { - "type": ["string", "null"] - }, - "accessToken": { - "type": ["string", "null"] - }, - "refreshToken": { - "type": ["string", "null"] - }, - "scopes": { - "type": ["array", "null"] - } - }, - "required": ["token"] - }, - "requestSignUp": { - "type": ["boolean", "null"] - }, - "scopes": { - "type": ["array", "null"], - "description": "Additional scopes to request from the provider" - }, - "errorCallbackURL": { - "type": ["string", "null"], - "description": "The URL to redirect to if there is an error during the link process" - }, - "disableRedirect": { - "type": ["boolean", "null"], - "description": "Disable automatic redirection to the provider. Useful for handling the redirection yourself" - }, - "additionalData": { - "type": ["string", "null"] - } - }, - "required": ["provider"] + "$ref": "#/components/schemas/UnsubscribeDto" } } } }, "responses": { "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "url": { - "type": "string", - "description": "The authorization URL to redirect the user to" - }, - "redirect": { - "type": "boolean", - "description": "Indicates if the user should be redirected to the authorization URL" - }, - "status": { - "type": "boolean" - } - }, - "required": ["redirect"] - } - } - } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." + "description": "Successfully unsubscribed" }, "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } + "description": "Subscriber not found" + } + }, + "summary": "Unsubscribe by email", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/preferences": { + "patch": { + "description": "Update topic tag preferences for a subscriber. Valid tags: bounties, hackathons, grants, updates.", + "operationId": "NewsletterController_updatePreferences", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdatePreferencesDto" } - }, - "description": "Not Found. The requested resource was not found." + } + } + }, + "responses": { + "200": { + "description": "Preferences updated successfully" }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + "400": { + "description": "Invalid tags provided" }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + "404": { + "description": "Subscriber not found" } - } + }, + "summary": "Update subscription preferences", + "tags": ["Newsletter"] } }, - "/api/auth/list-accounts": { + "/api/newsletter/tracking/open/{campaignId}/{subscriberId}": { "get": { - "tags": ["Default"], - "description": "List all accounts linked to the user", - "operationId": "listUserAccounts", - "security": [ + "description": "Open tracking pixel endpoint. Returns a 1x1 transparent GIF and records the open event. Used in campaign emails.", + "operationId": "NewsletterController_trackOpen", + "parameters": [ { - "bearerAuth": [] + "name": "campaignId", + "required": true, + "in": "path", + "description": "Campaign ID", + "schema": { + "type": "string" + } + }, + { + "name": "subscriberId", + "required": true, + "in": "path", + "description": "Subscriber ID", + "schema": { + "type": "string" + } } ], - "parameters": [], "responses": { "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "providerId": { - "type": "string" - }, - "createdAt": { - "type": "string", - "format": "date-time" - }, - "updatedAt": { - "type": "string", - "format": "date-time" - }, - "accountId": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "scopes": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "id", - "providerId", - "createdAt", - "updatedAt", - "accountId", - "userId", - "scopes" - ] - } - } - } + "description": "Returns 1x1 transparent GIF" + } + }, + "summary": "Track email open", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/tracking/click/{campaignId}/{subscriberId}": { + "get": { + "description": "Click tracking endpoint. Records the click event and redirects the subscriber to the target URL.", + "operationId": "NewsletterController_trackClick", + "parameters": [ + { + "name": "campaignId", + "required": true, + "in": "path", + "description": "Campaign ID", + "schema": { + "type": "string" } }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + { + "name": "subscriberId", + "required": true, + "in": "path", + "description": "Subscriber ID", + "schema": { + "type": "string" + } }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." + { + "name": "url", + "required": true, + "in": "query", + "description": "Target URL to redirect to after tracking", + "schema": { + "example": "https://www.boundlessfi.xyz/hackathons", + "type": "string" + } + } + ], + "responses": { + "302": { + "description": "Redirects to the target URL" + } + }, + "summary": "Track email link click", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/subscribers": { + "get": { + "description": "Get a paginated list of newsletter subscribers with optional filters by status, source, tags, and search.", + "operationId": "NewsletterController_getSubscribers", + "parameters": [ + { + "name": "status", + "required": false, + "in": "query", + "description": "Filter by status", + "schema": { + "enum": ["active", "pending", "unsubscribed", "bounced"], + "type": "string" + } }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." + { + "name": "source", + "required": false, + "in": "query", + "description": "Filter by source", + "schema": { + "example": "website", + "type": "string" + } }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." + { + "name": "tags", + "required": false, + "in": "query", + "description": "Filter by tags (comma-separated)", + "schema": { + "example": "updates,hackathons", + "type": "string" + } }, - "429": { + { + "name": "search", + "required": false, + "in": "query", + "description": "Search by email or name", + "schema": { + "example": "john", + "type": "string" + } + }, + { + "name": "page", + "required": false, + "in": "query", + "description": "Page number (default: 1)", + "schema": { + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "description": "Items per page (default: 50)", + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Subscribers retrieved successfully", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } + "example": { + "subscribers": [], + "total": 0, + "page": 1, + "limit": 50 } } } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + } }, - "500": { + "401": { + "description": "Unauthorized" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List newsletter subscribers", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/stats": { + "get": { + "description": "Get subscriber counts by status, subscription sources, and campaign statistics (sent, opens, clicks).", + "operationId": "NewsletterController_getStats", + "parameters": [], + "responses": { + "200": { + "description": "Statistics retrieved successfully", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" + "example": { + "subscribers": { + "total": 100, + "active": 80, + "pending": 10, + "unsubscribed": 8, + "bounced": 2 + }, + "bySource": [ + { + "source": "website", + "count": 60 + } + ], + "campaigns": { + "total": 5, + "totalSent": 400, + "totalOpens": 200, + "totalClicks": 50 } } } } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + }, + "401": { + "description": "Unauthorized" } - } - } - }, - "/api/auth/delete-user/callback": { - "get": { - "tags": ["Default"], - "description": "Callback to complete user deletion with verification token", + }, "security": [ { - "bearerAuth": [] + "bearer": [] } ], + "summary": "Get newsletter statistics", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/export": { + "get": { + "description": "Download a CSV file of subscribers with optional status and tag filters.", + "operationId": "NewsletterController_exportSubscribers", "parameters": [ { - "name": "token", + "name": "status", + "required": false, "in": "query", + "description": "Filter by subscriber status", "schema": { - "type": "string", - "description": "The token to verify the deletion request" + "enum": ["active", "pending", "unsubscribed", "bounced"], + "type": "string" } }, { - "name": "callbackURL", + "name": "tags", + "required": false, "in": "query", + "description": "Filter by tags (comma-separated)", "schema": { - "type": ["string", "null"], - "description": "The URL to redirect to after deletion" + "example": "updates,hackathons", + "type": "string" } } ], "responses": { "200": { - "description": "User successfully deleted", + "description": "CSV file downloaded", "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean", - "description": "Indicates if the deletion was successful" - }, - "message": { - "type": "string", - "enum": ["User deleted"], - "description": "Confirmation message" - } - }, - "required": ["success", "message"] - } - } + "text/csv": {} } }, - "400": { + "401": { + "description": "Unauthorized" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Export subscribers as CSV", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/subscribers/{id}": { + "delete": { + "description": "Permanently delete a newsletter subscriber by ID.", + "operationId": "NewsletterController_deleteSubscriber", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Subscriber ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Subscriber deleted successfully", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] + "example": { + "success": true + } + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Subscriber not found" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Delete a subscriber", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/campaigns": { + "post": { + "description": "Create a new newsletter campaign draft. Use {{name}} placeholder in content for personalization. Target specific subscribers using tags.", + "operationId": "NewsletterController_createCampaign", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateNewsletterCampaignDto" + } + } + } + }, + "responses": { + "201": { + "description": "Campaign created successfully" + }, + "400": { + "description": "Invalid tags provided" + }, + "401": { + "description": "Unauthorized" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Create a new campaign", + "tags": ["Newsletter"] + }, + "get": { + "description": "Get a paginated list of newsletter campaigns, ordered by most recent first.", + "operationId": "NewsletterController_getCampaigns", + "parameters": [ + { + "name": "page", + "required": false, + "in": "query", + "description": "Page number (default: 1)", + "schema": { + "type": "number" + } + }, + { + "name": "limit", + "required": false, + "in": "query", + "description": "Items per page (default: 20)", + "schema": { + "type": "number" + } + } + ], + "responses": { + "200": { + "description": "Campaigns retrieved successfully", + "content": { + "application/json": { + "schema": { + "example": { + "campaigns": [], + "total": 0, + "page": 1, + "limit": 20 + } + } + } + } + }, + "401": { + "description": "Unauthorized" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "List newsletter campaigns", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/campaigns/{id}": { + "get": { + "description": "Get detailed information about a specific campaign, including the most recent 100 send logs.", + "operationId": "NewsletterController_getCampaign", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Campaign ID", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Campaign details retrieved successfully" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Campaign not found" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Get campaign details", + "tags": ["Newsletter"] + } + }, + "/api/newsletter/campaigns/{id}/send": { + "post": { + "description": "Send a campaign to all matching subscribers. Delivers in batches of 10 with 1-second delays. Cannot re-send an already sent campaign.", + "operationId": "NewsletterController_sendCampaign", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "description": "Campaign ID to send", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Campaign sent successfully", + "content": { + "application/json": { + "schema": { + "example": { + "sentCount": 80, + "failedCount": 2, + "total": 82 + } + } + } + } + }, + "400": { + "description": "Campaign already sent or currently sending" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Campaign not found" + } + }, + "security": [ + { + "bearer": [] + } + ], + "summary": "Send a campaign", + "tags": ["Newsletter"] + } + }, + "/api/admin/queues/dlq/depth": { + "get": { + "operationId": "DlqAdminController_getDepth", + "parameters": [], + "responses": { + "200": { + "description": "Total parked jobs" + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Current DLQ depth (admin only)", + "tags": ["Admin / Queues"] + } + }, + "/api/admin/queues/dlq": { + "get": { + "operationId": "DlqAdminController_list", + "parameters": [ + { + "name": "limit", + "required": false, + "in": "query", + "description": "Max entries to return (1 to 200, default 50)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "List parked DLQ entries (admin only)", + "tags": ["Admin / Queues"] + } + }, + "/api/admin/queues/dlq/{jobId}": { + "get": { + "operationId": "DlqAdminController_getOne", + "parameters": [ + { + "name": "jobId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "" + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Fetch a single parked DLQ entry (admin only)", + "tags": ["Admin / Queues"] + } + }, + "/api/admin/queues/dlq/{jobId}/replay": { + "post": { + "description": "The DLQ row is removed on success. Replay uses the original queue's normal retry budget, so a job that died after 3 retries gets another 3 retries on replay.", + "operationId": "DlqAdminController_replay", + "parameters": [ + { + "name": "jobId", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + } + ], + "responses": { + "201": { + "description": "" + } + }, + "security": [ + { + "JWT-auth": [] + } + ], + "summary": "Re-enqueue a parked DLQ entry on its original queue", + "tags": ["Admin / Queues"] + } + }, + "/api/auth/sign-in/social": { + "post": { + "tags": ["Default"], + "description": "Sign in with a social provider", + "operationId": "socialSignIn", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "callbackURL": { + "type": ["string", "null"], + "description": "Callback URL to redirect to after the user has signed in" + }, + "newUserCallbackURL": { + "type": ["string", "null"] + }, + "errorCallbackURL": { + "type": ["string", "null"], + "description": "Callback URL to redirect to if an error happens" + }, + "provider": { + "type": "string" + }, + "disableRedirect": { + "type": ["boolean", "null"], + "description": "Disable automatic redirection to the provider. Useful for handling the redirection yourself" + }, + "idToken": { + "type": ["object", "null"], + "properties": { + "token": { + "type": "string", + "description": "ID token from the provider" + }, + "nonce": { + "type": ["string", "null"], + "description": "Nonce used to generate the token" + }, + "accessToken": { + "type": ["string", "null"], + "description": "Access token from the provider" + }, + "refreshToken": { + "type": ["string", "null"], + "description": "Refresh token from the provider" + }, + "expiresAt": { + "type": ["number", "null"], + "description": "Expiry date of the token" + } + }, + "required": ["token"] + }, + "scopes": { + "type": ["array", "null"], + "description": "Array of scopes to request from the provider. This will override the default scopes passed." + }, + "requestSignUp": { + "type": ["boolean", "null"], + "description": "Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider" + }, + "loginHint": { + "type": ["string", "null"], + "description": "The login hint to use for the authorization code request" + }, + "additionalData": { + "type": ["string", "null"] + } + }, + "required": ["provider"] + } + } + } + }, + "responses": { + "200": { + "description": "Success - Returns either session details or redirect URL", + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "Session response when idToken is provided", + "properties": { + "token": { + "type": "string" + }, + "user": { + "type": "object", + "$ref": "#/components/schemas/User" + }, + "url": { + "type": "string" + }, + "redirect": { + "type": "boolean", + "enum": [false] + } + }, + "required": ["redirect", "token", "user"] + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] } } }, @@ -25685,35 +26192,17 @@ } } }, - "/api/auth/unlink-account": { - "post": { + "/api/auth/get-session": { + "get": { "tags": ["Default"], - "description": "Unlink an account", + "description": "Get the current session", + "operationId": "getSession", "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "providerId": { - "type": "string" - }, - "accountId": { - "type": ["string", "null"] - } - }, - "required": ["providerId"] - } - } - } - }, "responses": { "200": { "description": "Success", @@ -25721,11 +26210,16 @@ "application/json": { "schema": { "type": "object", + "nullable": true, "properties": { - "status": { - "type": "boolean" + "session": { + "$ref": "#/components/schemas/Session" + }, + "user": { + "$ref": "#/components/schemas/User" } - } + }, + "required": ["session", "user"] } } } @@ -25825,10 +26319,11 @@ } } }, - "/api/auth/refresh-token": { + "/api/auth/sign-out": { "post": { "tags": ["Default"], - "description": "Refresh the access token using a refresh token", + "description": "Sign out the current user", + "operationId": "signOut", "security": [ { "bearerAuth": [] @@ -25836,57 +26331,25 @@ ], "parameters": [], "requestBody": { - "required": true, "content": { "application/json": { "schema": { "type": "object", - "properties": { - "providerId": { - "type": "string", - "description": "The provider ID for the OAuth provider" - }, - "accountId": { - "type": ["string", "null"], - "description": "The account ID associated with the refresh token" - }, - "userId": { - "type": ["string", "null"], - "description": "The user ID associated with the account" - } - }, - "required": ["providerId"] + "properties": {} } } } }, "responses": { "200": { - "description": "Access token refreshed successfully", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "tokenType": { - "type": "string" - }, - "idToken": { - "type": "string" - }, - "accessToken": { - "type": "string" - }, - "refreshToken": { - "type": "string" - }, - "accessTokenExpiresAt": { - "type": "string", - "format": "date-time" - }, - "refreshTokenExpiresAt": { - "type": "string", - "format": "date-time" + "success": { + "type": "boolean" } } } @@ -25894,7 +26357,20 @@ } }, "400": { - "description": "Invalid refresh token or provider configuration" + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." }, "401": { "content": { @@ -25975,10 +26451,11 @@ } } }, - "/api/auth/get-access-token": { + "/api/auth/sign-up/email": { "post": { "tags": ["Default"], - "description": "Get a valid access token, doing a refresh if needed", + "description": "Sign up a user using email and password", + "operationId": "signUpWithEmailAndPassword", "security": [ { "bearerAuth": [] @@ -25986,58 +26463,121 @@ ], "parameters": [], "requestBody": { - "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { - "providerId": { + "name": { "type": "string", - "description": "The provider ID for the OAuth provider" + "description": "The name of the user" }, - "accountId": { - "type": ["string", "null"], - "description": "The account ID associated with the refresh token" + "email": { + "type": "string", + "description": "The email of the user" }, - "userId": { - "type": ["string", "null"], - "description": "The user ID associated with the account" + "password": { + "type": "string", + "description": "The password of the user" + }, + "image": { + "type": "string", + "description": "The profile image URL of the user" + }, + "callbackURL": { + "type": "string", + "description": "The URL to use for email verification callback" + }, + "rememberMe": { + "type": "boolean", + "description": "If this is false, the session will not be remembered. Default is `true`." } }, - "required": ["providerId"] + "required": ["name", "email", "password"] } } } }, "responses": { "200": { - "description": "A Valid access token", + "description": "Successfully created user", "content": { "application/json": { "schema": { "type": "object", "properties": { - "tokenType": { - "type": "string" - }, - "idToken": { - "type": "string" - }, - "accessToken": { - "type": "string" - }, - "accessTokenExpiresAt": { + "token": { "type": "string", - "format": "date-time" + "nullable": true, + "description": "Authentication token for the session" + }, + "user": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The unique identifier of the user" + }, + "email": { + "type": "string", + "format": "email", + "description": "The email address of the user" + }, + "name": { + "type": "string", + "description": "The name of the user" + }, + "image": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "The profile image URL of the user" + }, + "emailVerified": { + "type": "boolean", + "description": "Whether the email has been verified" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "When the user was created" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "When the user was last updated" + } + }, + "required": [ + "id", + "email", + "name", + "emailVerified", + "createdAt", + "updatedAt" + ] } - } + }, + "required": ["user"] } } } }, "400": { - "description": "Invalid refresh token or provider configuration" + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." }, "401": { "content": { @@ -26085,6 +26625,21 @@ }, "description": "Not Found. The requested resource was not found." }, + "422": { + "description": "Unprocessable Entity. User already exists or failed to create user.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, "429": { "content": { "application/json": { @@ -26118,53 +26673,74 @@ } } }, - "/api/auth/account-info": { - "get": { + "/api/auth/sign-in/email": { + "post": { "tags": ["Default"], - "description": "Get the account info provided by the provider", + "description": "Sign in with email and password", + "operationId": "signInEmail", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email of the user" + }, + "password": { + "type": "string", + "description": "Password of the user" + }, + "callbackURL": { + "type": ["string", "null"], + "description": "Callback URL to use as a redirect for email verification" + }, + "rememberMe": { + "type": ["boolean", "null"], + "description": "If this is false, the session will not be remembered. Default is `true`.", + "default": true + } + }, + "required": ["email", "password"] + } + } + } + }, "responses": { "200": { - "description": "Success", + "description": "Success - Returns either session details or redirect URL", "content": { "application/json": { "schema": { "type": "object", + "description": "Session response when idToken is provided", "properties": { - "user": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "email": { - "type": "string" - }, - "image": { - "type": "string" - }, - "emailVerified": { - "type": "boolean" - } - }, - "required": ["id", "emailVerified"] + "redirect": { + "type": "boolean", + "enum": [false] }, - "data": { + "token": { + "type": "string", + "description": "Session token" + }, + "url": { + "type": "string", + "nullable": true + }, + "user": { "type": "object", - "properties": {}, - "additionalProperties": true + "$ref": "#/components/schemas/User" } }, - "required": ["user", "data"], - "additionalProperties": false + "required": ["redirect", "token", "user"] } } } @@ -26264,30 +26840,50 @@ } } }, - "/api/auth/ok": { - "get": { + "/api/auth/reset-password": { + "post": { "tags": ["Default"], - "description": "Check if the API is working", + "description": "Reset the password for a user", + "operationId": "resetPassword", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "newPassword": { + "type": "string", + "description": "The new password to set" + }, + "token": { + "type": ["string", "null"], + "description": "The token to reset the password" + } + }, + "required": ["newPassword"] + } + } + } + }, "responses": { "200": { - "description": "API is working", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "ok": { - "type": "boolean", - "description": "Indicates if the API is working" + "status": { + "type": "boolean" } - }, - "required": ["ok"] + } } } } @@ -26387,24 +26983,46 @@ } } }, - "/api/auth/error": { - "get": { + "/api/auth/verify-password": { + "post": { "tags": ["Default"], - "description": "Displays an error page", + "description": "Verify the current user's password", + "operationId": "verifyPassword", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "The password to verify" + } + }, + "required": ["password"] + } + } + } + }, "responses": { "200": { "description": "Success", "content": { - "text/html": { + "application/json": { "schema": { - "type": "string", - "description": "The HTML content of the error page" + "type": "object", + "properties": { + "status": { + "type": "boolean" + } + } } } } @@ -26504,45 +27122,35 @@ } } }, - "/api/auth/sign-in/username": { - "post": { - "tags": ["Username"], - "description": "Sign in with username", + "/api/auth/verify-email": { + "get": { + "tags": ["Default"], + "description": "Verify the email of the user", "security": [ { "bearerAuth": [] } ], - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "username": { - "type": "string", - "description": "The username of the user" - }, - "password": { - "type": "string", - "description": "The password of the user" - }, - "rememberMe": { - "type": ["boolean", "null"], - "description": "Remember the user session" - }, - "callbackURL": { - "type": ["string", "null"], - "description": "The URL to redirect to after email verification" - } - }, - "required": ["username", "password"] - } + "parameters": [ + { + "name": "token", + "in": "query", + "description": "The token to verify the email", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "callbackURL", + "in": "query", + "description": "The URL to redirect to after email verification", + "required": false, + "schema": { + "type": "string" } } - }, + ], "responses": { "200": { "description": "Success", @@ -26551,15 +27159,16 @@ "schema": { "type": "object", "properties": { - "token": { - "type": "string", - "description": "Session token for the authenticated session" - }, "user": { + "type": "object", "$ref": "#/components/schemas/User" + }, + "status": { + "type": "boolean", + "description": "Indicates if the email was verified successfully" } }, - "required": ["token", "user"] + "required": ["user", "status"] } } } @@ -26626,21 +27235,6 @@ }, "description": "Not Found. The requested resource was not found." }, - "422": { - "description": "Unprocessable Entity. Validation error", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - } - }, "429": { "content": { "application/json": { @@ -26674,9 +27268,11 @@ } } }, - "/api/auth/is-username-available": { + "/api/auth/send-verification-email": { "post": { - "tags": ["Username"], + "tags": ["Default"], + "description": "Send a verification email to the user", + "operationId": "sendVerificationEmail", "security": [ { "bearerAuth": [] @@ -26684,38 +27280,62 @@ ], "parameters": [], "requestBody": { - "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { - "username": { + "email": { "type": "string", - "description": "The username to check" + "description": "The email to send the verification email to", + "example": "user@example.com" + }, + "callbackURL": { + "type": "string", + "description": "The URL to use for email verification callback", + "example": "https://example.com/callback", + "nullable": true } }, - "required": ["username"] + "required": ["email"] } } } }, "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { + "type": "boolean", + "description": "Indicates if the email was sent successfully", + "example": true + } + } + } + } + } + }, "400": { + "description": "Bad Request", "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { - "type": "string" + "type": "string", + "description": "Error message", + "example": "Verification email isn't enabled" } - }, - "required": ["message"] + } } } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + } }, "401": { "content": { @@ -26796,10 +27416,10 @@ } } }, - "/api/auth/two-factor/get-totp-uri": { + "/api/auth/change-email": { "post": { - "tags": ["Two-factor"], - "description": "Use this endpoint to get the TOTP URI", + "tags": ["Default"], + "operationId": "changeEmail", "security": [ { "bearerAuth": [] @@ -26813,28 +27433,44 @@ "schema": { "type": "object", "properties": { - "password": { + "newEmail": { "type": "string", - "description": "User password" + "description": "The new email address to set must be a valid email address" + }, + "callbackURL": { + "type": ["string", "null"], + "description": "The URL to redirect to after email verification" } }, - "required": ["password"] + "required": ["newEmail"] } } } }, "responses": { "200": { - "description": "Successful response", + "description": "Email change request processed successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { - "totpURI": { - "type": "string" + "user": { + "type": "object", + "$ref": "#/components/schemas/User" + }, + "status": { + "type": "boolean", + "description": "Indicates if the request was successful" + }, + "message": { + "type": "string", + "enum": ["Email updated", "Verification email sent"], + "description": "Status message of the email change process", + "nullable": true } - } + }, + "required": ["status"] } } } @@ -26901,6 +27537,21 @@ }, "description": "Not Found. The requested resource was not found." }, + "422": { + "description": "Unprocessable Entity. Email already exists", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, "429": { "content": { "application/json": { @@ -26934,10 +27585,11 @@ } } }, - "/api/auth/two-factor/verify-totp": { + "/api/auth/change-password": { "post": { - "tags": ["Two-factor"], - "description": "Verify two factor TOTP", + "tags": ["Default"], + "description": "Change the password of the user", + "operationId": "changePassword", "security": [ { "bearerAuth": [] @@ -26951,32 +27603,85 @@ "schema": { "type": "object", "properties": { - "code": { + "newPassword": { "type": "string", - "description": "The otp code to verify. Eg: \"012345\"" + "description": "The new password to set" }, - "trustDevice": { + "currentPassword": { + "type": "string", + "description": "The current password is required" + }, + "revokeOtherSessions": { "type": ["boolean", "null"], - "description": "If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true" + "description": "Must be a boolean value" } }, - "required": ["code"] + "required": ["newPassword", "currentPassword"] } } } }, "responses": { "200": { - "description": "Successful response", + "description": "Password successfully changed", "content": { "application/json": { "schema": { "type": "object", "properties": { - "status": { - "type": "boolean" + "token": { + "type": "string", + "nullable": true, + "description": "New session token if other sessions were revoked" + }, + "user": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The unique identifier of the user" + }, + "email": { + "type": "string", + "format": "email", + "description": "The email address of the user" + }, + "name": { + "type": "string", + "description": "The name of the user" + }, + "image": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "The profile image URL of the user" + }, + "emailVerified": { + "type": "boolean", + "description": "Whether the email has been verified" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "When the user was created" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "When the user was last updated" + } + }, + "required": [ + "id", + "email", + "name", + "emailVerified", + "createdAt", + "updatedAt" + ] } - } + }, + "required": ["user"] } } } @@ -27076,26 +27781,48 @@ } } }, - "/api/auth/two-factor/send-otp": { + "/api/auth/update-user": { "post": { - "tags": ["Two-factor"], - "description": "Send two factor OTP to the user", + "tags": ["Default"], + "description": "Update the current user", + "operationId": "updateUser", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the user" + }, + "image": { + "type": "string", + "description": "The image of the user", + "nullable": true + } + } + } + } + } + }, "responses": { "200": { - "description": "Successful response", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "status": { - "type": "boolean" + "user": { + "type": "object", + "$ref": "#/components/schemas/User" } } } @@ -27197,10 +27924,11 @@ } } }, - "/api/auth/two-factor/verify-otp": { + "/api/auth/delete-user": { "post": { - "tags": ["Two-factor"], - "description": "Verify two factor OTP", + "tags": ["Default"], + "description": "Delete the user", + "operationId": "deleteUser", "security": [ { "bearerAuth": [] @@ -27208,82 +27936,47 @@ ], "parameters": [], "requestBody": { - "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { - "code": { + "callbackURL": { "type": "string", - "description": "The otp code to verify. Eg: \"012345\"" + "description": "The callback URL to redirect to after the user is deleted" }, - "trustDevice": { - "type": ["boolean", "null"] + "password": { + "type": "string", + "description": "The user's password. Required if session is not fresh" + }, + "token": { + "type": "string", + "description": "The deletion verification token" } - }, - "required": ["code"] + } } } } }, "responses": { "200": { - "description": "Two-factor OTP verified successfully", + "description": "User deletion processed successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { - "token": { - "type": "string", - "description": "Session token for the authenticated session" + "success": { + "type": "boolean", + "description": "Indicates if the operation was successful" }, - "user": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier of the user" - }, - "email": { - "type": "string", - "format": "email", - "nullable": true, - "description": "User's email address" - }, - "emailVerified": { - "type": "boolean", - "nullable": true, - "description": "Whether the email is verified" - }, - "name": { - "type": "string", - "nullable": true, - "description": "User's name" - }, - "image": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "User's profile image URL" - }, - "createdAt": { - "type": "string", - "format": "date-time", - "description": "Timestamp when the user was created" - }, - "updatedAt": { - "type": "string", - "format": "date-time", - "description": "Timestamp when the user was last updated" - } - }, - "required": ["id", "createdAt", "updatedAt"], - "description": "The authenticated user object" + "message": { + "type": "string", + "enum": ["User deleted", "Verification email sent"], + "description": "Status message of the deletion process" } }, - "required": ["token", "user"] + "required": ["success", "message"] } } } @@ -27383,10 +28076,11 @@ } } }, - "/api/auth/two-factor/verify-backup-code": { + "/api/auth/request-password-reset": { "post": { - "tags": ["Two-factor"], - "description": "Verify a backup code for two-factor authentication", + "tags": ["Default"], + "description": "Send a password reset email to the user", + "operationId": "requestPasswordReset", "security": [ { "bearerAuth": [] @@ -27400,111 +28094,35 @@ "schema": { "type": "object", "properties": { - "code": { + "email": { "type": "string", - "description": "A backup code to verify. Eg: \"123456\"" - }, - "disableSession": { - "type": ["boolean", "null"], - "description": "If true, the session cookie will not be set." + "description": "The email address of the user to send a password reset email to" }, - "trustDevice": { - "type": ["boolean", "null"], - "description": "If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true" + "redirectTo": { + "type": ["string", "null"], + "description": "The URL to redirect the user to reset their password. If the token isn't valid or expired, it'll be redirected with a query parameter `?error=INVALID_TOKEN`. If the token is valid, it'll be redirected with a query parameter `?token=VALID_TOKEN" } }, - "required": ["code"] + "required": ["email"] } } } }, "responses": { "200": { - "description": "Backup code verified successfully", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "user": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Unique identifier of the user" - }, - "email": { - "type": "string", - "format": "email", - "nullable": true, - "description": "User's email address" - }, - "emailVerified": { - "type": "boolean", - "nullable": true, - "description": "Whether the email is verified" - }, - "name": { - "type": "string", - "nullable": true, - "description": "User's name" - }, - "image": { - "type": "string", - "format": "uri", - "nullable": true, - "description": "User's profile image URL" - }, - "twoFactorEnabled": { - "type": "boolean", - "description": "Whether two-factor authentication is enabled for the user" - }, - "createdAt": { - "type": "string", - "format": "date-time", - "description": "Timestamp when the user was created" - }, - "updatedAt": { - "type": "string", - "format": "date-time", - "description": "Timestamp when the user was last updated" - } - }, - "required": [ - "id", - "twoFactorEnabled", - "createdAt", - "updatedAt" - ], - "description": "The authenticated user object with two-factor details" + "status": { + "type": "boolean" }, - "session": { - "type": "object", - "properties": { - "token": { - "type": "string", - "description": "Session token" - }, - "userId": { - "type": "string", - "description": "ID of the user associated with the session" - }, - "createdAt": { - "type": "string", - "format": "date-time", - "description": "Timestamp when the session was created" - }, - "expiresAt": { - "type": "string", - "format": "date-time", - "description": "Timestamp when the session expires" - } - }, - "required": ["token", "userId", "createdAt", "expiresAt"], - "description": "The current session object, included unless disableSession is true" + "message": { + "type": "string" } - }, - "required": ["user", "session"] + } } } } @@ -27604,55 +28222,48 @@ } } }, - "/api/auth/two-factor/generate-backup-codes": { - "post": { - "tags": ["Two-factor"], - "description": "Generate new backup codes for two-factor authentication", + "/api/auth/reset-password/{token}": { + "get": { + "tags": ["Default"], + "description": "Redirects the user to the callback URL with the token", + "operationId": "resetPasswordCallback", "security": [ { "bearerAuth": [] } ], - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "password": { - "type": "string", - "description": "The users password." - } - }, - "required": ["password"] - } + "parameters": [ + { + "name": "token", + "in": "path", + "required": true, + "description": "The token to reset the password", + "schema": { + "type": "string" + } + }, + { + "name": "callbackURL", + "in": "query", + "required": true, + "description": "The URL to redirect the user to reset their password", + "schema": { + "type": "string" } } - }, + ], "responses": { "200": { - "description": "Backup codes generated successfully", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "status": { - "type": "boolean", - "description": "Indicates if the backup codes were generated successfully", - "enum": [true] - }, - "backupCodes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Array of generated backup codes in plain text" + "token": { + "type": "string" } - }, - "required": ["status", "backupCodes"] + } } } } @@ -27752,56 +28363,26 @@ } } }, - "/api/auth/two-factor/enable": { - "post": { - "tags": ["Two-factor"], - "description": "Use this endpoint to enable two factor authentication. This will generate a TOTP URI and backup codes. Once the user verifies the TOTP URI, the two factor authentication will be enabled.", + "/api/auth/list-sessions": { + "get": { + "tags": ["Default"], + "description": "List all active sessions for the user", + "operationId": "listUserSessions", "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "password": { - "type": "string", - "description": "User password" - }, - "issuer": { - "type": ["string", "null"], - "description": "Custom issuer for the TOTP URI" - } - }, - "required": ["password"] - } - } - } - }, "responses": { "200": { - "description": "Successful response", + "description": "Success", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "totpURI": { - "type": "string", - "description": "TOTP URI" - }, - "backupCodes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Backup codes" - } + "type": "array", + "items": { + "$ref": "#/components/schemas/Session" } } } @@ -27902,10 +28483,10 @@ } } }, - "/api/auth/two-factor/disable": { + "/api/auth/revoke-session": { "post": { - "tags": ["Two-factor"], - "description": "Use this endpoint to disable two factor authentication.", + "tags": ["Default"], + "description": "Revoke a single session", "security": [ { "bearerAuth": [] @@ -27913,34 +28494,35 @@ ], "parameters": [], "requestBody": { - "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { - "password": { + "token": { "type": "string", - "description": "User password" + "description": "The token to revoke" } }, - "required": ["password"] + "required": ["token"] } } } }, "responses": { "200": { - "description": "Successful response", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { - "type": "boolean" + "type": "boolean", + "description": "Indicates if the session was revoked successfully" } - } + }, + "required": ["status"] } } } @@ -28040,10 +28622,10 @@ } } }, - "/api/auth/one-tap/callback": { + "/api/auth/revoke-sessions": { "post": { - "tags": ["One-tap"], - "description": "Use this endpoint to authenticate with Google One Tap", + "tags": ["Default"], + "description": "Revoke all sessions for the user", "security": [ { "bearerAuth": [] @@ -28051,43 +28633,48 @@ ], "parameters": [], "requestBody": { - "required": true, "content": { "application/json": { "schema": { "type": "object", - "properties": { - "idToken": { - "type": "string", - "description": "Google ID token, which the client obtains from the One Tap API" - } - }, - "required": ["idToken"] + "properties": {} } } } }, "responses": { "200": { - "description": "Successful response", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "session": { - "$ref": "#/components/schemas/Session" - }, - "user": { - "$ref": "#/components/schemas/User" + "status": { + "type": "boolean", + "description": "Indicates if all sessions were revoked successfully" } - } + }, + "required": ["status"] } } } }, "400": { - "description": "Invalid token" + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." }, "401": { "content": { @@ -28168,11 +28755,10 @@ } } }, - "/api/auth/email-otp/send-verification-otp": { + "/api/auth/revoke-other-sessions": { "post": { - "tags": ["Email-otp"], - "description": "Send a verification OTP to an email", - "operationId": "sendEmailVerificationOTP", + "tags": ["Default"], + "description": "Revoke all other sessions for the user except the current one", "security": [ { "bearerAuth": [] @@ -28180,22 +28766,11 @@ ], "parameters": [], "requestBody": { - "required": true, "content": { "application/json": { "schema": { "type": "object", - "properties": { - "email": { - "type": "string", - "description": "Email address to send the OTP" - }, - "type": { - "type": "string", - "description": "Type of the OTP" - } - }, - "required": ["email", "type"] + "properties": {} } } } @@ -28208,10 +28783,12 @@ "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "status": { + "type": "boolean", + "description": "Indicates if all other sessions were revoked successfully" } - } + }, + "required": ["status"] } } } @@ -28311,11 +28888,11 @@ } } }, - "/api/auth/email-otp/check-verification-otp": { + "/api/auth/link-social": { "post": { - "tags": ["Email-otp"], - "description": "Verify an email with an OTP", - "operationId": "verifyEmailWithOTP", + "tags": ["Default"], + "description": "Link a social account to the user", + "operationId": "linkSocialAccount", "security": [ { "bearerAuth": [] @@ -28329,20 +28906,54 @@ "schema": { "type": "object", "properties": { - "email": { - "type": "string", - "description": "Email address the OTP was sent to" + "callbackURL": { + "type": ["string", "null"], + "description": "The URL to redirect to after the user has signed in" }, - "type": { - "type": "string", - "description": "Type of the OTP" + "provider": { + "type": "string" }, - "otp": { - "type": "string", - "description": "OTP to verify" + "idToken": { + "type": ["object", "null"], + "properties": { + "token": { + "type": "string" + }, + "nonce": { + "type": ["string", "null"] + }, + "accessToken": { + "type": ["string", "null"] + }, + "refreshToken": { + "type": ["string", "null"] + }, + "scopes": { + "type": ["array", "null"] + } + }, + "required": ["token"] + }, + "requestSignUp": { + "type": ["boolean", "null"] + }, + "scopes": { + "type": ["array", "null"], + "description": "Additional scopes to request from the provider" + }, + "errorCallbackURL": { + "type": ["string", "null"], + "description": "The URL to redirect to if there is an error during the link process" + }, + "disableRedirect": { + "type": ["boolean", "null"], + "description": "Disable automatic redirection to the provider. Useful for handling the redirection yourself" + }, + "additionalData": { + "type": ["string", "null"] } }, - "required": ["email", "type", "otp"] + "required": ["provider"] } } } @@ -28355,10 +28966,19 @@ "schema": { "type": "object", "properties": { - "success": { + "url": { + "type": "string", + "description": "The authorization URL to redirect the user to" + }, + "redirect": { + "type": "boolean", + "description": "Indicates if the user should be redirected to the authorization URL" + }, + "status": { "type": "boolean" } - } + }, + "required": ["redirect"] } } } @@ -28458,60 +29078,64 @@ } } }, - "/api/auth/email-otp/verify-email": { - "post": { - "tags": ["Email-otp"], - "description": "Verify email with OTP", + "/api/auth/list-accounts": { + "get": { + "tags": ["Default"], + "description": "List all accounts linked to the user", + "operationId": "listUserAccounts", "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "description": "Email address to verify" - }, - "otp": { - "type": "string", - "description": "OTP to verify" - } - }, - "required": ["email", "otp"] - } - } - } - }, "responses": { "200": { "description": "Success", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "status": { - "type": "boolean", - "description": "Indicates if the verification was successful", - "enum": [true] - }, - "token": { - "type": "string", - "nullable": true, - "description": "Session token if autoSignInAfterVerification is enabled, otherwise null" + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "providerId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "accountId": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + } }, - "user": { - "$ref": "#/components/schemas/User" - } - }, - "required": ["status", "token", "user"] + "required": [ + "id", + "providerId", + "createdAt", + "updatedAt", + "accountId", + "userId", + "scopes" + ] + } } } } @@ -28611,55 +29235,52 @@ } } }, - "/api/auth/sign-in/email-otp": { - "post": { - "tags": ["Email-otp"], - "description": "Sign in with email and OTP", - "operationId": "signInWithEmailOTP", + "/api/auth/delete-user/callback": { + "get": { + "tags": ["Default"], + "description": "Callback to complete user deletion with verification token", "security": [ { "bearerAuth": [] } ], - "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "email": { - "type": "string", - "description": "Email address to sign in" - }, - "otp": { - "type": "string", - "description": "OTP sent to the email" - } - }, - "required": ["email", "otp"] - } + "parameters": [ + { + "name": "token", + "in": "query", + "schema": { + "type": "string", + "description": "The token to verify the deletion request" + } + }, + { + "name": "callbackURL", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "The URL to redirect to after deletion" } } - }, + ], "responses": { "200": { - "description": "Success", + "description": "User successfully deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { - "token": { - "type": "string", - "description": "Session token for the authenticated session" + "success": { + "type": "boolean", + "description": "Indicates if the deletion was successful" }, - "user": { - "$ref": "#/components/schemas/User" + "message": { + "type": "string", + "enum": ["User deleted"], + "description": "Confirmation message" } }, - "required": ["token", "user"] + "required": ["success", "message"] } } } @@ -28759,11 +29380,10 @@ } } }, - "/api/auth/email-otp/request-password-reset": { + "/api/auth/unlink-account": { "post": { - "tags": ["Email-otp"], - "description": "Request password reset with email and OTP", - "operationId": "requestPasswordResetWithEmailOTP", + "tags": ["Default"], + "description": "Unlink an account", "security": [ { "bearerAuth": [] @@ -28777,12 +29397,14 @@ "schema": { "type": "object", "properties": { - "email": { - "type": "string", - "description": "Email address to send the OTP" + "providerId": { + "type": "string" + }, + "accountId": { + "type": ["string", "null"] } }, - "required": ["email"] + "required": ["providerId"] } } } @@ -28795,9 +29417,8 @@ "schema": { "type": "object", "properties": { - "success": { - "type": "boolean", - "description": "Indicates if the OTP was sent successfully" + "status": { + "type": "boolean" } } } @@ -28899,11 +29520,10 @@ } } }, - "/api/auth/forget-password/email-otp": { + "/api/auth/refresh-token": { "post": { - "tags": ["Email-otp"], - "description": "Deprecated: Use /email-otp/request-password-reset instead.", - "operationId": "forgetPasswordWithEmailOTP", + "tags": ["Default"], + "description": "Refresh the access token using a refresh token", "security": [ { "bearerAuth": [] @@ -28917,27 +29537,51 @@ "schema": { "type": "object", "properties": { - "email": { + "providerId": { "type": "string", - "description": "Email address to send the OTP" + "description": "The provider ID for the OAuth provider" + }, + "accountId": { + "type": ["string", "null"], + "description": "The account ID associated with the refresh token" + }, + "userId": { + "type": ["string", "null"], + "description": "The user ID associated with the account" } }, - "required": ["email"] + "required": ["providerId"] } } } }, "responses": { "200": { - "description": "Success", + "description": "Access token refreshed successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean", - "description": "Indicates if the OTP was sent successfully" + "tokenType": { + "type": "string" + }, + "idToken": { + "type": "string" + }, + "accessToken": { + "type": "string" + }, + "refreshToken": { + "type": "string" + }, + "accessTokenExpiresAt": { + "type": "string", + "format": "date-time" + }, + "refreshTokenExpiresAt": { + "type": "string", + "format": "date-time" } } } @@ -28945,20 +29589,7 @@ } }, "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + "description": "Invalid refresh token or provider configuration" }, "401": { "content": { @@ -29039,11 +29670,10 @@ } } }, - "/api/auth/email-otp/reset-password": { + "/api/auth/get-access-token": { "post": { - "tags": ["Email-otp"], - "description": "Reset password with email and OTP", - "operationId": "resetPasswordWithEmailOTP", + "tags": ["Default"], + "description": "Get a valid access token, doing a refresh if needed", "security": [ { "bearerAuth": [] @@ -29057,34 +29687,44 @@ "schema": { "type": "object", "properties": { - "email": { + "providerId": { "type": "string", - "description": "Email address to reset the password" + "description": "The provider ID for the OAuth provider" }, - "otp": { - "type": "string", - "description": "OTP sent to the email" + "accountId": { + "type": ["string", "null"], + "description": "The account ID associated with the refresh token" }, - "password": { - "type": "string", - "description": "New password" + "userId": { + "type": ["string", "null"], + "description": "The user ID associated with the account" } }, - "required": ["email", "otp", "password"] + "required": ["providerId"] } } } }, "responses": { "200": { - "description": "Success", + "description": "A Valid access token", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "tokenType": { + "type": "string" + }, + "idToken": { + "type": "string" + }, + "accessToken": { + "type": "string" + }, + "accessTokenExpiresAt": { + "type": "string", + "format": "date-time" } } } @@ -29092,20 +29732,7 @@ } }, "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + "description": "Invalid refresh token or provider configuration" }, "401": { "content": { @@ -29186,53 +29813,16 @@ } } }, - "/api/auth/organization/create": { - "post": { - "tags": ["Organization"], - "description": "Create an organization", + "/api/auth/account-info": { + "get": { + "tags": ["Default"], + "description": "Get the account info provided by the provider", "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the organization" - }, - "slug": { - "type": "string", - "description": "The slug of the organization" - }, - "userId": { - "type": ["string", "null"], - "description": "The user id of the organization creator. If not provided, the current user will be used. Should only be used by admins or when called by the server. server-only. Eg: \"user-id\"" - }, - "logo": { - "type": ["string", "null"], - "description": "The logo of the organization" - }, - "metadata": { - "type": ["string", "null"], - "description": "The metadata of the organization" - }, - "keepCurrentActiveOrganization": { - "type": ["boolean", "null"], - "description": "Whether to keep the current active organization active after creating a new one. Eg: true" - } - }, - "required": ["name", "slug"] - } - } - } - }, "responses": { "200": { "description": "Success", @@ -29240,8 +29830,36 @@ "application/json": { "schema": { "type": "object", - "description": "The organization that was created", - "$ref": "#/components/schemas/Organization" + "properties": { + "user": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "image": { + "type": "string" + }, + "emailVerified": { + "type": "boolean" + } + }, + "required": ["id", "emailVerified"] + }, + "data": { + "type": "object", + "properties": {}, + "additionalProperties": true + } + }, + "required": ["user", "data"], + "additionalProperties": false } } } @@ -29341,63 +29959,30 @@ } } }, - "/api/auth/organization/update": { - "post": { - "tags": ["Organization"], - "description": "Update an organization", + "/api/auth/ok": { + "get": { + "tags": ["Default"], + "description": "Check if the API is working", "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "data": { - "type": "object", - "properties": { - "name": { - "type": ["string", "null"], - "description": "The name of the organization" - }, - "slug": { - "type": ["string", "null"], - "description": "The slug of the organization" - }, - "logo": { - "type": ["string", "null"], - "description": "The logo of the organization" - }, - "metadata": { - "type": ["string", "null"], - "description": "The metadata of the organization" - } - } - }, - "organizationId": { - "type": ["string", "null"], - "description": "The organization ID. Eg: \"org-id\"" - } - }, - "required": ["data"] - } - } - } - }, "responses": { "200": { - "description": "Success", + "description": "API is working", "content": { "application/json": { "schema": { "type": "object", - "description": "The updated organization", - "$ref": "#/components/schemas/Organization" + "properties": { + "ok": { + "type": "boolean", + "description": "Indicates if the API is working" + } + }, + "required": ["ok"] } } } @@ -29497,41 +30082,24 @@ } } }, - "/api/auth/organization/delete": { - "post": { - "tags": ["Organization"], - "description": "Delete an organization", + "/api/auth/error": { + "get": { + "tags": ["Default"], + "description": "Displays an error page", "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "organizationId": { - "type": "string", - "description": "The organization id to delete" - } - }, - "required": ["organizationId"] - } - } - } - }, "responses": { "200": { "description": "Success", "content": { - "application/json": { + "text/html": { "schema": { "type": "string", - "description": "The organization id that was deleted" + "description": "The HTML content of the error page" } } } @@ -29631,11 +30199,10 @@ } } }, - "/api/auth/organization/set-active": { + "/api/auth/sign-in/username": { "post": { - "tags": ["Organization"], - "description": "Set the active organization", - "operationId": "setActiveOrganization", + "tags": ["Username"], + "description": "Sign in with username", "security": [ { "bearerAuth": [] @@ -29649,15 +30216,24 @@ "schema": { "type": "object", "properties": { - "organizationId": { - "type": ["string", "null"] + "username": { + "type": "string", + "description": "The username of the user" }, - "organizationSlug": { + "password": { + "type": "string", + "description": "The password of the user" + }, + "rememberMe": { + "type": ["boolean", "null"], + "description": "Remember the user session" + }, + "callbackURL": { "type": ["string", "null"], - "description": "The organization slug to set as active. It can be null to unset the active organization if organizationId is not provided. Eg: \"org-slug\"" + "description": "The URL to redirect to after email verification" } }, - "required": [] + "required": ["username", "password"] } } } @@ -29669,8 +30245,16 @@ "application/json": { "schema": { "type": "object", - "description": "The organization", - "$ref": "#/components/schemas/Organization" + "properties": { + "token": { + "type": "string", + "description": "Session token for the authenticated session" + }, + "user": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["token", "user"] } } } @@ -29737,6 +30321,21 @@ }, "description": "Not Found. The requested resource was not found." }, + "422": { + "description": "Unprocessable Entity. Validation error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + } + }, "429": { "content": { "application/json": { @@ -29770,30 +30369,33 @@ } } }, - "/api/auth/organization/get-full-organization": { - "get": { - "tags": ["Organization"], - "description": "Get the full organization", - "operationId": "getOrganization", + "/api/auth/is-username-available": { + "post": { + "tags": ["Username"], "security": [ { "bearerAuth": [] } ], "parameters": [], - "responses": { - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "object", - "description": "The organization", - "$ref": "#/components/schemas/Organization" - } + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "The username to check" + } + }, + "required": ["username"] } } - }, + } + }, + "responses": { "400": { "content": { "application/json": { @@ -29889,25 +30491,44 @@ } } }, - "/api/auth/organization/list": { - "get": { - "tags": ["Organization"], - "description": "List all organizations", + "/api/auth/two-factor/get-totp-uri": { + "post": { + "tags": ["Two-factor"], + "description": "Use this endpoint to get the TOTP URI", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "User password" + } + }, + "required": ["password"] + } + } + } + }, "responses": { "200": { - "description": "Success", + "description": "Successful response", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Organization" + "type": "object", + "properties": { + "totpURI": { + "type": "string" + } } } } @@ -30008,11 +30629,10 @@ } } }, - "/api/auth/organization/invite-member": { + "/api/auth/two-factor/verify-totp": { "post": { - "tags": ["Organization"], - "description": "Create an invitation to an organization", - "operationId": "createOrganizationInvitation", + "tags": ["Two-factor"], + "description": "Verify two factor TOTP", "security": [ { "bearerAuth": [] @@ -30026,74 +30646,32 @@ "schema": { "type": "object", "properties": { - "email": { - "type": "string", - "description": "The email address of the user to invite" - }, - "role": { + "code": { "type": "string", - "description": "The role(s) to assign to the user. It can be `admin`, `member`, owner. Eg: \"member\"" - }, - "organizationId": { - "type": ["string", "null"], - "description": "The organization ID to invite the user to" + "description": "The otp code to verify. Eg: \"012345\"" }, - "resend": { + "trustDevice": { "type": ["boolean", "null"], - "description": "Resend the invitation email, if the user is already invited. Eg: true" - }, - "teamId": { - "type": "string" + "description": "If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true" } }, - "required": ["email", "role", "teamId"] + "required": ["code"] } } } }, "responses": { "200": { - "description": "Success", + "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "email": { - "type": "string" - }, - "role": { - "type": "string" - }, - "organizationId": { - "type": "string" - }, - "inviterId": { - "type": "string" - }, "status": { - "type": "string" - }, - "expiresAt": { - "type": "string" - }, - "createdAt": { - "type": "string" + "type": "boolean" } - }, - "required": [ - "id", - "email", - "role", - "organizationId", - "inviterId", - "status", - "expiresAt", - "createdAt" - ] + } } } } @@ -30193,33 +30771,32 @@ } } }, - "/api/auth/organization/cancel-invitation": { + "/api/auth/two-factor/send-otp": { "post": { - "tags": ["Organization"], + "tags": ["Two-factor"], + "description": "Send two factor OTP to the user", "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "invitationId": { - "type": "string", - "description": "The ID of the invitation to cancel" + "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { + "type": "boolean" + } } - }, - "required": ["invitationId"] + } } } - } - }, - "responses": { + }, "400": { "content": { "application/json": { @@ -30315,10 +30892,10 @@ } } }, - "/api/auth/organization/accept-invitation": { + "/api/auth/two-factor/verify-otp": { "post": { - "tags": ["Organization"], - "description": "Accept an invitation to an organization", + "tags": ["Two-factor"], + "description": "Verify two factor OTP", "security": [ { "bearerAuth": [] @@ -30332,31 +30909,76 @@ "schema": { "type": "object", "properties": { - "invitationId": { + "code": { "type": "string", - "description": "The ID of the invitation to accept" + "description": "The otp code to verify. Eg: \"012345\"" + }, + "trustDevice": { + "type": ["boolean", "null"] } }, - "required": ["invitationId"] + "required": ["code"] } } } }, "responses": { "200": { - "description": "Success", + "description": "Two-factor OTP verified successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { - "invitation": { - "type": "object" + "token": { + "type": "string", + "description": "Session token for the authenticated session" }, - "member": { - "type": "object" + "user": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique identifier of the user" + }, + "email": { + "type": "string", + "format": "email", + "nullable": true, + "description": "User's email address" + }, + "emailVerified": { + "type": "boolean", + "nullable": true, + "description": "Whether the email is verified" + }, + "name": { + "type": "string", + "nullable": true, + "description": "User's name" + }, + "image": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "User's profile image URL" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the user was created" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the user was last updated" + } + }, + "required": ["id", "createdAt", "updatedAt"], + "description": "The authenticated user object" } - } + }, + "required": ["token", "user"] } } } @@ -30456,76 +31078,128 @@ } } }, - "/api/auth/organization/get-invitation": { - "get": { - "tags": ["Organization"], - "description": "Get an invitation by ID", + "/api/auth/two-factor/verify-backup-code": { + "post": { + "tags": ["Two-factor"], + "description": "Verify a backup code for two-factor authentication", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "name": "id", - "in": "query", - "schema": { - "type": "string", - "description": "The ID of the invitation to get" + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "A backup code to verify. Eg: \"123456\"" + }, + "disableSession": { + "type": ["boolean", "null"], + "description": "If true, the session cookie will not be set." + }, + "trustDevice": { + "type": ["boolean", "null"], + "description": "If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true" + } + }, + "required": ["code"] + } } } - ], + }, "responses": { "200": { - "description": "Success", + "description": "Backup code verified successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "email": { - "type": "string" - }, - "role": { - "type": "string" - }, - "organizationId": { - "type": "string" - }, - "inviterId": { - "type": "string" - }, - "status": { - "type": "string" - }, - "expiresAt": { - "type": "string" - }, - "organizationName": { - "type": "string" - }, - "organizationSlug": { - "type": "string" + "user": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique identifier of the user" + }, + "email": { + "type": "string", + "format": "email", + "nullable": true, + "description": "User's email address" + }, + "emailVerified": { + "type": "boolean", + "nullable": true, + "description": "Whether the email is verified" + }, + "name": { + "type": "string", + "nullable": true, + "description": "User's name" + }, + "image": { + "type": "string", + "format": "uri", + "nullable": true, + "description": "User's profile image URL" + }, + "twoFactorEnabled": { + "type": "boolean", + "description": "Whether two-factor authentication is enabled for the user" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the user was created" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the user was last updated" + } + }, + "required": [ + "id", + "twoFactorEnabled", + "createdAt", + "updatedAt" + ], + "description": "The authenticated user object with two-factor details" }, - "inviterEmail": { - "type": "string" + "session": { + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "Session token" + }, + "userId": { + "type": "string", + "description": "ID of the user associated with the session" + }, + "createdAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the session was created" + }, + "expiresAt": { + "type": "string", + "format": "date-time", + "description": "Timestamp when the session expires" + } + }, + "required": ["token", "userId", "createdAt", "expiresAt"], + "description": "The current session object, included unless disableSession is true" } }, - "required": [ - "id", - "email", - "role", - "organizationId", - "inviterId", - "status", - "expiresAt", - "organizationName", - "organizationSlug", - "inviterEmail" - ] + "required": ["user", "session"] } } } @@ -30625,10 +31299,10 @@ } } }, - "/api/auth/organization/reject-invitation": { + "/api/auth/two-factor/generate-backup-codes": { "post": { - "tags": ["Organization"], - "description": "Reject an invitation to an organization", + "tags": ["Two-factor"], + "description": "Generate new backup codes for two-factor authentication", "security": [ { "bearerAuth": [] @@ -30642,32 +31316,38 @@ "schema": { "type": "object", "properties": { - "invitationId": { + "password": { "type": "string", - "description": "The ID of the invitation to reject" + "description": "The users password." } }, - "required": ["invitationId"] + "required": ["password"] } } } }, "responses": { "200": { - "description": "Success", + "description": "Backup codes generated successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { - "invitation": { - "type": "object" + "status": { + "type": "boolean", + "description": "Indicates if the backup codes were generated successfully", + "enum": [true] }, - "member": { - "type": "object", - "nullable": true + "backupCodes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of generated backup codes in plain text" } - } + }, + "required": ["status", "backupCodes"] } } } @@ -30767,143 +31447,57 @@ } } }, - "/api/auth/organization/list-invitations": { - "get": { - "tags": ["Organization"], + "/api/auth/two-factor/enable": { + "post": { + "tags": ["Two-factor"], + "description": "Use this endpoint to enable two factor authentication. This will generate a TOTP URI and backup codes. Once the user verifies the TOTP URI, the two factor authentication will be enabled.", "security": [ { "bearerAuth": [] } ], "parameters": [], - "responses": { - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "User password" }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." - }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." - }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." - }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." - }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } + "issuer": { + "type": ["string", "null"], + "description": "Custom issuer for the TOTP URI" } - } + }, + "required": ["password"] } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." - } - } - } - }, - "/api/auth/organization/get-active-member": { - "get": { - "tags": ["Organization"], - "description": "Get the member details of the active organization", - "security": [ - { - "bearerAuth": [] + } } - ], - "parameters": [], + }, "responses": { "200": { - "description": "Success", + "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "organizationId": { - "type": "string" + "totpURI": { + "type": "string", + "description": "TOTP URI" }, - "role": { - "type": "string" + "backupCodes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Backup codes" } - }, - "required": ["id", "userId", "organizationId", "role"] + } } } } @@ -31003,9 +31597,10 @@ } } }, - "/api/auth/organization/check-slug": { + "/api/auth/two-factor/disable": { "post": { - "tags": ["Organization"], + "tags": ["Two-factor"], + "description": "Use this endpoint to disable two factor authentication.", "security": [ { "bearerAuth": [] @@ -31019,17 +31614,32 @@ "schema": { "type": "object", "properties": { - "slug": { + "password": { "type": "string", - "description": "The organization slug to check. Eg: \"my-org\"" + "description": "User password" } }, - "required": ["slug"] + "required": ["password"] } } } }, "responses": { + "200": { + "description": "Successful response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { + "type": "boolean" + } + } + } + } + } + }, "400": { "content": { "application/json": { @@ -31125,10 +31735,10 @@ } } }, - "/api/auth/organization/remove-member": { + "/api/auth/one-tap/callback": { "post": { - "tags": ["Organization"], - "description": "Remove a member from an organization", + "tags": ["One-tap"], + "description": "Use this endpoint to authenticate with Google One Tap", "security": [ { "bearerAuth": [] @@ -31142,67 +31752,37 @@ "schema": { "type": "object", "properties": { - "memberIdOrEmail": { + "idToken": { "type": "string", - "description": "The ID or email of the member to remove" - }, - "organizationId": { - "type": ["string", "null"], - "description": "The ID of the organization to remove the member from. If not provided, the active organization will be used. Eg: \"org-id\"" + "description": "Google ID token, which the client obtains from the One Tap API" } }, - "required": ["memberIdOrEmail"] + "required": ["idToken"] } } } }, "responses": { "200": { - "description": "Success", + "description": "Successful response", "content": { "application/json": { "schema": { "type": "object", "properties": { - "member": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "organizationId": { - "type": "string" - }, - "role": { - "type": "string" - } - }, - "required": ["id", "userId", "organizationId", "role"] + "session": { + "$ref": "#/components/schemas/Session" + }, + "user": { + "$ref": "#/components/schemas/User" } - }, - "required": ["member"] + } } } } }, "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + "description": "Invalid token" }, "401": { "content": { @@ -31283,11 +31863,11 @@ } } }, - "/api/auth/organization/update-member-role": { + "/api/auth/email-otp/send-verification-otp": { "post": { - "tags": ["Organization"], - "description": "Update the role of a member in an organization", - "operationId": "updateOrganizationMemberRole", + "tags": ["Email-otp"], + "description": "Send a verification OTP to an email", + "operationId": "sendEmailVerificationOTP", "security": [ { "bearerAuth": [] @@ -31301,20 +31881,16 @@ "schema": { "type": "object", "properties": { - "role": { + "email": { "type": "string", - "description": "The new role to be applied. This can be a string or array of strings representing the roles. Eg: [\"admin\", \"sale\"]" + "description": "Email address to send the OTP" }, - "memberId": { + "type": { "type": "string", - "description": "The member id to apply the role update to. Eg: \"member-id\"" - }, - "organizationId": { - "type": ["string", "null"], - "description": "An optional organization ID which the member is a part of to apply the role update. If not provided, you must provide session headers to get the active organization. Eg: \"organization-id\"" + "description": "Type of the OTP" } }, - "required": ["role", "memberId"] + "required": ["email", "type"] } } } @@ -31327,26 +31903,10 @@ "schema": { "type": "object", "properties": { - "member": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "organizationId": { - "type": "string" - }, - "role": { - "type": "string" - } - }, - "required": ["id", "userId", "organizationId", "role"] + "success": { + "type": "boolean" } - }, - "required": ["member"] + } } } } @@ -31446,9 +32006,11 @@ } } }, - "/api/auth/organization/leave": { + "/api/auth/email-otp/check-verification-otp": { "post": { - "tags": ["Organization"], + "tags": ["Email-otp"], + "description": "Verify an email with an OTP", + "operationId": "verifyEmailWithOTP", "security": [ { "bearerAuth": [] @@ -31462,17 +32024,40 @@ "schema": { "type": "object", "properties": { - "organizationId": { + "email": { "type": "string", - "description": "The organization Id for the member to leave. Eg: \"organization-id\"" + "description": "Email address the OTP was sent to" + }, + "type": { + "type": "string", + "description": "Type of the OTP" + }, + "otp": { + "type": "string", + "description": "OTP to verify" } }, - "required": ["organizationId"] + "required": ["email", "type", "otp"] } } } }, "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, "400": { "content": { "application/json": { @@ -31568,72 +32153,60 @@ } } }, - "/api/auth/organization/list-user-invitations": { - "get": { - "tags": ["Organization"], - "description": "List all invitations a user has received", + "/api/auth/email-otp/verify-email": { + "post": { + "tags": ["Email-otp"], + "description": "Verify email with OTP", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email address to verify" + }, + "otp": { + "type": "string", + "description": "OTP to verify" + } + }, + "required": ["email", "otp"] + } + } + } + }, "responses": { "200": { "description": "Success", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "email": { - "type": "string" - }, - "role": { - "type": "string" - }, - "organizationId": { - "type": "string" - }, - "organizationName": { - "type": "string" - }, - "inviterId": { - "type": "string", - "description": "The ID of the user who created the invitation" - }, - "teamId": { - "type": "string", - "description": "The ID of the team associated with the invitation", - "nullable": true - }, - "status": { - "type": "string" - }, - "expiresAt": { - "type": "string" - }, - "createdAt": { - "type": "string" - } + "type": "object", + "properties": { + "status": { + "type": "boolean", + "description": "Indicates if the verification was successful", + "enum": [true] }, - "required": [ - "id", - "email", - "role", - "organizationId", - "organizationName", - "inviterId", - "status", - "expiresAt", - "createdAt" - ] - } + "token": { + "type": "string", + "nullable": true, + "description": "Session token if autoSignInAfterVerification is enabled, otherwise null" + }, + "user": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["status", "token", "user"] } } } @@ -31733,16 +32306,59 @@ } } }, - "/api/auth/organization/list-members": { - "get": { - "tags": ["Organization"], + "/api/auth/sign-in/email-otp": { + "post": { + "tags": ["Email-otp"], + "description": "Sign in with email and OTP", + "operationId": "signInWithEmailOTP", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email address to sign in" + }, + "otp": { + "type": "string", + "description": "OTP sent to the email" + } + }, + "required": ["email", "otp"] + } + } + } + }, "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "Session token for the authenticated session" + }, + "user": { + "$ref": "#/components/schemas/User" + } + }, + "required": ["token", "user"] + } + } + } + }, "400": { "content": { "application/json": { @@ -31838,16 +32454,51 @@ } } }, - "/api/auth/organization/get-active-member-role": { - "get": { - "tags": ["Organization"], + "/api/auth/email-otp/request-password-reset": { + "post": { + "tags": ["Email-otp"], + "description": "Request password reset with email and OTP", + "operationId": "requestPasswordResetWithEmailOTP", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email address to send the OTP" + } + }, + "required": ["email"] + } + } + } + }, "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "description": "Indicates if the OTP was sent successfully" + } + } + } + } + } + }, "400": { "content": { "application/json": { @@ -31943,10 +32594,11 @@ } } }, - "/api/auth/organization/has-permission": { + "/api/auth/forget-password/email-otp": { "post": { - "tags": ["Organization"], - "description": "Check if the user has permission", + "tags": ["Email-otp"], + "description": "Deprecated: Use /email-otp/request-password-reset instead.", + "operationId": "forgetPasswordWithEmailOTP", "security": [ { "bearerAuth": [] @@ -31954,22 +32606,18 @@ ], "parameters": [], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { - "permission": { - "type": "object", - "description": "The permission to check", - "deprecated": true - }, - "permissions": { - "type": "object", - "description": "The permission to check" + "email": { + "type": "string", + "description": "Email address to send the OTP" } }, - "required": ["permissions"] + "required": ["email"] } } } @@ -31982,14 +32630,11 @@ "schema": { "type": "object", "properties": { - "error": { - "type": "string" - }, "success": { - "type": "boolean" + "type": "boolean", + "description": "Indicates if the OTP was sent successfully" } - }, - "required": ["success"] + } } } } @@ -32089,11 +32734,11 @@ } } }, - "/api/auth/admin/set-role": { + "/api/auth/email-otp/reset-password": { "post": { - "tags": ["Admin"], - "description": "Set the role of a user", - "operationId": "setUserRole", + "tags": ["Email-otp"], + "description": "Reset password with email and OTP", + "operationId": "resetPasswordWithEmailOTP", "security": [ { "bearerAuth": [] @@ -32107,30 +32752,34 @@ "schema": { "type": "object", "properties": { - "userId": { + "email": { "type": "string", - "description": "The user id" + "description": "Email address to reset the password" }, - "role": { + "otp": { "type": "string", - "description": "The role to set, this can be a string or an array of strings. Eg: `admin` or `[admin, user]`" + "description": "OTP sent to the email" + }, + "password": { + "type": "string", + "description": "New password" } }, - "required": ["userId", "role"] + "required": ["email", "otp", "password"] } } } }, "responses": { "200": { - "description": "User role updated", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "user": { - "$ref": "#/components/schemas/User" + "success": { + "type": "boolean" } } } @@ -32232,38 +32881,62 @@ } } }, - "/api/auth/admin/get-user": { - "get": { - "tags": ["Admin"], - "description": "Get an existing user", - "operationId": "getUser", + "/api/auth/organization/create": { + "post": { + "tags": ["Organization"], + "description": "Create an organization", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "name": "id", - "in": "query", - "schema": { - "type": "string", - "description": "The id of the User" + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the organization" + }, + "slug": { + "type": "string", + "description": "The slug of the organization" + }, + "userId": { + "type": ["string", "null"], + "description": "The user id of the organization creator. If not provided, the current user will be used. Should only be used by admins or when called by the server. server-only. Eg: \"user-id\"" + }, + "logo": { + "type": ["string", "null"], + "description": "The logo of the organization" + }, + "metadata": { + "type": ["string", "null"], + "description": "The metadata of the organization" + }, + "keepCurrentActiveOrganization": { + "type": ["boolean", "null"], + "description": "Whether to keep the current active organization active after creating a new one. Eg: true" + } + }, + "required": ["name", "slug"] + } } } - ], + }, "responses": { "200": { - "description": "User", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", - "properties": { - "user": { - "$ref": "#/components/schemas/User" - } - } + "description": "The organization that was created", + "$ref": "#/components/schemas/Organization" } } } @@ -32363,11 +33036,10 @@ } } }, - "/api/auth/admin/create-user": { + "/api/auth/organization/update": { "post": { - "tags": ["Admin"], - "description": "Create a new user", - "operationId": "createUser", + "tags": ["Organization"], + "description": "Update an organization", "security": [ { "bearerAuth": [] @@ -32381,41 +33053,46 @@ "schema": { "type": "object", "properties": { - "email": { - "type": "string", - "description": "The email of the user" - }, - "password": { - "type": ["string", "null"] - }, - "name": { - "type": "string", - "description": "The name of the user" - }, - "role": { - "type": ["string", "null"] - }, "data": { - "type": ["string", "null"] + "type": "object", + "properties": { + "name": { + "type": ["string", "null"], + "description": "The name of the organization" + }, + "slug": { + "type": ["string", "null"], + "description": "The slug of the organization" + }, + "logo": { + "type": ["string", "null"], + "description": "The logo of the organization" + }, + "metadata": { + "type": ["string", "null"], + "description": "The metadata of the organization" + } + } + }, + "organizationId": { + "type": ["string", "null"], + "description": "The organization ID. Eg: \"org-id\"" } }, - "required": ["email", "name"] + "required": ["data"] } } } }, "responses": { "200": { - "description": "User created", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", - "properties": { - "user": { - "$ref": "#/components/schemas/User" - } - } + "description": "The updated organization", + "$ref": "#/components/schemas/Organization" } } } @@ -32515,11 +33192,10 @@ } } }, - "/api/auth/admin/update-user": { + "/api/auth/organization/delete": { "post": { - "tags": ["Admin"], - "description": "Update a user's details", - "operationId": "updateUser", + "tags": ["Organization"], + "description": "Delete an organization", "security": [ { "bearerAuth": [] @@ -32533,32 +33209,24 @@ "schema": { "type": "object", "properties": { - "userId": { - "type": "string", - "description": "The user id" - }, - "data": { + "organizationId": { "type": "string", - "description": "The user data to update" + "description": "The organization id to delete" } }, - "required": ["userId", "data"] + "required": ["organizationId"] } } } }, "responses": { "200": { - "description": "User updated", + "description": "Success", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "user": { - "$ref": "#/components/schemas/User" - } - } + "type": "string", + "description": "The organization id that was deleted" } } } @@ -32658,119 +33326,46 @@ } } }, - "/api/auth/admin/list-users": { - "get": { - "tags": ["Admin"], - "description": "List users", - "operationId": "listUsers", + "/api/auth/organization/set-active": { + "post": { + "tags": ["Organization"], + "description": "Set the active organization", + "operationId": "setActiveOrganization", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "name": "searchValue", - "in": "query", - "schema": { - "type": ["string", "null"] - } - }, - { - "name": "searchField", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "The field to search in, defaults to email. Can be `email` or `name`. Eg: \"name\"" - } - }, - { - "name": "searchOperator", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "The operator to use for the search. Can be `contains`, `starts_with` or `ends_with`. Eg: \"contains\"" - } - }, - { - "name": "limit", - "in": "query", - "schema": { - "type": ["string", "null"] - } - }, - { - "name": "offset", - "in": "query", - "schema": { - "type": ["string", "null"] - } - }, - { - "name": "sortBy", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "The field to sort by" - } - }, - { - "name": "sortDirection", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "The direction to sort by" - } - }, - { - "name": "filterField", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "The field to filter by" - } - }, - { - "name": "filterValue", - "in": "query", - "schema": { - "type": ["string", "null"] - } - }, - { - "name": "filterOperator", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "The operator to use for the filter" + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "organizationId": { + "type": ["string", "null"] + }, + "organizationSlug": { + "type": ["string", "null"], + "description": "The organization slug to set as active. It can be null to unset the active organization if organizationId is not provided. Eg: \"org-slug\"" + } + }, + "required": [] + } } } - ], + }, "responses": { "200": { - "description": "List of users", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", - "properties": { - "users": { - "type": "array", - "items": { - "$ref": "#/components/schemas/User" - } - }, - "total": { - "type": "number" - }, - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - } - }, - "required": ["users", "total"] + "description": "The organization", + "$ref": "#/components/schemas/Organization" } } } @@ -32870,48 +33465,144 @@ } } }, - "/api/auth/admin/list-user-sessions": { - "post": { - "tags": ["Admin"], - "description": "List user sessions", - "operationId": "listUserSessions", + "/api/auth/organization/get-full-organization": { + "get": { + "tags": ["Organization"], + "description": "Get the full organization", + "operationId": "getOrganization", "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "userId": { - "type": "string", - "description": "The user id" - } - }, - "required": ["userId"] - } - } - } - }, "responses": { "200": { - "description": "List of user sessions", + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "The organization", + "$ref": "#/components/schemas/Organization" + } + } + } + }, + "400": { "content": { "application/json": { "schema": { "type": "object", "properties": { - "sessions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Session" - } + "message": { + "type": "string" } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/organization/list": { + "get": { + "tags": ["Organization"], + "description": "List all organizations", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Organization" } } } @@ -33012,11 +33703,11 @@ } } }, - "/api/auth/admin/unban-user": { + "/api/auth/organization/invite-member": { "post": { - "tags": ["Admin"], - "description": "Unban a user", - "operationId": "unbanUser", + "tags": ["Organization"], + "description": "Create an invitation to an organization", + "operationId": "createOrganizationInvitation", "security": [ { "bearerAuth": [] @@ -33030,28 +33721,74 @@ "schema": { "type": "object", "properties": { - "userId": { + "email": { "type": "string", - "description": "The user id" + "description": "The email address of the user to invite" + }, + "role": { + "type": "string", + "description": "The role(s) to assign to the user. It can be `admin`, `member`, owner. Eg: \"member\"" + }, + "organizationId": { + "type": ["string", "null"], + "description": "The organization ID to invite the user to" + }, + "resend": { + "type": ["boolean", "null"], + "description": "Resend the invitation email, if the user is already invited. Eg: true" + }, + "teamId": { + "type": "string" } }, - "required": ["userId"] + "required": ["email", "role", "teamId"] } } } }, "responses": { "200": { - "description": "User unbanned", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "user": { - "$ref": "#/components/schemas/User" + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "string" + }, + "organizationId": { + "type": "string" + }, + "inviterId": { + "type": "string" + }, + "status": { + "type": "string" + }, + "expiresAt": { + "type": "string" + }, + "createdAt": { + "type": "string" } - } + }, + "required": [ + "id", + "email", + "role", + "organizationId", + "inviterId", + "status", + "expiresAt", + "createdAt" + ] } } } @@ -33151,11 +33888,9 @@ } } }, - "/api/auth/admin/ban-user": { + "/api/auth/organization/cancel-invitation": { "post": { - "tags": ["Admin"], - "description": "Ban a user", - "operationId": "banUser", + "tags": ["Organization"], "security": [ { "bearerAuth": [] @@ -33169,40 +33904,17 @@ "schema": { "type": "object", "properties": { - "userId": { + "invitationId": { "type": "string", - "description": "The user id" - }, - "banReason": { - "type": ["string", "null"], - "description": "The reason for the ban" - }, - "banExpiresIn": { - "type": ["number", "null"], - "description": "The number of seconds until the ban expires" + "description": "The ID of the invitation to cancel" } }, - "required": ["userId"] + "required": ["invitationId"] } } } }, "responses": { - "200": { - "description": "User banned", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "user": { - "$ref": "#/components/schemas/User" - } - } - } - } - } - }, "400": { "content": { "application/json": { @@ -33298,11 +34010,10 @@ } } }, - "/api/auth/admin/impersonate-user": { + "/api/auth/organization/accept-invitation": { "post": { - "tags": ["Admin"], - "description": "Impersonate a user", - "operationId": "impersonateUser", + "tags": ["Organization"], + "description": "Accept an invitation to an organization", "security": [ { "bearerAuth": [] @@ -33316,29 +34027,29 @@ "schema": { "type": "object", "properties": { - "userId": { + "invitationId": { "type": "string", - "description": "The user id" + "description": "The ID of the invitation to accept" } }, - "required": ["userId"] + "required": ["invitationId"] } } } }, "responses": { "200": { - "description": "Impersonation session created", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "session": { - "$ref": "#/components/schemas/Session" + "invitation": { + "type": "object" }, - "user": { - "$ref": "#/components/schemas/User" + "member": { + "type": "object" } } } @@ -33440,16 +34151,80 @@ } } }, - "/api/auth/admin/stop-impersonating": { - "post": { - "tags": ["Admin"], + "/api/auth/organization/get-invitation": { + "get": { + "tags": ["Organization"], + "description": "Get an invitation by ID", "security": [ { "bearerAuth": [] } ], - "parameters": [], + "parameters": [ + { + "name": "id", + "in": "query", + "schema": { + "type": "string", + "description": "The ID of the invitation to get" + } + } + ], "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "string" + }, + "organizationId": { + "type": "string" + }, + "inviterId": { + "type": "string" + }, + "status": { + "type": "string" + }, + "expiresAt": { + "type": "string" + }, + "organizationName": { + "type": "string" + }, + "organizationSlug": { + "type": "string" + }, + "inviterEmail": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "role", + "organizationId", + "inviterId", + "status", + "expiresAt", + "organizationName", + "organizationSlug", + "inviterEmail" + ] + } + } + } + }, "400": { "content": { "application/json": { @@ -33545,11 +34320,10 @@ } } }, - "/api/auth/admin/revoke-user-session": { + "/api/auth/organization/reject-invitation": { "post": { - "tags": ["Admin"], - "description": "Revoke a user session", - "operationId": "revokeUserSession", + "tags": ["Organization"], + "description": "Reject an invitation to an organization", "security": [ { "bearerAuth": [] @@ -33563,26 +34337,30 @@ "schema": { "type": "object", "properties": { - "sessionToken": { + "invitationId": { "type": "string", - "description": "The session token" + "description": "The ID of the invitation to reject" } }, - "required": ["sessionToken"] + "required": ["invitationId"] } } } }, "responses": { "200": { - "description": "Session revoked", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "invitation": { + "type": "object" + }, + "member": { + "type": "object", + "nullable": true } } } @@ -33684,46 +34462,143 @@ } } }, - "/api/auth/admin/revoke-user-sessions": { - "post": { - "tags": ["Admin"], - "description": "Revoke all user sessions", - "operationId": "revokeUserSessions", + "/api/auth/organization/list-invitations": { + "get": { + "tags": ["Organization"], "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "userId": { - "type": "string", - "description": "The user id" + "responses": { + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } } - }, - "required": ["userId"] + } } - } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." } - }, + } + } + }, + "/api/auth/organization/get-active-member": { + "get": { + "tags": ["Organization"], + "description": "Get the member details of the active organization", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], "responses": { "200": { - "description": "Sessions revoked", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "id": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "organizationId": { + "type": "string" + }, + "role": { + "type": "string" } - } + }, + "required": ["id", "userId", "organizationId", "role"] } } } @@ -33823,11 +34698,9 @@ } } }, - "/api/auth/admin/remove-user": { + "/api/auth/organization/check-slug": { "post": { - "tags": ["Admin"], - "description": "Delete a user and all their sessions and accounts. Cannot be undone.", - "operationId": "removeUser", + "tags": ["Organization"], "security": [ { "bearerAuth": [] @@ -33841,32 +34714,17 @@ "schema": { "type": "object", "properties": { - "userId": { + "slug": { "type": "string", - "description": "The user id" + "description": "The organization slug to check. Eg: \"my-org\"" } }, - "required": ["userId"] + "required": ["slug"] } } } }, "responses": { - "200": { - "description": "User removed", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - } - } - } - } - } - }, "400": { "content": { "application/json": { @@ -33962,11 +34820,10 @@ } } }, - "/api/auth/admin/set-user-password": { + "/api/auth/organization/remove-member": { "post": { - "tags": ["Admin"], - "description": "Set a user's password", - "operationId": "setUserPassword", + "tags": ["Organization"], + "description": "Remove a member from an organization", "security": [ { "bearerAuth": [] @@ -33980,32 +34837,48 @@ "schema": { "type": "object", "properties": { - "newPassword": { + "memberIdOrEmail": { "type": "string", - "description": "The new password" + "description": "The ID or email of the member to remove" }, - "userId": { - "type": "string", - "description": "The user id" + "organizationId": { + "type": ["string", "null"], + "description": "The ID of the organization to remove the member from. If not provided, the active organization will be used. Eg: \"org-id\"" } }, - "required": ["newPassword", "userId"] + "required": ["memberIdOrEmail"] } } } }, "responses": { "200": { - "description": "Password set", + "description": "Success", "content": { "application/json": { "schema": { "type": "object", "properties": { - "status": { - "type": "boolean" + "member": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "organizationId": { + "type": "string" + }, + "role": { + "type": "string" + } + }, + "required": ["id", "userId", "organizationId", "role"] } - } + }, + "required": ["member"] } } } @@ -34105,10 +34978,11 @@ } } }, - "/api/auth/admin/has-permission": { + "/api/auth/organization/update-member-role": { "post": { - "tags": ["Admin"], - "description": "Check if the user has permission", + "tags": ["Organization"], + "description": "Update the role of a member in an organization", + "operationId": "updateOrganizationMemberRole", "security": [ { "bearerAuth": [] @@ -34116,22 +34990,26 @@ ], "parameters": [], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { - "permission": { - "type": "object", - "description": "The permission to check", - "deprecated": true + "role": { + "type": "string", + "description": "The new role to be applied. This can be a string or array of strings representing the roles. Eg: [\"admin\", \"sale\"]" }, - "permissions": { - "type": "object", - "description": "The permission to check" + "memberId": { + "type": "string", + "description": "The member id to apply the role update to. Eg: \"member-id\"" + }, + "organizationId": { + "type": ["string", "null"], + "description": "An optional organization ID which the member is a part of to apply the role update. If not provided, you must provide session headers to get the active organization. Eg: \"organization-id\"" } }, - "required": ["permissions"] + "required": ["role", "memberId"] } } } @@ -34144,14 +35022,26 @@ "schema": { "type": "object", "properties": { - "error": { - "type": "string" - }, - "success": { - "type": "boolean" + "member": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "organizationId": { + "type": "string" + }, + "role": { + "type": "string" + } + }, + "required": ["id", "userId", "organizationId", "role"] } }, - "required": ["success"] + "required": ["member"] } } } @@ -34251,127 +35141,33 @@ } } }, - "/api/auth/passkey/generate-register-options": { - "get": { - "tags": ["Passkey"], - "description": "Generate registration options for a new passkey", - "operationId": "generatePasskeyRegistrationOptions", + "/api/auth/organization/leave": { + "post": { + "tags": ["Organization"], "security": [ { "bearerAuth": [] } ], "parameters": [], - "responses": { - "200": { - "description": "Success", - "parameters": { - "query": { - "authenticatorAttachment": { - "description": "Type of authenticator to use for registration.\n \"platform\" for device-specific authenticators,\n \"cross-platform\" for authenticators that can be used across devices.", - "required": false - }, - "name": { - "description": "Optional custom name for the passkey.\n This can help identify the passkey when managing multiple credentials.", - "required": false - } - } - }, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "challenge": { - "type": "string" - }, - "rp": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "string" - } - } - }, - "user": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "displayName": { - "type": "string" - } - } - }, - "pubKeyCredParams": { - "type": "array", - "items": { - "type": "object", - "properties": { - "type": { - "type": "string" - }, - "alg": { - "type": "number" - } - } - } - }, - "timeout": { - "type": "number" - }, - "excludeCredentials": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "transports": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "authenticatorSelection": { - "type": "object", - "properties": { - "authenticatorAttachment": { - "type": "string" - }, - "requireResidentKey": { - "type": "boolean" - }, - "userVerification": { - "type": "string" - } - } - }, - "attestation": { - "type": "string" - }, - "extensions": { - "type": "object" - } + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "The organization Id for the member to leave. Eg: \"organization-id\"" } - } + }, + "required": ["organizationId"] } } - }, + } + }, + "responses": { "400": { "content": { "application/json": { @@ -34467,11 +35263,10 @@ } } }, - "/api/auth/passkey/generate-authenticate-options": { + "/api/auth/organization/list-user-invitations": { "get": { - "tags": ["Passkey"], - "description": "Generate authentication options for a passkey", - "operationId": "passkeyGenerateAuthenticateOptions", + "tags": ["Organization"], + "description": "List all invitations a user has received", "security": [ { "bearerAuth": [] @@ -34484,79 +35279,55 @@ "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "challenge": { - "type": "string" - }, - "rp": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "string" - } - } - }, - "user": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "displayName": { - "type": "string" - } - } - }, - "timeout": { - "type": "number" - }, - "allowCredentials": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "type": { - "type": "string" - }, - "transports": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "userVerification": { - "type": "string" - }, - "authenticatorSelection": { - "type": "object", - "properties": { - "authenticatorAttachment": { - "type": "string" - }, - "requireResidentKey": { - "type": "boolean" - }, - "userVerification": { - "type": "string" - } + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "type": "string" + }, + "organizationId": { + "type": "string" + }, + "organizationName": { + "type": "string" + }, + "inviterId": { + "type": "string", + "description": "The ID of the user who created the invitation" + }, + "teamId": { + "type": "string", + "description": "The ID of the team associated with the invitation", + "nullable": true + }, + "status": { + "type": "string" + }, + "expiresAt": { + "type": "string" + }, + "createdAt": { + "type": "string" } }, - "extensions": { - "type": "object" - } + "required": [ + "id", + "email", + "role", + "organizationId", + "organizationName", + "inviterId", + "status", + "expiresAt", + "createdAt" + ] } } } @@ -34657,50 +35428,31 @@ } } }, - "/api/auth/passkey/verify-registration": { - "post": { - "tags": ["Passkey"], - "description": "Verify registration of a new passkey", - "operationId": "passkeyVerifyRegistration", + "/api/auth/organization/list-members": { + "get": { + "tags": ["Organization"], "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "response": { - "type": "string" - }, - "name": { - "type": ["string", "null"], - "description": "Name of the passkey" - } - }, - "required": ["response"] - } - } - } - }, "responses": { - "200": { - "description": "Success", + "400": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Passkey" + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] } } - } - }, - "400": { - "description": "Bad request" + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." }, "401": { "content": { @@ -34781,52 +35533,16 @@ } } }, - "/api/auth/passkey/verify-authentication": { - "post": { - "tags": ["Passkey"], - "description": "Verify authentication of a passkey", - "operationId": "passkeyVerifyAuthentication", + "/api/auth/organization/get-active-member-role": { + "get": { + "tags": ["Organization"], "security": [ { "bearerAuth": [] } ], "parameters": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "response": { - "type": "string" - } - }, - "required": ["response"] - } - } - } - }, "responses": { - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "session": { - "$ref": "#/components/schemas/Session" - }, - "user": { - "$ref": "#/components/schemas/User" - } - } - } - } - } - }, "400": { "content": { "application/json": { @@ -34922,34 +35638,53 @@ } } }, - "/api/auth/passkey/list-user-passkeys": { - "get": { - "tags": ["Passkey"], - "description": "List all passkeys for the authenticated user", + "/api/auth/organization/has-permission": { + "post": { + "tags": ["Organization"], + "description": "Check if the user has permission", "security": [ { "bearerAuth": [] } ], "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "permission": { + "type": "object", + "description": "The permission to check", + "deprecated": true + }, + "permissions": { + "type": "object", + "description": "The permission to check" + } + }, + "required": ["permissions"] + } + } + } + }, "responses": { "200": { - "description": "Passkeys retrieved successfully", + "description": "Success", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Passkey", - "required": [ - "id", - "userId", - "publicKey", - "createdAt", - "updatedAt" - ] + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "success": { + "type": "boolean" + } }, - "description": "Array of passkey objects associated with the user" + "required": ["success"] } } } @@ -35049,10 +35784,11 @@ } } }, - "/api/auth/passkey/delete-passkey": { + "/api/auth/admin/set-role": { "post": { - "tags": ["Passkey"], - "description": "Delete a specific passkey", + "tags": ["Admin"], + "description": "Set the role of a user", + "operationId": "setUserRole", "security": [ { "bearerAuth": [] @@ -35066,30 +35802,32 @@ "schema": { "type": "object", "properties": { - "id": { + "userId": { "type": "string", - "description": "The ID of the passkey to delete. Eg: \"some-passkey-id\"" + "description": "The user id" + }, + "role": { + "type": "string", + "description": "The role to set, this can be a string or an array of strings. Eg: `admin` or `[admin, user]`" } }, - "required": ["id"] + "required": ["userId", "role"] } } } }, "responses": { "200": { - "description": "Passkey deleted successfully", + "description": "User role updated", "content": { "application/json": { "schema": { "type": "object", "properties": { - "status": { - "type": "boolean", - "description": "Indicates whether the deletion was successful" + "user": { + "$ref": "#/components/schemas/User" } - }, - "required": ["status"] + } } } } @@ -35189,10 +35927,142 @@ } } }, - "/api/auth/passkey/update-passkey": { + "/api/auth/admin/get-user": { + "get": { + "tags": ["Admin"], + "description": "Get an existing user", + "operationId": "getUser", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "name": "id", + "in": "query", + "schema": { + "type": "string", + "description": "The id of the User" + } + } + ], + "responses": { + "200": { + "description": "User", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/create-user": { "post": { - "tags": ["Passkey"], - "description": "Update a specific passkey's name", + "tags": ["Admin"], + "description": "Create a new user", + "operationId": "createUser", "security": [ { "bearerAuth": [] @@ -35206,33 +36076,41 @@ "schema": { "type": "object", "properties": { - "id": { + "email": { "type": "string", - "description": "The ID of the passkey which will be updated. Eg: \"passkey-id\"" + "description": "The email of the user" + }, + "password": { + "type": ["string", "null"] }, "name": { "type": "string", - "description": "The new name which the passkey will be updated to. Eg: \"my-new-passkey-name\"" + "description": "The name of the user" + }, + "role": { + "type": ["string", "null"] + }, + "data": { + "type": ["string", "null"] } }, - "required": ["id", "name"] + "required": ["email", "name"] } } } }, "responses": { "200": { - "description": "Passkey updated successfully", + "description": "User created", "content": { "application/json": { "schema": { "type": "object", "properties": { - "passkey": { - "$ref": "#/components/schemas/Passkey" + "user": { + "$ref": "#/components/schemas/User" } - }, - "required": ["passkey"] + } } } } @@ -35332,11 +36210,11 @@ } } }, - "/api/auth/sign-in/magic-link": { + "/api/auth/admin/update-user": { "post": { - "tags": ["Magic-link"], - "description": "Sign in with magic link", - "operationId": "signInWithMagicLink", + "tags": ["Admin"], + "description": "Update a user's details", + "operationId": "updateUser", "security": [ { "bearerAuth": [] @@ -35350,1790 +36228,7328 @@ "schema": { "type": "object", "properties": { - "email": { + "userId": { "type": "string", - "description": "Email address to send the magic link" - }, - "name": { - "type": ["string", "null"], - "description": "User display name. Only used if the user is registering for the first time. Eg: \"my-name\"" - }, - "callbackURL": { - "type": ["string", "null"], - "description": "URL to redirect after magic link verification" - }, - "newUserCallbackURL": { - "type": ["string", "null"], - "description": "URL to redirect after new user signup. Only used if the user is registering for the first time." + "description": "The user id" }, - "errorCallbackURL": { - "type": ["string", "null"], - "description": "URL to redirect after error." + "data": { + "type": "string", + "description": "The user data to update" } }, - "required": ["email"] + "required": ["userId", "data"] } } } }, "responses": { "200": { - "description": "Success", + "description": "User updated", "content": { "application/json": { "schema": { "type": "object", "properties": { - "status": { - "type": "boolean" + "user": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/list-users": { + "get": { + "tags": ["Admin"], + "description": "List users", + "operationId": "listUsers", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "name": "searchValue", + "in": "query", + "schema": { + "type": ["string", "null"] + } + }, + { + "name": "searchField", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "The field to search in, defaults to email. Can be `email` or `name`. Eg: \"name\"" + } + }, + { + "name": "searchOperator", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "The operator to use for the search. Can be `contains`, `starts_with` or `ends_with`. Eg: \"contains\"" + } + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": ["string", "null"] + } + }, + { + "name": "offset", + "in": "query", + "schema": { + "type": ["string", "null"] + } + }, + { + "name": "sortBy", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "The field to sort by" + } + }, + { + "name": "sortDirection", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "The direction to sort by" + } + }, + { + "name": "filterField", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "The field to filter by" + } + }, + { + "name": "filterValue", + "in": "query", + "schema": { + "type": ["string", "null"] + } + }, + { + "name": "filterOperator", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "The operator to use for the filter" + } + } + ], + "responses": { + "200": { + "description": "List of users", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "users": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + }, + "total": { + "type": "number" + }, + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + } + }, + "required": ["users", "total"] + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" } } } } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/list-user-sessions": { + "post": { + "tags": ["Admin"], + "description": "List user sessions", + "operationId": "listUserSessions", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The user id" + } + }, + "required": ["userId"] + } + } + } + }, + "responses": { + "200": { + "description": "List of user sessions", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "sessions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Session" + } + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/unban-user": { + "post": { + "tags": ["Admin"], + "description": "Unban a user", + "operationId": "unbanUser", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The user id" + } + }, + "required": ["userId"] + } + } + } + }, + "responses": { + "200": { + "description": "User unbanned", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/ban-user": { + "post": { + "tags": ["Admin"], + "description": "Ban a user", + "operationId": "banUser", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The user id" + }, + "banReason": { + "type": ["string", "null"], + "description": "The reason for the ban" + }, + "banExpiresIn": { + "type": ["number", "null"], + "description": "The number of seconds until the ban expires" + } + }, + "required": ["userId"] + } + } + } + }, + "responses": { + "200": { + "description": "User banned", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/impersonate-user": { + "post": { + "tags": ["Admin"], + "description": "Impersonate a user", + "operationId": "impersonateUser", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The user id" + } + }, + "required": ["userId"] + } + } + } + }, + "responses": { + "200": { + "description": "Impersonation session created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "session": { + "$ref": "#/components/schemas/Session" + }, + "user": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/stop-impersonating": { + "post": { + "tags": ["Admin"], + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "responses": { + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/revoke-user-session": { + "post": { + "tags": ["Admin"], + "description": "Revoke a user session", + "operationId": "revokeUserSession", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "sessionToken": { + "type": "string", + "description": "The session token" + } + }, + "required": ["sessionToken"] + } + } + } + }, + "responses": { + "200": { + "description": "Session revoked", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/revoke-user-sessions": { + "post": { + "tags": ["Admin"], + "description": "Revoke all user sessions", + "operationId": "revokeUserSessions", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The user id" + } + }, + "required": ["userId"] + } + } + } + }, + "responses": { + "200": { + "description": "Sessions revoked", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/remove-user": { + "post": { + "tags": ["Admin"], + "description": "Delete a user and all their sessions and accounts. Cannot be undone.", + "operationId": "removeUser", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "The user id" + } + }, + "required": ["userId"] + } + } + } + }, + "responses": { + "200": { + "description": "User removed", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/set-user-password": { + "post": { + "tags": ["Admin"], + "description": "Set a user's password", + "operationId": "setUserPassword", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "newPassword": { + "type": "string", + "description": "The new password" + }, + "userId": { + "type": "string", + "description": "The user id" + } + }, + "required": ["newPassword", "userId"] + } + } + } + }, + "responses": { + "200": { + "description": "Password set", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { + "type": "boolean" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/admin/has-permission": { + "post": { + "tags": ["Admin"], + "description": "Check if the user has permission", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "permission": { + "type": "object", + "description": "The permission to check", + "deprecated": true + }, + "permissions": { + "type": "object", + "description": "The permission to check" + } + }, + "required": ["permissions"] + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": ["success"] + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/passkey/generate-register-options": { + "get": { + "tags": ["Passkey"], + "description": "Generate registration options for a new passkey", + "operationId": "generatePasskeyRegistrationOptions", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Success", + "parameters": { + "query": { + "authenticatorAttachment": { + "description": "Type of authenticator to use for registration.\n \"platform\" for device-specific authenticators,\n \"cross-platform\" for authenticators that can be used across devices.", + "required": false + }, + "name": { + "description": "Optional custom name for the passkey.\n This can help identify the passkey when managing multiple credentials.", + "required": false + } + } + }, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "challenge": { + "type": "string" + }, + "rp": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "user": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "displayName": { + "type": "string" + } + } + }, + "pubKeyCredParams": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "alg": { + "type": "number" + } + } + } + }, + "timeout": { + "type": "number" + }, + "excludeCredentials": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "transports": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "authenticatorSelection": { + "type": "object", + "properties": { + "authenticatorAttachment": { + "type": "string" + }, + "requireResidentKey": { + "type": "boolean" + }, + "userVerification": { + "type": "string" + } + } + }, + "attestation": { + "type": "string" + }, + "extensions": { + "type": "object" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/passkey/generate-authenticate-options": { + "get": { + "tags": ["Passkey"], + "description": "Generate authentication options for a passkey", + "operationId": "passkeyGenerateAuthenticateOptions", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "challenge": { + "type": "string" + }, + "rp": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "user": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "displayName": { + "type": "string" + } + } + }, + "timeout": { + "type": "number" + }, + "allowCredentials": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "transports": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "userVerification": { + "type": "string" + }, + "authenticatorSelection": { + "type": "object", + "properties": { + "authenticatorAttachment": { + "type": "string" + }, + "requireResidentKey": { + "type": "boolean" + }, + "userVerification": { + "type": "string" + } + } + }, + "extensions": { + "type": "object" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/passkey/verify-registration": { + "post": { + "tags": ["Passkey"], + "description": "Verify registration of a new passkey", + "operationId": "passkeyVerifyRegistration", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "response": { + "type": "string" + }, + "name": { + "type": ["string", "null"], + "description": "Name of the passkey" + } + }, + "required": ["response"] + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Passkey" + } + } + } + }, + "400": { + "description": "Bad request" + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/passkey/verify-authentication": { + "post": { + "tags": ["Passkey"], + "description": "Verify authentication of a passkey", + "operationId": "passkeyVerifyAuthentication", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "response": { + "type": "string" + } + }, + "required": ["response"] + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "session": { + "$ref": "#/components/schemas/Session" + }, + "user": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/passkey/list-user-passkeys": { + "get": { + "tags": ["Passkey"], + "description": "List all passkeys for the authenticated user", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "responses": { + "200": { + "description": "Passkeys retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Passkey", + "required": [ + "id", + "userId", + "publicKey", + "createdAt", + "updatedAt" + ] + }, + "description": "Array of passkey objects associated with the user" + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/passkey/delete-passkey": { + "post": { + "tags": ["Passkey"], + "description": "Delete a specific passkey", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The ID of the passkey to delete. Eg: \"some-passkey-id\"" + } + }, + "required": ["id"] + } + } + } + }, + "responses": { + "200": { + "description": "Passkey deleted successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { + "type": "boolean", + "description": "Indicates whether the deletion was successful" + } + }, + "required": ["status"] + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/passkey/update-passkey": { + "post": { + "tags": ["Passkey"], + "description": "Update a specific passkey's name", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The ID of the passkey which will be updated. Eg: \"passkey-id\"" + }, + "name": { + "type": "string", + "description": "The new name which the passkey will be updated to. Eg: \"my-new-passkey-name\"" + } + }, + "required": ["id", "name"] + } + } + } + }, + "responses": { + "200": { + "description": "Passkey updated successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "passkey": { + "$ref": "#/components/schemas/Passkey" + } + }, + "required": ["passkey"] + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/sign-in/magic-link": { + "post": { + "tags": ["Magic-link"], + "description": "Sign in with magic link", + "operationId": "signInWithMagicLink", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string", + "description": "Email address to send the magic link" + }, + "name": { + "type": ["string", "null"], + "description": "User display name. Only used if the user is registering for the first time. Eg: \"my-name\"" + }, + "callbackURL": { + "type": ["string", "null"], + "description": "URL to redirect after magic link verification" + }, + "newUserCallbackURL": { + "type": ["string", "null"], + "description": "URL to redirect after new user signup. Only used if the user is registering for the first time." + }, + "errorCallbackURL": { + "type": ["string", "null"], + "description": "URL to redirect after error." + } + }, + "required": ["email"] + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "status": { + "type": "boolean" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + }, + "/api/auth/magic-link/verify": { + "get": { + "tags": ["Magic-link"], + "description": "Verify magic link", + "operationId": "verifyMagicLink", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "name": "token", + "in": "query", + "schema": { + "type": "string", + "description": "Verification token" + } + }, + { + "name": "callbackURL", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "URL to redirect after magic link verification, if not provided the user will be redirected to the root URL. Eg: \"/dashboard\"" + } + }, + { + "name": "errorCallbackURL", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "URL to redirect after error." + } + }, + { + "name": "newUserCallbackURL", + "in": "query", + "schema": { + "type": ["string", "null"], + "description": "URL to redirect after new user signup. Only used if the user is registering for the first time." + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "session": { + "$ref": "#/components/schemas/Session" + }, + "user": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "400": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Bad Request. Usually due to missing parameters, or invalid parameters." + }, + "401": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + }, + "required": ["message"] + } + } + }, + "description": "Unauthorized. Due to missing or invalid authentication." + }, + "403": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Forbidden. You do not have permission to access this resource or to perform this action." + }, + "404": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Not Found. The requested resource was not found." + }, + "429": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + }, + "500": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + } + } + }, + "description": "Internal Server Error. This is a problem with the server that you cannot fix." + } + } + } + } + }, + "info": { + "title": "Boundless API", + "description": "The Boundless API description", + "version": "1.0", + "contact": {} + }, + "tags": [ + { + "name": "boundless", + "description": "" + }, + { + "name": "Default", + "description": "Default endpoints that are included with Better Auth by default. These endpoints are not part of any plugin." + } + ], + "servers": [ + { + "url": "http://localhost:8000", + "description": "Development server" + } + ], + "components": { + "securitySchemes": { + "JWT-auth": { + "scheme": "bearer", + "bearerFormat": "JWT", + "type": "http", + "name": "JWT", + "description": "Enter JWT token", + "in": "header" + }, + "apiKeyCookie": { + "type": "apiKey", + "in": "cookie", + "name": "apiKeyCookie", + "description": "API Key authentication via cookie" + }, + "bearerAuth": { + "type": "http", + "scheme": "bearer", + "description": "Bearer token authentication" + } + }, + "schemas": { + "NotificationPreferencesDto": { + "type": "object", + "properties": {} + }, + "UpdatePrivacySettingsDto": { + "type": "object", + "properties": { + "publicProfile": { + "type": "boolean", + "description": "Public profile", + "example": true + }, + "emailVisibility": { + "type": "boolean", + "description": "Email visibility", + "example": true + }, + "locationVisibility": { + "type": "boolean", + "description": "Location visibility", + "example": true + }, + "companyVisibility": { + "type": "boolean", + "description": "Company visibility", + "example": true + }, + "websiteVisibility": { + "type": "boolean", + "description": "Website visibility", + "example": true + }, + "socialLinksVisibility": { + "type": "boolean", + "description": "Social links visibility", + "example": true + } + }, + "required": [ + "publicProfile", + "emailVisibility", + "locationVisibility", + "companyVisibility", + "websiteVisibility", + "socialLinksVisibility" + ] + }, + "UpdateAppearanceSettingsDto": { + "type": "object", + "properties": { + "theme": { + "type": "string", + "description": "Theme", + "example": "light", + "enum": ["light", "dark", "auto"] + } + }, + "required": ["theme"] + }, + "PublicEarningsSummaryDto": { + "type": "object", + "properties": { + "totalEarned": { + "type": "number", + "description": "All-time total earned (normalized, e.g. USDC 7 decimals)", + "example": 50000 + } + }, + "required": ["totalEarned"] + }, + "EarningsBreakdownDto": { + "type": "object", + "properties": { + "hackathons": { + "type": "number", + "description": "Total from hackathons", + "example": 20000 + }, + "grants": { + "type": "number", + "description": "Total from grants", + "example": 10000 + }, + "crowdfunding": { + "type": "number", + "description": "Total from crowdfunding", + "example": 15000 + }, + "bounties": { + "type": "number", + "description": "Total from bounties", + "example": 5000 + } + }, + "required": ["hackathons", "grants", "crowdfunding", "bounties"] + }, + "PublicEarningActivityDto": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique activity id" + }, + "source": { + "type": "string", + "description": "Earnings source category", + "enum": ["hackathons", "grants", "crowdfunding", "bounties"] + }, + "title": { + "type": "string", + "description": "Human-readable title", + "example": "Winner of Stellar Hackathon Q1" + }, + "amount": { + "type": "number", + "description": "Amount (normalized)", + "example": 5000 + }, + "currency": { + "type": "string", + "description": "Currency code", + "example": "USDC" + }, + "occurredAt": { + "type": "string", + "description": "When the earning occurred (ISO date string)", + "example": "2024-01-19T14:30:00Z" + } + }, + "required": [ + "id", + "source", + "title", + "amount", + "currency", + "occurredAt" + ] + }, + "PublicEarningsResponseDto": { + "type": "object", + "properties": { + "summary": { + "$ref": "#/components/schemas/PublicEarningsSummaryDto" + }, + "breakdown": { + "$ref": "#/components/schemas/EarningsBreakdownDto" + }, + "activities": { + "description": "Verified activity history (completed only)", + "type": "array", + "items": { + "$ref": "#/components/schemas/PublicEarningActivityDto" + } + } + }, + "required": ["summary", "breakdown", "activities"] + }, + "EarningsSummaryDto": { + "type": "object", + "properties": { + "totalEarned": { + "type": "number", + "description": "All-time total earned (normalized, e.g. USDC 7 decimals)", + "example": 50000 + }, + "pendingWithdrawal": { + "type": "number", + "description": "Amount currently claimable / pending withdrawal", + "example": 10000 + }, + "completedWithdrawal": { + "type": "number", + "description": "Amount already paid out (completed withdrawals)", + "example": 40000 + } + }, + "required": ["totalEarned", "pendingWithdrawal", "completedWithdrawal"] + }, + "EarningActivityDto": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Unique activity id (e.g. submissionId or milestoneId)" + }, + "source": { + "type": "string", + "description": "Earnings source category", + "enum": ["hackathons", "grants", "crowdfunding", "bounties"] + }, + "title": { + "type": "string", + "description": "Human-readable title", + "example": "Winner of Stellar Hackathon Q1" + }, + "amount": { + "type": "number", + "description": "Amount (normalized)", + "example": 5000 + }, + "currency": { + "type": "string", + "description": "Currency code", + "example": "USDC" + }, + "status": { + "type": "string", + "description": "Activity status", + "enum": ["pending", "claimable", "completed"] + }, + "occurredAt": { + "type": "string", + "description": "When the earning occurred (ISO date string)", + "example": "2024-01-19T14:30:00Z" + }, + "entityId": { + "type": "string", + "description": "Entity id for claim (e.g. submissionId, milestoneId)" + }, + "txHash": { + "type": "string", + "description": "On-chain payout transaction hash (when settled)." + } + }, + "required": [ + "id", + "source", + "title", + "amount", + "currency", + "status", + "occurredAt" + ] + }, + "EarningsResponseDto": { + "type": "object", + "properties": { + "summary": { + "$ref": "#/components/schemas/EarningsSummaryDto" + }, + "breakdown": { + "$ref": "#/components/schemas/EarningsBreakdownDto" + }, + "activities": { + "description": "Activity feed", + "type": "array", + "items": { + "$ref": "#/components/schemas/EarningActivityDto" + } + } + }, + "required": ["summary", "breakdown", "activities"] + }, + "DashboardUserStatsDto": { + "type": "object", + "properties": { + "followers": { + "type": "number" + }, + "following": { + "type": "number" + } + }, + "required": ["followers", "following"] + }, + "DashboardUserDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string", + "nullable": true + }, + "email": { + "type": "string" + }, + "username": { + "type": "string", + "nullable": true + }, + "displayUsername": { + "type": "string", + "nullable": true + }, + "image": { + "type": "string", + "nullable": true + }, + "role": { + "type": "string" + }, + "createdAt": { + "format": "date-time", + "type": "string" + }, + "stats": { + "$ref": "#/components/schemas/DashboardUserStatsDto" + } + }, + "required": [ + "id", + "name", + "email", + "username", + "displayUsername", + "image", + "role", + "createdAt" + ] + }, + "UserStatsDto": { + "type": "object", + "properties": { + "projectsCreated": { + "type": "number" + }, + "projectsFunded": { + "type": "number" + }, + "totalContributed": { + "type": "number" + }, + "commentsPosted": { + "type": "number" + }, + "votes": { + "type": "number" + }, + "grants": { + "type": "number" + }, + "hackathons": { + "type": "number" + }, + "followers": { + "type": "number" + }, + "following": { + "type": "number" + }, + "reputation": { + "type": "number" + }, + "communityScore": { + "type": "number" + } + }, + "required": [ + "projectsCreated", + "projectsFunded", + "totalContributed", + "commentsPosted", + "votes", + "grants", + "hackathons", + "followers", + "following", + "reputation", + "communityScore" + ] + }, + "ChartDataPointDto": { + "type": "object", + "properties": { + "date": { + "type": "string", + "description": "Date in YYYY-MM-DD format" + }, + "count": { + "type": "number", + "description": "Count for that date" + } + }, + "required": ["date", "count"] + }, + "ChartDto": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChartDataPointDto" + } + } + }, + "required": ["data"] + }, + "ActivitiesGraphDto": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChartDataPointDto" + } + } + }, + "required": ["data"] + }, + "ActivityProjectDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "banner": { + "type": "string", + "nullable": true + }, + "logo": { + "type": "string", + "nullable": true + } + }, + "required": ["id", "title"] + }, + "ActivityOrganizationDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": ["id", "name"] + }, + "RecentActivityDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "userId": { + "type": "string" + }, + "projectId": { + "type": "string", + "nullable": true + }, + "organizationId": { + "type": "string", + "nullable": true + }, + "createdAt": { + "format": "date-time", + "type": "string" + }, + "project": { + "$ref": "#/components/schemas/ActivityProjectDto" + }, + "organization": { + "$ref": "#/components/schemas/ActivityOrganizationDto" + } + }, + "required": ["id", "type", "userId", "createdAt"] + }, + "DashboardDto": { + "type": "object", + "properties": { + "user": { + "description": "User profile data", + "allOf": [ + { + "$ref": "#/components/schemas/DashboardUserDto" + } + ] + }, + "stats": { + "$ref": "#/components/schemas/UserStatsDto" + }, + "chart": { + "$ref": "#/components/schemas/ChartDto" + }, + "activitiesGraph": { + "$ref": "#/components/schemas/ActivitiesGraphDto" + }, + "recentActivities": { + "description": "Recent activities", + "type": "array", + "items": { + "$ref": "#/components/schemas/RecentActivityDto" + } + } + }, + "required": [ + "user", + "stats", + "chart", + "activitiesGraph", + "recentActivities" + ] + }, + "UpdateProfileDto": { + "type": "object", + "properties": {} + }, + "UpdateUserDto": { + "type": "object", + "properties": {} + }, + "UploadResponseDto": { + "type": "object", + "properties": {} + }, + "MultipleUploadResponseDto": { + "type": "object", + "properties": {} + }, + "FileInfoResponseDto": { + "type": "object", + "properties": {} + }, + "SearchFilesResponseDto": { + "type": "object", + "properties": {} + }, + "OptimizedUrlResponseDto": { + "type": "object", + "properties": {} + }, + "ResponsiveUrlsResponseDto": { + "type": "object", + "properties": {} + }, + "UsageStatsResponseDto": { + "type": "object", + "properties": {} + }, + "RegisterDto": { + "type": "object", + "properties": {} + }, + "LoginDto": { + "type": "object", + "properties": {} + }, + "RefreshTokenDto": { + "type": "object", + "properties": {} + }, + "VerifySignatureDto": { + "type": "object", + "properties": {} + }, + "CreateConversationDto": { + "type": "object", + "properties": { + "otherUserId": { + "type": "string", + "description": "User ID of the other participant" + } + }, + "required": ["otherUserId"] + }, + "CreateMessageDto": { + "type": "object", + "properties": { + "body": { + "type": "string", + "description": "Message text", + "maxLength": 10000 + } + }, + "required": ["body"] + }, + "ContactDto": { + "type": "object", + "properties": {} + }, + "CreateCampaignDto": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "Title of the campaign", + "example": "Web3 Campaign" + }, + "logo": { + "type": "string", + "description": "Logo of the campaign", + "example": "https://example.com/logo.png" + }, + "vision": { + "type": "string", + "description": "Vision of the campaign", + "example": "Web3 Campaign" + }, + "banner": { + "type": "string", + "description": "Banner image URL of the campaign", + "example": "https://example.com/banner.png" + }, + "category": { + "type": "string", + "description": "Category of the campaign", + "example": "web3" + }, + "details": { + "type": "string", + "description": "Details of the campaign", + "example": "Web3 Campaign" + }, + "fundingAmount": { + "type": "number", + "description": "Funding amount of the campaign", + "example": 1000 + }, + "githubUrl": { + "type": "string", + "description": "Github URL of the campaign", + "example": "https://github.com/example/project" + }, + "gitlabUrl": { + "type": "string", + "description": "Gitlab URL of the campaign", + "example": "https://gitlab.com/example/project" + }, + "bitbucketUrl": { + "type": "string", + "description": "Bitbucket URL of the campaign", + "example": "https://bitbucket.com/example/project" + }, + "projectWebsite": { + "type": "string", + "description": "Project website of the campaign", + "example": "https://example.com/project" + }, + "demoVideo": { + "type": "string", + "description": "Demo video of the campaign", + "example": "https://example.com/demo.mp4" + }, + "milestones": { + "description": "Milestones of the campaign", + "example": [ + { + "name": "Milestone 1", + "description": "Milestone 1 description", + "startDate": "2025-01-01", + "endDate": "2025-01-02", + "amount": 1000 + } + ], + "type": "array", + "items": { + "type": "string" + } + }, + "team": { + "description": "Team of the campaign (optional; solo builders may omit)", + "example": [ + { + "name": "John Doe", + "role": "Developer", + "email": "john.doe@example.com", + "linkedin": "https://linkedin.com/in/john-doe", + "twitter": "https://twitter.com/john-doe" + } + ], + "type": "array", + "items": { + "type": "string" + } + }, + "contact": { + "description": "Contact of the campaign", + "example": { + "primary": "john.doe", + "backup": "john.doe@example.com" + }, + "allOf": [ + { + "$ref": "#/components/schemas/ContactDto" + } + ] + }, + "socialLinks": { + "description": "Social links of the campaign (optional)", + "example": [ + { + "platform": "twitter", + "url": "https://twitter.com/john-doe" + } + ], + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "title", + "logo", + "vision", + "banner", + "category", + "details", + "fundingAmount", + "githubUrl", + "gitlabUrl", + "bitbucketUrl", + "projectWebsite", + "demoVideo", + "milestones", + "contact" + ] + }, + "CreateDraftDto": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "Working title for the campaign", + "example": "Stellar Analytics Dashboard" + } + }, + "required": ["title"] + }, + "UpdateCampaignDto": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "Title of the campaign", + "example": "Web3 Campaign" + }, + "logo": { + "type": "string", + "description": "Logo of the campaign", + "example": "https://example.com/logo.png" + }, + "vision": { + "type": "string", + "description": "Vision of the campaign", + "example": "Web3 Campaign" + }, + "banner": { + "type": "string", + "description": "Banner image URL of the campaign", + "example": "https://example.com/banner.png" + }, + "category": { + "type": "string", + "description": "Category of the campaign", + "example": "web3" + }, + "details": { + "type": "string", + "description": "Details of the campaign", + "example": "Web3 Campaign" + }, + "fundingAmount": { + "type": "number", + "description": "Funding amount of the campaign", + "example": 1000 + }, + "githubUrl": { + "type": "string", + "description": "Github URL of the campaign", + "example": "https://github.com/example/project" + }, + "gitlabUrl": { + "type": "string", + "description": "Gitlab URL of the campaign", + "example": "https://gitlab.com/example/project" + }, + "bitbucketUrl": { + "type": "string", + "description": "Bitbucket URL of the campaign", + "example": "https://bitbucket.com/example/project" + }, + "projectWebsite": { + "type": "string", + "description": "Project website of the campaign", + "example": "https://example.com/project" + }, + "demoVideo": { + "type": "string", + "description": "Demo video of the campaign", + "example": "https://example.com/demo.mp4" + }, + "milestones": { + "description": "Milestones of the campaign", + "example": [ + { + "name": "Milestone 1", + "description": "Milestone 1 description", + "startDate": "2025-01-01", + "endDate": "2025-01-02", + "amount": 1000 + } + ], + "type": "array", + "items": { + "type": "string" + } + }, + "team": { + "description": "Team of the campaign (optional; solo builders may omit)", + "example": [ + { + "name": "John Doe", + "role": "Developer", + "email": "john.doe@example.com", + "linkedin": "https://linkedin.com/in/john-doe", + "twitter": "https://twitter.com/john-doe" + } + ], + "type": "array", + "items": { + "type": "string" + } + }, + "contact": { + "description": "Contact of the campaign", + "example": { + "primary": "john.doe", + "backup": "john.doe@example.com" + }, + "allOf": [ + { + "$ref": "#/components/schemas/ContactDto" + } + ] + }, + "socialLinks": { + "description": "Social links of the campaign (optional)", + "example": [ + { + "platform": "twitter", + "url": "https://twitter.com/john-doe" + } + ], + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "InviteTeamMemberDto": { + "type": "object", + "properties": { + "email": { + "type": "string", + "example": "user@example.com", + "description": "The email address of the team member to invite" + }, + "role": { + "type": "string", + "example": "Developer", + "description": "The role of the team member in the campaign" + } + }, + "required": ["email", "role"] + }, + "ValidateMilestoneSubmissionDto": { + "type": "object", + "properties": { + "proofOfWorkFiles": { + "description": "Array of proof of work file URLs (documents, images, reports, etc.) - must be valid URLs with http, https, or ipfs protocol", + "example": [ + "https://example.com/report.pdf", + "https://example.com/screenshot.png" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "proofOfWorkLinks": { + "description": "Array of proof of work links (GitHub PRs, demos, deployed sites, etc.) - must be valid URLs", + "example": [ + "https://github.com/user/repo/pull/123", + "https://demo.example.com" + ], + "type": "array", + "items": { + "type": "string" + } + }, + "submissionNotes": { + "type": "string", + "description": "Additional notes about the submission - optional but must be at least 10 characters if provided", + "minLength": 10, + "example": "Successfully deployed the MVP with all core features implemented and tested." + } + }, + "required": ["proofOfWorkFiles", "proofOfWorkLinks"] + }, + "UpdateMilestoneDto": { + "type": "object", + "properties": { + "proofOfWorkFiles": { + "description": "Array of proof of work file URLs (documents, images, etc.)", + "type": "array", + "items": { + "type": "string" + } + }, + "proofOfWorkLinks": { + "description": "Array of proof of work links (GitHub PRs, demos, etc.)", + "type": "array", + "items": { + "type": "string" + } + }, + "submissionNotes": { + "type": "string", + "description": "Additional notes about the submission", + "minLength": 10 + } + }, + "required": ["proofOfWorkFiles", "proofOfWorkLinks"] + }, + "PublishCrowdfundingEscrowDto": { + "type": "object", + "properties": { + "builderAddress": { + "type": "string", + "description": "Stellar G-address that signs create_event. Strictly the builder's Boundless abstracted wallet (D9). Optional: defaults to the authenticated builder's managed wallet, the only valid value.", + "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" + }, + "tokenAddress": { + "type": "string", + "description": "Whitelisted SAC token contract (USDC by default).", + "example": "CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA" + }, + "fundingGoal": { + "type": "string", + "description": "Funding goal in token-native units (e.g. 5000 = 5000 USDC). Informational on chain; backers determine the actual raised total.", + "example": "5000" + }, + "nMilestones": { + "type": "number", + "description": "Number of milestones for ReleaseKind::Multi(n).", + "example": 3 + }, + "fundingDeadline": { + "type": "number", + "description": "Funding deadline as Unix seconds.", + "example": 1735689600 + }, + "contentUri": { + "type": "string", + "description": "Override content URI." + } + }, + "required": [ + "tokenAddress", + "fundingGoal", + "nMilestones", + "fundingDeadline" + ] + }, + "CancelCrowdfundingEscrowDto": { + "type": "object", + "properties": { + "builderAddress": { + "type": "string", + "description": "Builder G-address. Optional: defaults to the authenticated builder's managed wallet (the only valid value)." + } + } + }, + "ContributeCrowdfundingDto": { + "type": "object", + "properties": { + "contributorAddress": { + "type": "string", + "description": "G-address that signs add_funds.", + "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" + }, + "walletOrigin": { + "type": "string", + "description": "Wallet origin: BOUNDLESS uses the managed signer; EXTERNAL returns an unsigned XDR for the connected wallet (D9).", + "enum": ["BOUNDLESS", "EXTERNAL"], + "example": "BOUNDLESS" + }, + "amount": { + "type": "string", + "description": "Amount in token-native units (10 USDC minimum).", + "example": "25" + }, + "message": { + "type": "string", + "description": "Optional message attached." + }, + "anonymous": { + "type": "boolean", + "description": "Hide displayName / usernameSnapshot if true.", + "default": false + } + }, + "required": ["contributorAddress", "walletOrigin", "amount"] + }, + "CrowdfundingSubmitSignedXdrDto": { + "type": "object", + "properties": { + "signedXdr": { + "type": "string", + "description": "Signed transaction XDR returned by the wallet." + } + }, + "required": ["signedXdr"] + }, + "CastCrowdfundingVoteDto": { + "type": "object", + "properties": { + "choice": { + "type": "string", + "description": "UP supports the campaign, DOWN opposes it.", + "enum": ["UP", "DOWN"], + "example": "UP" + } + }, + "required": ["choice"] + }, + "ApproveCrowdfundingCampaignDto": { + "type": "object", + "properties": { + "delegatedReviewerId": { + "type": "string", + "description": "The user delegated to validate this campaign's milestones. D6=A: exactly one reviewer per campaign, assigned at approval time.", + "example": "user_1234567890" + }, + "voteGoal": { + "type": "number", + "description": "Minimum total community votes required to resolve the vote (quorum). Defaults to 1 for now (target is 10 at launch).", + "example": 10, + "minimum": 1 + }, + "bypassVoting": { + "type": "boolean", + "description": "Bypass community voting and approve straight to launch-ready (REVIEW_APPROVED). Default false: the campaign enters community voting.", + "example": false + } + }, + "required": ["delegatedReviewerId"] + }, + "RejectCrowdfundingCampaignDto": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "Reason for rejection; surfaced to the builder." + } + } + }, + "ExtendCrowdfundingFundingDto": { + "type": "object", + "properties": { + "fundingEndDate": { + "type": "string", + "description": "New funding deadline (ISO 8601). Must be in the future. Enforced off-chain by the contribute gate.", + "example": "2026-08-01T00:00:00.000Z" + } + }, + "required": ["fundingEndDate"] + }, + "PauseCrowdfundingCampaignDto": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "Reason for the pause." + } + } + }, + "ApproveCrowdfundingMilestoneDto": { + "type": "object", + "properties": {} + }, + "RejectCrowdfundingMilestoneDto": { + "type": "object", + "properties": { + "rejectionFeedback": { + "type": "string", + "description": "Feedback shown to the builder." + }, + "resubmissionDeadline": { + "type": "string", + "description": "Deadline by which the builder must resubmit (ISO 8601)." + } + }, + "required": ["rejectionFeedback"] + }, + "FileDisputeDto": { + "type": "object", + "properties": { + "milestoneId": { + "type": "string", + "description": "Specific milestone being disputed (optional)." + }, + "reason": { + "type": "string", + "enum": [ + "MILESTONE_NOT_DELIVERED", + "POOR_QUALITY_WORK", + "DEADLINE_MISSED", + "MISUSE_OF_FUNDS", + "COMMUNICATION_ISSUES", + "SCOPE_CHANGE", + "OTHER" + ] + }, + "description": { + "type": "string", + "minLength": 10, + "maxLength": 2000 + }, + "evidenceLinks": { + "description": "Links to supporting evidence (max 10).", + "type": "array", + "items": { + "type": "string" + } + }, + "evidenceFiles": { + "description": "Uploaded evidence file references (max 10).", + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["reason", "description"] + }, + "DisputeResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "campaignId": { + "type": "string" + }, + "milestoneId": { + "type": "string", + "nullable": true + }, + "reason": { + "type": "string" + }, + "status": { + "type": "string" + }, + "description": { + "type": "string" + }, + "createdAt": { + "type": "string", + "description": "ISO timestamp the dispute was filed" + } + }, + "required": [ + "id", + "campaignId", + "milestoneId", + "reason", + "status", + "description", + "createdAt" + ] + }, + "ReclaimDormantDto": { + "type": "object", + "properties": { + "minIdleDays": { + "type": "number", + "description": "Minimum days a wallet must have been idle to be eligible. Default 90.", + "minimum": 7, + "maximum": 3650, + "example": 90 + }, + "maxToProcess": { + "type": "number", + "description": "Maximum number of wallets to reclaim in this call. Hard-capped at 100.", + "minimum": 1, + "maximum": 100, + "example": 25 + }, + "dryRun": { + "type": "boolean", + "description": "When true (default), report what would be reclaimed without submitting transactions. Set false to actually merge accounts.", + "example": true + } + } + }, + "AddTrustlineDto": { + "type": "object", + "properties": { + "assetCode": { + "type": "string", + "description": "Asset code to add a trustline for (e.g. USDC, EURC)", + "example": "USDC", + "minLength": 1, + "maxLength": 12 + } + }, + "required": ["assetCode"] + }, + "UserSendDto": { + "type": "object", + "properties": { + "destinationPublicKey": { + "type": "string", + "description": "Stellar destination public key (G...)", + "example": "GABCD..." + }, + "amount": { + "type": "number", + "description": "Amount to send (positive number)", + "example": 100.5 + }, + "currency": { + "type": "string", + "description": "Asset code (XLM, USDC, EURC, etc.)", + "example": "USDC" + }, + "memo": { + "type": "string", + "description": "Memo (required by some exchanges). Max 28 bytes UTF-8." + }, + "memoRequired": { + "type": "boolean", + "description": "If true, request fails when memo is missing (e.g. exchange requires it)" + }, + "idempotencyKey": { + "type": "string", + "description": "Idempotency key to prevent duplicate sends" + } + }, + "required": ["destinationPublicKey", "amount", "currency"] + }, + "SendPayoutDto": { + "type": "object", + "properties": { + "destinationPublicKey": { + "type": "string", + "description": "Stellar destination public key (G...)", + "example": "GABCD..." + }, + "amount": { + "type": "number", + "description": "Amount to send (positive number)", + "example": 100.5 + }, + "currency": { + "type": "string", + "description": "Asset code (XLM, USDC, EURC, etc. – must be supported on network)", + "example": "USDC" + }, + "memo": { + "type": "string", + "description": "Memo (required by some exchanges). Max 28 bytes UTF-8." + }, + "memoType": { + "type": "string", + "description": "Memo type", + "enum": ["text", "id"] + }, + "memoRequired": { + "type": "boolean", + "description": "If true, request fails when memo is missing (e.g. exchange requires it)" + }, + "idempotencyKey": { + "type": "string", + "description": "Idempotency key to prevent duplicate payouts" + }, + "reference": { + "type": "string", + "description": "Reference for audit (e.g. earnings-payout-123)" + } + }, + "required": ["destinationPublicKey", "amount", "currency"] + }, + "CreateCommentDto": { + "type": "object", + "properties": { + "content": { + "type": "string", + "description": "Comment content", + "example": "This is a great project!", + "minLength": 1, + "maxLength": 2000 + }, + "entityType": { + "type": "string", + "description": "Entity type for the comment", + "enum": [ + "PROJECT", + "BOUNTY", + "CROWDFUNDING_CAMPAIGN", + "GRANT", + "GRANT_APPLICATION", + "HACKATHON", + "HACKATHON_SUBMISSION", + "BLOG_POST" + ], + "example": "PROJECT" + }, + "entityId": { + "type": "string", + "description": "Entity ID for the comment", + "example": "cm12345abcde" + }, + "parentId": { + "type": "string", + "description": "Parent comment ID for threaded replies", + "example": "cm12345abcde" + } + }, + "required": ["content", "entityType", "entityId"] + }, + "UpdateCommentDto": { + "type": "object", + "properties": {} + }, + "AddReactionDto": { + "type": "object", + "properties": { + "reactionType": { + "type": "string", + "description": "Type of reaction", + "enum": [ + "LIKE", + "DISLIKE", + "LOVE", + "LAUGH", + "THUMBS_UP", + "THUMBS_DOWN", + "FIRE", + "ROCKET" + ], + "example": "LIKE" + } + }, + "required": ["reactionType"] + }, + "ReportCommentDto": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "Reason for reporting the comment", + "enum": [ + "SPAM", + "HARASSMENT", + "HATE_SPEECH", + "INAPPROPRIATE_CONTENT", + "COPYRIGHT_VIOLATION", + "OTHER" + ], + "example": "SPAM" + }, + "description": { + "type": "string", + "description": "Additional details about the report", + "example": "This comment contains unsolicited advertising", + "maxLength": 500 + } + }, + "required": ["reason"] + }, + "ResolveReportDto": { + "type": "object", + "properties": { + "status": { + "type": "string", + "description": "Resolution status for the report", + "enum": ["PENDING", "REVIEWED", "RESOLVED", "DISMISSED"], + "example": "RESOLVED" + }, + "resolution": { + "type": "string", + "description": "Moderator notes about the resolution", + "example": "Comment was reviewed and found to violate community guidelines", + "maxLength": 500 + } + }, + "required": ["status"] + }, + "HackathonsListResponseDto": { + "type": "object", + "properties": {} + }, + "FeeEstimateResponseDto": { + "type": "object", + "properties": { + "totalPool": { + "type": "number", + "example": 5000, + "description": "Total prize pool (USDC)" + }, + "feeRate": { + "type": "number", + "example": 0.023, + "description": "Fee rate as decimal" + }, + "feeRatePercent": { + "type": "number", + "example": 2.3, + "description": "Fee rate as percentage" + }, + "feeAmount": { + "type": "number", + "example": 115, + "description": "Fee amount (USDC)" + }, + "totalFunds": { + "type": "number", + "example": 5115, + "description": "Total to pay (prize pool + fee)" + }, + "feeLabel": { + "type": "string", + "example": "Platform Fee (2.3%)", + "description": "Display label for the fee" + } + }, + "required": [ + "totalPool", + "feeRate", + "feeRatePercent", + "feeAmount", + "totalFunds", + "feeLabel" + ] + }, + "ParticipantDto": { + "type": "object", + "properties": { + "username": { + "type": "string", + "description": "Username of the participant" + }, + "avatar": { + "type": "object", + "description": "Avatar URL of the participant" + } + }, + "required": ["username"] + }, + "HackathonWinnerDto": { + "type": "object", + "properties": { + "rank": { + "type": "number", + "description": "Rank of the winner (1, 2, 3, etc.)" + }, + "projectName": { + "type": "string", + "description": "Name of the project" + }, + "teamName": { + "type": "object", + "description": "Name of the team" + }, + "logo": { + "type": "object", + "description": "Logo of the project" + }, + "participants": { + "description": "List of participants", + "type": "array", + "items": { + "$ref": "#/components/schemas/ParticipantDto" + } + }, + "prize": { + "type": "string", + "description": "Prize information" + }, + "submissionId": { + "type": "string", + "description": "Submission ID" + } + }, + "required": [ + "rank", + "projectName", + "participants", + "prize", + "submissionId" + ] + }, + "HackathonWinnersResponseDto": { + "type": "object", + "properties": { + "hackathonId": { + "type": "string", + "description": "Hackathon ID" + }, + "winners": { + "description": "List of winners", + "type": "array", + "items": { + "$ref": "#/components/schemas/HackathonWinnerDto" + } + } + }, + "required": ["hackathonId", "winners"] + }, + "PublicAggregatedJudgingResultDto": { + "type": "object", + "properties": { + "submissionId": { + "type": "string" + }, + "projectName": { + "type": "string" + }, + "teamId": { + "type": "object" + }, + "participantId": { + "type": "string" + }, + "status": { + "type": "string" + }, + "submittedAt": { + "format": "date-time", + "type": "string" + }, + "averageScore": { + "type": "number" + }, + "totalScore": { + "type": "number" + }, + "judgeCount": { + "type": "number" + }, + "expectedJudgeCount": { + "type": "number" + }, + "judgingProgress": { + "type": "string" + }, + "rank": { + "type": "object" + }, + "isComplete": { + "type": "boolean" + }, + "isPending": { + "type": "boolean" + }, + "hasDisagreement": { + "type": "boolean" + } + }, + "required": [ + "submissionId", + "projectName", + "participantId", + "status", + "submittedAt", + "averageScore", + "totalScore", + "judgeCount", + "expectedJudgeCount", + "judgingProgress", + "isComplete", + "isPending", + "hasDisagreement" + ] + }, + "JudgingResultsMetadataDto": { + "type": "object", + "properties": { + "sortedBy": { + "type": "string" + }, + "includesVariance": { + "type": "boolean" + }, + "includesIndividualScores": { + "type": "boolean" + }, + "includesProgressTracking": { + "type": "boolean" + }, + "onlyWinners": { + "type": "boolean" + } + }, + "required": [ + "sortedBy", + "includesVariance", + "includesIndividualScores", + "includesProgressTracking" + ] + }, + "PublicJudgingResultsResponseDto": { + "type": "object", + "properties": { + "hackathonId": { + "type": "string" + }, + "totalSubmissions": { + "type": "number" + }, + "submissionsScoredCount": { + "type": "number" + }, + "submissionsPendingCount": { + "type": "number" + }, + "averageScoreAcrossAll": { + "type": "number" + }, + "resultsPublished": { + "type": "boolean" + }, + "judgesAssigned": { + "type": "number" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PublicAggregatedJudgingResultDto" + } + }, + "generatedAt": { + "format": "date-time", + "type": "string" + }, + "winnerOverrides": { + "type": "object", + "additionalProperties": { + "type": "number" + }, + "description": "Manual winner assignments override (submissionId -> rank)" + }, + "metadata": { + "$ref": "#/components/schemas/JudgingResultsMetadataDto" + } + }, + "required": [ + "hackathonId", + "totalSubmissions", + "submissionsScoredCount", + "submissionsPendingCount", + "averageScoreAcrossAll", + "resultsPublished", + "judgesAssigned", + "results", + "generatedAt", + "metadata" + ] + }, + "CreatorRelationDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "username": { + "type": "string" + }, + "image": { + "type": "string" + } + }, + "required": ["id", "name"] + }, + "OrganizationRelationDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "logo": { + "type": "string" + }, + "slug": { + "type": "string" + } + }, + "required": ["id", "name"] + }, + "HackathonResponseDto": { + "type": "object", + "properties": { + "createdBy": { + "$ref": "#/components/schemas/CreatorRelationDto" + }, + "organization": { + "$ref": "#/components/schemas/OrganizationRelationDto" + } + }, + "required": ["createdBy"] + }, + "VerifyHackathonAccessDto": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "The access password for a private hackathon" + } + }, + "required": ["password"] + }, + "HackathonAccessTokenResponseDto": { + "type": "object", + "properties": { + "accessToken": { + "type": "string" + } + }, + "required": ["accessToken"] + }, + "JoinHackathonDto": { + "type": "object", + "properties": { + "customAnswers": { + "type": "object", + "description": "Answers to REGISTRATION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select).", + "example": { + "cq_role": "Backend developer" + } + } + } + }, + "ParticipationResponseDto": { + "type": "object", + "properties": {} + }, + "ParticipantResponseDto": { + "type": "object", + "properties": {} + }, + "HackathonParticipantsResponseDto": { + "type": "object", + "properties": { + "participants": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ParticipantResponseDto" + } + } + }, + "required": ["participants"] + }, + "TeamMemberDto": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "User ID of the team member", + "example": "user_1234567890" + }, + "name": { + "type": "string", + "description": "Name of the team member", + "example": "John Doe" + }, + "username": { + "type": "string", + "description": "Username of the team member", + "example": "johndoe" + }, + "role": { + "type": "string", + "description": "Role of the team member in the project", + "example": "Full Stack Developer" + }, + "avatar": { + "type": "string", + "description": "Avatar URL of the team member", + "example": "https://example.com/avatar.png" + } + }, + "required": ["userId", "name", "role"] + }, + "SubmissionLinkDto": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of link. Each fixed type (github, demo, video, document, presentation) can be used at most once per submission. Use \"other\" for additional links, up to a maximum of 5.", + "example": "github", + "enum": [ + "github", + "demo", + "video", + "document", + "presentation", + "other" + ] + }, + "url": { + "type": "string", + "description": "URL of the link", + "example": "https://github.com/username/project" + }, + "description": { + "type": "string", + "description": "Optional description of the link", + "example": "Main repository with source code" + } + }, + "required": ["type", "url"] + }, + "SocialLinksDto": { + "type": "object", + "properties": { + "github": { + "type": "string", + "description": "GitHub profile or repository", + "example": "https://github.com/username" + }, + "telegram": { + "type": "string", + "description": "Telegram username or group", + "example": "https://t.me/username" + }, + "twitter": { + "type": "string", + "description": "Twitter/X handle", + "example": "https://twitter.com/username" + }, + "email": { + "type": "string", + "description": "Email address", + "example": "contact@example.com" + } + } + }, + "SubmissionResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "hackathonId": { + "type": "string" + }, + "projectId": { + "type": "string" + }, + "participantId": { + "type": "string" + }, + "organizationId": { + "type": "string" + }, + "participationType": { + "type": "string", + "enum": ["INDIVIDUAL", "TEAM"] + }, + "teamId": { + "type": "string" + }, + "teamName": { + "type": "string" + }, + "teamMembers": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TeamMemberDto" + } + }, + "projectName": { + "type": "string" + }, + "category": { + "type": "string" + }, + "description": { + "type": "string" + }, + "logo": { + "type": "string" + }, + "banner": { + "type": "string" + }, + "videoUrl": { + "type": "string" + }, + "introduction": { + "type": "string" + }, + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SubmissionLinkDto" + } + }, + "socialLinks": { + "$ref": "#/components/schemas/SocialLinksDto" + }, + "status": { + "type": "string" + }, + "rank": { + "type": "number" + }, + "trackEntries": { + "description": "Track entries this submission has opted into. Each entry carries the track slug/name and a wonRank stamped when the submission won that track (null until results are published).", + "type": "array", + "items": { + "type": "array" + } + }, + "tagline": { + "type": "string" + }, + "builtWith": { + "type": "array", + "items": { + "type": "string" + } + }, + "screenshots": { + "type": "array", + "items": { + "type": "string" + } + }, + "license": { + "type": "string" + }, + "codeAttestedAt": { + "format": "date-time", + "type": "string" + }, + "registeredAt": { + "format": "date-time", + "type": "string" + }, + "submittedAt": { + "format": "date-time", + "type": "string" + }, + "createdAt": { + "format": "date-time", + "type": "string" + }, + "updatedAt": { + "format": "date-time", + "type": "string" + } + }, + "required": [ + "id", + "hackathonId", + "projectId", + "participantId", + "organizationId", + "participationType", + "projectName", + "category", + "description", + "links", + "status", + "registeredAt", + "createdAt", + "updatedAt" + ] + }, + "CreateSubmissionDto": { + "type": "object", + "properties": { + "organizationId": { + "type": "string", + "description": "Organization ID", + "example": "org_1234567890" + }, + "projectId": { + "type": "string", + "description": "Project ID (must be owned by the user or organization). If not provided, a base project will be created automatically.", + "example": "proj_1234567890" + }, + "participationType": { + "type": "string", + "description": "Type of participation", + "enum": ["INDIVIDUAL", "TEAM"], + "example": "INDIVIDUAL" + }, + "teamId": { + "type": "string", + "description": "[Ignored by backend.] Team ID is snapshotted from the user's authoritative team record at submission time. Field accepted for backwards compatibility only.", + "example": "team_1234567890", + "deprecated": true + }, + "teamName": { + "type": "string", + "description": "[Ignored by backend.] Team name is snapshotted from the user's authoritative team record at submission time.", + "example": "Awesome Hackers", + "deprecated": true + }, + "teamMembers": { + "description": "[Ignored by backend.] Team members are snapshotted from the user's authoritative team record at submission time. Sending this field has no effect.", + "deprecated": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/TeamMemberDto" + } + }, + "projectName": { + "type": "string", + "description": "Project name for the submission", + "example": "DeFi Lending Platform" + }, + "category": { + "type": "string", + "description": "Category of the project", + "example": "DeFi" + }, + "description": { + "type": "string", + "description": "Detailed description of the project", + "example": "A decentralized lending platform built on Stellar..." + }, + "logo": { + "type": "string", + "description": "Project logo URL", + "example": "https://example.com/logo.png" + }, + "banner": { + "type": "string", + "description": "Project banner image URL (wide hero image)", + "example": "https://example.com/banner.png" + }, + "videoUrl": { + "type": "string", + "description": "Video demonstration URL", + "example": "https://youtube.com/watch?v=xyz" + }, + "introduction": { + "type": "string", + "description": "Brief introduction to the project", + "example": "We built a platform that allows users to..." + }, + "links": { + "description": "Links to project resources. Each fixed link type (github, demo, video, document, presentation) can appear at most once. Use \"other\" for additional links, up to a maximum of 5.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SubmissionLinkDto" + } + }, + "socialLinks": { + "description": "Social links for the project", + "allOf": [ + { + "$ref": "#/components/schemas/SocialLinksDto" + } + ] + }, + "trackIds": { + "description": "Optional list of track ids to enter. Only allowed when the hackathon has prizeStructure != OVERALL_ONLY. Capped at Hackathon.tracksMaxPerSubmission.", + "example": ["trk_abc", "trk_def"], + "type": "array", + "items": { + "type": "string" + } + }, + "trackAnswers": { + "type": "object", + "description": "Per-track answers. Keyed by trackId; each value is { promptAnswer?, customAnswers?, artifacts? }. Phase B.", + "example": { + "trk_abc": { + "promptAnswer": "We focused on a one-tap escrow flow.", + "customAnswers": { + "q_audience": "Freelancers" + }, + "artifacts": { + "figma": "https://figma.com/file/..." + } + } + } + }, + "customAnswers": { + "type": "object", + "description": "Answers to hackathon-level SUBMISSION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). Validated against the question set.", + "example": { + "cq_audience": "Freelancers", + "cq_stack": ["Web", "AI"] + } + }, + "tagline": { + "type": "string", + "description": "Short elevator pitch shown on cards / sidebars / judge queue. Max ~160 chars.", + "example": "Milestone-based escrow for one-time freelance gigs on Stellar." + }, + "builtWith": { + "description": "Free-form tech-stack tags. Max 20 entries, 40 chars each.", + "example": ["Soroban", "Stellar SDK", "Next.js", "Rust"], + "type": "array", + "items": { + "type": "string" + } + }, + "screenshots": { + "description": "Up to 5 screenshot URLs for the project gallery.", + "type": "array", + "items": { + "type": "string" + } + }, + "license": { + "type": "string", + "description": "License the submission ships under.", + "enum": [ + "MIT", + "Apache-2.0", + "GPL-3.0", + "BSD-3", + "PROPRIETARY", + "OTHER" + ] + }, + "codeAttested": { + "type": "boolean", + "description": "Submitter attests the code is original or properly attributed. Required to mark a submission SUBMITTED (vs DRAFT)." + } + }, + "required": [ + "organizationId", + "participationType", + "projectName", + "category", + "description", + "links" + ] + }, + "UpdateSubmissionDto": { + "type": "object", + "properties": { + "projectName": { + "type": "string", + "description": "Project name for the submission", + "example": "DeFi Lending Platform" + }, + "category": { + "type": "string", + "description": "Category of the project", + "example": "DeFi" + }, + "description": { + "type": "string", + "description": "Detailed description of the project", + "example": "A decentralized lending platform built on Stellar..." + }, + "logo": { + "type": "string", + "description": "Project logo URL", + "example": "https://example.com/logo.png" + }, + "banner": { + "type": "string", + "description": "Project banner image URL (wide hero image)", + "example": "https://example.com/banner.png" + }, + "videoUrl": { + "type": "string", + "description": "Video demonstration URL", + "example": "https://youtube.com/watch?v=xyz" + }, + "introduction": { + "type": "string", + "description": "Brief introduction to the project", + "example": "We built a platform that allows users to..." + }, + "links": { + "description": "Links to project resources. Each fixed link type (github, demo, video, document, presentation) can appear at most once. Use \"other\" for additional links, up to a maximum of 5.", + "type": "array", + "items": { + "$ref": "#/components/schemas/SubmissionLinkDto" + } + }, + "socialLinks": { + "description": "Social links for the project", + "allOf": [ + { + "$ref": "#/components/schemas/SocialLinksDto" + } + ] + }, + "teamMembers": { + "description": "Team members (for team submissions)", + "type": "array", + "items": { + "$ref": "#/components/schemas/TeamMemberDto" + } + }, + "trackIds": { + "description": "Replace the submission's track picks. Omit to leave existing entries untouched; pass an empty array to clear all picks.", + "type": "array", + "items": { + "type": "string" + } + }, + "trackAnswers": { + "type": "object", + "description": "Per-track answers, same shape as on create. Phase B." + }, + "customAnswers": { + "type": "object", + "description": "Answers to hackathon-level SUBMISSION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). Replaces the stored answers when provided.", + "example": { + "cq_audience": "Freelancers", + "cq_stack": ["Web", "AI"] + } + }, + "tagline": { + "type": "string" + }, + "builtWith": { + "type": "array", + "items": { + "type": "string" + } + }, + "screenshots": { + "type": "array", + "items": { + "type": "string" + } + }, + "license": { + "type": "string", + "enum": [ + "MIT", + "Apache-2.0", + "GPL-3.0", + "BSD-3", + "PROPRIETARY", + "OTHER" + ] + }, + "codeAttested": { + "type": "boolean" + } + } + }, + "TeamMemberResponseDto": { + "type": "object", + "properties": { + "userId": { + "type": "string", + "description": "User ID" + }, + "username": { + "type": "string", + "description": "Username" + }, + "name": { + "type": "string", + "description": "Display name" + }, + "role": { + "type": "string", + "description": "Role in team (e.g. leader, member)" + }, + "image": { + "type": "string", + "description": "Profile image URL" + }, + "joinedAt": { + "type": "string", + "description": "When the member joined the team (ISO string)" + } + }, + "required": ["userId", "username", "name", "role", "joinedAt"] + }, + "LookingForRoleDto": { + "type": "object", + "properties": { + "role": { + "type": "string", + "description": "Role title (e.g. \"Frontend Developer\", \"UI Designer\")", + "example": "Frontend Developer" + }, + "skills": { + "description": "Optional free-form skills associated with this role", + "example": ["React", "TypeScript"], + "type": "array", + "items": { + "type": "array" + } + } + }, + "required": ["role"] + }, + "TeamRoleResponseDto": { + "type": "object", + "properties": { + "skill": { + "type": "string", + "description": "Skill/role name" + }, + "hired": { + "type": "boolean", + "description": "Whether this role has been filled" + } + }, + "required": ["skill", "hired"] + }, + "TeamResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Team ID", + "example": "team_1234567890" + }, + "teamName": { + "type": "string", + "description": "Team name", + "example": "Stellar Innovators" + }, + "description": { + "type": "string", + "description": "Team description" + }, + "hackathonId": { + "type": "string", + "description": "Hackathon ID" + }, + "leader": { + "type": "object", + "description": "Team leader information" + }, + "members": { + "description": "Team members", + "type": "array", + "items": { + "$ref": "#/components/schemas/TeamMemberResponseDto" + } + }, + "memberCount": { + "type": "number", + "description": "Current number of members", + "example": 3 + }, + "maxSize": { + "type": "number", + "description": "Maximum team size allowed", + "example": 5 + }, + "lookingFor": { + "description": "Roles the team is looking for, with optional free-form skills", + "type": "array", + "items": { + "$ref": "#/components/schemas/LookingForRoleDto" } }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." + "rolesStatus": { + "description": "Hired status per role (when using lookingFor)", + "type": "array", + "items": { + "$ref": "#/components/schemas/TeamRoleResponseDto" + } }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." + "contactInfo": { + "type": "object", + "description": "Contact information (e.g. telegram, discord, email)" }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." + "isOpen": { + "type": "boolean", + "description": "Whether team is accepting new members", + "example": true }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + "createdAt": { + "type": "string", + "description": "Team creation date" }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." - } - } - } - }, - "/api/auth/magic-link/verify": { - "get": { - "tags": ["Magic-link"], - "description": "Verify magic link", - "operationId": "verifyMagicLink", - "security": [ - { - "bearerAuth": [] + "updatedAt": { + "type": "string", + "description": "Last update date" } - ], - "parameters": [ - { - "name": "token", - "in": "query", - "schema": { - "type": "string", - "description": "Verification token" + }, + "required": [ + "id", + "teamName", + "description", + "hackathonId", + "leader", + "members", + "memberCount", + "maxSize", + "isOpen", + "createdAt", + "updatedAt" + ] + }, + "TeamListResponseDto": { + "type": "object", + "properties": { + "teams": { + "description": "List of teams", + "type": "array", + "items": { + "$ref": "#/components/schemas/TeamResponseDto" } }, - { - "name": "callbackURL", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "URL to redirect after magic link verification, if not provided the user will be redirected to the root URL. Eg: \"/dashboard\"" - } + "pagination": { + "type": "object", + "description": "Pagination metadata" + } + }, + "required": ["teams", "pagination"] + }, + "CreateTeamDto": { + "type": "object", + "properties": { + "teamName": { + "type": "string", + "description": "Team name", + "example": "Stellar Innovators", + "minLength": 3, + "maxLength": 100 }, - { - "name": "errorCallbackURL", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "URL to redirect after error." + "description": { + "type": "string", + "description": "Team description", + "example": "We are building the next generation DeFi platform", + "minLength": 10, + "maxLength": 500 + }, + "lookingFor": { + "description": "Roles the team is looking for. Each entry is a role title with optional free-form skills. Team will be CLOSED unless at least one role is specified. The number of roles is bounded by the hackathon's teamMin/teamMax (excluding the leader).", + "type": "array", + "items": { + "$ref": "#/components/schemas/LookingForRoleDto" } }, - { - "name": "newUserCallbackURL", - "in": "query", - "schema": { - "type": ["string", "null"], - "description": "URL to redirect after new user signup. Only used if the user is registering for the first time." + "contactInfo": { + "type": "object", + "description": "Contact information for interested members", + "example": { + "telegram": "@teamlead", + "discord": "lead#1234" } } - ], - "responses": { - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "session": { - "$ref": "#/components/schemas/Session" - }, - "user": { - "$ref": "#/components/schemas/User" - } - } - } - } - } - }, - "400": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Bad Request. Usually due to missing parameters, or invalid parameters." - }, - "401": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - }, - "required": ["message"] - } - } - }, - "description": "Unauthorized. Due to missing or invalid authentication." + }, + "required": ["teamName", "description"] + }, + "UpdateTeamDto": { + "type": "object", + "properties": { + "teamName": { + "type": "string", + "description": "Updated team name", + "example": "Stellar Innovators Pro" }, - "403": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Forbidden. You do not have permission to access this resource or to perform this action." + "description": { + "type": "string", + "description": "Updated team description" }, - "404": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Not Found. The requested resource was not found." + "lookingFor": { + "description": "Roles the team is looking for. Set to empty array to close the team. Each entry is a role title with optional free-form skills.", + "type": "array", + "items": { + "$ref": "#/components/schemas/LookingForRoleDto" + } }, - "429": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Too Many Requests. You have exceeded the rate limit. Try again later." + "contactInfo": { + "type": "object", + "description": "Updated contact information" }, - "500": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "message": { - "type": "string" - } - } - } - } - }, - "description": "Internal Server Error. This is a problem with the server that you cannot fix." + "isOpen": { + "type": "boolean", + "description": "Explicitly set team open/closed status. Can only be true if lookingFor is not empty." } } - } - } - }, - "info": { - "title": "Boundless API", - "description": "The Boundless API description", - "version": "1.0", - "contact": {} - }, - "tags": [ - { - "name": "boundless", - "description": "" - }, - { - "name": "Default", - "description": "Default endpoints that are included with Better Auth by default. These endpoints are not part of any plugin." - } - ], - "servers": [ - { - "url": "http://localhost:8000", - "description": "Development server" - } - ], - "components": { - "securitySchemes": { - "JWT-auth": { - "scheme": "bearer", - "bearerFormat": "JWT", - "type": "http", - "name": "JWT", - "description": "Enter JWT token", - "in": "header" - }, - "apiKeyCookie": { - "type": "apiKey", - "in": "cookie", - "name": "apiKeyCookie", - "description": "API Key authentication via cookie" }, - "bearerAuth": { - "type": "http", - "scheme": "bearer", - "description": "Bearer token authentication" - } - }, - "schemas": { - "NotificationPreferencesDto": { + "InviteToTeamDto": { "type": "object", - "properties": {} + "properties": { + "inviteeIdentifier": { + "type": "string", + "description": "User ID or username of the person to invite", + "example": "user_1234567890" + }, + "message": { + "type": "string", + "description": "Optional message to include with the invitation", + "example": "We would love to have you on our team!", + "maxLength": 500 + } + }, + "required": ["inviteeIdentifier"] }, - "UpdatePrivacySettingsDto": { + "TeamInvitationResponseDto": { "type": "object", "properties": { - "publicProfile": { - "type": "boolean", - "description": "Public profile", - "example": true + "id": { + "type": "string", + "description": "Invitation ID", + "example": "inv_1234567890" }, - "emailVisibility": { - "type": "boolean", - "description": "Email visibility", - "example": true + "teamId": { + "type": "string", + "description": "Team ID", + "example": "team_1234567890" }, - "locationVisibility": { - "type": "boolean", - "description": "Location visibility", - "example": true + "hackathon": { + "type": "object", + "description": "Hackathon information" }, - "companyVisibility": { - "type": "boolean", - "description": "Company visibility", - "example": true + "invitee": { + "type": "object", + "description": "Invitee information" }, - "websiteVisibility": { - "type": "boolean", - "description": "Website visibility", - "example": true + "inviter": { + "type": "object", + "description": "Inviter information" }, - "socialLinksVisibility": { - "type": "boolean", - "description": "Social links visibility", - "example": true + "status": { + "type": "string", + "description": "Invitation status", + "example": "pending", + "enum": ["pending", "accepted", "rejected", "expired"] + }, + "message": { + "type": "object", + "description": "Optional message from inviter", + "example": "We would love to have you on our team!" + }, + "role": { + "type": "object", + "description": "Role in the team", + "example": "member" + }, + "expiresAt": { + "format": "date-time", + "type": "string", + "description": "Invitation expiration date", + "example": "2026-01-30T12:00:00.000Z" + }, + "createdAt": { + "format": "date-time", + "type": "string", + "description": "Invitation creation date", + "example": "2026-01-23T12:00:00.000Z" + }, + "respondedAt": { + "type": "object", + "description": "Date when invitation was responded to", + "example": "2026-01-24T12:00:00.000Z" } }, "required": [ - "publicProfile", - "emailVisibility", - "locationVisibility", - "companyVisibility", - "websiteVisibility", - "socialLinksVisibility" + "id", + "teamId", + "hackathon", + "invitee", + "inviter", + "status", + "role", + "expiresAt", + "createdAt" ] }, - "UpdateAppearanceSettingsDto": { + "TeamInvitationListResponseDto": { "type": "object", "properties": { - "theme": { + "invitations": { + "description": "List of invitations", + "type": "array", + "items": { + "$ref": "#/components/schemas/TeamInvitationResponseDto" + } + }, + "total": { + "type": "number", + "description": "Total count", + "example": 5 + } + }, + "required": ["invitations", "total"] + }, + "InvitationActionResponseDto": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Success message", + "example": "Successfully accepted team invitation" + }, + "teamId": { "type": "string", - "description": "Theme", - "example": "light", - "enum": ["light", "dark", "auto"] + "description": "Team ID that was joined (only for accept)", + "example": "team_1234567890" + }, + "invitation": { + "description": "Updated invitation", + "allOf": [ + { + "$ref": "#/components/schemas/TeamInvitationResponseDto" + } + ] } }, - "required": ["theme"] + "required": ["message", "teamId", "invitation"] }, - "PublicEarningsSummaryDto": { + "ToggleRoleHiredDto": { "type": "object", "properties": { - "totalEarned": { - "type": "number", - "description": "All-time total earned (normalized, e.g. USDC 7 decimals)", - "example": 50000 + "skill": { + "type": "string", + "description": "Skill/role name to toggle hired status", + "example": "Rust Developer" } }, - "required": ["totalEarned"] + "required": ["skill"] }, - "EarningsBreakdownDto": { + "TransferLeadershipDto": { "type": "object", "properties": { - "hackathons": { - "type": "number", - "description": "Total from hackathons", - "example": 20000 - }, - "grants": { - "type": "number", - "description": "Total from grants", - "example": 10000 - }, - "crowdfunding": { - "type": "number", - "description": "Total from crowdfunding", - "example": 15000 + "newLeaderId": { + "type": "string", + "description": "User ID of the new team leader (must be an existing member)", + "example": "user_1234567890" }, - "bounties": { - "type": "number", - "description": "Total from bounties", - "example": 5000 + "reason": { + "type": "string", + "description": "Optional reason for the leadership transfer", + "example": "Stepping down to focus on development tasks", + "maxLength": 500 } }, - "required": ["hackathons", "grants", "crowdfunding", "bounties"] + "required": ["newLeaderId"] }, - "PublicEarningActivityDto": { + "LeadershipTransferResponseDto": { "type": "object", "properties": { - "id": { + "message": { "type": "string", - "description": "Unique activity id" + "description": "Success message", + "example": "Leadership successfully transferred" }, - "source": { - "type": "string", - "description": "Earnings source category", - "enum": ["hackathons", "grants", "crowdfunding", "bounties"] + "team": { + "description": "Updated team with new leader", + "allOf": [ + { + "$ref": "#/components/schemas/TeamResponseDto" + } + ] }, - "title": { + "previousLeaderId": { "type": "string", - "description": "Human-readable title", - "example": "Winner of Stellar Hackathon Q1" - }, - "amount": { - "type": "number", - "description": "Amount (normalized)", - "example": 5000 + "description": "Previous leader ID", + "example": "user_1234567890" }, - "currency": { + "newLeaderId": { "type": "string", - "description": "Currency code", - "example": "USDC" + "description": "New leader ID", + "example": "user_0987654321" }, - "occurredAt": { + "transferredAt": { + "format": "date-time", "type": "string", - "description": "When the earning occurred (ISO date string)", - "example": "2024-01-19T14:30:00Z" + "description": "Timestamp of the transfer", + "example": "2026-02-16T10:30:00.000Z" } }, "required": [ - "id", - "source", - "title", - "amount", - "currency", - "occurredAt" + "message", + "team", + "previousLeaderId", + "newLeaderId", + "transferredAt" ] }, - "PublicEarningsResponseDto": { + "InfoFormData": { "type": "object", "properties": { - "summary": { - "$ref": "#/components/schemas/PublicEarningsSummaryDto" + "name": { + "type": "string", + "description": "Hackathon title", + "minLength": 3, + "maxLength": 100 }, - "breakdown": { - "$ref": "#/components/schemas/EarningsBreakdownDto" + "banner": { + "type": "string", + "description": "Banner image URL", + "format": "uri" }, - "activities": { - "description": "Verified activity history (completed only)", + "description": { + "type": "string", + "description": "Hackathon description", + "minLength": 10, + "maxLength": 5000 + }, + "categories": { "type": "array", + "description": "One or more hackathon categories", "items": { - "$ref": "#/components/schemas/PublicEarningActivityDto" + "type": "string", + "enum": [ + "DeFi", + "Payments", + "Stablecoins", + "Lending & Borrowing", + "Trading & DEXs", + "Derivatives", + "Prediction Markets", + "NFTs", + "Creator Economy", + "Social", + "Social Tokens", + "DAOs", + "Governance", + "Web3 Gaming", + "Metaverse", + "Layer 1", + "Layer 2", + "Cross-chain", + "Interoperability", + "Infrastructure", + "Developer Tooling", + "Wallets", + "Account Abstraction", + "Oracles", + "Data & Indexing", + "Analytics", + "AI", + "AI Agents", + "DePIN", + "DeSci", + "Privacy", + "Zero-Knowledge", + "Security", + "Identity", + "Real World Assets", + "Tokenization", + "Supply Chain", + "Sustainability", + "Climate", + "Education", + "Healthcare", + "Consumer Apps", + "Mobile", + "Other" + ] } + }, + "venueType": { + "type": "string", + "description": "Venue type", + "enum": ["virtual", "physical"] + }, + "tagline": { + "type": "string", + "description": "Short tagline", + "maxLength": 200 + }, + "country": { + "type": "string" + }, + "state": { + "type": "string" + }, + "city": { + "type": "string" + }, + "venueName": { + "type": "string" + }, + "venueAddress": { + "type": "string" + }, + "slug": { + "type": "string", + "description": "Read-only URL slug (server-assigned)" } }, - "required": ["summary", "breakdown", "activities"] + "required": [ + "name", + "banner", + "description", + "categories", + "venueType", + "tagline" + ] }, - "EarningsSummaryDto": { + "PhaseDto": { "type": "object", "properties": { - "totalEarned": { - "type": "number", - "description": "All-time total earned (normalized, e.g. USDC 7 decimals)", - "example": 50000 + "name": { + "type": "string", + "description": "Phase name" }, - "pendingWithdrawal": { - "type": "number", - "description": "Amount currently claimable / pending withdrawal", - "example": 10000 + "startDate": { + "type": "string", + "format": "date-time" }, - "completedWithdrawal": { - "type": "number", - "description": "Amount already paid out (completed withdrawals)", - "example": 40000 + "endDate": { + "type": "string", + "format": "date-time" + }, + "description": { + "type": "string" } }, - "required": ["totalEarned", "pendingWithdrawal", "completedWithdrawal"] + "required": ["name", "startDate", "endDate"] }, - "EarningActivityDto": { + "TimelineFormData": { "type": "object", "properties": { - "id": { + "startDate": { "type": "string", - "description": "Unique activity id (e.g. submissionId or milestoneId)" + "format": "date-time" }, - "source": { + "submissionDeadline": { "type": "string", - "description": "Earnings source category", - "enum": ["hackathons", "grants", "crowdfunding", "bounties"] + "format": "date-time" }, - "title": { + "timezone": { "type": "string", - "description": "Human-readable title", - "example": "Winner of Stellar Hackathon Q1" - }, - "amount": { - "type": "number", - "description": "Amount (normalized)", - "example": 5000 + "description": "IANA timezone" }, - "currency": { + "registrationDeadline": { "type": "string", - "description": "Currency code", - "example": "USDC" + "format": "date-time" }, - "status": { + "judgingDeadline": { "type": "string", - "description": "Activity status", - "enum": ["pending", "claimable", "completed"] + "format": "date-time" }, - "occurredAt": { + "phases": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PhaseDto" + } + }, + "submissionDeadlineOriginal": { "type": "string", - "description": "When the earning occurred (ISO date string)", - "example": "2024-01-19T14:30:00Z" + "format": "date-time", + "description": "Read-only: original submission deadline before any extension" }, - "entityId": { + "submissionDeadlineExtendedAt": { "type": "string", - "description": "Entity id for claim (e.g. submissionId, milestoneId)" + "format": "date-time", + "description": "Read-only: timestamp the submission deadline was last extended" } }, - "required": [ - "id", - "source", - "title", - "amount", - "currency", - "status", - "occurredAt" - ] + "required": ["startDate", "submissionDeadline", "timezone"] }, - "EarningsResponseDto": { + "ParticipantFormData": { "type": "object", "properties": { - "summary": { - "$ref": "#/components/schemas/EarningsSummaryDto" + "participantType": { + "type": "string", + "enum": ["individual", "team", "team_or_individual"] }, - "breakdown": { - "$ref": "#/components/schemas/EarningsBreakdownDto" + "teamMin": { + "type": "number", + "minimum": 1, + "maximum": 20 }, - "activities": { - "description": "Activity feed", - "type": "array", - "items": { - "$ref": "#/components/schemas/EarningActivityDto" - } + "teamMax": { + "type": "number", + "minimum": 1, + "maximum": 20 + }, + "maxParticipants": { + "type": "number", + "minimum": 1, + "description": "Participant cap; omit for unlimited" + }, + "require_github": { + "type": "boolean" + }, + "require_demo_video": { + "type": "boolean" + }, + "require_other_links": { + "type": "boolean" + }, + "detailsTab": { + "type": "boolean" + }, + "participantsTab": { + "type": "boolean" + }, + "resourcesTab": { + "type": "boolean" + }, + "submissionTab": { + "type": "boolean" + }, + "announcementsTab": { + "type": "boolean" + }, + "discussionTab": { + "type": "boolean" + }, + "winnersTab": { + "type": "boolean" + }, + "sponsorsTab": { + "type": "boolean" + }, + "joinATeamTab": { + "type": "boolean" + }, + "rulesTab": { + "type": "boolean" + }, + "submissionVisibility": { + "type": "string", + "enum": ["PUBLIC", "PARTICIPANTS_ONLY"] + }, + "submissionStatusVisibility": { + "type": "string", + "enum": ["ALL", "ACCEPTED_SHORTLISTED", "HIDDEN_UNTIL_RESULTS"] } }, - "required": ["summary", "breakdown", "activities"] + "required": ["participantType"] }, - "DashboardUserStatsDto": { + "HackathonDraftTracksDto": { "type": "object", "properties": { - "followers": { - "type": "number" - }, - "following": { - "type": "number" + "tracksMaxPerSubmission": { + "type": "number", + "description": "Max number of tracks a single submission may enter (1-20)." } - }, - "required": ["followers", "following"] + } }, - "DashboardUserDto": { + "PrizeTierDto": { "type": "object", "properties": { "id": { - "type": "string" - }, - "name": { - "type": "string", - "nullable": true - }, - "email": { - "type": "string" - }, - "username": { "type": "string", - "nullable": true + "description": "Client-generated tier id" }, - "displayUsername": { + "place": { "type": "string", - "nullable": true + "description": "Placement label, e.g. \"1st Place\"" }, - "image": { + "prizeAmount": { "type": "string", - "nullable": true + "description": "Prize amount as a decimal string" }, - "role": { + "description": { "type": "string" }, - "createdAt": { - "format": "date-time", + "currency": { "type": "string" }, - "stats": { - "$ref": "#/components/schemas/DashboardUserStatsDto" + "passMark": { + "type": "number", + "minimum": 0, + "maximum": 100 + }, + "kind": { + "type": "string", + "enum": ["OVERALL", "TRACK"] + }, + "trackId": { + "type": "string" } }, - "required": [ - "id", - "name", - "email", - "username", - "displayUsername", - "image", - "role", - "createdAt" - ] + "required": ["id", "place", "prizeAmount", "passMark"] }, - "UserStatsDto": { + "PrizePlacementWriteDto": { "type": "object", "properties": { - "projectsCreated": { - "type": "number" - }, - "projectsFunded": { - "type": "number" - }, - "totalContributed": { - "type": "number" - }, - "commentsPosted": { - "type": "number" + "position": { + "type": "number", + "description": "1 = 1st place; unique within a prize" }, - "votes": { - "type": "number" + "label": { + "type": "string" }, - "grants": { - "type": "number" + "amount": { + "type": "string", + "description": "Prize amount as a decimal string" }, - "hackathons": { - "type": "number" + "currency": { + "type": "string" }, - "followers": { - "type": "number" + "passMark": { + "type": "number", + "minimum": 0, + "maximum": 100 + } + }, + "required": ["position", "amount"] + }, + "PrizeWriteDto": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Prize name, e.g. \"Grand Prize\" or \"Best UI/UX\"" }, - "following": { - "type": "number" + "description": { + "type": "string" }, - "reputation": { - "type": "number" + "trackIds": { + "description": "Linked HackathonTrack ids; empty = overall prize", + "type": "array", + "items": { + "type": "string" + } }, - "communityScore": { - "type": "number" + "placements": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PrizePlacementWriteDto" + } } }, - "required": [ - "projectsCreated", - "projectsFunded", - "totalContributed", - "commentsPosted", - "votes", - "grants", - "hackathons", - "followers", - "following", - "reputation", - "communityScore" - ] + "required": ["name", "trackIds", "placements"] }, - "ChartDataPointDto": { + "WinnerOverrideDto": { "type": "object", "properties": { - "date": { + "submissionId": { "type": "string", - "description": "Date in YYYY-MM-DD format" + "description": "Submission id the override targets" }, - "count": { + "rank": { "type": "number", - "description": "Count for that date" + "minimum": 1 + }, + "prizeAmount": { + "type": "string" + }, + "currency": { + "type": "string" } }, - "required": ["date", "count"] + "required": ["submissionId"] }, - "ChartDto": { + "RewardsFormData": { "type": "object", "properties": { - "data": { + "prizeTiers": { "type": "array", "items": { - "$ref": "#/components/schemas/ChartDataPointDto" + "$ref": "#/components/schemas/PrizeTierDto" + } + }, + "prizes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PrizeWriteDto" + } + }, + "winnerOverrides": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WinnerOverrideDto" + } + }, + "prizeStructure": { + "type": "string", + "enum": ["OVERALL_ONLY", "OVERALL_AND_TRACKS", "TRACKS_ONLY"] + }, + "tracksMaxPerSubmission": { + "type": "number", + "minimum": 1, + "maximum": 20 + }, + "allowWinnerStacking": { + "type": "boolean" + } + } + }, + "ResourceItemDto": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Client-generated resource id" + }, + "link": { + "type": "string" + }, + "description": { + "type": "string" + }, + "file": { + "type": "object", + "description": "Uploaded file metadata", + "properties": { + "url": { + "type": "string" + }, + "name": { + "type": "string" + } } } }, - "required": ["data"] + "required": ["id"] }, - "ActivitiesGraphDto": { + "ResourcesFormData": { "type": "object", "properties": { - "data": { + "resources": { "type": "array", "items": { - "$ref": "#/components/schemas/ChartDataPointDto" + "$ref": "#/components/schemas/ResourceItemDto" } } }, - "required": ["data"] + "required": ["resources"] }, - "ActivityProjectDto": { + "CriterionDto": { "type": "object", "properties": { "id": { - "type": "string" - }, - "title": { - "type": "string" - }, - "banner": { "type": "string", - "nullable": true + "description": "Client-generated criterion id" }, - "logo": { + "name": { "type": "string", - "nullable": true + "description": "Criterion name" + }, + "weight": { + "type": "number", + "minimum": 0, + "maximum": 100 + }, + "description": { + "type": "string" } }, - "required": ["id", "title"] + "required": ["id", "name", "weight"] }, - "ActivityOrganizationDto": { + "JudgingFormData": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" + "criteria": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CriterionDto" + } } }, - "required": ["id", "name"] + "required": ["criteria"] }, - "RecentActivityDto": { + "SponsorPartnerDto": { "type": "object", "properties": { "id": { - "type": "string" + "type": "string", + "description": "Client-generated sponsor/partner id" }, - "type": { + "name": { "type": "string" }, - "userId": { + "logo": { "type": "string" }, - "projectId": { - "type": "string", - "nullable": true - }, - "organizationId": { - "type": "string", - "nullable": true - }, - "createdAt": { - "format": "date-time", + "link": { "type": "string" - }, - "project": { - "$ref": "#/components/schemas/ActivityProjectDto" - }, - "organization": { - "$ref": "#/components/schemas/ActivityOrganizationDto" } }, - "required": ["id", "type", "userId", "createdAt"] + "required": ["id"] }, - "DashboardDto": { + "CollaborationFormData": { "type": "object", "properties": { - "user": { - "description": "User profile data", - "allOf": [ - { - "$ref": "#/components/schemas/DashboardUserDto" - } - ] + "contactEmail": { + "type": "string", + "description": "Organizer contact email" }, - "stats": { - "$ref": "#/components/schemas/UserStatsDto" + "telegram": { + "type": "string" }, - "chart": { - "$ref": "#/components/schemas/ChartDto" + "discord": { + "type": "string" }, - "activitiesGraph": { - "$ref": "#/components/schemas/ActivitiesGraphDto" + "socialLinks": { + "type": "array", + "items": { + "type": "string" + } }, - "recentActivities": { - "description": "Recent activities", + "sponsorsPartners": { "type": "array", "items": { - "$ref": "#/components/schemas/RecentActivityDto" + "$ref": "#/components/schemas/SponsorPartnerDto" } } }, - "required": [ - "user", - "stats", - "chart", - "activitiesGraph", - "recentActivities" - ] - }, - "UpdateProfileDto": { - "type": "object", - "properties": {} - }, - "UpdateUserDto": { - "type": "object", - "properties": {} - }, - "UploadResponseDto": { - "type": "object", - "properties": {} - }, - "MultipleUploadResponseDto": { - "type": "object", - "properties": {} - }, - "FileInfoResponseDto": { - "type": "object", - "properties": {} - }, - "SearchFilesResponseDto": { - "type": "object", - "properties": {} - }, - "OptimizedUrlResponseDto": { - "type": "object", - "properties": {} - }, - "ResponsiveUrlsResponseDto": { - "type": "object", - "properties": {} - }, - "UsageStatsResponseDto": { - "type": "object", - "properties": {} - }, - "RegisterDto": { - "type": "object", - "properties": {} - }, - "LoginDto": { - "type": "object", - "properties": {} - }, - "RefreshTokenDto": { - "type": "object", - "properties": {} + "required": ["contactEmail"] }, - "VerifySignatureDto": { + "HackathonDraftDataDto": { "type": "object", - "properties": {} + "properties": { + "information": { + "$ref": "#/components/schemas/InfoFormData" + }, + "timeline": { + "$ref": "#/components/schemas/TimelineFormData" + }, + "participation": { + "$ref": "#/components/schemas/ParticipantFormData" + }, + "tracks": { + "$ref": "#/components/schemas/HackathonDraftTracksDto" + }, + "rewards": { + "$ref": "#/components/schemas/RewardsFormData" + }, + "resources": { + "$ref": "#/components/schemas/ResourcesFormData" + }, + "judging": { + "$ref": "#/components/schemas/JudgingFormData" + }, + "collaboration": { + "$ref": "#/components/schemas/CollaborationFormData" + } + } }, - "CreateConversationDto": { + "HackathonDraftAiGenerationDto": { "type": "object", "properties": { - "otherUserId": { + "generationId": { "type": "string", - "description": "User ID of the other participant" + "description": "AI generationId that produced or last-updated this draft." } }, - "required": ["otherUserId"] + "required": ["generationId"] }, - "CreateMessageDto": { + "HackathonDraftPrizePlacementDto": { "type": "object", "properties": { - "body": { + "id": { + "type": "string" + }, + "position": { + "type": "number", + "description": "1 = 1st place, unique within a prize" + }, + "label": { "type": "string", - "description": "Message text", - "maxLength": 10000 + "nullable": true + }, + "amount": { + "type": "string", + "description": "Decimal string in the prize currency" + }, + "currency": { + "type": "string" + }, + "passMark": { + "type": "number", + "description": "Minimum score (0-100) to win this placement" } }, - "required": ["body"] - }, - "ContactDto": { - "type": "object", - "properties": {} + "required": ["id", "position", "amount", "currency", "passMark"] }, - "CreateCampaignDto": { + "HackathonDraftPrizeDto": { "type": "object", "properties": { - "title": { - "type": "string", - "description": "Title of the campaign", - "example": "Web3 Campaign" + "id": { + "type": "string" }, - "logo": { - "type": "string", - "description": "Logo of the campaign", - "example": "https://example.com/logo.png" + "name": { + "type": "string" }, - "vision": { + "description": { "type": "string", - "description": "Vision of the campaign", - "example": "Web3 Campaign" + "nullable": true }, - "banner": { - "type": "string", - "description": "Banner image URL of the campaign", - "example": "https://example.com/banner.png" + "displayOrder": { + "type": "number" }, - "category": { - "type": "string", - "description": "Category of the campaign", - "example": "web3" + "trackIds": { + "description": "Linked track ids; empty = overall prize", + "type": "array", + "items": { + "type": "string" + } }, - "details": { + "placements": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HackathonDraftPrizePlacementDto" + } + } + }, + "required": ["id", "name", "displayOrder", "trackIds", "placements"] + }, + "HackathonDraftResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "status": { "type": "string", - "description": "Details of the campaign", - "example": "Web3 Campaign" + "enum": [ + "DRAFT", + "DRAFT_AWAITING_FUNDING", + "PUBLISHED", + "ARCHIVED", + "CANCELLED" + ] }, - "fundingAmount": { + "currentStep": { "type": "number", - "description": "Funding amount of the campaign", - "example": 1000 + "description": "First incomplete step (1-based)" }, - "githubUrl": { - "type": "string", - "description": "Github URL of the campaign", - "example": "https://github.com/example/project" + "completedSteps": { + "type": "array", + "items": { + "type": "string" + } }, - "gitlabUrl": { - "type": "string", - "description": "Gitlab URL of the campaign", - "example": "https://gitlab.com/example/project" + "data": { + "$ref": "#/components/schemas/HackathonDraftDataDto" }, - "bitbucketUrl": { - "type": "string", - "description": "Bitbucket URL of the campaign", - "example": "https://bitbucket.com/example/project" + "isValidForPublish": { + "type": "boolean" }, - "projectWebsite": { + "validationErrors": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Per-section validation messages, keyed by step" + }, + "createdAt": { "type": "string", - "description": "Project website of the campaign", - "example": "https://example.com/project" + "format": "date-time" }, - "demoVideo": { + "updatedAt": { "type": "string", - "description": "Demo video of the campaign", - "example": "https://example.com/demo.mp4" + "format": "date-time" }, - "milestones": { - "description": "Milestones of the campaign", - "example": [ + "aiGeneration": { + "description": "Present when the draft was generated with Organizer Assist; enables per-section AI regenerate in the wizard.", + "allOf": [ { - "name": "Milestone 1", - "description": "Milestone 1 description", - "startDate": "2025-01-01", - "endDate": "2025-01-02", - "amount": 1000 + "$ref": "#/components/schemas/HackathonDraftAiGenerationDto" } - ], - "type": "array", - "items": { - "type": "string" - } + ] }, - "team": { - "description": "Team of the campaign (optional; solo builders may omit)", - "example": [ - { - "name": "John Doe", - "role": "Developer", - "email": "john.doe@example.com", - "linkedin": "https://linkedin.com/in/john-doe", - "twitter": "https://twitter.com/john-doe" - } - ], + "prizes": { + "description": "Prize entity (named prizes + linked tracks + placements). Additive read path alongside data.rewards.prizeTiers; becomes authoritative as readers cut over.", "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/HackathonDraftPrizeDto" } + } + }, + "required": [ + "id", + "status", + "currentStep", + "completedSteps", + "data", + "isValidForPublish", + "validationErrors", + "createdAt", + "updatedAt", + "prizes" + ] + }, + "UpdateHackathonDraftDto": { + "type": "object", + "properties": { + "information": { + "$ref": "#/components/schemas/InfoFormData" + }, + "timeline": { + "$ref": "#/components/schemas/TimelineFormData" + }, + "participation": { + "$ref": "#/components/schemas/ParticipantFormData" + }, + "rewards": { + "$ref": "#/components/schemas/RewardsFormData" + }, + "resources": { + "$ref": "#/components/schemas/ResourcesFormData" + }, + "judging": { + "$ref": "#/components/schemas/JudgingFormData" + }, + "collaboration": { + "$ref": "#/components/schemas/CollaborationFormData" + }, + "autoSave": { + "type": "boolean", + "description": "Hint that this is an autosave (no completion side effects)." + } + } + }, + "GenerateDraftFromBriefDto": { + "type": "object", + "properties": { + "brief": { + "type": "string", + "description": "Free-text brief describing the hackathon to generate.", + "minLength": 10, + "maxLength": 2000, + "example": "A two-week hackathon for AI agent tooling on Stellar, aimed at indie builders." }, - "contact": { - "description": "Contact of the campaign", - "example": { - "primary": "john.doe", - "backup": "john.doe@example.com" - }, - "allOf": [ - { - "$ref": "#/components/schemas/ContactDto" - } - ] + "budgetCapUsdc": { + "type": "string", + "description": "Total budget cap in USDC, as a decimal string.", + "example": "10000" }, - "socialLinks": { - "description": "Social links of the campaign (optional)", - "example": [ - { - "platform": "twitter", - "url": "https://twitter.com/john-doe" - } - ], + "earliestStart": { + "type": "string", + "description": "Earliest the hackathon may start (YYYY-MM-DD).", + "example": "2026-07-01" + }, + "examples": { + "description": "Up to 3 example briefs/drafts to steer style.", + "maxItems": 3, "type": "array", "items": { "type": "string" } } }, - "required": [ - "title", - "logo", - "vision", - "banner", - "category", - "details", - "fundingAmount", - "githubUrl", - "gitlabUrl", - "bitbucketUrl", - "projectWebsite", - "demoVideo", - "milestones", - "contact" - ] + "required": ["brief", "budgetCapUsdc", "earliestStart"] }, - "CreateDraftDto": { + "AiGenerationMetaDto": { "type": "object", "properties": { - "title": { + "generationId": { + "type": "string" + }, + "model": { + "type": "string" + }, + "promptVersion": { + "type": "string" + }, + "costUsd": { "type": "string", - "description": "Working title for the campaign", - "example": "Stellar Analytics Dashboard" + "description": "Cost in USD as a decimal string (never a float)." } }, - "required": ["title"] + "required": ["generationId", "model", "promptVersion", "costUsd"] }, - "UpdateCampaignDto": { + "GenerateDraftFromBriefResponseDto": { "type": "object", "properties": { - "title": { - "type": "string", - "description": "Title of the campaign", - "example": "Web3 Campaign" - }, - "logo": { - "type": "string", - "description": "Logo of the campaign", - "example": "https://example.com/logo.png" - }, - "vision": { - "type": "string", - "description": "Vision of the campaign", - "example": "Web3 Campaign" - }, - "banner": { + "draftId": { "type": "string", - "description": "Banner image URL of the campaign", - "example": "https://example.com/banner.png" + "description": "Id of the created draft." }, - "category": { - "type": "string", - "description": "Category of the campaign", - "example": "web3" + "draft": { + "$ref": "#/components/schemas/HackathonDraftResponseDto" }, - "details": { + "generation": { + "$ref": "#/components/schemas/AiGenerationMetaDto" + } + }, + "required": ["draftId", "draft", "generation"] + }, + "RegenerateDraftSectionDto": { + "type": "object", + "properties": { + "section": { "type": "string", - "description": "Details of the campaign", - "example": "Web3 Campaign" - }, - "fundingAmount": { - "type": "number", - "description": "Funding amount of the campaign", - "example": 1000 + "enum": ["criteria", "prizes", "tracks", "timeline", "description"] }, - "githubUrl": { + "instructions": { "type": "string", - "description": "Github URL of the campaign", - "example": "https://github.com/example/project" - }, - "gitlabUrl": { + "description": "Optional steering instructions for the regeneration.", + "maxLength": 1000 + } + }, + "required": ["section"] + }, + "RegenerateDraftSectionResponseDto": { + "type": "object", + "properties": { + "section": { "type": "string", - "description": "Gitlab URL of the campaign", - "example": "https://gitlab.com/example/project" + "enum": ["criteria", "prizes", "tracks", "timeline", "description"] }, - "bitbucketUrl": { - "type": "string", - "description": "Bitbucket URL of the campaign", - "example": "https://bitbucket.com/example/project" + "data": { + "type": "object", + "additionalProperties": true, + "description": "Regenerated values in the wizard section shape." }, - "projectWebsite": { + "generation": { + "$ref": "#/components/schemas/AiGenerationMetaDto" + } + }, + "required": ["section", "data", "generation"] + }, + "UpdateVisibilitySettingsDto": { + "type": "object", + "properties": { + "submissionVisibility": { "type": "string", - "description": "Project website of the campaign", - "example": "https://example.com/project" + "description": "Who can view hackathon submissions", + "enum": ["PUBLIC", "PARTICIPANTS_ONLY"], + "example": "PUBLIC" }, - "demoVideo": { + "submissionStatusVisibility": { "type": "string", - "description": "Demo video of the campaign", - "example": "https://example.com/demo.mp4" - }, - "milestones": { - "description": "Milestones of the campaign", - "example": [ - { - "name": "Milestone 1", - "description": "Milestone 1 description", - "startDate": "2025-01-01", - "endDate": "2025-01-02", - "amount": 1000 - } - ], - "type": "array", - "items": { - "type": "string" - } - }, - "team": { - "description": "Team of the campaign (optional; solo builders may omit)", - "example": [ - { - "name": "John Doe", - "role": "Developer", - "email": "john.doe@example.com", - "linkedin": "https://linkedin.com/in/john-doe", - "twitter": "https://twitter.com/john-doe" - } - ], - "type": "array", - "items": { - "type": "string" - } - }, - "contact": { - "description": "Contact of the campaign", - "example": { - "primary": "john.doe", - "backup": "john.doe@example.com" - }, - "allOf": [ - { - "$ref": "#/components/schemas/ContactDto" - } - ] - }, - "socialLinks": { - "description": "Social links of the campaign (optional)", - "example": [ - { - "platform": "twitter", - "url": "https://twitter.com/john-doe" - } - ], - "type": "array", - "items": { - "type": "string" - } + "description": "Which submission statuses are visible to others. ALL exposes SUBMITTED and SHORTLISTED. ACCEPTED_SHORTLISTED exposes only SHORTLISTED. HIDDEN_UNTIL_RESULTS hides every submission from non-owners and non-organizers until the hackathon results are published, then exposes only SHORTLISTED. DISQUALIFIED is never visible to anyone other than the owner or an organizer.", + "enum": ["ALL", "ACCEPTED_SHORTLISTED", "HIDDEN_UNTIL_RESULTS"], + "example": "ACCEPTED_SHORTLISTED" } } }, - "InviteTeamMemberDto": { + "ReviewSubmissionDto": { "type": "object", "properties": { - "email": { + "judgeId": { "type": "string", - "example": "user@example.com", - "description": "The email address of the team member to invite" + "description": "ID of the assigned judge performing the review", + "example": "user_1234567890" }, - "role": { + "status": { "type": "string", - "example": "Developer", - "description": "The role of the team member in the campaign" + "description": "Review action", + "example": "SHORTLISTED", + "enum": ["SHORTLISTED", "SUBMITTED"] + }, + "notes": { + "type": "string", + "description": "Reviewer notes or feedback", + "example": "Great project with innovative approach", + "maxLength": 1000 + }, + "rank": { + "type": "number", + "description": "Rank/position for the submission", + "example": 1 + }, + "isOrganizerOverride": { + "type": "boolean", + "description": "Whether this is an organizational override (bypasses COI and assignment checks)", + "default": false } }, - "required": ["email", "role"] + "required": ["judgeId", "status"] }, - "ValidateMilestoneSubmissionDto": { + "OrganizationHackathonParticipantsResponseDto": { + "type": "object", + "properties": {} + }, + "DisqualifySubmissionDto": { "type": "object", "properties": { - "proofOfWorkFiles": { - "description": "Array of proof of work file URLs (documents, images, reports, etc.) - must be valid URLs with http, https, or ipfs protocol", - "example": [ - "https://example.com/report.pdf", - "https://example.com/screenshot.png" - ], - "type": "array", - "items": { - "type": "string" - } - }, - "proofOfWorkLinks": { - "description": "Array of proof of work links (GitHub PRs, demos, deployed sites, etc.) - must be valid URLs", - "example": [ - "https://github.com/user/repo/pull/123", - "https://demo.example.com" - ], - "type": "array", - "items": { - "type": "string" - } - }, - "submissionNotes": { + "disqualificationReason": { "type": "string", - "description": "Additional notes about the submission - optional but must be at least 10 characters if provided", + "description": "Reason for disqualification", + "example": "Submission does not meet hackathon requirements", "minLength": 10, - "example": "Successfully deployed the MVP with all core features implemented and tested." + "maxLength": 500 } }, - "required": ["proofOfWorkFiles", "proofOfWorkLinks"] + "required": ["disqualificationReason"] }, - "UpdateMilestoneDto": { + "BulkSubmissionActionDto": { "type": "object", "properties": { - "proofOfWorkFiles": { - "description": "Array of proof of work file URLs (documents, images, etc.)", + "submissionIds": { + "description": "Array of submission IDs", + "example": ["sub_1234567890", "sub_0987654321"], "type": "array", "items": { "type": "string" } }, - "proofOfWorkLinks": { - "description": "Array of proof of work links (GitHub PRs, demos, etc.)", - "type": "array", - "items": { - "type": "string" - } + "action": { + "type": "string", + "description": "Action to perform", + "example": "SHORTLISTED", + "enum": ["SHORTLISTED", "SUBMITTED", "DISQUALIFIED"] }, - "submissionNotes": { + "reason": { "type": "string", - "description": "Additional notes about the submission", - "minLength": 10 + "description": "Reason (required for DISQUALIFIED action)", + "example": "Does not meet requirements" } }, - "required": ["proofOfWorkFiles", "proofOfWorkLinks"] + "required": ["submissionIds", "action"] }, - "PublishCrowdfundingEscrowDto": { + "SummaryMetricsDto": { "type": "object", "properties": { - "builderAddress": { - "type": "string", - "description": "Stellar G-address that signs create_event. Strictly the builder's Boundless abstracted wallet (D9). MANAGED funding is the only path.", - "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" - }, - "tokenAddress": { - "type": "string", - "description": "Whitelisted SAC token contract (USDC by default).", - "example": "CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA" - }, - "fundingGoal": { - "type": "string", - "description": "Funding goal in token-native units (e.g. 5000 = 5000 USDC). Informational on chain; backers determine the actual raised total.", - "example": "5000" + "participantsCount": { + "type": "number", + "example": 120 }, - "nMilestones": { + "submissionsCount": { "type": "number", - "description": "Number of milestones for ReleaseKind::Multi(n).", - "example": 3 + "example": 45 }, - "fundingDeadline": { + "activeJudges": { "type": "number", - "description": "Funding deadline as Unix seconds.", - "example": 1735689600 + "example": 6 }, - "contentUri": { - "type": "string", - "description": "Override content URI." + "completedMilestones": { + "type": "number", + "example": 3 } }, "required": [ - "builderAddress", - "tokenAddress", - "fundingGoal", - "nMilestones", - "fundingDeadline" + "participantsCount", + "submissionsCount", + "activeJudges", + "completedMilestones" ] }, - "CancelCrowdfundingEscrowDto": { + "TrendPointDto": { "type": "object", "properties": { - "builderAddress": { + "date": { "type": "string", - "description": "Builder G-address." + "example": "2026-02-01" + }, + "count": { + "type": "number", + "example": 5 } }, - "required": ["builderAddress"] + "required": ["date", "count"] }, - "ClaimCrowdfundingMilestoneDto": { + "TrendsDto": { "type": "object", "properties": { - "builderAddress": { - "type": "string", - "description": "Builder G-address (must match campaign)." + "submissionsOverTime": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TrendPointDto" + } }, - "crowdfundingMilestoneId": { - "type": "string", - "description": "Crowdfunding milestone id." + "participantSignupsOverTime": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TrendPointDto" + } } }, - "required": ["builderAddress", "crowdfundingMilestoneId"] + "required": ["submissionsOverTime", "participantSignupsOverTime"] }, - "ContributeCrowdfundingDto": { + "TimelinePhaseDto": { "type": "object", "properties": { - "contributorAddress": { - "type": "string", - "description": "G-address that signs add_funds.", - "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" - }, - "walletOrigin": { + "phase": { "type": "string", - "description": "Wallet origin: BOUNDLESS uses the managed signer; EXTERNAL returns an unsigned XDR for the connected wallet (D9).", - "enum": ["BOUNDLESS", "EXTERNAL"], - "example": "BOUNDLESS" + "example": "Registration" }, - "amount": { + "description": { "type": "string", - "description": "Amount in token-native units (10 USDC minimum).", - "example": "25" + "example": "Individuals and teams are signing up to participate in the hackathon." }, - "message": { + "date": { "type": "string", - "description": "Optional message attached." + "example": "2026-01-20" }, - "anonymous": { - "type": "boolean", - "description": "Hide displayName / usernameSnapshot if true.", - "default": false - } - }, - "required": ["contributorAddress", "walletOrigin", "amount"] - }, - "CrowdfundingSubmitSignedXdrDto": { - "type": "object", - "properties": { - "signedXdr": { + "status": { "type": "string", - "description": "Signed transaction XDR returned by the wallet." + "enum": ["upcoming", "ongoing", "completed"] } }, - "required": ["signedXdr"] + "required": ["phase", "description", "date", "status"] }, - "CastCrowdfundingVoteDto": { + "HackathonAnalyticsResponseDto": { "type": "object", "properties": { - "choice": { + "hackathonId": { "type": "string", - "description": "UP supports the campaign, DOWN opposes it.", - "enum": ["UP", "DOWN"], - "example": "UP" + "example": "hack_1234567890" + }, + "summary": { + "$ref": "#/components/schemas/SummaryMetricsDto" + }, + "trends": { + "$ref": "#/components/schemas/TrendsDto" + }, + "timeline": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TimelinePhaseDto" + } } }, - "required": ["choice"] + "required": ["hackathonId", "summary", "trends", "timeline"] }, - "ApproveCrowdfundingCampaignDto": { + "AnnouncementAuthorDto": { "type": "object", "properties": { - "delegatedReviewerId": { - "type": "string", - "description": "The user delegated to validate this campaign's milestones. D6=A: exactly one reviewer per campaign, assigned at approval time.", - "example": "user_1234567890" + "id": { + "type": "string" }, - "voteGoal": { - "type": "number", - "description": "Minimum total community votes required to resolve the vote (quorum). Defaults to 1 for now (target is 10 at launch).", - "example": 10, - "minimum": 1 + "name": { + "type": "string" + }, + "image": { + "type": "string" + }, + "username": { + "type": "string" } }, - "required": ["delegatedReviewerId"] + "required": ["id", "name"] }, - "RejectCrowdfundingCampaignDto": { + "AnnouncementResponseDto": { "type": "object", "properties": { - "reason": { - "type": "string", - "description": "Reason for rejection; surfaced to the builder." + "id": { + "type": "string" + }, + "hackathonId": { + "type": "string" + }, + "title": { + "type": "string" + }, + "content": { + "type": "string" + }, + "isDraft": { + "type": "boolean" + }, + "isPinned": { + "type": "boolean" + }, + "publishedAt": { + "format": "date-time", + "type": "string" + }, + "createdAt": { + "format": "date-time", + "type": "string" + }, + "updatedAt": { + "format": "date-time", + "type": "string" + }, + "author": { + "$ref": "#/components/schemas/AnnouncementAuthorDto" } - } + }, + "required": [ + "id", + "hackathonId", + "title", + "content", + "isDraft", + "isPinned", + "createdAt", + "updatedAt", + "author" + ] }, - "ExtendCrowdfundingFundingDto": { + "CreateAnnouncementDto": { "type": "object", "properties": { - "fundingEndDate": { + "title": { "type": "string", - "description": "New funding deadline (ISO 8601). Must be in the future. Enforced off-chain by the contribute gate.", - "example": "2026-08-01T00:00:00.000Z" + "description": "Title of the announcement", + "example": "Hackathon Starts Now!", + "minLength": 3, + "maxLength": 100 + }, + "content": { + "type": "string", + "description": "Content of the announcement in Markdown", + "example": "# Welcome\n\nWe are excited to start...", + "minLength": 10, + "maxLength": 10000 + }, + "isDraft": { + "type": "boolean", + "description": "Whether the announcement is a draft", + "default": true + }, + "isPinned": { + "type": "boolean", + "description": "Whether the announcement should be pinned", + "default": false } }, - "required": ["fundingEndDate"] + "required": ["title", "content"] }, - "PauseCrowdfundingCampaignDto": { + "UpdateAnnouncementDto": { "type": "object", "properties": { - "reason": { + "title": { "type": "string", - "description": "Reason for the pause." + "description": "Title of the announcement", + "example": "Hackathon Starts Now!", + "minLength": 3, + "maxLength": 100 + }, + "content": { + "type": "string", + "description": "Content of the announcement in Markdown", + "example": "# Welcome\n\nWe are excited to start...", + "minLength": 10, + "maxLength": 10000 + }, + "isDraft": { + "type": "boolean", + "description": "Whether the announcement is a draft" + }, + "isPinned": { + "type": "boolean", + "description": "Whether the announcement should be pinned" } } }, - "ApproveCrowdfundingMilestoneDto": { - "type": "object", - "properties": {} - }, - "RejectCrowdfundingMilestoneDto": { + "CriterionScoreDto": { "type": "object", "properties": { - "rejectionFeedback": { + "criterionId": { "type": "string", - "description": "Feedback shown to the builder." + "description": "Criterion ID or name", + "example": "Technical Complexity" }, - "resubmissionDeadline": { + "score": { + "type": "number", + "description": "Score for this criterion (0-10)", + "example": 8.5 + }, + "comment": { "type": "string", - "description": "Deadline by which the builder must resubmit (ISO 8601)." + "description": "Optional comment for this criterion", + "example": "Great technical implementation" } }, - "required": ["rejectionFeedback"] + "required": ["criterionId", "score"] }, - "ReclaimDormantDto": { + "ScoreSubmissionDto": { "type": "object", "properties": { - "minIdleDays": { - "type": "number", - "description": "Minimum days a wallet must have been idle to be eligible. Default 90.", - "minimum": 7, - "maximum": 3650, - "example": 90 + "submissionId": { + "type": "string", + "description": "Submission ID being judged", + "example": "sub_1234567890" }, - "maxToProcess": { - "type": "number", - "description": "Maximum number of wallets to reclaim in this call. Hard-capped at 100.", - "minimum": 1, - "maximum": 100, - "example": 25 + "criteriaScores": { + "description": "Scores for each individual criterion", + "type": "array", + "items": { + "$ref": "#/components/schemas/CriterionScoreDto" + } }, - "dryRun": { + "judgeId": { + "type": "string", + "description": "Optional ID of the judge to attribute this score to (defaults to calling user)", + "example": "user_123" + }, + "notes": { + "type": "string", + "description": "Optional admin notes", + "example": "Score adjusted per appeal" + }, + "isOrganizerOverride": { "type": "boolean", - "description": "When true (default), report what would be reclaimed without submitting transactions. Set false to actually merge accounts.", - "example": true + "description": "Whether this is an organizational override (bypasses COI and assignment checks)", + "default": false } - } + }, + "required": ["submissionId", "criteriaScores"] }, - "AddTrustlineDto": { + "UserDetailsDto": { "type": "object", "properties": { - "assetCode": { - "type": "string", - "description": "Asset code to add a trustline for (e.g. USDC, EURC)", - "example": "USDC", - "minLength": 1, - "maxLength": 12 + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "username": { + "type": "string" + }, + "image": { + "type": "string" } }, - "required": ["assetCode"] + "required": ["id", "email", "name", "username"] }, - "UserSendDto": { + "JudgingSubmissionParticipantDto": { "type": "object", "properties": { - "destinationPublicKey": { - "type": "string", - "description": "Stellar destination public key (G...)", - "example": "GABCD..." + "id": { + "type": "string" }, - "amount": { - "type": "number", - "description": "Amount to send (positive number)", - "example": 100.5 + "userId": { + "type": "string" }, - "currency": { - "type": "string", - "description": "Asset code (XLM, USDC, EURC, etc.)", - "example": "USDC" + "user": { + "$ref": "#/components/schemas/UserDetailsDto" }, - "memo": { - "type": "string", - "description": "Memo (required by some exchanges). Max 28 bytes UTF-8." + "participationType": { + "type": "string" }, - "memoRequired": { - "type": "boolean", - "description": "If true, request fails when memo is missing (e.g. exchange requires it)" + "teamId": { + "type": "string" }, - "idempotencyKey": { - "type": "string", - "description": "Idempotency key to prevent duplicate sends" + "teamName": { + "type": "string" + }, + "teamMembers": { + "type": "array", + "items": { + "type": "object" + } } }, - "required": ["destinationPublicKey", "amount", "currency"] + "required": ["id", "userId", "user", "participationType"] }, - "SendPayoutDto": { + "JudgingSubmissionDataDto": { "type": "object", "properties": { - "destinationPublicKey": { - "type": "string", - "description": "Stellar destination public key (G...)", - "example": "GABCD..." + "id": { + "type": "string" }, - "amount": { - "type": "number", - "description": "Amount to send (positive number)", - "example": 100.5 + "projectName": { + "type": "string" }, - "currency": { - "type": "string", - "description": "Asset code (XLM, USDC, EURC, etc. – must be supported on network)", - "example": "USDC" + "category": { + "type": "string" }, - "memo": { - "type": "string", - "description": "Memo (required by some exchanges). Max 28 bytes UTF-8." + "description": { + "type": "string" }, - "memoType": { - "type": "string", - "description": "Memo type", - "enum": ["text", "id"] + "logo": { + "type": "string" }, - "memoRequired": { - "type": "boolean", - "description": "If true, request fails when memo is missing (e.g. exchange requires it)" + "videoUrl": { + "type": "string" }, - "idempotencyKey": { - "type": "string", - "description": "Idempotency key to prevent duplicate payouts" + "introduction": { + "type": "string" }, - "reference": { - "type": "string", - "description": "Reference for audit (e.g. earnings-payout-123)" - } - }, - "required": ["destinationPublicKey", "amount", "currency"] - }, - "CreateCommentDto": { - "type": "object", - "properties": { - "content": { - "type": "string", - "description": "Comment content", - "example": "This is a great project!", - "minLength": 1, - "maxLength": 2000 + "links": { + "type": "array", + "items": { + "type": "object" + } }, - "entityType": { - "type": "string", - "description": "Entity type for the comment", - "enum": [ - "PROJECT", - "BOUNTY", - "CROWDFUNDING_CAMPAIGN", - "GRANT", - "GRANT_APPLICATION", - "HACKATHON", - "HACKATHON_SUBMISSION", - "BLOG_POST" - ], - "example": "PROJECT" + "socialLinks": { + "type": "object", + "additionalProperties": true }, - "entityId": { - "type": "string", - "description": "Entity ID for the comment", - "example": "cm12345abcde" + "submissionDate": { + "type": "string" }, - "parentId": { - "type": "string", - "description": "Parent comment ID for threaded replies", - "example": "cm12345abcde" + "status": { + "type": "string" + }, + "rank": { + "type": "number" } }, - "required": ["content", "entityType", "entityId"] - }, - "UpdateCommentDto": { - "type": "object", - "properties": {} + "required": [ + "id", + "projectName", + "category", + "description", + "submissionDate", + "status" + ] }, - "AddReactionDto": { + "IndividualJudgingResultDto": { "type": "object", "properties": { - "reactionType": { - "type": "string", - "description": "Type of reaction", - "enum": [ - "LIKE", - "DISLIKE", - "LOVE", - "LAUGH", - "THUMBS_UP", - "THUMBS_DOWN", - "FIRE", - "ROCKET" - ], - "example": "LIKE" + "judgeId": { + "type": "string" + }, + "judgeName": { + "type": "string" + }, + "criteriaScores": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CriterionScoreDto" + } + }, + "totalScore": { + "type": "number" + }, + "submittedAt": { + "format": "date-time", + "type": "string" } }, - "required": ["reactionType"] + "required": [ + "judgeId", + "judgeName", + "criteriaScores", + "totalScore", + "submittedAt" + ] }, - "ReportCommentDto": { + "JudgingSubmissionDto": { "type": "object", "properties": { - "reason": { - "type": "string", - "description": "Reason for reporting the comment", - "enum": [ - "SPAM", - "HARASSMENT", - "HATE_SPEECH", - "INAPPROPRIATE_CONTENT", - "COPYRIGHT_VIOLATION", - "OTHER" - ], - "example": "SPAM" + "participant": { + "$ref": "#/components/schemas/JudgingSubmissionParticipantDto" }, - "description": { - "type": "string", - "description": "Additional details about the report", - "example": "This comment contains unsolicited advertising", - "maxLength": 500 + "submission": { + "$ref": "#/components/schemas/JudgingSubmissionDataDto" + }, + "myScore": { + "$ref": "#/components/schemas/IndividualJudgingResultDto" + }, + "averageScore": { + "type": "object", + "nullable": true + }, + "judgeCount": { + "type": "number" } }, - "required": ["reason"] + "required": ["participant", "submission", "averageScore", "judgeCount"] }, - "ResolveReportDto": { + "JudgingPaginationDto": { "type": "object", "properties": { - "status": { - "type": "string", - "description": "Resolution status for the report", - "enum": ["PENDING", "REVIEWED", "RESOLVED", "DISMISSED"], - "example": "RESOLVED" + "page": { + "type": "number" }, - "resolution": { - "type": "string", - "description": "Moderator notes about the resolution", - "example": "Comment was reviewed and found to violate community guidelines", - "maxLength": 500 + "limit": { + "type": "number" + }, + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" } }, - "required": ["status"] - }, - "HackathonsListResponseDto": { - "type": "object", - "properties": {} + "required": ["page", "limit", "total", "totalPages"] }, - "FeeEstimateResponseDto": { + "JudgingSubmissionsResponseDto": { "type": "object", "properties": { - "totalPool": { - "type": "number", - "example": 5000, - "description": "Total prize pool (USDC)" - }, - "feeRate": { - "type": "number", - "example": 0.023, - "description": "Fee rate as decimal" + "submissions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/JudgingSubmissionDto" + } }, - "feeRatePercent": { - "type": "number", - "example": 2.3, - "description": "Fee rate as percentage" + "criteria": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CriterionDto" + } }, - "feeAmount": { - "type": "number", - "example": 115, - "description": "Fee amount (USDC)" + "pagination": { + "$ref": "#/components/schemas/JudgingPaginationDto" }, - "totalFunds": { + "scoredCount": { "type": "number", - "example": 5115, - "description": "Total to pay (prize pool + fee)" - }, - "feeLabel": { - "type": "string", - "example": "Platform Fee (2.3%)", - "description": "Display label for the fee" + "description": "Number of submissions in this hackathon that the calling judge has already scored. Independent of pagination so the progress strip is accurate even when the user is on page 2." } }, - "required": [ - "totalPool", - "feeRate", - "feeRatePercent", - "feeAmount", - "totalFunds", - "feeLabel" - ] + "required": ["submissions", "criteria", "pagination"] }, - "ParticipantDto": { + "AddJudgeDto": { "type": "object", "properties": { - "username": { + "email": { "type": "string", - "description": "Username of the participant" - }, - "avatar": { - "type": "object", - "description": "Avatar URL of the participant" + "description": "Email address of the user to be assigned as a judge", + "example": "judge@example.com" } }, - "required": ["username"] + "required": ["email"] }, - "HackathonWinnerDto": { + "JudgeResponseDto": { "type": "object", "properties": { - "rank": { - "type": "number", - "description": "Rank of the winner (1, 2, 3, etc.)" + "id": { + "type": "string" }, - "projectName": { - "type": "string", - "description": "Name of the project" + "userId": { + "type": "string" }, - "teamName": { - "type": "object", - "description": "Name of the team" + "name": { + "type": "string" }, - "logo": { - "type": "object", - "description": "Logo of the project" + "image": { + "type": "object" + } + }, + "required": ["id", "userId", "name"] + }, + "IndividualScoreDto": { + "type": "object", + "properties": { + "judgeId": { + "type": "string" }, - "participants": { - "description": "List of participants", - "type": "array", - "items": { - "$ref": "#/components/schemas/ParticipantDto" - } + "judgeName": { + "type": "string" }, - "prize": { - "type": "string", - "description": "Prize information" + "score": { + "type": "number" + } + }, + "required": ["judgeId", "judgeName", "score"] + }, + "ScoreRangeDto": { + "type": "object", + "properties": { + "min": { + "type": "number" }, - "submissionId": { - "type": "string", - "description": "Submission ID" + "max": { + "type": "number" } }, - "required": [ - "rank", - "projectName", - "participants", - "prize", - "submissionId" - ] + "required": ["min", "max"] }, - "HackathonWinnersResponseDto": { + "CriteriaBreakdownDto": { "type": "object", "properties": { - "hackathonId": { - "type": "string", - "description": "Hackathon ID" + "criterionId": { + "type": "string" }, - "winners": { - "description": "List of winners", - "type": "array", - "items": { - "$ref": "#/components/schemas/HackathonWinnerDto" - } + "averageScore": { + "type": "number" + }, + "min": { + "type": "number" + }, + "max": { + "type": "number" + }, + "variance": { + "type": "number" } }, - "required": ["hackathonId", "winners"] + "required": ["criterionId", "averageScore", "min", "max", "variance"] }, - "PublicAggregatedJudgingResultDto": { + "AggregatedJudgingResultDto": { "type": "object", "properties": { "submissionId": { @@ -37170,9 +43586,33 @@ "judgingProgress": { "type": "string" }, + "individualScores": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IndividualScoreDto" + } + }, + "scoreVariance": { + "type": "number" + }, + "scoreRange": { + "$ref": "#/components/schemas/ScoreRangeDto" + }, + "criteriaBreakdown": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CriteriaBreakdownDto" + } + }, "rank": { "type": "object" }, + "computedRank": { + "type": "number" + }, + "prize": { + "type": "string" + }, "isComplete": { "type": "boolean" }, @@ -37181,6 +43621,23 @@ }, "hasDisagreement": { "type": "boolean" + }, + "trackIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "recommendedOverall": { + "type": "boolean", + "description": "True when this submission is in the top X% overall per the recommendation threshold." + }, + "recommendedTrackIds": { + "description": "Track ids where this submission is in the top X% per the per-track recommendation threshold.", + "type": "array", + "items": { + "type": "string" + } } }, "required": [ @@ -37194,38 +43651,16 @@ "judgeCount", "expectedJudgeCount", "judgingProgress", + "individualScores", + "scoreVariance", + "scoreRange", + "criteriaBreakdown", "isComplete", "isPending", "hasDisagreement" ] }, - "JudgingResultsMetadataDto": { - "type": "object", - "properties": { - "sortedBy": { - "type": "string" - }, - "includesVariance": { - "type": "boolean" - }, - "includesIndividualScores": { - "type": "boolean" - }, - "includesProgressTracking": { - "type": "boolean" - }, - "onlyWinners": { - "type": "boolean" - } - }, - "required": [ - "sortedBy", - "includesVariance", - "includesIndividualScores", - "includesProgressTracking" - ] - }, - "PublicJudgingResultsResponseDto": { + "JudgingResultsResponseDto": { "type": "object", "properties": { "hackathonId": { @@ -37252,7 +43687,7 @@ "results": { "type": "array", "items": { - "$ref": "#/components/schemas/PublicAggregatedJudgingResultDto" + "$ref": "#/components/schemas/AggregatedJudgingResultDto" } }, "generatedAt": { @@ -37283,5574 +43718,6171 @@ "metadata" ] }, - "CreatorRelationDto": { + "SetPlacementWinnerDto": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "username": { - "type": "string" - }, - "image": { - "type": "string" + "submissionId": { + "type": "string", + "description": "The submission to award this placement to." } }, - "required": ["id", "name"] + "required": ["submissionId"] }, - "OrganizationRelationDto": { + "InviteJudgeDto": { "type": "object", "properties": { - "id": { - "type": "string" + "email": { + "type": "string", + "example": "judge@example.com" }, - "name": { - "type": "string" + "displayName": { + "type": "string", + "description": "Optional public display name for the judge" }, - "logo": { - "type": "string" + "title": { + "type": "string", + "description": "Optional title/role shown with the judge (e.g. \"Time Traveler\")." }, - "slug": { - "type": "string" - } - }, - "required": ["id", "name"] - }, - "HackathonResponseDto": { - "type": "object", - "properties": { - "createdBy": { - "$ref": "#/components/schemas/CreatorRelationDto" + "message": { + "type": "string", + "description": "Personal message included in the invitation email" }, - "organization": { - "$ref": "#/components/schemas/OrganizationRelationDto" + "expiresInDays": { + "type": "number", + "description": "Override expiry in days (default 14). Maximum 60 to prevent indefinite invitations.", + "minimum": 1, + "maximum": 60 } }, - "required": ["createdBy"] + "required": ["email"] }, - "VerifyHackathonAccessDto": { + "BulkInviteJudgesDto": { "type": "object", "properties": { - "password": { - "type": "string", - "description": "The access password for a private hackathon" + "invites": { + "description": "Up to 25 judges per request", + "type": "array", + "items": { + "$ref": "#/components/schemas/InviteJudgeDto" + } } }, - "required": ["password"] + "required": ["invites"] }, - "HackathonAccessTokenResponseDto": { + "BulkInviteRowResultDto": { "type": "object", "properties": { - "accessToken": { + "email": { "type": "string" + }, + "status": { + "type": "string", + "enum": ["invited", "failed"], + "description": "'invited' = sent; 'failed' = skipped with a reason." + }, + "reason": { + "type": "string", + "description": "Failure reason when status is failed." } }, - "required": ["accessToken"] - }, - "JoinHackathonDto": { - "type": "object", - "properties": { - "customAnswers": { - "type": "object", - "description": "Answers to REGISTRATION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select).", - "example": { - "cq_role": "Backend developer" - } - } - } - }, - "ParticipationResponseDto": { - "type": "object", - "properties": {} - }, - "ParticipantResponseDto": { - "type": "object", - "properties": {} + "required": ["email", "status"] }, - "HackathonParticipantsResponseDto": { + "BulkInviteResultDto": { "type": "object", "properties": { - "participants": { + "results": { "type": "array", "items": { - "$ref": "#/components/schemas/ParticipantResponseDto" + "$ref": "#/components/schemas/BulkInviteRowResultDto" } + }, + "invited": { + "type": "number", + "description": "Count of invitations sent." + }, + "failed": { + "type": "number", + "description": "Count of rows that failed / were skipped." } }, - "required": ["participants"] + "required": ["results", "invited", "failed"] }, - "TeamMemberDto": { + "RecommendationThresholdDto": { "type": "object", "properties": { - "userId": { - "type": "string", - "description": "User ID of the team member", - "example": "user_1234567890" - }, - "name": { - "type": "string", - "description": "Name of the team member", - "example": "John Doe" + "id": { + "type": "string" }, - "username": { - "type": "string", - "description": "Username of the team member", - "example": "johndoe" + "hackathonId": { + "type": "string" }, - "role": { + "trackId": { "type": "string", - "description": "Role of the team member in the project", - "example": "Full Stack Developer" + "nullable": true, + "description": "null = overall threshold; otherwise the scoped track id." }, - "avatar": { - "type": "string", - "description": "Avatar URL of the team member", - "example": "https://example.com/avatar.png" + "topPercent": { + "type": "number", + "description": "Top percent (0-100)." } }, - "required": ["userId", "name", "role"] + "required": ["id", "hackathonId", "topPercent"] }, - "SubmissionLinkDto": { + "SetRecommendationThresholdDto": { "type": "object", "properties": { - "type": { - "type": "string", - "description": "Type of link. Each fixed type (github, demo, video, document, presentation) can be used at most once per submission. Use \"other\" for additional links, up to a maximum of 5.", - "example": "github", - "enum": [ - "github", - "demo", - "video", - "document", - "presentation", - "other" - ] - }, - "url": { + "trackId": { "type": "string", - "description": "URL of the link", - "example": "https://github.com/username/project" + "description": "Track id to scope the threshold to; omit for the overall cut." }, - "description": { - "type": "string", - "description": "Optional description of the link", - "example": "Main repository with source code" + "topPercent": { + "type": "number", + "description": "Top percent (0-100) of submissions flagged as recommended.", + "minimum": 0, + "maximum": 100, + "example": 10 } }, - "required": ["type", "url"] + "required": ["topPercent"] }, - "SocialLinksDto": { + "RecommendationComputeDiagnosticsDto": { "type": "object", "properties": { - "github": { - "type": "string", - "description": "GitHub profile or repository", - "example": "https://github.com/username" + "shortlistedSubmissions": { + "type": "number", + "description": "Submissions currently SHORTLISTED." }, - "telegram": { - "type": "string", - "description": "Telegram username or group", - "example": "https://t.me/username" + "scoredSubmissions": { + "type": "number", + "description": "Shortlisted submissions with at least one counted score (active judge or promoted AI scorecard; advisory AI_ASSIST excluded). These are the only submissions a threshold can rank." }, - "twitter": { - "type": "string", - "description": "Twitter/X handle", - "example": "https://twitter.com/username" + "overallThresholdConfigured": { + "type": "boolean", + "description": "Whether an overall (all-submissions) cut is set." }, - "email": { - "type": "string", - "description": "Email address", - "example": "contact@example.com" + "trackThresholdsConfigured": { + "type": "number", + "description": "Number of per-track cuts configured." + }, + "reasons": { + "description": "Human-readable reasons explaining the outcome (e.g. why nothing was flagged). Empty when the compute produced recommendations with nothing outstanding.", + "example": [ + "No recommendation thresholds are configured. Set a top-X% cut (overall or per track), then recompute." + ], + "type": "array", + "items": { + "type": "string" + } } - } + }, + "required": [ + "shortlistedSubmissions", + "scoredSubmissions", + "overallThresholdConfigured", + "trackThresholdsConfigured", + "reasons" + ] }, - "SubmissionResponseDto": { + "RecommendationComputeResultDto": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "hackathonId": { - "type": "string" - }, - "projectId": { - "type": "string" - }, - "participantId": { - "type": "string" - }, - "organizationId": { - "type": "string" - }, - "participationType": { - "type": "string", - "enum": ["INDIVIDUAL", "TEAM"] - }, - "teamId": { - "type": "string" - }, - "teamName": { - "type": "string" + "overallRecommended": { + "type": "number", + "description": "Submissions flagged recommendedOverall." }, - "teamMembers": { + "tracks": { + "description": "Per-track recommended counts.", + "example": [ + { + "trackId": "trk_1", + "recommended": 3 + } + ], "type": "array", "items": { - "$ref": "#/components/schemas/TeamMemberDto" + "type": "string" } }, - "projectName": { - "type": "string" - }, - "category": { - "type": "string" - }, - "description": { - "type": "string" - }, - "logo": { - "type": "string" + "diagnostics": { + "description": "Why the compute produced what it did, so an empty result is never silent.", + "allOf": [ + { + "$ref": "#/components/schemas/RecommendationComputeDiagnosticsDto" + } + ] + } + }, + "required": ["overallRecommended", "tracks", "diagnostics"] + }, + "AcceptJudgeInvitationDto": { + "type": "object", + "properties": { + "displayName": { + "type": "string", + "description": "Optional display name override. If omitted, the inviter-provided displayName (or the user’s account name) is used." + } + } + }, + "PublishedInfoFormDataDto": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 3, + "maxLength": 100, + "example": "Web3 Innovation Hackathon" }, "banner": { - "type": "string" - }, - "videoUrl": { - "type": "string" + "type": "string", + "example": "https://example.com/banner.png" }, - "introduction": { - "type": "string" + "description": { + "type": "string", + "minLength": 10, + "maxLength": 5000, + "example": "Build products for the decentralized future." }, - "links": { + "categories": { "type": "array", "items": { - "$ref": "#/components/schemas/SubmissionLinkDto" + "type": "string", + "enum": [ + "DeFi", + "NFTs", + "DAOs", + "Layer 2", + "Cross-chain", + "Web3 Gaming", + "Social Tokens", + "Infrastructure", + "Privacy", + "Sustainability", + "Real World Assets", + "Other" + ] } }, - "socialLinks": { - "$ref": "#/components/schemas/SocialLinksDto" - }, - "status": { - "type": "string" - }, - "rank": { - "type": "number" - }, - "trackEntries": { - "description": "Track entries this submission has opted into. Each entry carries the track slug/name and a wonRank stamped when the submission won that track (null until results are published).", - "type": "array", - "items": { - "type": "array" - } + "venueType": { + "type": "string", + "enum": ["virtual", "physical"], + "example": "virtual" }, "tagline": { - "type": "string" - }, - "builtWith": { - "type": "array", - "items": { - "type": "string" - } - }, - "screenshots": { - "type": "array", - "items": { - "type": "string" - } + "type": "string", + "maxLength": 200, + "example": "Build the future of Web3" }, - "license": { - "type": "string" + "country": { + "type": "string", + "example": "Nigeria" }, - "codeAttestedAt": { - "format": "date-time", - "type": "string" + "state": { + "type": "string", + "example": "Lagos" }, - "registeredAt": { - "format": "date-time", - "type": "string" + "city": { + "type": "string", + "example": "Ikeja" }, - "submittedAt": { - "format": "date-time", - "type": "string" + "venueName": { + "type": "string", + "example": "Eko Convention Center" }, - "createdAt": { - "format": "date-time", - "type": "string" + "venueAddress": { + "type": "string", + "example": "Plot 1415 Adetokunbo Ademola St" }, - "updatedAt": { - "format": "date-time", - "type": "string" + "slug": { + "type": "string", + "example": "web3-innovation-hackathon" } }, "required": [ - "id", - "hackathonId", - "projectId", - "participantId", - "organizationId", - "participationType", - "projectName", - "category", + "name", + "banner", "description", - "links", - "status", - "registeredAt", - "createdAt", - "updatedAt" + "categories", + "venueType", + "tagline" ] }, - "CreateSubmissionDto": { + "PublishedSponsorPartnerDto": { "type": "object", "properties": { - "organizationId": { + "id": { "type": "string", - "description": "Organization ID", - "example": "org_1234567890" + "example": "sp-1" }, - "projectId": { + "name": { "type": "string", - "description": "Project ID (must be owned by the user or organization). If not provided, a base project will be created automatically.", - "example": "proj_1234567890" + "example": "Stellar Foundation" }, - "participationType": { + "logo": { "type": "string", - "description": "Type of participation", - "enum": ["INDIVIDUAL", "TEAM"], - "example": "INDIVIDUAL" + "example": "https://example.com/logo.png" }, - "teamId": { + "link": { "type": "string", - "description": "[Ignored by backend.] Team ID is snapshotted from the user's authoritative team record at submission time. Field accepted for backwards compatibility only.", - "example": "team_1234567890", - "deprecated": true + "example": "https://stellar.org" + } + }, + "required": ["id"] + }, + "PublishedCollaborationFormDataDto": { + "type": "object", + "properties": { + "contactEmail": { + "type": "string", + "example": "organizer@boundless.dev" }, - "teamName": { + "telegram": { "type": "string", - "description": "[Ignored by backend.] Team name is snapshotted from the user's authoritative team record at submission time.", - "example": "Awesome Hackers", - "deprecated": true + "example": "@boundless" }, - "teamMembers": { - "description": "[Ignored by backend.] Team members are snapshotted from the user's authoritative team record at submission time. Sending this field has no effect.", - "deprecated": true, + "discord": { + "type": "string", + "example": "boundless-hackathon" + }, + "socialLinks": { + "example": ["https://x.com/boundless"], "type": "array", "items": { - "$ref": "#/components/schemas/TeamMemberDto" + "type": "string" } }, - "projectName": { + "sponsorsPartners": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PublishedSponsorPartnerDto" + } + } + }, + "required": ["contactEmail", "socialLinks", "sponsorsPartners"] + }, + "UpdatePublishedHackathonContentDto": { + "type": "object", + "properties": { + "information": { + "$ref": "#/components/schemas/PublishedInfoFormDataDto" + }, + "collaboration": { + "$ref": "#/components/schemas/PublishedCollaborationFormDataDto" + } + } + }, + "PublishedPhaseDto": { + "type": "object", + "properties": { + "name": { "type": "string", - "description": "Project name for the submission", - "example": "DeFi Lending Platform" + "example": "Building Phase" }, - "category": { + "startDate": { "type": "string", - "description": "Category of the project", - "example": "DeFi" + "example": "2026-04-01T00:00:00.000Z" + }, + "endDate": { + "type": "string", + "example": "2026-04-10T00:00:00.000Z" }, "description": { "type": "string", - "description": "Detailed description of the project", - "example": "A decentralized lending platform built on Stellar..." + "example": "Core build phase for teams" + } + }, + "required": ["name", "startDate", "endDate"] + }, + "PublishedTimelineFormDataDto": { + "type": "object", + "properties": { + "startDate": { + "type": "string", + "example": "2026-04-01T00:00:00.000Z" }, - "logo": { + "submissionDeadline": { "type": "string", - "description": "Project logo URL", - "example": "https://example.com/logo.png" + "example": "2026-04-15T00:00:00.000Z" }, - "banner": { + "timezone": { "type": "string", - "description": "Project banner image URL (wide hero image)", - "example": "https://example.com/banner.png" + "example": "Africa/Lagos" }, - "videoUrl": { + "registrationDeadline": { "type": "string", - "description": "Video demonstration URL", - "example": "https://youtube.com/watch?v=xyz" + "example": "2026-04-02T00:00:00.000Z", + "description": "Optional. When null, registration stays open until submission deadline." }, - "introduction": { + "judgingDeadline": { "type": "string", - "description": "Brief introduction to the project", - "example": "We built a platform that allows users to..." + "example": "2026-04-18T00:00:00.000Z", + "description": "Optional judging deadline. When null, no judging phase is rendered on the timeline." }, - "links": { - "description": "Links to project resources. Each fixed link type (github, demo, video, document, presentation) can appear at most once. Use \"other\" for additional links, up to a maximum of 5.", + "phases": { "type": "array", "items": { - "$ref": "#/components/schemas/SubmissionLinkDto" + "$ref": "#/components/schemas/PublishedPhaseDto" } + } + } + }, + "PublishedParticipantFormDataDto": { + "type": "object", + "properties": { + "participantType": { + "type": "string", + "enum": ["individual", "team", "team_or_individual"] }, - "socialLinks": { - "description": "Social links for the project", - "allOf": [ - { - "$ref": "#/components/schemas/SocialLinksDto" - } - ] + "teamMin": { + "type": "number", + "minimum": 1, + "maximum": 20, + "example": 2 }, - "trackIds": { - "description": "Optional list of track ids to enter. Only allowed when the hackathon has prizeStructure != OVERALL_ONLY. Capped at Hackathon.tracksMaxPerSubmission.", - "example": ["trk_abc", "trk_def"], - "type": "array", - "items": { - "type": "string" - } + "teamMax": { + "type": "number", + "minimum": 1, + "maximum": 20, + "example": 5 }, - "trackAnswers": { - "type": "object", - "description": "Per-track answers. Keyed by trackId; each value is { promptAnswer?, customAnswers?, artifacts? }. Phase B.", - "example": { - "trk_abc": { - "promptAnswer": "We focused on a one-tap escrow flow.", - "customAnswers": { - "q_audience": "Freelancers" - }, - "artifacts": { - "figma": "https://figma.com/file/..." - } - } - } + "maxParticipants": { + "type": "number", + "minimum": 1, + "example": 200, + "description": "Optional cap on total participants. null = unlimited. Can be updated after publishing." }, - "customAnswers": { - "type": "object", - "description": "Answers to hackathon-level SUBMISSION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). Validated against the question set.", - "example": { - "cq_audience": "Freelancers", - "cq_stack": ["Web", "AI"] - } + "require_github": { + "type": "boolean", + "example": true }, - "tagline": { - "type": "string", - "description": "Short elevator pitch shown on cards / sidebars / judge queue. Max ~160 chars.", - "example": "Milestone-based escrow for one-time freelance gigs on Stellar." + "require_demo_video": { + "type": "boolean", + "example": false }, - "builtWith": { - "description": "Free-form tech-stack tags. Max 20 entries, 40 chars each.", - "example": ["Soroban", "Stellar SDK", "Next.js", "Rust"], - "type": "array", - "items": { - "type": "string" - } + "require_other_links": { + "type": "boolean", + "example": true }, - "screenshots": { - "description": "Up to 5 screenshot URLs for the project gallery.", - "type": "array", - "items": { - "type": "string" - } + "detailsTab": { + "type": "boolean" }, - "license": { - "type": "string", - "description": "License the submission ships under.", - "enum": [ - "MIT", - "Apache-2.0", - "GPL-3.0", - "BSD-3", - "PROPRIETARY", - "OTHER" - ] + "participantsTab": { + "type": "boolean" }, - "codeAttested": { - "type": "boolean", - "description": "Submitter attests the code is original or properly attributed. Required to mark a submission SUBMITTED (vs DRAFT)." + "resourcesTab": { + "type": "boolean" + }, + "submissionTab": { + "type": "boolean" + }, + "announcementsTab": { + "type": "boolean" + }, + "discussionTab": { + "type": "boolean" + }, + "winnersTab": { + "type": "boolean" + }, + "sponsorsTab": { + "type": "boolean" + }, + "joinATeamTab": { + "type": "boolean" + }, + "rulesTab": { + "type": "boolean" } }, - "required": [ - "organizationId", - "participationType", - "projectName", - "category", - "description", - "links" - ] + "required": ["participantType"] }, - "UpdateSubmissionDto": { + "UpdatePublishedHackathonScheduleDto": { "type": "object", "properties": { - "projectName": { - "type": "string", - "description": "Project name for the submission", - "example": "DeFi Lending Platform" + "timeline": { + "$ref": "#/components/schemas/PublishedTimelineFormDataDto" }, - "category": { + "participation": { + "$ref": "#/components/schemas/PublishedParticipantFormDataDto" + } + } + }, + "PublishedPrizeTierDto": { + "type": "object", + "properties": { + "id": { "type": "string", - "description": "Category of the project", - "example": "DeFi" + "example": "tier-1" }, - "description": { + "place": { "type": "string", - "description": "Detailed description of the project", - "example": "A decentralized lending platform built on Stellar..." + "example": "1st Place" }, - "logo": { + "prizeAmount": { "type": "string", - "description": "Project logo URL", - "example": "https://example.com/logo.png" + "example": "5000" }, - "banner": { + "currency": { "type": "string", - "description": "Project banner image URL (wide hero image)", - "example": "https://example.com/banner.png" + "example": "USDC" }, - "videoUrl": { + "description": { "type": "string", - "description": "Video demonstration URL", - "example": "https://youtube.com/watch?v=xyz" + "example": "Top overall project" }, - "introduction": { - "type": "string", - "description": "Brief introduction to the project", - "example": "We built a platform that allows users to..." + "rank": { + "type": "number", + "minimum": 1, + "example": 1, + "description": "Display rank / ordering of the tier (1 = highest)" }, - "links": { - "description": "Links to project resources. Each fixed link type (github, demo, video, document, presentation) can appear at most once. Use \"other\" for additional links, up to a maximum of 5.", - "type": "array", - "items": { - "$ref": "#/components/schemas/SubmissionLinkDto" - } + "passMark": { + "type": "number", + "minimum": 0, + "maximum": 100, + "example": 70 }, - "socialLinks": { - "description": "Social links for the project", - "allOf": [ - { - "$ref": "#/components/schemas/SocialLinksDto" - } - ] + "kind": { + "type": "string", + "enum": ["OVERALL", "TRACK"] }, - "teamMembers": { - "description": "Team members (for team submissions)", + "trackId": { + "type": "string", + "description": "Required when kind=TRACK. References a HackathonTrack id." + } + }, + "required": ["id", "place", "prizeAmount", "passMark"] + }, + "PublishedRewardsFormDataDto": { + "type": "object", + "properties": { + "prizeTiers": { "type": "array", "items": { - "$ref": "#/components/schemas/TeamMemberDto" + "$ref": "#/components/schemas/PublishedPrizeTierDto" } }, - "trackIds": { - "description": "Replace the submission's track picks. Omit to leave existing entries untouched; pass an empty array to clear all picks.", + "prizes": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/PrizeWriteDto" } }, - "trackAnswers": { - "type": "object", - "description": "Per-track answers, same shape as on create. Phase B." - }, - "customAnswers": { + "winnerOverrides": { "type": "object", - "description": "Answers to hackathon-level SUBMISSION-scope custom questions. Keyed by question id; each value is a string (or string[] for multi-select). Replaces the stored answers when provided.", "example": { - "cq_audience": "Freelancers", - "cq_stack": ["Web", "AI"] + "sub-1": 1, + "sub-2": 2 + }, + "description": "Manual winner assignments override (submissionId -> rank)", + "additionalProperties": { + "type": "number" } }, - "tagline": { - "type": "string" + "prizeStructure": { + "type": "string", + "enum": ["OVERALL_ONLY", "OVERALL_AND_TRACKS", "TRACKS_ONLY"] }, - "builtWith": { - "type": "array", - "items": { - "type": "string" - } + "tracksMaxPerSubmission": { + "type": "number", + "minimum": 1, + "maximum": 20 }, - "screenshots": { - "type": "array", - "items": { - "type": "string" - } + "allowWinnerStacking": { + "type": "boolean" + } + } + }, + "UpdatePublishedHackathonFinancialDto": { + "type": "object", + "properties": { + "rewards": { + "$ref": "#/components/schemas/PublishedRewardsFormDataDto" + } + }, + "required": ["rewards"] + }, + "AdvancedSettingsFormDataDto": { + "type": "object", + "properties": { + "isPublic": { + "type": "boolean", + "example": true }, - "license": { + "allowLateRegistration": { + "type": "boolean", + "example": false + }, + "requireApproval": { + "type": "boolean", + "example": true + }, + "maxParticipants": { + "type": "number", + "minimum": 1, + "maximum": 100000, + "example": 500 + }, + "customDomain": { + "type": "string", + "example": "hackathons.boundless.dev" + }, + "enableDiscord": { + "type": "boolean", + "example": true + }, + "discordInviteLink": { + "type": "string", + "example": "https://discord.gg/boundless" + }, + "enableTelegram": { + "type": "boolean", + "example": true + }, + "telegramInviteLink": { + "type": "string", + "example": "https://t.me/boundless" + } + }, + "required": [ + "isPublic", + "allowLateRegistration", + "requireApproval", + "enableDiscord", + "enableTelegram" + ] + }, + "UpdatePublishedHackathonAdvancedSettingsDto": { + "type": "object", + "properties": { + "advancedSettings": { + "$ref": "#/components/schemas/AdvancedSettingsFormDataDto" + } + }, + "required": ["advancedSettings"] + }, + "SetHackathonAccessDto": { + "type": "object", + "properties": { + "visibility": { "type": "string", - "enum": [ - "MIT", - "Apache-2.0", - "GPL-3.0", - "BSD-3", - "PROPRIETARY", - "OTHER" - ] + "enum": ["PUBLIC", "PRIVATE"] }, - "codeAttested": { - "type": "boolean" + "password": { + "type": "string", + "description": "Access password. Required when first making a hackathon private; ignored (cleared) when visibility is PUBLIC." } - } + }, + "required": ["visibility"] }, - "TeamMemberResponseDto": { + "InvitePartnerDto": { "type": "object", "properties": { - "userId": { + "partnerEmail": { "type": "string", - "description": "User ID" + "example": "sponsor@partner.io" }, - "username": { + "partnerName": { "type": "string", - "description": "Username" + "example": "Acme Corp" }, - "name": { + "partnerLogo": { "type": "string", - "description": "Display name" + "example": "https://cdn.example.com/logo.png" }, - "role": { + "partnerLink": { "type": "string", - "description": "Role in team (e.g. leader, member)" + "example": "https://acme.io" }, - "image": { + "pledgedAmount": { + "type": "number", + "example": 1000, + "description": "Pledged amount in USDC" + }, + "currency": { "type": "string", - "description": "Profile image URL" + "example": "USDC", + "default": "USDC" }, - "joinedAt": { + "message": { "type": "string", - "description": "When the member joined the team (ISO string)" + "description": "Optional message included in the invite" + }, + "showPublicly": { + "type": "boolean", + "description": "Whether the partner is shown publicly on the hackathon page", + "default": true } }, - "required": ["userId", "username", "name", "role", "joinedAt"] + "required": ["partnerEmail", "partnerName", "pledgedAmount"] }, - "LookingForRoleDto": { + "AllocationTargetDto": { "type": "object", "properties": { - "role": { + "placementId": { "type": "string", - "description": "Role title (e.g. \"Frontend Developer\", \"UI Designer\")", - "example": "Frontend Developer" + "description": "PrizePlacement id (the fundable slot) this allocation adds to. Placements are created in the Rewards step." }, - "skills": { - "description": "Optional free-form skills associated with this role", - "example": ["React", "TypeScript"], + "amount": { + "type": "number", + "description": "Net amount (USDC) to add to the placement" + } + }, + "required": ["placementId", "amount"] + }, + "AllocateContributionDto": { + "type": "object", + "properties": { + "targets": { + "description": "One or more tiers to allocate this contribution into", "type": "array", "items": { - "type": "array" + "$ref": "#/components/schemas/AllocationTargetDto" } } }, - "required": ["role"] + "required": ["targets"] }, - "TeamRoleResponseDto": { + "PrepareFundTransactionDto": { "type": "object", "properties": { - "skill": { + "signerAddress": { "type": "string", - "description": "Skill/role name" + "description": "Stellar address of the partner wallet that will sign the transaction" + } + }, + "required": ["signerAddress"] + }, + "SubmitSignedTransactionDto": { + "type": "object", + "properties": { + "signedXdr": { + "type": "string", + "description": "Signed transaction XDR returned by the partner wallet" + } + }, + "required": ["signedXdr"] + }, + "TrackCustomQuestionDto": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Stable id, unique within the track." }, - "hired": { + "label": { + "type": "string", + "description": "Question label shown on the submission form." + }, + "type": { + "type": "string", + "enum": ["short", "long", "url"], + "description": "Input type. 'short' = single-line, 'long' = textarea, 'url' = URL field." + }, + "maxLength": { + "type": "number", + "description": "Optional maxLength override (defaults: short=200, long=1000)." + }, + "required": { "type": "boolean", - "description": "Whether this role has been filled" + "description": "Whether an answer is required." } }, - "required": ["skill", "hired"] + "required": ["id", "label", "type"] }, - "TeamResponseDto": { + "TrackRequiredArtifactDto": { "type": "object", "properties": { "id": { "type": "string", - "description": "Team ID", - "example": "team_1234567890" + "description": "Stable id, unique within the track." }, - "teamName": { + "label": { "type": "string", - "description": "Team name", - "example": "Stellar Innovators" + "description": "Artifact label (e.g. \"Figma file URL\")." }, - "description": { + "type": { "type": "string", - "description": "Team description" + "enum": ["figma", "github", "video", "pdf", "url"], + "description": "Artifact type — drives the placeholder + light hint UI." + }, + "required": { + "type": "boolean", + "description": "Whether submitting this artifact is required." + } + }, + "required": ["id", "label", "type"] + }, + "TrackResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string" }, "hackathonId": { + "type": "string" + }, + "slug": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "type": { + "type": "string" + }, + "eligibility": { "type": "string", - "description": "Hackathon ID" + "enum": ["OPT_IN", "OPEN"] }, - "leader": { - "type": "object", - "description": "Team leader information" + "displayOrder": { + "type": "number" }, - "members": { - "description": "Team members", - "type": "array", - "items": { - "$ref": "#/components/schemas/TeamMemberResponseDto" - } + "isArchived": { + "type": "boolean" }, - "memberCount": { + "entryCount": { "type": "number", - "description": "Current number of members", - "example": 3 + "description": "Count of submissions that have opted into this track. Useful for organizer dashboards." }, - "maxSize": { - "type": "number", - "description": "Maximum team size allowed", - "example": 5 + "prompt": { + "type": "string", + "description": "Per-track customization (Phase B)." }, - "lookingFor": { - "description": "Roles the team is looking for, with optional free-form skills", + "customQuestions": { "type": "array", "items": { - "$ref": "#/components/schemas/LookingForRoleDto" + "$ref": "#/components/schemas/TrackCustomQuestionDto" } }, - "rolesStatus": { - "description": "Hired status per role (when using lookingFor)", + "requiredArtifacts": { "type": "array", "items": { - "$ref": "#/components/schemas/TeamRoleResponseDto" + "$ref": "#/components/schemas/TrackRequiredArtifactDto" } }, - "contactInfo": { - "type": "object", - "description": "Contact information (e.g. telegram, discord, email)" - }, - "isOpen": { - "type": "boolean", - "description": "Whether team is accepting new members", - "example": true - }, "createdAt": { - "type": "string", - "description": "Team creation date" + "format": "date-time", + "type": "string" }, "updatedAt": { - "type": "string", - "description": "Last update date" + "format": "date-time", + "type": "string" } }, "required": [ "id", - "teamName", - "description", "hackathonId", - "leader", - "members", - "memberCount", - "maxSize", - "isOpen", + "slug", + "name", + "eligibility", + "displayOrder", + "isArchived", + "entryCount", "createdAt", "updatedAt" ] }, - "TeamListResponseDto": { + "CustomQuestionResponseDto": { "type": "object", "properties": { - "teams": { - "description": "List of teams", + "id": { + "type": "string" + }, + "hackathonId": { + "type": "string" + }, + "scope": { + "type": "string", + "enum": ["REGISTRATION", "SUBMISSION"] + }, + "label": { + "type": "string" + }, + "helpText": { + "type": "string", + "nullable": true + }, + "type": { + "type": "string", + "enum": [ + "SHORT", + "LONG", + "URL", + "SINGLE_SELECT", + "MULTI_SELECT", + "BOOLEAN" + ] + }, + "required": { + "type": "boolean" + }, + "options": { + "nullable": true, "type": "array", "items": { - "$ref": "#/components/schemas/TeamResponseDto" + "type": "string" } }, - "pagination": { - "type": "object", - "description": "Pagination metadata" + "maxLength": { + "type": "number", + "nullable": true + }, + "displayOrder": { + "type": "number" } }, - "required": ["teams", "pagination"] + "required": [ + "id", + "hackathonId", + "scope", + "label", + "type", + "required", + "displayOrder" + ] }, - "CreateTeamDto": { + "UpdateTracksConfigDto": { "type": "object", "properties": { - "teamName": { + "tracksMaxPerSubmission": { + "type": "number", + "minimum": 1, + "maximum": 20, + "description": "Max number of tracks a single submission may enter (1-20)." + } + } + }, + "CreateTrackDto": { + "type": "object", + "properties": { + "name": { "type": "string", - "description": "Team name", - "example": "Stellar Innovators", - "minLength": 3, - "maxLength": 100 + "description": "Human-readable track name shown on the hackathon page.", + "example": "Best UI/UX" + }, + "slug": { + "type": "string", + "description": "URL-safe handle, unique within the hackathon. Auto-generated from name if omitted.", + "example": "best-ui-ux" }, "description": { "type": "string", - "description": "Team description", - "example": "We are building the next generation DeFi platform", - "minLength": 10, - "maxLength": 500 + "description": "Short blurb shown in the track picker and on results.", + "example": "Best end-to-end user experience and visual polish." }, - "lookingFor": { - "description": "Roles the team is looking for. Each entry is a role title with optional free-form skills. Team will be CLOSED unless at least one role is specified. The number of roles is bounded by the hackathon's teamMin/teamMax (excluding the leader).", + "type": { + "type": "string", + "description": "Free-form classifier for badge styling. Common values: skill, technology, theme, special.", + "example": "skill" + }, + "eligibility": { + "type": "string", + "description": "OPT_IN (default): submitters explicitly enter. OPEN: every submission auto-eligible.", + "enum": ["OPT_IN", "OPEN"], + "default": "OPT_IN" + }, + "displayOrder": { + "type": "number", + "description": "Sort order. Lower numbers render first. Defaults to 0.", + "example": 10 + }, + "prompt": { + "type": "string", + "description": "Single open-ended prompt shown on the submission form. When set, the submitter must answer to opt in.", + "example": "Why does this project fit Best UI/UX?" + }, + "customQuestions": { "type": "array", "items": { - "$ref": "#/components/schemas/LookingForRoleDto" + "$ref": "#/components/schemas/TrackCustomQuestionDto" } }, - "contactInfo": { - "type": "object", - "description": "Contact information for interested members", - "example": { - "telegram": "@teamlead", - "discord": "lead#1234" + "requiredArtifacts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TrackRequiredArtifactDto" } } }, - "required": ["teamName", "description"] + "required": ["name"] }, - "UpdateTeamDto": { + "UpdateTrackDto": { "type": "object", "properties": { - "teamName": { - "type": "string", - "description": "Updated team name", - "example": "Stellar Innovators Pro" + "name": { + "type": "string" + }, + "slug": { + "type": "string" }, "description": { + "type": "string" + }, + "type": { + "type": "string" + }, + "eligibility": { "type": "string", - "description": "Updated team description" + "enum": ["OPT_IN", "OPEN"] }, - "lookingFor": { - "description": "Roles the team is looking for. Set to empty array to close the team. Each entry is a role title with optional free-form skills.", + "displayOrder": { + "type": "number" + }, + "isArchived": { + "type": "boolean", + "description": "Soft-archive instead of delete when entries already exist. Cannot be unset via this endpoint; recreate the track if needed." + }, + "prompt": { + "type": "string", + "description": "Single open-ended prompt." + }, + "customQuestions": { "type": "array", "items": { - "$ref": "#/components/schemas/LookingForRoleDto" + "$ref": "#/components/schemas/TrackCustomQuestionDto" } }, - "contactInfo": { - "type": "object", - "description": "Updated contact information" - }, - "isOpen": { - "type": "boolean", - "description": "Explicitly set team open/closed status. Can only be true if lookingFor is not empty." + "requiredArtifacts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TrackRequiredArtifactDto" + } } } }, - "InviteToTeamDto": { + "CustomQuestionWriteDto": { "type": "object", "properties": { - "inviteeIdentifier": { + "scope": { "type": "string", - "description": "User ID or username of the person to invite", - "example": "user_1234567890" + "enum": ["REGISTRATION", "SUBMISSION"] }, - "message": { - "type": "string", - "description": "Optional message to include with the invitation", - "example": "We would love to have you on our team!", - "maxLength": 500 - } - }, - "required": ["inviteeIdentifier"] - }, - "TeamInvitationResponseDto": { - "type": "object", - "properties": { - "id": { + "label": { "type": "string", - "description": "Invitation ID", - "example": "inv_1234567890" + "description": "Question shown to the participant." }, - "teamId": { + "helpText": { "type": "string", - "description": "Team ID", - "example": "team_1234567890" - }, - "hackathon": { - "type": "object", - "description": "Hackathon information" - }, - "invitee": { - "type": "object", - "description": "Invitee information" - }, - "inviter": { - "type": "object", - "description": "Inviter information" + "description": "Optional helper text under the field." }, - "status": { + "type": { "type": "string", - "description": "Invitation status", - "example": "pending", - "enum": ["pending", "accepted", "rejected", "expired"] - }, - "message": { - "type": "object", - "description": "Optional message from inviter", - "example": "We would love to have you on our team!" + "enum": [ + "SHORT", + "LONG", + "URL", + "SINGLE_SELECT", + "MULTI_SELECT", + "BOOLEAN" + ], + "default": "SHORT" }, - "role": { - "type": "object", - "description": "Role in the team", - "example": "member" + "required": { + "type": "boolean", + "description": "Whether an answer is required." }, - "expiresAt": { - "format": "date-time", - "type": "string", - "description": "Invitation expiration date", - "example": "2026-01-30T12:00:00.000Z" + "options": { + "description": "Choices for SINGLE_SELECT / MULTI_SELECT.", + "type": "array", + "items": { + "type": "string" + } }, - "createdAt": { - "format": "date-time", - "type": "string", - "description": "Invitation creation date", - "example": "2026-01-23T12:00:00.000Z" + "maxLength": { + "type": "number", + "description": "Optional length cap for SHORT / LONG answers." }, - "respondedAt": { - "type": "object", - "description": "Date when invitation was responded to", - "example": "2026-01-24T12:00:00.000Z" + "displayOrder": { + "type": "number", + "description": "Sort order; lower renders first." } }, - "required": [ - "id", - "teamId", - "hackathon", - "invitee", - "inviter", - "status", - "role", - "expiresAt", - "createdAt" - ] + "required": ["scope", "label", "type"] }, - "TeamInvitationListResponseDto": { + "UpsertCustomQuestionsDto": { "type": "object", "properties": { - "invitations": { - "description": "List of invitations", + "questions": { "type": "array", "items": { - "$ref": "#/components/schemas/TeamInvitationResponseDto" + "$ref": "#/components/schemas/CustomQuestionWriteDto" } - }, - "total": { - "type": "number", - "description": "Total count", - "example": 5 } }, - "required": ["invitations", "total"] + "required": ["questions"] }, - "InvitationActionResponseDto": { + "RequestFundingOtpResponseDto": { "type": "object", "properties": { - "message": { - "type": "string", - "description": "Success message", - "example": "Successfully accepted team invitation" + "required": { + "type": "boolean", + "description": "Whether funding step-up is enforced for this action" }, - "teamId": { - "type": "string", - "description": "Team ID that was joined (only for accept)", - "example": "team_1234567890" + "alreadyVerified": { + "type": "boolean", + "description": "True when a recent verification is still valid; the client can fund without entering a new code" }, - "invitation": { - "description": "Updated invitation", - "allOf": [ - { - "$ref": "#/components/schemas/TeamInvitationResponseDto" - } - ] + "sent": { + "type": "boolean", + "description": "True when a fresh code was just emailed" + }, + "expiresInSeconds": { + "type": "number", + "description": "Seconds until the emailed code expires (0 when none sent)" } }, - "required": ["message", "teamId", "invitation"] + "required": ["required", "alreadyVerified", "sent", "expiresInSeconds"] }, - "ToggleRoleHiredDto": { + "VerifyFundingOtpDto": { "type": "object", "properties": { - "skill": { + "code": { "type": "string", - "description": "Skill/role name to toggle hired status", - "example": "Rust Developer" + "description": "The 6-digit code emailed to the organizer", + "example": "123456" } }, - "required": ["skill"] + "required": ["code"] }, - "TransferLeadershipDto": { + "VerifyFundingOtpResponseDto": { "type": "object", "properties": { - "newLeaderId": { - "type": "string", - "description": "User ID of the new team leader (must be an existing member)", - "example": "user_1234567890" + "verified": { + "type": "boolean", + "description": "True when the code was accepted" }, - "reason": { - "type": "string", - "description": "Optional reason for the leadership transfer", - "example": "Stepping down to focus on development tasks", - "maxLength": 500 + "expiresInSeconds": { + "type": "number", + "description": "Seconds the funding authorization remains valid" } }, - "required": ["newLeaderId"] + "required": ["verified", "expiresInSeconds"] }, - "LeadershipTransferResponseDto": { + "WinnerDistributionEntryDto": { "type": "object", "properties": { - "message": { + "position": { + "type": "number", + "description": "Winner position (1-indexed; 1 = top winner).", + "example": 1, + "minimum": 1 + }, + "percent": { + "type": "number", + "description": "Percentage of the total budget allocated to this position. All entries must sum to exactly 100.", + "example": 100, + "minimum": 1 + } + }, + "required": ["position", "percent"] + }, + "PublishHackathonEscrowDto": { + "type": "object", + "properties": { + "ownerAddress": { "type": "string", - "description": "Success message", - "example": "Leadership successfully transferred" + "description": "Stellar G-address that will own and sign the on-chain create_event transaction. For managed wallets, this is the platform-derived address tied to the organizer's account; for connected/multisig, it's the org treasury's G-address.", + "example": "GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ" }, - "team": { - "description": "Updated team with new leader", - "allOf": [ - { - "$ref": "#/components/schemas/TeamResponseDto" - } - ] + "tokenAddress": { + "type": "string", + "description": "Stellar Asset Contract (SAC) address the prize pool is denominated in. Must be whitelisted on the events contract (see admin runbook).", + "example": "CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA" }, - "previousLeaderId": { + "budget": { "type": "string", - "description": "Previous leader ID", - "example": "user_1234567890" + "description": "Total prize budget in token-native units (e.g. 1000 = 1000 USDC, NOT stroops). Use a string when the value exceeds JavaScript's safe integer range. The backend converts to stroops via *10^7.", + "example": "1000" }, - "newLeaderId": { + "winnerDistribution": { + "description": "Optional override for the winner distribution. Each entry maps a position to a percent of total_budget. Percents must sum to exactly 100. Defaults to a single winner at position 1 taking 100%.", + "type": "array", + "items": { + "$ref": "#/components/schemas/WinnerDistributionEntryDto" + } + }, + "contentUri": { "type": "string", - "description": "New leader ID", - "example": "user_0987654321" + "description": "Override for the public content_uri the contract stores against the event. Defaults to https://api.boundless.fi/hackathons//content.", + "example": "https://api.boundless.fi/hackathons/abc/content", + "maxLength": 512 }, - "transferredAt": { - "format": "date-time", + "fundingMode": { "type": "string", - "description": "Timestamp of the transfer", - "example": "2026-02-16T10:30:00.000Z" + "description": "Signing path. Defaults to EXTERNAL (return unsigned XDR for the caller to sign). Set to MANAGED to have the backend sign + submit using the caller user's managed wallet; the response carries the op in PENDING_CONFIRM with a txHash.", + "enum": ["EXTERNAL", "MANAGED"], + "default": "EXTERNAL", + "example": "MANAGED" + }, + "sourceWalletId": { + "type": "string", + "description": "For MANAGED funding, the organization treasury wallet to fund from. When set, the backend signs with that treasury (managed) wallet instead of the caller's personal wallet; ownerAddress must match the treasury wallet address. Omit to fund from the personal managed wallet." } }, - "required": [ - "message", - "team", - "previousLeaderId", - "newLeaderId", - "transferredAt" - ] + "required": ["ownerAddress", "tokenAddress", "budget"] }, - "InfoFormData": { + "HackathonEscrowOpResponseDto": { "type": "object", "properties": { - "name": { + "id": { "type": "string", - "description": "Hackathon title", - "minLength": 3, - "maxLength": 100 + "description": "Internal uuid for the EscrowOp row. Use this for follow-up calls.", + "example": "cmpwiox7u0000yy4404ojbk9t" }, - "banner": { + "opId": { "type": "string", - "description": "Banner image URL", - "format": "uri" + "description": "Hex-encoded 32-byte op_id derived deterministically from the operation parameters. Used by the on-chain idempotency check.", + "example": "3cc257d743b1b44423dc8dbd417aedfe6e47ad489b5d301a2fbec5284d36de1c" }, - "description": { + "kind": { "type": "string", - "description": "Hackathon description", - "minLength": 10, - "maxLength": 5000 + "description": "Contract operation kind.", + "enum": [ + "CREATE_EVENT", + "CANCEL_EVENT", + "ADD_FUNDS", + "APPLY_TO_BOUNTY", + "WITHDRAW_APPLICATION", + "SUBMIT", + "WITHDRAW_SUBMISSION", + "SELECT_WINNERS", + "CLAIM_MILESTONE" + ], + "example": "CREATE_EVENT" }, - "categories": { - "type": "array", - "description": "One or more hackathon categories", - "items": { - "type": "string", - "enum": [ - "DeFi", - "Payments", - "Stablecoins", - "Lending & Borrowing", - "Trading & DEXs", - "Derivatives", - "Prediction Markets", - "NFTs", - "Creator Economy", - "Social", - "Social Tokens", - "DAOs", - "Governance", - "Web3 Gaming", - "Metaverse", - "Layer 1", - "Layer 2", - "Cross-chain", - "Interoperability", - "Infrastructure", - "Developer Tooling", - "Wallets", - "Account Abstraction", - "Oracles", - "Data & Indexing", - "Analytics", - "AI", - "AI Agents", - "DePIN", - "DeSci", - "Privacy", - "Zero-Knowledge", - "Security", - "Identity", - "Real World Assets", - "Tokenization", - "Supply Chain", - "Sustainability", - "Climate", - "Education", - "Healthcare", - "Consumer Apps", - "Mobile", - "Other" - ] - } + "status": { + "type": "string", + "description": "Status of the EscrowOp in its lifecycle.", + "enum": [ + "PENDING_BUILD", + "PENDING_SIGN", + "PENDING_SUBMIT", + "PENDING_CONFIRM", + "COMPLETED", + "FAILED", + "CANCELLED" + ], + "example": "PENDING_SIGN" }, - "venueType": { + "entityKind": { "type": "string", - "description": "Venue type", - "enum": ["virtual", "physical"] + "description": "Entity kind the op operates on. Matches the application-level row (hackathon, bounty, grant, etc.).", + "example": "HACKATHON" }, - "tagline": { + "entityId": { "type": "string", - "description": "Short tagline", - "maxLength": 200 + "description": "Application-level row id this op acts on.", + "example": "cmpwihilf0000fd44iln3dzbg" }, - "country": { - "type": "string" + "unsignedXdr": { + "type": "string", + "nullable": true, + "description": "Unsigned XDR transaction the wallet must sign. Present after the build phase completes (PENDING_SIGN onwards).", + "example": "AAAAAgAAAACdiamX7q...truncated..." }, - "state": { - "type": "string" + "signerHint": { + "type": "string", + "nullable": true, + "description": "Stellar G-address expected to sign this op. The wallet routing layer on the webapp uses this to pick the right signer.", + "example": "GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ" }, - "city": { - "type": "string" + "txHash": { + "type": "string", + "nullable": true, + "description": "Soroban tx hash assigned at submit time. Set once the op reaches PENDING_CONFIRM or beyond.", + "example": "daafec9027da007b54eec34c54a5919edd7a8682bc96ccf7c7072982305cfa3b" }, - "venueName": { - "type": "string" + "errorCode": { + "type": "string", + "nullable": true, + "description": "Contract error code when the op transitions to FAILED. Mirrors the on-chain error name (e.g. \"InsufficientEscrow\", \"OpAlreadySeen\", \"txBadAuth\").", + "example": "txBadAuth" }, - "venueAddress": { - "type": "string" + "createdAt": { + "format": "date-time", + "type": "string", + "description": "Row creation time.", + "example": "2026-06-02T11:45:36.927Z" }, - "slug": { + "updatedAt": { + "format": "date-time", "type": "string", - "description": "Read-only URL slug (server-assigned)" + "description": "Row last-updated time.", + "example": "2026-06-02T11:45:44.310Z" } }, "required": [ - "name", - "banner", - "description", - "categories", - "venueType", - "tagline" + "id", + "opId", + "kind", + "status", + "entityKind", + "entityId", + "createdAt", + "updatedAt" ] }, - "PhaseDto": { + "CancelHackathonEscrowDto": { "type": "object", "properties": { - "name": { + "ownerAddress": { "type": "string", - "description": "Phase name" + "description": "Organizer's Stellar G-address. Must match the on-chain hackathon owner.", + "example": "GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ" }, - "startDate": { + "fundingMode": { "type": "string", - "format": "date-time" + "description": "Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side with the caller's platform-held wallet.", + "enum": ["EXTERNAL", "MANAGED"], + "default": "EXTERNAL" }, - "endDate": { + "sourceWalletId": { "type": "string", - "format": "date-time" - }, - "description": { - "type": "string" + "description": "For MANAGED, the organization treasury wallet to sign with (the event contract-auth identity). ownerAddress must match it. Omit to use the caller's personal managed wallet." } }, - "required": ["name", "startDate", "endDate"] + "required": ["ownerAddress"] }, - "TimelineFormData": { + "HackathonWinnerSelectionDto": { "type": "object", "properties": { - "startDate": { - "type": "string", - "format": "date-time" - }, - "submissionDeadline": { + "submissionId": { "type": "string", - "format": "date-time" + "description": "ID of the winning submission. The payout recipient is resolved server-side = the submitter's (team leader's) Boundless managed wallet; no on-chain submission anchor is required.", + "example": "cmq7sgwst0001abcd1234efgh" }, - "timezone": { - "type": "string", - "description": "IANA timezone" + "position": { + "type": "number", + "description": "Winner position, 1-indexed. Must exist in the hackathon's on-chain winner_distribution.", + "example": 1, + "minimum": 1 }, - "registrationDeadline": { - "type": "string", - "format": "date-time" + "creditEarn": { + "type": "number", + "description": "Override the platform default credit_earn for this position. Defaults to 20/10/5 for positions 1/2/3 and 3 for the rest. Capped at 100 by the contract.", + "minimum": 0, + "maximum": 100, + "example": 20 }, - "judgingDeadline": { + "reputationBump": { + "type": "number", + "description": "Override the platform default reputation_bump for this position. Defaults to 50/25/10 for positions 1/2/3 and 5 for the rest.", + "minimum": 0, + "example": 50 + } + }, + "required": ["submissionId", "position"] + }, + "SelectHackathonWinnersDto": { + "type": "object", + "properties": { + "ownerAddress": { "type": "string", - "format": "date-time" + "description": "Organizer's Stellar G-address — a hint only. select_winners is authorized by the event manager resolved on-chain (the org treasury for new events), which the backend signs with server-side; this value is used only as a fallback when that on-chain read is unavailable (legacy/pre-upgrade events). Omit for the MANAGED flow.", + "example": "GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ" }, - "phases": { + "selections": { + "description": "Winners to declare, each by winning submissionId + position. The payout recipient is resolved server-side = the submitter's (team leader's) Boundless managed wallet; no on-chain submission anchor is required. Positions and submissionIds must be unique within the array.", "type": "array", "items": { - "$ref": "#/components/schemas/PhaseDto" + "$ref": "#/components/schemas/HackathonWinnerSelectionDto" } }, - "submissionDeadlineOriginal": { + "fundingMode": { "type": "string", - "format": "date-time", - "description": "Read-only: original submission deadline before any extension" + "description": "Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side.", + "enum": ["EXTERNAL", "MANAGED"], + "default": "EXTERNAL" }, - "submissionDeadlineExtendedAt": { + "sourceWalletId": { "type": "string", - "format": "date-time", - "description": "Read-only: timestamp the submission deadline was last extended" + "description": "For MANAGED, the organization treasury wallet to sign with (the event contract-auth identity). ownerAddress must match it. Omit to use the caller's personal managed wallet." } }, - "required": ["startDate", "submissionDeadline", "timezone"] + "required": ["selections"] }, - "ParticipantFormData": { + "HackathonSubmitSignedXdrDto": { "type": "object", "properties": { - "participantType": { + "signedXdr": { "type": "string", - "enum": ["individual", "team", "team_or_individual"] - }, - "teamMin": { - "type": "number", - "minimum": 1, - "maximum": 20 - }, - "teamMax": { - "type": "number", - "minimum": 1, - "maximum": 20 - }, - "maxParticipants": { - "type": "number", - "minimum": 1, - "description": "Participant cap; omit for unlimited" - }, - "require_github": { - "type": "boolean" - }, - "require_demo_video": { - "type": "boolean" - }, - "require_other_links": { - "type": "boolean" - }, - "detailsTab": { - "type": "boolean" - }, - "participantsTab": { - "type": "boolean" - }, - "resourcesTab": { - "type": "boolean" - }, - "submissionTab": { - "type": "boolean" - }, - "announcementsTab": { - "type": "boolean" - }, - "discussionTab": { - "type": "boolean" - }, - "winnersTab": { - "type": "boolean" + "description": "The fully-signed XDR returned by the wallet (Freighter, Albedo, platform-managed signer, or a multisig coordinator). Backend submits this verbatim to Soroban RPC.", + "example": "AAAAAgAAAACdiamX7q...truncated..." + } + }, + "required": ["signedXdr"] + }, + "SubmitHackathonDto": { + "type": "object", + "properties": { + "applicantAddress": { + "type": "string", + "description": "Caller's Stellar G-address. Must match the caller's linked wallet.", + "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" }, - "sponsorsTab": { - "type": "boolean" + "fundingMode": { + "type": "string", + "description": "Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet.", + "enum": ["EXTERNAL", "MANAGED"], + "default": "EXTERNAL" }, - "joinATeamTab": { - "type": "boolean" + "contentUri": { + "type": "string", + "description": "On-chain content URI for the submission. Stored verbatim in the contract's submission anchor; off-chain content lives wherever the URI points (IPFS, S3, GitHub PR, etc.).", + "example": "ipfs://Qm.../project.json", + "minLength": 1, + "maxLength": 1024 + } + }, + "required": ["applicantAddress", "contentUri"] + }, + "WithdrawHackathonSubmissionDto": { + "type": "object", + "properties": { + "applicantAddress": { + "type": "string", + "description": "Caller's Stellar G-address. Must match the caller's linked wallet.", + "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" }, - "rulesTab": { - "type": "boolean" + "fundingMode": { + "type": "string", + "description": "Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet.", + "enum": ["EXTERNAL", "MANAGED"], + "default": "EXTERNAL" + } + }, + "required": ["applicantAddress"] + }, + "ContributeHackathonDto": { + "type": "object", + "properties": { + "applicantAddress": { + "type": "string", + "description": "Caller's Stellar G-address. Must match the caller's linked wallet.", + "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" }, - "submissionVisibility": { + "fundingMode": { "type": "string", - "enum": ["PUBLIC", "PARTICIPANTS_ONLY"] + "description": "Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet.", + "enum": ["EXTERNAL", "MANAGED"], + "default": "EXTERNAL" }, - "submissionStatusVisibility": { + "amount": { "type": "string", - "enum": ["ALL", "ACCEPTED_SHORTLISTED", "HIDDEN_UNTIL_RESULTS"] + "description": "Amount in token-native units (e.g. 30 = 30 USDC, NOT stroops). Must be >= 10 USDC (contract minimum).", + "example": "30" } }, - "required": ["participantType"] + "required": ["applicantAddress", "amount"] }, - "HackathonDraftTracksDto": { + "CreateOrganizationDto": { + "type": "object", + "properties": {} + }, + "OrganizationProfileStatsDto": { "type": "object", "properties": { - "tracksMaxPerSubmission": { + "projectsCount": { "type": "number", - "description": "Max number of tracks a single submission may enter (1-20)." + "description": "Number of projects under this organization", + "example": 12 + }, + "totalHackathons": { + "type": "number", + "description": "Total hackathons run by this organization", + "example": 5 + }, + "totalBounties": { + "type": "number", + "description": "Total bounties offered by this organization", + "example": 8 + }, + "totalGrants": { + "type": "number", + "description": "Total grants (projects with grants) under this organization", + "example": 3 } - } + }, + "required": [ + "projectsCount", + "totalHackathons", + "totalBounties", + "totalGrants" + ] }, - "PrizeTierDto": { + "OrganizationProfileDto": { "type": "object", "properties": { "id": { "type": "string", - "description": "Client-generated tier id" + "description": "Organization ID", + "example": "org_1234567890" }, - "place": { + "name": { "type": "string", - "description": "Placement label, e.g. \"1st Place\"" + "description": "Organization name", + "example": "Tech Innovators" }, - "prizeAmount": { + "slug": { "type": "string", - "description": "Prize amount as a decimal string" + "description": "Organization slug", + "example": "tech-innovators" + }, + "logoUrl": { + "type": "string", + "description": "Logo URL", + "example": "https://example.com/logo.png" }, "description": { - "type": "string" + "type": "string", + "description": "Organization description (from about or tagline)", + "example": "We are a community of developers building the future." }, - "currency": { + "stats": { + "description": "Key stats for the organization profile", + "allOf": [ + { + "$ref": "#/components/schemas/OrganizationProfileStatsDto" + } + ] + } + }, + "required": ["id", "name", "slug", "logoUrl", "description", "stats"] + }, + "UpdateOrganizationDto": { + "type": "object", + "properties": {} + }, + "UpdateMemberRoleDto": { + "type": "object", + "properties": {} + }, + "InviteMemberDto": { + "type": "object", + "properties": {} + }, + "TreasuryWalletResponseDto": { + "type": "object", + "properties": { + "id": { "type": "string" }, - "passMark": { - "type": "number", - "minimum": 0, - "maximum": 100 + "organizationId": { + "type": "string" }, "kind": { "type": "string", - "enum": ["OVERALL", "TRACK"] + "enum": ["MANAGED", "CONNECTED"] }, - "trackId": { + "publicKey": { "type": "string" - } - }, - "required": ["id", "place", "prizeAmount", "passMark"] - }, - "PrizePlacementWriteDto": { - "type": "object", - "properties": { - "position": { - "type": "number", - "description": "1 = 1st place; unique within a prize" }, "label": { "type": "string" }, - "amount": { + "isDefault": { + "type": "boolean" + }, + "status": { "type": "string", - "description": "Prize amount as a decimal string" + "enum": ["ACTIVE", "ARCHIVED", "NEEDS_REVIEW"] }, - "currency": { - "type": "string" + "isMultisig": { + "type": "boolean" }, - "passMark": { + "multisigThreshold": { "type": "number", - "minimum": 0, - "maximum": 100 + "nullable": true + }, + "connectionMethod": { + "type": "string", + "nullable": true + }, + "lastVerifiedAt": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" } }, - "required": ["position", "amount"] + "required": [ + "id", + "organizationId", + "kind", + "publicKey", + "label", + "isDefault", + "status", + "isMultisig", + "multisigThreshold", + "connectionMethod", + "lastVerifiedAt", + "createdAt", + "updatedAt" + ] }, - "PrizeWriteDto": { + "CreateManagedWalletDto": { "type": "object", "properties": { - "name": { + "label": { "type": "string", - "description": "Prize name, e.g. \"Grand Prize\" or \"Best UI/UX\"" - }, - "description": { - "type": "string" - }, - "trackIds": { - "description": "Linked HackathonTrack ids; empty = overall prize", - "type": "array", - "items": { - "type": "string" - } - }, - "placements": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PrizePlacementWriteDto" - } + "description": "Display label for the wallet", + "example": "Main treasury" } }, - "required": ["name", "trackIds", "placements"] + "required": ["label"] }, - "WinnerOverrideDto": { + "RegisterConnectedWalletDto": { "type": "object", "properties": { - "submissionId": { + "publicKey": { "type": "string", - "description": "Submission id the override targets" - }, - "rank": { - "type": "number", - "minimum": 1 + "description": "G-address of the external wallet" }, - "prizeAmount": { - "type": "string" + "label": { + "type": "string", + "description": "Display label", + "example": "Company multisig" }, - "currency": { - "type": "string" + "connectionMethod": { + "type": "string", + "enum": [ + "freighter", + "lobstr", + "albedo", + "xbull", + "hana", + "rabet", + "walletkit_generic" + ] } }, - "required": ["submissionId"] + "required": ["publicKey", "label", "connectionMethod"] }, - "RewardsFormData": { + "UpdateTreasuryWalletDto": { "type": "object", "properties": { - "prizeTiers": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PrizeTierDto" - } - }, - "prizes": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PrizeWriteDto" - } - }, - "winnerOverrides": { - "type": "array", - "items": { - "$ref": "#/components/schemas/WinnerOverrideDto" - } - }, - "prizeStructure": { + "label": { "type": "string", - "enum": ["OVERALL_ONLY", "OVERALL_AND_TRACKS", "TRACKS_ONLY"] - }, - "tracksMaxPerSubmission": { - "type": "number", - "minimum": 1, - "maximum": 20 + "description": "New display label" }, - "allowWinnerStacking": { - "type": "boolean" + "isDefault": { + "type": "boolean", + "description": "Make this the organization default" } } }, - "ResourceItemDto": { + "WalletBalanceResponseDto": { "type": "object", "properties": { - "id": { - "type": "string", - "description": "Client-generated resource id" - }, - "link": { + "publicKey": { "type": "string" }, - "description": { - "type": "string" + "usdc": { + "type": "string", + "description": "USDC balance" }, - "file": { - "type": "object", - "description": "Uploaded file metadata", - "properties": { - "url": { - "type": "string" - }, - "name": { - "type": "string" - } - } + "xlm": { + "type": "string", + "description": "XLM balance (fee float)" } }, - "required": ["id"] + "required": ["publicKey", "usdc", "xlm"] }, - "ResourcesFormData": { + "TreasuryPolicyRuleDto": { "type": "object", "properties": { - "resources": { + "min_usdc": { + "type": "number", + "example": 0 + }, + "max_usdc": { + "type": "object", + "example": 1000, + "nullable": true + }, + "required_approvals": { + "type": "number", + "example": 1 + }, + "approver_roles": { + "example": ["owner", "admin"], "type": "array", "items": { - "$ref": "#/components/schemas/ResourceItemDto" + "type": "string" } } }, - "required": ["resources"] + "required": ["min_usdc", "required_approvals", "approver_roles"] }, - "CriterionDto": { + "TreasuryPolicyResponseDto": { "type": "object", "properties": { - "id": { - "type": "string", - "description": "Client-generated criterion id" + "organizationId": { + "type": "string" }, - "name": { + "defaultWalletId": { "type": "string", - "description": "Criterion name" + "nullable": true }, - "weight": { - "type": "number", - "minimum": 0, - "maximum": 100 + "rules": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TreasuryPolicyRuleDto" + } }, - "description": { - "type": "string" + "isDefault": { + "type": "boolean", + "description": "True when no policy is saved yet (defaults returned)" + }, + "updatedAt": { + "type": "string", + "nullable": true } }, - "required": ["id", "name", "weight"] + "required": [ + "organizationId", + "defaultWalletId", + "rules", + "isDefault", + "updatedAt" + ] }, - "JudgingFormData": { + "UpdateTreasuryPolicyDto": { "type": "object", "properties": { - "criteria": { + "rules": { "type": "array", "items": { - "$ref": "#/components/schemas/CriterionDto" + "$ref": "#/components/schemas/TreasuryPolicyRuleDto" } + }, + "defaultWalletId": { + "type": "string", + "description": "Default source wallet id" } }, - "required": ["criteria"] + "required": ["rules"] }, - "SponsorPartnerDto": { + "InitiateSpendDto": { "type": "object", "properties": { - "id": { + "sourceWalletId": { "type": "string", - "description": "Client-generated sponsor/partner id" + "description": "Treasury wallet to spend from" }, - "name": { - "type": "string" + "destination": { + "type": "string", + "description": "Destination G-address or escrow contract id" }, - "logo": { - "type": "string" + "amount": { + "type": "string", + "description": "Amount in USDC", + "example": "2500.00" }, - "link": { + "purpose": { + "type": "string", + "description": "What the spend funds", + "example": "fund_hackathon_escrow" + }, + "referenceType": { + "type": "string", + "enum": ["hackathon", "bounty", "grant"] + }, + "referenceId": { "type": "string" } }, - "required": ["id"] + "required": ["sourceWalletId", "destination", "amount", "purpose"] }, - "CollaborationFormData": { + "SpendRequestResponseDto": { "type": "object", "properties": { - "contactEmail": { - "type": "string", - "description": "Organizer contact email" + "id": { + "type": "string" }, - "telegram": { + "organizationId": { "type": "string" }, - "discord": { + "sourceWalletId": { "type": "string" }, - "socialLinks": { - "type": "array", - "items": { - "type": "string" - } + "destination": { + "type": "string" }, - "sponsorsPartners": { + "amount": { + "type": "string" + }, + "currency": { + "type": "string" + }, + "purpose": { + "type": "string" + }, + "referenceType": { + "type": "string", + "nullable": true + }, + "referenceId": { + "type": "string", + "nullable": true + }, + "initiatorUserId": { + "type": "string" + }, + "requiredApprovals": { + "type": "number" + }, + "approvals": { "type": "array", "items": { - "$ref": "#/components/schemas/SponsorPartnerDto" + "type": "object" } + }, + "status": { + "type": "string" + }, + "onChainTxHash": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string" + }, + "approvedAt": { + "type": "string", + "nullable": true + } + }, + "required": [ + "id", + "organizationId", + "sourceWalletId", + "destination", + "amount", + "currency", + "purpose", + "referenceType", + "referenceId", + "initiatorUserId", + "requiredApprovals", + "approvals", + "status", + "onChainTxHash", + "createdAt", + "approvedAt" + ] + }, + "SendTreasuryFundsDto": { + "type": "object", + "properties": { + "sourceWalletId": { + "type": "string", + "description": "Wallet to send from" + }, + "destination": { + "type": "string", + "description": "Recipient Stellar address (starts with G)", + "example": "GA..." + }, + "amount": { + "type": "string", + "description": "Amount in USDC", + "example": "250.00" + }, + "note": { + "type": "string", + "description": "What this payment is for (shown in your activity log)", + "example": "Contributor payout" + } + }, + "required": ["sourceWalletId", "destination", "amount"] + }, + "SendDestinationReadinessDto": { + "type": "object", + "properties": { + "exists": { + "type": "boolean", + "description": "Whether the recipient account exists on-chain" + }, + "hasUsdcTrustline": { + "type": "boolean", + "description": "Whether the recipient has a USDC trustline (so it can receive USDC)" } }, - "required": ["contactEmail"] + "required": ["exists", "hasUsdcTrustline"] }, - "HackathonDraftDataDto": { + "SpendDecisionDto": { "type": "object", "properties": { - "information": { - "$ref": "#/components/schemas/InfoFormData" - }, - "timeline": { - "$ref": "#/components/schemas/TimelineFormData" - }, - "participation": { - "$ref": "#/components/schemas/ParticipantFormData" - }, - "tracks": { - "$ref": "#/components/schemas/HackathonDraftTracksDto" - }, - "rewards": { - "$ref": "#/components/schemas/RewardsFormData" - }, - "resources": { - "$ref": "#/components/schemas/ResourcesFormData" - }, - "judging": { - "$ref": "#/components/schemas/JudgingFormData" - }, - "collaboration": { - "$ref": "#/components/schemas/CollaborationFormData" + "note": { + "type": "string", + "description": "Optional note for the decision" } } }, - "HackathonDraftAiGenerationDto": { + "BuildSpendXdrResponseDto": { "type": "object", "properties": { - "generationId": { + "unsignedXdr": { "type": "string", - "description": "AI generationId that produced or last-updated this draft." + "description": "Unsigned transaction XDR to sign in-browser" + }, + "request": { + "$ref": "#/components/schemas/SpendRequestResponseDto" } }, - "required": ["generationId"] + "required": ["unsignedXdr", "request"] }, - "HackathonDraftPrizePlacementDto": { + "SubmitSpendSignedXdrDto": { + "type": "object", + "properties": { + "signedXdr": { + "type": "string", + "description": "The browser-signed transaction XDR" + } + }, + "required": ["signedXdr"] + }, + "TreasuryActorDto": { "type": "object", "properties": { "id": { "type": "string" }, - "position": { - "type": "number", - "description": "1 = 1st place, unique within a prize" - }, - "label": { + "name": { "type": "string", "nullable": true }, - "amount": { + "image": { "type": "string", - "description": "Decimal string in the prize currency" - }, - "currency": { - "type": "string" - }, - "passMark": { - "type": "number", - "description": "Minimum score (0-100) to win this placement" + "nullable": true } }, - "required": ["id", "position", "amount", "currency", "passMark"] + "required": ["id", "name", "image"] }, - "HackathonDraftPrizeDto": { + "TreasuryAuditEntryDto": { "type": "object", "properties": { "id": { "type": "string" }, - "name": { + "action": { "type": "string" }, - "description": { + "actorUserId": { "type": "string", "nullable": true }, - "displayOrder": { - "type": "number" + "actorKind": { + "type": "string" }, - "trackIds": { - "description": "Linked track ids; empty = overall prize", - "type": "array", - "items": { - "type": "string" - } + "actor": { + "nullable": true, + "description": "Resolved profile of the actor (name + avatar), if a user.", + "allOf": [ + { + "$ref": "#/components/schemas/TreasuryActorDto" + } + ] }, - "placements": { + "walletId": { + "type": "string", + "nullable": true + }, + "spendRequestId": { + "type": "string", + "nullable": true + }, + "details": { + "type": "object", + "additionalProperties": true, + "nullable": true + }, + "createdAt": { + "type": "string" + } + }, + "required": [ + "id", + "action", + "actorUserId", + "actorKind", + "actor", + "walletId", + "spendRequestId", + "details", + "createdAt" + ] + }, + "TreasuryAuditLogResponseDto": { + "type": "object", + "properties": { + "data": { "type": "array", "items": { - "$ref": "#/components/schemas/HackathonDraftPrizePlacementDto" + "$ref": "#/components/schemas/TreasuryAuditEntryDto" } + }, + "total": { + "type": "number" + }, + "page": { + "type": "number" + }, + "limit": { + "type": "number" } }, - "required": ["id", "name", "displayOrder", "trackIds", "placements"] + "required": ["data", "total", "page", "limit"] }, - "HackathonDraftResponseDto": { + "ReceiptResponseDto": { "type": "object", "properties": { "id": { "type": "string" }, - "status": { + "receiptNumber": { "type": "string", - "enum": [ - "DRAFT", - "DRAFT_AWAITING_FUNDING", - "PUBLISHED", - "ARCHIVED", - "CANCELLED" - ] - }, - "currentStep": { - "type": "number", - "description": "First incomplete step (1-based)" + "example": "RCPT-100001" }, - "completedSteps": { - "type": "array", - "items": { - "type": "string" - } + "organizationId": { + "type": "string" }, - "data": { - "$ref": "#/components/schemas/HackathonDraftDataDto" + "type": { + "type": "string", + "example": "TREASURY_SEND" }, - "isValidForPublish": { - "type": "boolean" + "typeLabel": { + "type": "string", + "example": "Funds sent" }, - "validationErrors": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - }, - "description": "Per-section validation messages, keyed by step" + "status": { + "type": "string", + "example": "ISSUED" }, - "createdAt": { + "direction": { "type": "string", - "format": "date-time" + "example": "OUTGOING" }, - "updatedAt": { + "amount": { "type": "string", - "format": "date-time" + "example": "250.00" }, - "aiGeneration": { - "description": "Present when the draft was generated with Organizer Assist; enables per-section AI regenerate in the wizard.", - "allOf": [ - { - "$ref": "#/components/schemas/HackathonDraftAiGenerationDto" - } - ] + "currency": { + "type": "string", + "example": "USDC" }, - "prizes": { - "description": "Prize entity (named prizes + linked tracks + placements). Additive read path alongside data.rewards.prizeTiers; becomes authoritative as readers cut over.", - "type": "array", - "items": { - "$ref": "#/components/schemas/HackathonDraftPrizeDto" - } - } - }, - "required": [ - "id", - "status", - "currentStep", - "completedSteps", - "data", - "isValidForPublish", - "validationErrors", - "createdAt", - "updatedAt", - "prizes" - ] - }, - "UpdateHackathonDraftDto": { - "type": "object", - "properties": { - "information": { - "$ref": "#/components/schemas/InfoFormData" + "fromLabel": { + "type": "object", + "nullable": true }, - "timeline": { - "$ref": "#/components/schemas/TimelineFormData" + "fromAddress": { + "type": "object", + "nullable": true }, - "participation": { - "$ref": "#/components/schemas/ParticipantFormData" + "toLabel": { + "type": "object", + "nullable": true }, - "rewards": { - "$ref": "#/components/schemas/RewardsFormData" + "toAddress": { + "type": "object", + "nullable": true }, - "resources": { - "$ref": "#/components/schemas/ResourcesFormData" + "description": { + "type": "object", + "nullable": true }, - "judging": { - "$ref": "#/components/schemas/JudgingFormData" + "onChainTxHash": { + "type": "object", + "nullable": true }, - "collaboration": { - "$ref": "#/components/schemas/CollaborationFormData" + "explorerUrl": { + "type": "object", + "nullable": true }, - "autoSave": { - "type": "boolean", - "description": "Hint that this is an autosave (no completion side effects)." - } - } - }, - "GenerateDraftFromBriefDto": { - "type": "object", - "properties": { - "brief": { - "type": "string", - "description": "Free-text brief describing the hackathon to generate.", - "minLength": 10, - "maxLength": 2000, - "example": "A two-week hackathon for AI agent tooling on Stellar, aimed at indie builders." + "network": { + "type": "object", + "nullable": true }, - "budgetCapUsdc": { - "type": "string", - "description": "Total budget cap in USDC, as a decimal string.", - "example": "10000" + "issuedByUserId": { + "type": "object", + "nullable": true }, - "earliestStart": { - "type": "string", - "description": "Earliest the hackathon may start (YYYY-MM-DD).", - "example": "2026-07-01" + "issuedAt": { + "type": "string" }, - "examples": { - "description": "Up to 3 example briefs/drafts to steer style.", - "maxItems": 3, - "type": "array", - "items": { - "type": "string" - } + "voidedAt": { + "type": "object", + "nullable": true } }, - "required": ["brief", "budgetCapUsdc", "earliestStart"] + "required": [ + "id", + "receiptNumber", + "organizationId", + "type", + "typeLabel", + "status", + "direction", + "amount", + "currency", + "fromLabel", + "fromAddress", + "toLabel", + "toAddress", + "description", + "onChainTxHash", + "explorerUrl", + "network", + "issuedByUserId", + "issuedAt", + "voidedAt" + ] }, - "AiGenerationMetaDto": { + "ReceiptListResponseDto": { "type": "object", "properties": { - "generationId": { - "type": "string" + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReceiptResponseDto" + } }, - "model": { - "type": "string" + "total": { + "type": "number" }, - "promptVersion": { - "type": "string" + "page": { + "type": "number" }, - "costUsd": { - "type": "string", - "description": "Cost in USD as a decimal string (never a float)." + "limit": { + "type": "number" } }, - "required": ["generationId", "model", "promptVersion", "costUsd"] + "required": ["data", "total", "page", "limit"] }, - "GenerateDraftFromBriefResponseDto": { + "SendReceiptDto": { "type": "object", "properties": { - "draftId": { + "email": { "type": "string", - "description": "Id of the created draft." - }, - "draft": { - "$ref": "#/components/schemas/HackathonDraftResponseDto" - }, - "generation": { - "$ref": "#/components/schemas/AiGenerationMetaDto" + "description": "Where to email the receipt. Defaults to your account email." } - }, - "required": ["draftId", "draft", "generation"] + } }, - "RegenerateDraftSectionDto": { + "VoidReceiptDto": { "type": "object", "properties": { - "section": { - "type": "string", - "enum": ["criteria", "prizes", "tracks", "timeline", "description"] - }, - "instructions": { + "reason": { "type": "string", - "description": "Optional steering instructions for the regeneration.", - "maxLength": 1000 + "description": "Why the receipt is being voided" } - }, - "required": ["section"] + } }, - "RegenerateDraftSectionResponseDto": { + "CreateVoteDto": { "type": "object", "properties": { - "section": { + "projectId": { "type": "string", - "enum": ["criteria", "prizes", "tracks", "timeline", "description"] + "description": "ID of the project being voted on" }, - "data": { - "type": "object", - "additionalProperties": true, - "description": "Regenerated values in the wizard section shape." + "entityType": { + "type": "string", + "enum": [ + "PROJECT", + "CROWDFUNDING_CAMPAIGN", + "HACKATHON_SUBMISSION", + "GRANT" + ], + "description": "Type of entity being voted on" }, - "generation": { - "$ref": "#/components/schemas/AiGenerationMetaDto" + "voteType": { + "type": "string", + "enum": ["UPVOTE", "DOWNVOTE"], + "default": "UPVOTE", + "description": "Type of vote (UPVOTE or DOWNVOTE)" + }, + "weight": { + "type": "number", + "default": 1, + "description": "Weight of the vote" } }, - "required": ["section", "data", "generation"] + "required": ["projectId", "entityType"] }, - "UpdateVisibilitySettingsDto": { + "CreateBlogPostDto": { "type": "object", "properties": { - "submissionVisibility": { + "title": { "type": "string", - "description": "Who can view hackathon submissions", - "enum": ["PUBLIC", "PARTICIPANTS_ONLY"], - "example": "PUBLIC" + "description": "Blog post title", + "example": "Getting Started with Stellar Smart Contracts", + "minLength": 3, + "maxLength": 300 }, - "submissionStatusVisibility": { + "content": { "type": "string", - "description": "Which submission statuses are visible to others. ALL exposes SUBMITTED and SHORTLISTED. ACCEPTED_SHORTLISTED exposes only SHORTLISTED. HIDDEN_UNTIL_RESULTS hides every submission from non-owners and non-organizers until the hackathon results are published, then exposes only SHORTLISTED. DISQUALIFIED is never visible to anyone other than the owner or an organizer.", - "enum": ["ALL", "ACCEPTED_SHORTLISTED", "HIDDEN_UNTIL_RESULTS"], - "example": "ACCEPTED_SHORTLISTED" - } - } - }, - "ReviewSubmissionDto": { - "type": "object", - "properties": { - "judgeId": { + "description": "Blog post content in markdown format", + "example": "# Introduction\n\nThis tutorial will teach you...", + "minLength": 10 + }, + "excerpt": { "type": "string", - "description": "ID of the assigned judge performing the review", - "example": "user_1234567890" + "description": "Short excerpt or summary", + "example": "Learn how to build your first smart contract on Stellar", + "maxLength": 500 + }, + "coverImage": { + "type": "string", + "description": "Cover image URL", + "example": "https://res.cloudinary.com/demo/image/upload/v1234567890/post-cover.jpg" }, "status": { "type": "string", - "description": "Review action", - "example": "SHORTLISTED", - "enum": ["SHORTLISTED", "SUBMITTED"] + "description": "Post status", + "enum": ["DRAFT", "PUBLISHED", "ARCHIVED", "SCHEDULED"], + "example": "DRAFT", + "default": "DRAFT" }, - "notes": { + "tags": { + "description": "Post tags", + "example": ["smart-contracts", "soroban", "tutorial"], + "type": "array", + "items": { + "type": "string" + } + }, + "categories": { + "description": "Post categories", + "example": ["tutorials"], + "type": "array", + "items": { + "type": "string" + } + }, + "isFeatured": { + "type": "boolean", + "description": "Mark as featured post", + "example": false, + "default": false + }, + "isPinned": { + "type": "boolean", + "description": "Pin post to top", + "example": false, + "default": false + }, + "readingTime": { + "type": "number", + "description": "Reading time in minutes (auto-calculated if not provided)", + "example": 5 + }, + "seoTitle": { "type": "string", - "description": "Reviewer notes or feedback", - "example": "Great project with innovative approach", - "maxLength": 1000 + "description": "SEO title (overrides post title)", + "maxLength": 70 + }, + "seoDescription": { + "type": "string", + "description": "SEO meta description", + "maxLength": 160 + }, + "seoKeywords": { + "description": "SEO keywords", + "example": ["stellar", "blockchain", "smart contracts"], + "type": "array", + "items": { + "type": "string" + } }, - "rank": { - "type": "number", - "description": "Rank/position for the submission", - "example": 1 + "scheduledFor": { + "type": "string", + "description": "Schedule publication date (for SCHEDULED status)", + "example": "2025-12-31T10:00:00Z" }, - "isOrganizerOverride": { + "generateAI": { "type": "boolean", - "description": "Whether this is an organizational override (bypasses COI and assignment checks)", + "description": "Generate AI content (excerpt, reading time, SEO, tags, category) if not provided", + "example": true, "default": false } }, - "required": ["judgeId", "status"] + "required": ["title", "content"] }, - "OrganizationHackathonParticipantsResponseDto": { + "UpdateBlogPostDto": { "type": "object", "properties": {} }, - "DisqualifySubmissionDto": { + "MetricDataDto": { "type": "object", "properties": { - "disqualificationReason": { + "value": { + "type": "number", + "description": "The metric value", + "example": 1250 + }, + "change": { + "type": "number", + "description": "Percentage change", + "example": 12.5 + }, + "changeType": { "type": "string", - "description": "Reason for disqualification", - "example": "Submission does not meet hackathon requirements", - "minLength": 10, - "maxLength": 500 - } - }, - "required": ["disqualificationReason"] - }, - "BulkSubmissionActionDto": { - "type": "object", - "properties": { - "submissionIds": { - "description": "Array of submission IDs", - "example": ["sub_1234567890", "sub_0987654321"], - "type": "array", - "items": { - "type": "string" - } + "enum": ["positive", "negative", "neutral"], + "description": "Type of change", + "example": "positive" }, - "action": { + "label": { "type": "string", - "description": "Action to perform", - "example": "SHORTLISTED", - "enum": ["SHORTLISTED", "SUBMITTED", "DISQUALIFIED"] + "description": "Metric label", + "example": "Total Users" }, - "reason": { + "description": { "type": "string", - "description": "Reason (required for DISQUALIFIED action)", - "example": "Does not meet requirements" + "description": "Additional description", + "example": "Active users in the platform" } }, - "required": ["submissionIds", "action"] + "required": ["value", "change", "changeType", "label"] }, - "SummaryMetricsDto": { + "HackathonMetricDataDto": { "type": "object", "properties": { - "participantsCount": { + "value": { "type": "number", - "example": 120 + "description": "The metric value", + "example": 1250 }, - "submissionsCount": { + "change": { "type": "number", - "example": 45 + "description": "Percentage change", + "example": 12.5 }, - "activeJudges": { - "type": "number", - "example": 6 + "changeType": { + "type": "string", + "enum": ["positive", "negative", "neutral"], + "description": "Type of change", + "example": "positive" }, - "completedMilestones": { - "type": "number", - "example": 3 + "label": { + "type": "string", + "description": "Metric label", + "example": "Total Users" + }, + "description": { + "type": "string", + "description": "Additional description", + "example": "Active users in the platform" + }, + "additionalInfo": { + "type": "string", + "description": "Additional hackathon info", + "example": "3 active, 7 upcoming" } }, - "required": [ - "participantsCount", - "submissionsCount", - "activeJudges", - "completedMilestones" - ] + "required": ["value", "change", "changeType", "label"] }, - "TrendPointDto": { + "OverviewMetricsDto": { "type": "object", "properties": { - "date": { - "type": "string", - "example": "2026-02-01" + "totalUsers": { + "$ref": "#/components/schemas/MetricDataDto" }, - "count": { - "type": "number", - "example": 5 + "organizations": { + "$ref": "#/components/schemas/MetricDataDto" + }, + "projects": { + "$ref": "#/components/schemas/MetricDataDto" + }, + "hackathons": { + "$ref": "#/components/schemas/HackathonMetricDataDto" } }, - "required": ["date", "count"] + "required": ["totalUsers", "organizations", "projects", "hackathons"] }, - "TrendsDto": { + "OverviewChartDataDto": { "type": "object", "properties": { - "submissionsOverTime": { + "data": { "type": "array", "items": { - "$ref": "#/components/schemas/TrendPointDto" + "$ref": "#/components/schemas/ChartDataPointDto" } }, - "participantSignupsOverTime": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TrendPointDto" - } + "timeRange": { + "type": "string", + "enum": ["7d", "30d", "90d"], + "description": "Time range for the chart", + "example": "7d" } }, - "required": ["submissionsOverTime", "participantSignupsOverTime"] + "required": ["data", "timeRange"] }, - "TimelinePhaseDto": { + "AdminOverviewResponseDto": { "type": "object", "properties": { - "phase": { - "type": "string", - "example": "Registration" - }, - "description": { - "type": "string", - "example": "Individuals and teams are signing up to participate in the hackathon." + "metrics": { + "$ref": "#/components/schemas/OverviewMetricsDto" }, - "date": { - "type": "string", - "example": "2026-01-20" + "chart": { + "$ref": "#/components/schemas/OverviewChartDataDto" }, - "status": { + "lastUpdated": { "type": "string", - "enum": ["upcoming", "ongoing", "completed"] + "description": "Last updated timestamp", + "example": "2025-12-26T10:30:00Z" } }, - "required": ["phase", "description", "date", "status"] + "required": ["metrics", "chart", "lastUpdated"] }, - "HackathonAnalyticsResponseDto": { + "AdminCrowdfundingRejectDto": { "type": "object", "properties": { - "hackathonId": { + "reason": { "type": "string", - "example": "hack_1234567890" - }, - "summary": { - "$ref": "#/components/schemas/SummaryMetricsDto" - }, - "trends": { - "$ref": "#/components/schemas/TrendsDto" - }, - "timeline": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TimelinePhaseDto" - } + "description": "Reason for rejection", + "example": "Campaign does not meet requirements" } - }, - "required": ["hackathonId", "summary", "trends", "timeline"] + } }, - "AnnouncementAuthorDto": { + "AdminCrowdfundingRequestRevisionDto": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "image": { - "type": "string" + "message": { + "type": "string", + "description": "Message for the creator explaining requested revisions", + "example": "Please update the project description to be more detailed" }, - "username": { - "type": "string" + "reasons": { + "description": "Optional structured reasons", + "example": ["incomplete_description", "missing_team_info"], + "type": "array", + "items": { + "type": "string" + } } }, - "required": ["id", "name"] + "required": ["message"] }, - "AnnouncementResponseDto": { + "AdminCrowdfundingNoteDto": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "hackathonId": { - "type": "string" - }, - "title": { - "type": "string" - }, - "content": { - "type": "string" - }, - "isDraft": { - "type": "boolean" - }, - "isPinned": { - "type": "boolean" - }, - "publishedAt": { - "format": "date-time", - "type": "string" - }, - "createdAt": { - "format": "date-time", - "type": "string" - }, - "updatedAt": { - "format": "date-time", - "type": "string" - }, - "author": { - "$ref": "#/components/schemas/AnnouncementAuthorDto" + "note": { + "type": "string", + "description": "Short admin note or comment", + "example": "Reviewed initial submission" } }, - "required": [ - "id", - "hackathonId", - "title", - "content", - "isDraft", - "isPinned", - "createdAt", - "updatedAt", - "author" - ] + "required": ["note"] }, - "CreateAnnouncementDto": { + "AdminCrowdfundingAssignDto": { "type": "object", "properties": { - "title": { - "type": "string", - "description": "Title of the announcement", - "example": "Hackathon Starts Now!", - "minLength": 3, - "maxLength": 100 - }, - "content": { + "reviewerId": { "type": "string", - "description": "Content of the announcement in Markdown", - "example": "# Welcome\n\nWe are excited to start...", - "minLength": 10, - "maxLength": 10000 - }, - "isDraft": { - "type": "boolean", - "description": "Whether the announcement is a draft", - "default": true - }, - "isPinned": { - "type": "boolean", - "description": "Whether the announcement should be pinned", - "default": false + "description": "Reviewer (user) id to assign", + "example": "550e8400-e29b-41d4-a716-446655440000" } }, - "required": ["title", "content"] + "required": ["reviewerId"] }, - "UpdateAnnouncementDto": { + "ApproveMilestoneDto": { "type": "object", "properties": { - "title": { - "type": "string", - "description": "Title of the announcement", - "example": "Hackathon Starts Now!", - "minLength": 3, - "maxLength": 100 - }, - "content": { + "notes": { "type": "string", - "description": "Content of the announcement in Markdown", - "example": "# Welcome\n\nWe are excited to start...", - "minLength": 10, - "maxLength": 10000 - }, - "isDraft": { - "type": "boolean", - "description": "Whether the announcement is a draft" - }, - "isPinned": { - "type": "boolean", - "description": "Whether the announcement should be pinned" + "description": "Optional approval notes", + "example": "Milestone completed successfully" } } }, - "CriterionScoreDto": { + "RejectMilestoneDto": { "type": "object", "properties": { - "criterionId": { + "rejectionFeedback": { "type": "string", - "description": "Criterion ID or name", - "example": "Technical Complexity" - }, - "score": { - "type": "number", - "description": "Score for this criterion (0-10)", - "example": 8.5 + "description": "Feedback shown to the builder; what needs to change.", + "minLength": 3, + "maxLength": 1000 }, - "comment": { + "resubmissionDeadline": { "type": "string", - "description": "Optional comment for this criterion", - "example": "Great technical implementation" + "description": "Optional ISO date by which the builder must resubmit." } }, - "required": ["criterionId", "score"] + "required": ["rejectionFeedback"] }, - "ScoreSubmissionDto": { + "RequestMilestoneResubmissionDto": { "type": "object", "properties": { - "submissionId": { - "type": "string", - "description": "Submission ID being judged", - "example": "sub_1234567890" - }, - "criteriaScores": { - "description": "Scores for each individual criterion", - "type": "array", - "items": { - "$ref": "#/components/schemas/CriterionScoreDto" - } - }, - "judgeId": { + "feedback": { "type": "string", - "description": "Optional ID of the judge to attribute this score to (defaults to calling user)", - "example": "user_123" + "description": "Feedback explaining what needs to change", + "example": "Please improve the documentation and add more test cases" }, - "notes": { + "resubmissionDeadline": { "type": "string", - "description": "Optional admin notes", - "example": "Score adjusted per appeal" - }, - "isOrganizerOverride": { - "type": "boolean", - "description": "Whether this is an organizational override (bypasses COI and assignment checks)", - "default": false - } - }, - "required": ["submissionId", "criteriaScores"] - }, - "UserDetailsDto": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "email": { - "type": "string" - }, - "name": { - "type": "string" - }, - "username": { - "type": "string" - }, - "image": { - "type": "string" + "description": "Deadline for resubmission", + "example": "2025-02-15" } }, - "required": ["id", "email", "name", "username"] + "required": ["feedback", "resubmissionDeadline"] }, - "JudgingSubmissionParticipantDto": { + "AddMilestoneReviewNoteDto": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "userId": { - "type": "string" - }, - "user": { - "$ref": "#/components/schemas/UserDetailsDto" - }, - "participationType": { - "type": "string" - }, - "teamId": { - "type": "string" - }, - "teamName": { - "type": "string" - }, - "teamMembers": { - "type": "array", - "items": { - "type": "object" - } + "note": { + "type": "string", + "description": "Review note content", + "example": "Reviewed the code quality and found it satisfactory" } }, - "required": ["id", "userId", "user", "participationType"] + "required": ["note"] }, - "JudgingSubmissionDataDto": { + "ManualEscrowActionDto": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "projectName": { - "type": "string" - }, - "category": { - "type": "string" - }, - "description": { - "type": "string" - }, - "logo": { - "type": "string" - }, - "videoUrl": { - "type": "string" - }, - "introduction": { - "type": "string" - }, - "links": { - "type": "array", - "items": { - "type": "object" - } - }, - "socialLinks": { - "type": "object", - "additionalProperties": true + "action": { + "type": "string", + "enum": ["RELEASE", "REFUND", "PAUSE", "RESUME"], + "description": "Type of escrow action to execute", + "example": "RELEASE" }, - "submissionDate": { - "type": "string" + "amount": { + "type": "number", + "description": "Amount to transfer (for RELEASE/REFUND)", + "example": 1000 }, - "status": { - "type": "string" + "notes": { + "type": "string", + "description": "Optional notes for this action", + "example": "Releasing funds for completed milestone" }, - "rank": { - "type": "number" + "recipientAddress": { + "type": "string", + "description": "Recipient address (for RELEASE/REFUND)", + "example": "GAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" } }, - "required": [ - "id", - "projectName", - "category", - "description", - "submissionDate", - "status" - ] + "required": ["action"] }, - "IndividualJudgingResultDto": { + "AssignDisputeDto": { "type": "object", "properties": { - "judgeId": { - "type": "string" - }, - "judgeName": { - "type": "string" - }, - "criteriaScores": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CriterionScoreDto" - } - }, - "totalScore": { - "type": "number" - }, - "submittedAt": { - "format": "date-time", - "type": "string" + "assignedToStaffId": { + "type": "string", + "nullable": true, + "description": "staff_users id to assign the dispute to, or null to unassign." } }, - "required": [ - "judgeId", - "judgeName", - "criteriaScores", - "totalScore", - "submittedAt" - ] + "required": ["assignedToStaffId"] }, - "JudgingSubmissionDto": { + "AddDisputeNoteDto": { "type": "object", "properties": { - "participant": { - "$ref": "#/components/schemas/JudgingSubmissionParticipantDto" - }, - "submission": { - "$ref": "#/components/schemas/JudgingSubmissionDataDto" - }, - "myScore": { - "$ref": "#/components/schemas/IndividualJudgingResultDto" - }, - "averageScore": { - "type": "object", - "nullable": true + "message": { + "type": "string", + "description": "Message content", + "example": "Contacted the project creator for more information" }, - "judgeCount": { - "type": "number" + "isInternal": { + "type": "boolean", + "description": "Whether this is an internal note (not visible to parties)", + "example": false } }, - "required": ["participant", "submission", "averageScore", "judgeCount"] + "required": ["message"] }, - "JudgingPaginationDto": { + "ResolveDisputeDto": { "type": "object", "properties": { - "page": { - "type": "number" - }, - "limit": { - "type": "number" - }, - "total": { - "type": "number" + "resolution": { + "type": "string", + "enum": [ + "APPROVED_WITH_CONDITIONS", + "REQUIRE_RESUBMISSION", + "PARTIAL_REFUND", + "FULL_REFUND", + "DISMISSED", + "ARBITRATION" + ], + "description": "Resolution outcome recorded on the dispute." }, - "totalPages": { - "type": "number" + "resolutionNotes": { + "type": "string", + "description": "Resolution notes shown to the reporter and campaign creator.", + "minLength": 3, + "maxLength": 1000 } }, - "required": ["page", "limit", "total", "totalPages"] + "required": ["resolution", "resolutionNotes"] }, - "JudgingSubmissionsResponseDto": { + "EscalateDisputeDto": { "type": "object", "properties": { - "submissions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/JudgingSubmissionDto" - } - }, - "criteria": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CriterionDto" - } - }, - "pagination": { - "$ref": "#/components/schemas/JudgingPaginationDto" - }, - "scoredCount": { - "type": "number", - "description": "Number of submissions in this hackathon that the calling judge has already scored. Independent of pagination so the progress strip is accurate even when the user is on page 2." + "reason": { + "type": "string", + "description": "Why this dispute is being escalated to arbitration. Recorded in the audit log.", + "minLength": 3, + "maxLength": 500 } }, - "required": ["submissions", "criteria", "pagination"] + "required": ["reason"] }, - "AddJudgeDto": { + "RejectManualProjectDto": { + "type": "object", + "properties": {} + }, + "RequestManualProjectChangesDto": { + "type": "object", + "properties": {} + }, + "RejectProjectEditDto": { + "type": "object", + "properties": {} + }, + "AdminWalletStatsDto": { "type": "object", "properties": { - "email": { - "type": "string", - "description": "Email address of the user to be assigned as a judge", - "example": "judge@example.com" + "totalWallets": { + "$ref": "#/components/schemas/MetricDataDto" + }, + "activatedWallets": { + "$ref": "#/components/schemas/MetricDataDto" + }, + "inactiveWallets": { + "$ref": "#/components/schemas/MetricDataDto" } }, - "required": ["email"] + "required": ["totalWallets", "activatedWallets", "inactiveWallets"] }, - "JudgeResponseDto": { + "AdminWalletUserDto": { "type": "object", "properties": { "id": { "type": "string" }, - "userId": { + "name": { "type": "string" }, - "name": { + "email": { + "type": "string" + }, + "username": { "type": "string" }, "image": { - "type": "object" + "type": "string" } }, - "required": ["id", "userId", "name"] + "required": ["id", "name", "email"] }, - "IndividualScoreDto": { + "AdminWalletListItemDto": { "type": "object", "properties": { - "judgeId": { + "id": { "type": "string" }, - "judgeName": { + "publicKey": { "type": "string" }, - "score": { - "type": "number" - } - }, - "required": ["judgeId", "judgeName", "score"] - }, - "ScoreRangeDto": { - "type": "object", - "properties": { - "min": { - "type": "number" + "isActivated": { + "type": "boolean" }, - "max": { - "type": "number" + "createdAt": { + "format": "date-time", + "type": "string" + }, + "users": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminWalletUserDto" + } } }, - "required": ["min", "max"] + "required": ["id", "publicKey", "isActivated", "createdAt", "users"] }, - "CriteriaBreakdownDto": { + "AdminWalletListResponseDto": { "type": "object", "properties": { - "criterionId": { - "type": "string" + "wallets": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminWalletListItemDto" + } }, - "averageScore": { + "total": { "type": "number" }, - "min": { + "page": { "type": "number" }, - "max": { + "limit": { "type": "number" }, - "variance": { + "totalPages": { "type": "number" } }, - "required": ["criterionId", "averageScore", "min", "max", "variance"] + "required": ["wallets", "total", "page", "limit", "totalPages"] }, - "AggregatedJudgingResultDto": { + "AdminWalletBalanceDto": { "type": "object", "properties": { - "submissionId": { - "type": "string" - }, - "projectName": { + "balance": { "type": "string" }, - "teamId": { - "type": "object" - }, - "participantId": { + "assetCode": { "type": "string" }, - "status": { + "assetIssuer": { "type": "string" }, - "submittedAt": { - "format": "date-time", + "assetType": { "type": "string" - }, - "averageScore": { - "type": "number" - }, - "totalScore": { - "type": "number" - }, - "judgeCount": { - "type": "number" - }, - "expectedJudgeCount": { - "type": "number" - }, - "judgingProgress": { + } + }, + "required": ["balance", "assetCode", "assetType"] + }, + "AdminWalletDetailsDto": { + "type": "object", + "properties": { + "id": { "type": "string" }, - "individualScores": { - "type": "array", - "items": { - "$ref": "#/components/schemas/IndividualScoreDto" - } - }, - "scoreVariance": { - "type": "number" - }, - "scoreRange": { - "$ref": "#/components/schemas/ScoreRangeDto" - }, - "criteriaBreakdown": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CriteriaBreakdownDto" - } - }, - "rank": { - "type": "object" - }, - "computedRank": { - "type": "number" - }, - "prize": { + "publicKey": { "type": "string" }, - "isComplete": { - "type": "boolean" - }, - "isPending": { + "isActivated": { "type": "boolean" }, - "hasDisagreement": { - "type": "boolean" + "createdAt": { + "format": "date-time", + "type": "string" }, - "trackIds": { + "balances": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/AdminWalletBalanceDto" } }, - "recommendedOverall": { - "type": "boolean", - "description": "True when this submission is in the top X% overall per the recommendation threshold." - }, - "recommendedTrackIds": { - "description": "Track ids where this submission is in the top X% per the per-track recommendation threshold.", + "users": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/AdminWalletUserDto" } } }, "required": [ - "submissionId", - "projectName", - "participantId", - "status", - "submittedAt", - "averageScore", - "totalScore", - "judgeCount", - "expectedJudgeCount", - "judgingProgress", - "individualScores", - "scoreVariance", - "scoreRange", - "criteriaBreakdown", - "isComplete", - "isPending", - "hasDisagreement" + "id", + "publicKey", + "isActivated", + "createdAt", + "balances", + "users" ] }, - "JudgingResultsResponseDto": { + "ReviewWindowDto": { "type": "object", "properties": { - "hackathonId": { - "type": "string" - }, - "totalSubmissions": { - "type": "number" - }, - "submissionsScoredCount": { - "type": "number" - }, - "submissionsPendingCount": { - "type": "number" - }, - "averageScoreAcrossAll": { - "type": "number" - }, - "resultsPublished": { - "type": "boolean" - }, - "judgesAssigned": { - "type": "number" - }, - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AggregatedJudgingResultDto" - } - }, - "generatedAt": { - "format": "date-time", - "type": "string" + "minBusinessDays": { + "type": "number", + "example": 1 }, - "winnerOverrides": { - "type": "object", - "additionalProperties": { - "type": "number" - }, - "description": "Manual winner assignments override (submissionId -> rank)" + "maxBusinessDays": { + "type": "number", + "example": 3 }, - "metadata": { - "$ref": "#/components/schemas/JudgingResultsMetadataDto" + "estimatedCompletionAt": { + "type": "string", + "description": "ISO timestamp by which the review is expected to complete." } }, "required": [ - "hackathonId", - "totalSubmissions", - "submissionsScoredCount", - "submissionsPendingCount", - "averageScoreAcrossAll", - "resultsPublished", - "judgesAssigned", - "results", - "generatedAt", - "metadata" + "minBusinessDays", + "maxBusinessDays", + "estimatedCompletionAt" ] }, - "SetPlacementWinnerDto": { + "DeclineDetailsDto": { "type": "object", "properties": { - "submissionId": { + "reason": { "type": "string", - "description": "The submission to award this placement to." + "description": "Human-readable reason from Didit, if available." + }, + "canRetry": { + "type": "boolean", + "description": "Whether the user is allowed to start a new verification.", + "example": true } }, - "required": ["submissionId"] + "required": ["canRetry"] }, - "InviteJudgeDto": { + "VerificationStatusDto": { "type": "object", "properties": { - "email": { + "state": { "type": "string", - "example": "judge@example.com" + "description": "Normalized verification state. Frontend should hide the verify button unless this is one of: not_started, declined, abandoned, expired.", + "enum": [ + "not_started", + "in_progress", + "in_review", + "approved", + "declined", + "abandoned", + "expired" + ] }, - "displayName": { + "canStartNew": { + "type": "boolean", + "description": "Whether the user can start a new verification session." + }, + "message": { "type": "string", - "description": "Optional public display name for the judge" + "description": "Polite, render-ready copy summarising the current state." }, - "title": { + "verifiedAt": { "type": "string", - "description": "Optional title/role shown with the judge (e.g. \"Time Traveler\")." + "description": "ISO timestamp when the user became verified." }, - "message": { + "reviewedAt": { "type": "string", - "description": "Personal message included in the invitation email" + "description": "ISO timestamp of the last status transition." }, - "expiresInDays": { - "type": "number", - "description": "Override expiry in days (default 14). Maximum 60 to prevent indefinite invitations.", - "minimum": 1, - "maximum": 60 + "reviewWindow": { + "description": "Estimated review window. Present only when state === \"in_review\".", + "allOf": [ + { + "$ref": "#/components/schemas/ReviewWindowDto" + } + ] + }, + "decline": { + "description": "Decline details. Present only when state === \"declined\".", + "allOf": [ + { + "$ref": "#/components/schemas/DeclineDetailsDto" + } + ] } }, - "required": ["email"] + "required": ["state", "canStartNew", "message"] }, - "BulkInviteJudgesDto": { + "PricingPreviewResponseDto": { "type": "object", "properties": { - "invites": { - "description": "Up to 25 judges per request", - "type": "array", - "items": { - "$ref": "#/components/schemas/InviteJudgeDto" - } + "feeBps": { + "type": "number", + "description": "Effective rate applied to this preview." + }, + "feeStroops": { + "type": "string", + "description": "Fee in stroops. String to preserve i128 precision." + }, + "poolStroops": { + "type": "string", + "description": "Pool released to winners; equals the requested budget." + }, + "totalDepositStroops": { + "type": "string", + "description": "budgetStroops + feeStroops; what the organizer signs for." + }, + "reason": { + "type": "string", + "description": "Audit label for the rate choice: default | foundation-tier | sales-override:* | waiver:*." } }, - "required": ["invites"] + "required": [ + "feeBps", + "feeStroops", + "poolStroops", + "totalDepositStroops", + "reason" + ] }, - "BulkInviteRowResultDto": { + "StaffPrincipalDto": { "type": "object", "properties": { + "id": { + "type": "string" + }, "email": { "type": "string" }, - "status": { - "type": "string", - "enum": ["invited", "failed"], - "description": "'invited' = sent; 'failed' = skipped with a reason." + "name": { + "type": "string" }, - "reason": { + "role": { + "type": "string" + }, + "totpEnabled": { + "type": "boolean", + "description": "Whether an authenticator (TOTP) is activated" + }, + "lastStepUpAt": { "type": "string", - "description": "Failure reason when status is failed." + "nullable": true, + "description": "ISO timestamp of the last successful step-up" } }, - "required": ["email", "status"] + "required": [ + "id", + "email", + "name", + "role", + "totpEnabled", + "lastStepUpAt" + ] }, - "BulkInviteResultDto": { + "MeResponseDto": { "type": "object", "properties": { - "results": { - "type": "array", - "items": { - "$ref": "#/components/schemas/BulkInviteRowResultDto" - } + "staff": { + "$ref": "#/components/schemas/StaffPrincipalDto" + } + }, + "required": ["staff"] + }, + "AnalyticsTotalsDto": { + "type": "object", + "properties": { + "users": { + "type": "number" + }, + "organizations": { + "type": "number" + }, + "programs": { + "type": "number", + "description": "All pillars combined" + }, + "disputes": { + "type": "number" + }, + "wallets": { + "type": "number" + } + }, + "required": [ + "users", + "organizations", + "programs", + "disputes", + "wallets" + ] + }, + "ProgramsByPillarDto": { + "type": "object", + "properties": { + "hackathons": { + "type": "number" }, - "invited": { - "type": "number", - "description": "Count of invitations sent." + "bounties": { + "type": "number" }, - "failed": { - "type": "number", - "description": "Count of rows that failed / were skipped." + "grants": { + "type": "number" + }, + "crowdfunding": { + "type": "number" } }, - "required": ["results", "invited", "failed"] + "required": ["hackathons", "bounties", "grants", "crowdfunding"] }, - "RecommendationThresholdDto": { + "AnalyticsBucketDto": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "hackathonId": { + "label": { "type": "string" }, - "trackId": { - "type": "string", - "nullable": true, - "description": "null = overall threshold; otherwise the scoped track id." - }, - "topPercent": { - "type": "number", - "description": "Top percent (0-100)." + "count": { + "type": "number" } }, - "required": ["id", "hackathonId", "topPercent"] + "required": ["label", "count"] }, - "SetRecommendationThresholdDto": { + "AnalyticsTrendPointDto": { "type": "object", "properties": { - "trackId": { + "date": { "type": "string", - "description": "Track id to scope the threshold to; omit for the overall cut." + "description": "UTC day, YYYY-MM-DD" }, - "topPercent": { - "type": "number", - "description": "Top percent (0-100) of submissions flagged as recommended.", - "minimum": 0, - "maximum": 100, - "example": 10 + "count": { + "type": "number" } }, - "required": ["topPercent"] + "required": ["date", "count"] }, - "RecommendationComputeDiagnosticsDto": { + "AnalyticsDto": { "type": "object", "properties": { - "shortlistedSubmissions": { - "type": "number", - "description": "Submissions currently SHORTLISTED." + "totals": { + "$ref": "#/components/schemas/AnalyticsTotalsDto" }, - "scoredSubmissions": { + "newUsers30d": { "type": "number", - "description": "Shortlisted submissions with at least one counted score (active judge or promoted AI scorecard; advisory AI_ASSIST excluded). These are the only submissions a threshold can rank." + "description": "New users in the last 30 days" }, - "overallThresholdConfigured": { - "type": "boolean", - "description": "Whether an overall (all-submissions) cut is set." + "programsByPillar": { + "$ref": "#/components/schemas/ProgramsByPillarDto" }, - "trackThresholdsConfigured": { - "type": "number", - "description": "Number of per-track cuts configured." + "disputesByStatus": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnalyticsBucketDto" + } }, - "reasons": { - "description": "Human-readable reasons explaining the outcome (e.g. why nothing was flagged). Empty when the compute produced recommendations with nothing outstanding.", - "example": [ - "No recommendation thresholds are configured. Set a top-X% cut (overall or per track), then recompute." - ], + "crowdfundingByStatus": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/AnalyticsBucketDto" + } + }, + "newUsersTrend": { + "description": "New users per day, last 14 days", + "type": "array", + "items": { + "$ref": "#/components/schemas/AnalyticsTrendPointDto" } } }, "required": [ - "shortlistedSubmissions", - "scoredSubmissions", - "overallThresholdConfigured", - "trackThresholdsConfigured", - "reasons" + "totals", + "newUsers30d", + "programsByPillar", + "disputesByStatus", + "crowdfundingByStatus", + "newUsersTrend" ] }, - "RecommendationComputeResultDto": { + "OverviewDto": { "type": "object", "properties": { - "overallRecommended": { - "type": "number", - "description": "Submissions flagged recommendedOverall." + "users": { + "type": "number" }, - "tracks": { - "description": "Per-track recommended counts.", - "example": [ - { - "trackId": "trk_1", - "recommended": 3 - } - ], - "type": "array", - "items": { - "type": "string" - } + "organizations": { + "type": "number" }, - "diagnostics": { - "description": "Why the compute produced what it did, so an empty result is never silent.", - "allOf": [ - { - "$ref": "#/components/schemas/RecommendationComputeDiagnosticsDto" - } - ] + "hackathons": { + "type": "number" + }, + "crowdfundingCampaigns": { + "type": "number" + }, + "openDisputes": { + "type": "number", + "description": "Disputes in OPEN status" } }, - "required": ["overallRecommended", "tracks", "diagnostics"] - }, - "AcceptJudgeInvitationDto": { - "type": "object", - "properties": { - "displayName": { - "type": "string", - "description": "Optional display name override. If omitted, the inviter-provided displayName (or the user’s account name) is used." - } - } + "required": [ + "users", + "organizations", + "hackathons", + "crowdfundingCampaigns", + "openDisputes" + ] }, - "PublishedInfoFormDataDto": { + "AdminUserListItemDto": { "type": "object", "properties": { + "id": { + "type": "string" + }, "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "image": { "type": "string", - "minLength": 3, - "maxLength": 100, - "example": "Web3 Innovation Hackathon" + "nullable": true, + "description": "Profile photo URL, when set" }, - "banner": { + "username": { "type": "string", - "example": "https://example.com/banner.png" + "nullable": true }, - "description": { + "role": { "type": "string", - "minLength": 10, - "maxLength": 5000, - "example": "Build products for the decentralized future." + "nullable": true }, - "categories": { + "status": { + "type": "string", + "enum": ["active", "banned"] + }, + "joined": { + "type": "string", + "description": "ISO timestamp the user joined" + } + }, + "required": [ + "id", + "name", + "email", + "image", + "username", + "role", + "status", + "joined" + ] + }, + "PaginatedUsersDto": { + "type": "object", + "properties": { + "items": { "type": "array", "items": { - "type": "string", - "enum": [ - "DeFi", - "NFTs", - "DAOs", - "Layer 2", - "Cross-chain", - "Web3 Gaming", - "Social Tokens", - "Infrastructure", - "Privacy", - "Sustainability", - "Real World Assets", - "Other" - ] + "$ref": "#/components/schemas/AdminUserListItemDto" } }, - "venueType": { + "page": { + "type": "number" + }, + "limit": { + "type": "number" + }, + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" + } + }, + "required": ["items", "page", "limit", "total", "totalPages"] + }, + "AdminUserDetailDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "image": { "type": "string", - "enum": ["virtual", "physical"], - "example": "virtual" + "nullable": true, + "description": "Profile photo URL, when set" }, - "tagline": { + "username": { "type": "string", - "maxLength": 200, - "example": "Build the future of Web3" + "nullable": true }, - "country": { + "role": { "type": "string", - "example": "Nigeria" + "nullable": true }, - "state": { + "status": { "type": "string", - "example": "Lagos" + "enum": ["active", "banned"] }, - "city": { + "banReason": { "type": "string", - "example": "Ikeja" + "nullable": true, + "description": "Reason, when banned" }, - "venueName": { + "verification": { "type": "string", - "example": "Eko Convention Center" + "nullable": true, + "description": "Identity (KYC) verification status, when known" }, - "venueAddress": { + "walletAddress": { "type": "string", - "example": "Plot 1415 Adetokunbo Ademola St" + "nullable": true, + "description": "Public key of the user's abstracted wallet, when one exists" }, - "slug": { + "organizations": { + "type": "number", + "description": "Number of organizations the user belongs to" + }, + "joined": { "type": "string", - "example": "web3-innovation-hackathon" + "description": "ISO timestamp the user joined" } }, "required": [ + "id", "name", - "banner", - "description", - "categories", - "venueType", - "tagline" + "email", + "image", + "username", + "role", + "status", + "banReason", + "verification", + "walletAddress", + "organizations", + "joined" ] }, - "PublishedSponsorPartnerDto": { + "AdminUserOrganizationDto": { "type": "object", "properties": { "id": { - "type": "string", - "example": "sp-1" + "type": "string" }, "name": { + "type": "string" + }, + "slug": { "type": "string", - "example": "Stellar Foundation" + "nullable": true }, - "logo": { + "role": { "type": "string", - "example": "https://example.com/logo.png" + "description": "The user's role in this organization" }, - "link": { + "joinedAt": { "type": "string", - "example": "https://stellar.org" + "description": "ISO timestamp the user joined the organization" } }, - "required": ["id"] + "required": ["id", "name", "slug", "role", "joinedAt"] }, - "PublishedCollaborationFormDataDto": { + "AdminUserWalletBalanceDto": { "type": "object", "properties": { - "contactEmail": { + "balance": { "type": "string", - "example": "organizer@boundless.dev" + "description": "On-chain balance, as a decimal string" }, - "telegram": { + "assetCode": { "type": "string", - "example": "@boundless" + "description": "Asset code, e.g. XLM or USDC" }, - "discord": { + "assetIssuer": { "type": "string", - "example": "boundless-hackathon" + "nullable": true, + "description": "Asset issuer (null for native XLM)" }, - "socialLinks": { - "example": ["https://x.com/boundless"], - "type": "array", - "items": { - "type": "string" - } + "assetType": { + "type": "string", + "description": "Stellar asset type, e.g. native or credit_alphanum4" }, - "sponsorsPartners": { + "usdValue": { + "type": "number", + "nullable": true, + "description": "Estimated USD value, when priced" + } + }, + "required": [ + "balance", + "assetCode", + "assetIssuer", + "assetType", + "usdValue" + ] + }, + "AdminUserWalletDto": { + "type": "object", + "properties": { + "hasWallet": { + "type": "boolean", + "description": "Whether the user has an abstracted wallet" + }, + "address": { + "type": "string", + "nullable": true, + "description": "Stellar public key (G-address)" + }, + "isActivated": { + "type": "boolean", + "description": "Whether the on-chain account is activated" + }, + "createdAt": { + "type": "string", + "nullable": true, + "description": "ISO timestamp the wallet was created" + }, + "balances": { + "description": "Live on-chain balances. Empty when the account is unfunded or Horizon is unreachable.", "type": "array", "items": { - "$ref": "#/components/schemas/PublishedSponsorPartnerDto" + "$ref": "#/components/schemas/AdminUserWalletBalanceDto" } } }, - "required": ["contactEmail", "socialLinks", "sponsorsPartners"] + "required": [ + "hasWallet", + "address", + "isActivated", + "createdAt", + "balances" + ] }, - "UpdatePublishedHackathonContentDto": { + "BanUserDto": { "type": "object", "properties": { - "information": { - "$ref": "#/components/schemas/PublishedInfoFormDataDto" + "banned": { + "type": "boolean", + "description": "true to ban, false to lift the ban" }, - "collaboration": { - "$ref": "#/components/schemas/PublishedCollaborationFormDataDto" + "reason": { + "type": "string", + "description": "Reason for the ban (recorded in the audit log)" } - } + }, + "required": ["banned"] }, - "PublishedPhaseDto": { + "BanUserResponseDto": { "type": "object", "properties": { - "name": { - "type": "string", - "example": "Building Phase" - }, - "startDate": { - "type": "string", - "example": "2026-04-01T00:00:00.000Z" - }, - "endDate": { - "type": "string", - "example": "2026-04-10T00:00:00.000Z" + "id": { + "type": "string" }, - "description": { - "type": "string", - "example": "Core build phase for teams" + "banned": { + "type": "boolean" } }, - "required": ["name", "startDate", "endDate"] + "required": ["id", "banned"] }, - "PublishedTimelineFormDataDto": { + "AdminOrgListItemDto": { "type": "object", "properties": { - "startDate": { - "type": "string", - "example": "2026-04-01T00:00:00.000Z" + "id": { + "type": "string" }, - "submissionDeadline": { - "type": "string", - "example": "2026-04-15T00:00:00.000Z" + "name": { + "type": "string" }, - "timezone": { + "slug": { "type": "string", - "example": "Africa/Lagos" + "nullable": true }, - "registrationDeadline": { - "type": "string", - "example": "2026-04-02T00:00:00.000Z", - "description": "Optional. When null, registration stays open until submission deadline." + "members": { + "type": "number", + "description": "Member count" }, - "judgingDeadline": { + "programs": { + "type": "number", + "description": "Programs run by the org (hackathons + bounties)" + }, + "suspendedAt": { "type": "string", - "example": "2026-04-18T00:00:00.000Z", - "description": "Optional judging deadline. When null, no judging phase is rendered on the timeline." + "nullable": true, + "description": "ISO timestamp the org was suspended, or null if active" }, - "phases": { + "created": { + "type": "string", + "description": "ISO timestamp the org was created" + } + }, + "required": [ + "id", + "name", + "slug", + "members", + "programs", + "suspendedAt", + "created" + ] + }, + "PaginatedOrganizationsDto": { + "type": "object", + "properties": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/PublishedPhaseDto" + "$ref": "#/components/schemas/AdminOrgListItemDto" } + }, + "page": { + "type": "number" + }, + "limit": { + "type": "number" + }, + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" } - } + }, + "required": ["items", "page", "limit", "total", "totalPages"] }, - "PublishedParticipantFormDataDto": { + "AdminOrgDetailDto": { "type": "object", "properties": { - "participantType": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "slug": { "type": "string", - "enum": ["individual", "team", "team_or_individual"] + "nullable": true }, - "teamMin": { + "members": { "type": "number", - "minimum": 1, - "maximum": 20, - "example": 2 + "description": "Member count" }, - "teamMax": { + "hackathons": { "type": "number", - "minimum": 1, - "maximum": 20, - "example": 5 + "description": "Hackathons run by the org" }, - "maxParticipants": { + "bounties": { "type": "number", - "minimum": 1, - "example": 200, - "description": "Optional cap on total participants. null = unlimited. Can be updated after publishing." + "description": "Bounties run by the org" }, - "require_github": { - "type": "boolean", - "example": true + "suspendedAt": { + "type": "string", + "nullable": true, + "description": "ISO timestamp the org was suspended, or null if active" }, - "require_demo_video": { - "type": "boolean", - "example": false + "suspendedByEmail": { + "type": "string", + "nullable": true }, - "require_other_links": { - "type": "boolean", - "example": true + "suspensionReason": { + "type": "string", + "nullable": true }, - "detailsTab": { - "type": "boolean" + "created": { + "type": "string", + "description": "ISO timestamp the org was created" + } + }, + "required": [ + "id", + "name", + "slug", + "members", + "hackathons", + "bounties", + "suspendedAt", + "suspendedByEmail", + "suspensionReason", + "created" + ] + }, + "UpdateOrgDto": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 2, + "maxLength": 200 }, - "participantsTab": { - "type": "boolean" + "slug": { + "type": "string", + "description": "URL slug (lowercase letters, numbers, hyphens)" }, - "resourcesTab": { - "type": "boolean" + "logo": { + "type": "string", + "description": "Logo URL" }, - "submissionTab": { - "type": "boolean" + "announcementsEnabled": { + "type": "boolean", + "description": "Whether org announcements are enabled" + } + } + }, + "OrgActionResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string" }, - "announcementsTab": { - "type": "boolean" + "name": { + "type": "string" }, - "discussionTab": { - "type": "boolean" + "slug": { + "type": "string", + "nullable": true }, - "winnersTab": { + "announcementsEnabled": { "type": "boolean" + } + }, + "required": ["id", "name", "slug", "announcementsEnabled"] + }, + "SuspendOrgDto": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "Why the organization is being suspended (shown in audit log)", + "minLength": 3, + "maxLength": 500 + } + }, + "required": ["reason"] + }, + "OrgSuspensionResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string" }, - "sponsorsTab": { - "type": "boolean" + "name": { + "type": "string" }, - "joinATeamTab": { - "type": "boolean" + "slug": { + "type": "string", + "nullable": true }, - "rulesTab": { - "type": "boolean" + "suspendedAt": { + "type": "string", + "nullable": true, + "description": "ISO timestamp the org was suspended, or null if active" + }, + "suspensionReason": { + "type": "string", + "nullable": true } }, - "required": ["participantType"] + "required": ["id", "name", "slug", "suspendedAt", "suspensionReason"] }, - "UpdatePublishedHackathonScheduleDto": { + "ReinstateOrgDto": { "type": "object", "properties": { - "timeline": { - "$ref": "#/components/schemas/PublishedTimelineFormDataDto" - }, - "participation": { - "$ref": "#/components/schemas/PublishedParticipantFormDataDto" + "note": { + "type": "string", + "description": "Optional note recorded with the reinstatement", + "maxLength": 500 } } }, - "PublishedPrizeTierDto": { + "AdminProgramListItemDto": { "type": "object", "properties": { "id": { - "type": "string", - "example": "tier-1" + "type": "string" }, - "place": { + "type": { "type": "string", - "example": "1st Place" + "enum": ["hackathon", "bounty", "grant", "crowdfunding"] }, - "prizeAmount": { - "type": "string", - "example": "5000" + "title": { + "type": "string" }, - "currency": { + "status": { "type": "string", - "example": "USDC" + "description": "Pillar-specific lifecycle status" }, - "description": { + "organization": { "type": "string", - "example": "Top overall project" - }, - "rank": { - "type": "number", - "minimum": 1, - "example": 1, - "description": "Display rank / ordering of the tier (1 = highest)" - }, - "passMark": { - "type": "number", - "minimum": 0, - "maximum": 100, - "example": 70 + "nullable": true, + "description": "Owning organization name, when the pillar has one" }, - "kind": { - "type": "string", - "enum": ["OVERALL", "TRACK"] + "isFeatured": { + "type": "boolean", + "description": "Marketplace featured boost (always false for pillars without it)" }, - "trackId": { + "created": { "type": "string", - "description": "Required when kind=TRACK. References a HackathonTrack id." + "description": "ISO timestamp the program was created" } }, - "required": ["id", "place", "prizeAmount", "passMark"] + "required": [ + "id", + "type", + "title", + "status", + "organization", + "isFeatured", + "created" + ] }, - "PublishedRewardsFormDataDto": { + "PaginatedProgramsDto": { "type": "object", "properties": { - "prizeTiers": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PublishedPrizeTierDto" - } - }, - "prizes": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/PrizeWriteDto" + "$ref": "#/components/schemas/AdminProgramListItemDto" } }, - "winnerOverrides": { - "type": "object", - "example": { - "sub-1": 1, - "sub-2": 2 - }, - "description": "Manual winner assignments override (submissionId -> rank)", - "additionalProperties": { - "type": "number" - } + "page": { + "type": "number" }, - "prizeStructure": { - "type": "string", - "enum": ["OVERALL_ONLY", "OVERALL_AND_TRACKS", "TRACKS_ONLY"] + "limit": { + "type": "number" }, - "tracksMaxPerSubmission": { - "type": "number", - "minimum": 1, - "maximum": 20 + "total": { + "type": "number" }, - "allowWinnerStacking": { - "type": "boolean" - } - } - }, - "UpdatePublishedHackathonFinancialDto": { - "type": "object", - "properties": { - "rewards": { - "$ref": "#/components/schemas/PublishedRewardsFormDataDto" + "totalPages": { + "type": "number" } }, - "required": ["rewards"] + "required": ["items", "page", "limit", "total", "totalPages"] }, - "AdvancedSettingsFormDataDto": { + "AdminProgramDetailDto": { "type": "object", "properties": { - "isPublic": { - "type": "boolean", - "example": true + "id": { + "type": "string" }, - "allowLateRegistration": { - "type": "boolean", - "example": false + "type": { + "type": "string", + "enum": ["hackathon", "bounty", "grant", "crowdfunding"] }, - "requireApproval": { - "type": "boolean", - "example": true + "title": { + "type": "string" }, - "maxParticipants": { - "type": "number", - "minimum": 1, - "maximum": 100000, - "example": 500 + "status": { + "type": "string" }, - "customDomain": { + "organization": { "type": "string", - "example": "hackathons.boundless.dev" - }, - "enableDiscord": { - "type": "boolean", - "example": true + "nullable": true }, - "discordInviteLink": { + "description": { "type": "string", - "example": "https://discord.gg/boundless" - }, - "enableTelegram": { - "type": "boolean", - "example": true + "nullable": true }, - "telegramInviteLink": { + "created": { "type": "string", - "example": "https://t.me/boundless" + "description": "ISO timestamp the program was created" } }, "required": [ - "isPublic", - "allowLateRegistration", - "requireApproval", - "enableDiscord", - "enableTelegram" + "id", + "type", + "title", + "status", + "organization", + "description", + "created" ] }, - "UpdatePublishedHackathonAdvancedSettingsDto": { - "type": "object", - "properties": { - "advancedSettings": { - "$ref": "#/components/schemas/AdvancedSettingsFormDataDto" - } - }, - "required": ["advancedSettings"] - }, - "SetHackathonAccessDto": { + "SetFeaturedDto": { "type": "object", "properties": { - "visibility": { + "type": { "type": "string", - "enum": ["PUBLIC", "PRIVATE"] + "enum": ["hackathon", "bounty", "grant", "crowdfunding"], + "description": "Which pillar the id is in." }, - "password": { - "type": "string", - "description": "Access password. Required when first making a hackathon private; ignored (cleared) when visibility is PUBLIC." + "featured": { + "type": "boolean", + "description": "Feature (true) or unfeature (false) the program." } }, - "required": ["visibility"] + "required": ["type", "featured"] }, - "InvitePartnerDto": { + "ProgramActionResponseDto": { "type": "object", "properties": { - "partnerEmail": { - "type": "string", - "example": "sponsor@partner.io" - }, - "partnerName": { - "type": "string", - "example": "Acme Corp" - }, - "partnerLogo": { - "type": "string", - "example": "https://cdn.example.com/logo.png" - }, - "partnerLink": { - "type": "string", - "example": "https://acme.io" - }, - "pledgedAmount": { - "type": "number", - "example": 1000, - "description": "Pledged amount in USDC" + "id": { + "type": "string" }, - "currency": { + "type": { "type": "string", - "example": "USDC", - "default": "USDC" + "enum": ["hackathon", "bounty", "grant", "crowdfunding"] }, - "message": { + "status": { "type": "string", - "description": "Optional message included in the invite" + "description": "Status after the action" }, - "showPublicly": { + "isFeatured": { "type": "boolean", - "description": "Whether the partner is shown publicly on the hackathon page", - "default": true + "description": "Whether the program is featured (false if unsupported)" } }, - "required": ["partnerEmail", "partnerName", "pledgedAmount"] + "required": ["id", "type", "status", "isFeatured"] }, - "AllocationTargetDto": { + "SetProgramStatusDto": { "type": "object", "properties": { - "placementId": { + "type": { "type": "string", - "description": "PrizePlacement id (the fundable slot) this allocation adds to. Placements are created in the Rewards step." + "enum": ["hackathon", "bounty", "grant", "crowdfunding"], + "description": "Which pillar the id is in." }, - "amount": { - "type": "number", - "description": "Net amount (USDC) to add to the placement" - } - }, - "required": ["placementId", "amount"] - }, - "AllocateContributionDto": { - "type": "object", - "properties": { - "targets": { - "description": "One or more tiers to allocate this contribution into", - "type": "array", - "items": { - "$ref": "#/components/schemas/AllocationTargetDto" - } - } - }, - "required": ["targets"] - }, - "PrepareFundTransactionDto": { - "type": "object", - "properties": { - "signerAddress": { - "type": "string", - "description": "Stellar address of the partner wallet that will sign the transaction" - } - }, - "required": ["signerAddress"] - }, - "SubmitSignedTransactionDto": { - "type": "object", - "properties": { - "signedXdr": { + "status": { "type": "string", - "description": "Signed transaction XDR returned by the partner wallet" + "description": "Target lifecycle status. Must be one of the admin-settable states for the pillar (archive/suspend/cancel-type)." } }, - "required": ["signedXdr"] + "required": ["type", "status"] }, - "TrackCustomQuestionDto": { + "AdminDisputeListItemDto": { "type": "object", "properties": { "id": { + "type": "string" + }, + "campaign": { "type": "string", - "description": "Stable id, unique within the track." + "nullable": true, + "description": "Title of the campaign the dispute is against" }, - "label": { + "reason": { "type": "string", - "description": "Question label shown on the submission form." + "description": "Reported reason" }, - "type": { + "status": { "type": "string", - "enum": ["short", "long", "url"], - "description": "Input type. 'short' = single-line, 'long' = textarea, 'url' = URL field." + "description": "Dispute lifecycle status" }, - "maxLength": { - "type": "number", - "description": "Optional maxLength override (defaults: short=200, long=1000)." + "reportedBy": { + "type": "string", + "nullable": true, + "description": "Reporter name" }, - "required": { - "type": "boolean", - "description": "Whether an answer is required." + "assignedTo": { + "type": "string", + "nullable": true, + "description": "Assigned staff name, when assigned" + }, + "created": { + "type": "string", + "description": "ISO timestamp the dispute was opened" } }, - "required": ["id", "label", "type"] + "required": [ + "id", + "campaign", + "reason", + "status", + "reportedBy", + "assignedTo", + "created" + ] }, - "TrackRequiredArtifactDto": { + "PaginatedDisputesDto": { "type": "object", "properties": { - "id": { - "type": "string", - "description": "Stable id, unique within the track." + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminDisputeListItemDto" + } }, - "label": { - "type": "string", - "description": "Artifact label (e.g. \"Figma file URL\")." + "page": { + "type": "number" }, - "type": { - "type": "string", - "enum": ["figma", "github", "video", "pdf", "url"], - "description": "Artifact type — drives the placeholder + light hint UI." + "limit": { + "type": "number" }, - "required": { - "type": "boolean", - "description": "Whether submitting this artifact is required." + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" } }, - "required": ["id", "label", "type"] + "required": ["items", "page", "limit", "total", "totalPages"] }, - "TrackResponseDto": { + "AdminDisputeDetailDto": { "type": "object", "properties": { "id": { "type": "string" }, - "hackathonId": { - "type": "string" + "campaign": { + "type": "string", + "nullable": true }, - "slug": { + "reason": { "type": "string" }, - "name": { + "status": { "type": "string" }, "description": { "type": "string" }, - "type": { - "type": "string" - }, - "eligibility": { - "type": "string", - "enum": ["OPT_IN", "OPEN"] - }, - "displayOrder": { - "type": "number" - }, - "isArchived": { - "type": "boolean" - }, - "entryCount": { - "type": "number", - "description": "Count of submissions that have opted into this track. Useful for organizer dashboards." - }, - "prompt": { + "milestone": { "type": "string", - "description": "Per-track customization (Phase B)." + "nullable": true, + "description": "Title of the disputed milestone, if the dispute names one" }, - "customQuestions": { + "evidenceLinks": { + "description": "Evidence links the reporter provided", "type": "array", "items": { - "$ref": "#/components/schemas/TrackCustomQuestionDto" + "type": "string" } }, - "requiredArtifacts": { + "evidenceFiles": { + "description": "Evidence file references the reporter provided", "type": "array", "items": { - "$ref": "#/components/schemas/TrackRequiredArtifactDto" + "type": "string" } }, - "createdAt": { - "format": "date-time", - "type": "string" + "reportedBy": { + "type": "string", + "nullable": true }, - "updatedAt": { - "format": "date-time", - "type": "string" + "assignedTo": { + "type": "string", + "nullable": true, + "description": "Assigned staff email, when assigned" + }, + "assignedToStaffId": { + "type": "string", + "nullable": true, + "description": "Assigned staff id (for pre-selecting the assignee)" + }, + "resolution": { + "type": "string", + "nullable": true, + "description": "Resolution outcome" + }, + "resolutionNotes": { + "type": "string", + "nullable": true + }, + "created": { + "type": "string", + "description": "ISO timestamp the dispute was opened" } }, "required": [ "id", - "hackathonId", - "slug", - "name", - "eligibility", - "displayOrder", - "isArchived", - "entryCount", - "createdAt", - "updatedAt" + "campaign", + "reason", + "status", + "description", + "milestone", + "evidenceLinks", + "evidenceFiles", + "reportedBy", + "assignedTo", + "assignedToStaffId", + "resolution", + "resolutionNotes", + "created" ] }, - "CustomQuestionResponseDto": { + "DisputeAssignmentResponseDto": { "type": "object", "properties": { "id": { "type": "string" }, - "hackathonId": { - "type": "string" - }, - "scope": { + "assignedTo": { "type": "string", - "enum": ["REGISTRATION", "SUBMISSION"] - }, - "label": { - "type": "string" + "nullable": true, + "description": "Assigned staff email, or null when unassigned" }, - "helpText": { + "assignedAt": { "type": "string", "nullable": true - }, - "type": { + } + }, + "required": ["id", "assignedTo", "assignedAt"] + }, + "NoteDisputeDto": { + "type": "object", + "properties": { + "note": { "type": "string", - "enum": [ - "SHORT", - "LONG", - "URL", - "SINGLE_SELECT", - "MULTI_SELECT", - "BOOLEAN" - ] - }, - "required": { - "type": "boolean" - }, - "options": { - "nullable": true, - "type": "array", - "items": { - "type": "string" - } + "description": "Internal note recorded on the dispute audit trail.", + "minLength": 1, + "maxLength": 2000 + } + }, + "required": ["note"] + }, + "DisputeNoteResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string" }, - "maxLength": { - "type": "number", - "nullable": true + "note": { + "type": "string" }, - "displayOrder": { - "type": "number" + "createdAt": { + "type": "string", + "description": "ISO timestamp the note was recorded" } }, - "required": [ - "id", - "hackathonId", - "scope", - "label", - "type", - "required", - "displayOrder" - ] + "required": ["id", "note", "createdAt"] }, - "UpdateTracksConfigDto": { + "DisputeActionResponseDto": { "type": "object", "properties": { - "tracksMaxPerSubmission": { - "type": "number", - "minimum": 1, - "maximum": 20, - "description": "Max number of tracks a single submission may enter (1-20)." + "id": { + "type": "string" + }, + "status": { + "type": "string", + "description": "New dispute lifecycle status" + }, + "resolution": { + "type": "string", + "nullable": true, + "description": "Resolution outcome, when resolved" + }, + "escalatedToArbitration": { + "type": "boolean", + "description": "Whether the dispute is escalated to arbitration" } - } + }, + "required": ["id", "status", "resolution", "escalatedToArbitration"] }, - "CreateTrackDto": { + "AdminMoneyEntryDto": { "type": "object", "properties": { - "name": { - "type": "string", - "description": "Human-readable track name shown on the hackathon page.", - "example": "Best UI/UX" + "id": { + "type": "string" }, - "slug": { + "kind": { "type": "string", - "description": "URL-safe handle, unique within the hackathon. Auto-generated from name if omitted.", - "example": "best-ui-ux" + "enum": ["escrow", "payout"] }, - "description": { + "reference": { "type": "string", - "description": "Short blurb shown in the track picker and on results.", - "example": "Best end-to-end user experience and visual polish." + "description": "On-chain reference: tx hash or destination key" }, - "type": { + "label": { "type": "string", - "description": "Free-form classifier for badge styling. Common values: skill, technology, theme, special.", - "example": "skill" + "description": "What the movement is (tx type, or \"Payout\")" }, - "eligibility": { + "amount": { "type": "string", - "description": "OPT_IN (default): submitters explicitly enter. OPEN: every submission auto-eligible.", - "enum": ["OPT_IN", "OPEN"], - "default": "OPT_IN" + "description": "Amount, as a precise string" }, - "displayOrder": { - "type": "number", - "description": "Sort order. Lower numbers render first. Defaults to 0.", - "example": 10 + "currency": { + "type": "string", + "nullable": true, + "description": "Currency, if known" }, - "prompt": { + "status": { "type": "string", - "description": "Single open-ended prompt shown on the submission form. When set, the submitter must answer to opt in.", - "example": "Why does this project fit Best UI/UX?" + "description": "Settlement status" }, - "customQuestions": { + "created": { + "type": "string", + "description": "ISO timestamp the movement was created" + } + }, + "required": [ + "id", + "kind", + "reference", + "label", + "amount", + "currency", + "status", + "created" + ] + }, + "PaginatedMoneyDto": { + "type": "object", + "properties": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/TrackCustomQuestionDto" + "$ref": "#/components/schemas/AdminMoneyEntryDto" } }, - "requiredArtifacts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TrackRequiredArtifactDto" - } + "page": { + "type": "number" + }, + "limit": { + "type": "number" + }, + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" } }, - "required": ["name"] + "required": ["items", "page", "limit", "total", "totalPages"] }, - "UpdateTrackDto": { + "EscrowRequestDto": { "type": "object", "properties": { - "name": { + "id": { "type": "string" }, - "slug": { - "type": "string" + "kind": { + "type": "string", + "enum": ["release", "refund"] }, - "description": { + "campaignId": { "type": "string" }, - "type": { - "type": "string" + "milestoneId": { + "type": "string", + "nullable": true }, - "eligibility": { + "amount": { "type": "string", - "enum": ["OPT_IN", "OPEN"] + "description": "Amount as a string (decimal-safe)" }, - "displayOrder": { - "type": "number" + "currency": { + "type": "string" }, - "isArchived": { - "type": "boolean", - "description": "Soft-archive instead of delete when entries already exist. Cannot be unset via this endpoint; recreate the track if needed." + "toAddress": { + "type": "string", + "nullable": true }, - "prompt": { + "reason": { "type": "string", - "description": "Single open-ended prompt." + "nullable": true }, - "customQuestions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TrackCustomQuestionDto" - } + "status": { + "type": "string", + "description": "PROPOSED | APPROVED | REJECTED | EXECUTED" }, - "requiredArtifacts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TrackRequiredArtifactDto" - } - } - } - }, - "CustomQuestionWriteDto": { - "type": "object", - "properties": { - "scope": { + "proposedBy": { "type": "string", - "enum": ["REGISTRATION", "SUBMISSION"] + "description": "Maker email" }, - "label": { + "decidedBy": { "type": "string", - "description": "Question shown to the participant." + "nullable": true, + "description": "Checker email" }, - "helpText": { + "decidedAt": { "type": "string", - "description": "Optional helper text under the field." + "nullable": true }, - "type": { + "decisionNote": { "type": "string", - "enum": [ - "SHORT", - "LONG", - "URL", - "SINGLE_SELECT", - "MULTI_SELECT", - "BOOLEAN" - ], - "default": "SHORT" + "nullable": true }, - "required": { - "type": "boolean", - "description": "Whether an answer is required." + "txHash": { + "type": "string", + "nullable": true, + "description": "Settled tx hash" }, - "options": { - "description": "Choices for SINGLE_SELECT / MULTI_SELECT.", - "type": "array", - "items": { - "type": "string" - } + "executedBy": { + "type": "string", + "nullable": true }, - "maxLength": { - "type": "number", - "description": "Optional length cap for SHORT / LONG answers." + "executedAt": { + "type": "string", + "nullable": true }, - "displayOrder": { - "type": "number", - "description": "Sort order; lower renders first." + "created": { + "type": "string" } }, - "required": ["scope", "label", "type"] + "required": [ + "id", + "kind", + "campaignId", + "milestoneId", + "amount", + "currency", + "toAddress", + "reason", + "status", + "proposedBy", + "decidedBy", + "decidedAt", + "decisionNote", + "txHash", + "executedBy", + "executedAt", + "created" + ] }, - "UpsertCustomQuestionsDto": { + "EscrowRequestListResponseDto": { "type": "object", "properties": { - "questions": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/CustomQuestionWriteDto" + "$ref": "#/components/schemas/EscrowRequestDto" } } }, - "required": ["questions"] + "required": ["items"] }, - "RequestFundingOtpResponseDto": { + "ProposeEscrowRequestDto": { "type": "object", "properties": { - "required": { - "type": "boolean", - "description": "Whether funding step-up is enforced for this action" + "kind": { + "type": "string", + "enum": ["release", "refund"] }, - "alreadyVerified": { - "type": "boolean", - "description": "True when a recent verification is still valid; the client can fund without entering a new code" + "campaignId": { + "type": "string", + "description": "Campaign whose escrow is being acted on" }, - "sent": { - "type": "boolean", - "description": "True when a fresh code was just emailed" + "milestoneId": { + "type": "string", + "description": "Milestone id, for a milestone release" }, - "expiresInSeconds": { + "amount": { "type": "number", - "description": "Seconds until the emailed code expires (0 when none sent)" - } - }, - "required": ["required", "alreadyVerified", "sent", "expiresInSeconds"] - }, - "VerifyFundingOtpDto": { - "type": "object", - "properties": { - "code": { + "description": "Amount to move" + }, + "currency": { "type": "string", - "description": "The 6-digit code emailed to the organizer", - "example": "123456" + "default": "USDC" + }, + "toAddress": { + "type": "string", + "description": "Destination address (for a release)" + }, + "reason": { + "type": "string", + "description": "Why the funds are being moved" } }, - "required": ["code"] + "required": ["kind", "campaignId", "amount"] }, - "VerifyFundingOtpResponseDto": { + "DecideEscrowRequestDto": { "type": "object", "properties": { - "verified": { - "type": "boolean", - "description": "True when the code was accepted" + "decision": { + "type": "string", + "enum": ["approve", "reject"] }, - "expiresInSeconds": { - "type": "number", - "description": "Seconds the funding authorization remains valid" + "note": { + "type": "string", + "description": "Note recorded with the decision" } }, - "required": ["verified", "expiresInSeconds"] + "required": ["decision"] }, - "WinnerDistributionEntryDto": { + "ExecuteEscrowRequestDto": { "type": "object", "properties": { - "position": { - "type": "number", - "description": "Winner position (1-indexed; 1 = top winner).", - "example": 1, - "minimum": 1 - }, - "percent": { - "type": "number", - "description": "Percentage of the total budget allocated to this position. All entries must sum to exactly 100.", - "example": 100, - "minimum": 1 + "txHash": { + "type": "string", + "description": "Hash of the settled, offline-signed release/refund tx" } }, - "required": ["position", "percent"] + "required": ["txHash"] }, - "PublishHackathonEscrowDto": { + "PayoutRequestDto": { "type": "object", "properties": { - "ownerAddress": { - "type": "string", - "description": "Stellar G-address that will own and sign the on-chain create_event transaction. For managed wallets, this is the platform-derived address tied to the organizer's account; for connected/multisig, it's the org treasury's G-address.", - "example": "GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ" + "id": { + "type": "string" }, - "tokenAddress": { - "type": "string", - "description": "Stellar Asset Contract (SAC) address the prize pool is denominated in. Must be whitelisted on the events contract (see admin runbook).", - "example": "CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA" + "destinationPublicKey": { + "type": "string" }, - "budget": { + "amount": { "type": "string", - "description": "Total prize budget in token-native units (e.g. 1000 = 1000 USDC, NOT stroops). Use a string when the value exceeds JavaScript's safe integer range. The backend converts to stroops via *10^7.", - "example": "1000" + "description": "Amount as a string (decimal-safe)" }, - "winnerDistribution": { - "description": "Optional override for the winner distribution. Each entry maps a position to a percent of total_budget. Percents must sum to exactly 100. Defaults to a single winner at position 1 taking 100%.", - "type": "array", - "items": { - "$ref": "#/components/schemas/WinnerDistributionEntryDto" - } + "currency": { + "type": "string" }, - "contentUri": { + "memo": { "type": "string", - "description": "Override for the public content_uri the contract stores against the event. Defaults to https://api.boundless.fi/hackathons//content.", - "example": "https://api.boundless.fi/hackathons/abc/content", - "maxLength": 512 + "nullable": true }, - "fundingMode": { + "memoType": { "type": "string", - "description": "Signing path. Defaults to EXTERNAL (return unsigned XDR for the caller to sign). Set to MANAGED to have the backend sign + submit using the caller user's managed wallet; the response carries the op in PENDING_CONFIRM with a txHash.", - "enum": ["EXTERNAL", "MANAGED"], - "default": "EXTERNAL", - "example": "MANAGED" + "nullable": true }, - "sourceWalletId": { - "type": "string", - "description": "For MANAGED funding, the organization treasury wallet to fund from. When set, the backend signs with that treasury (managed) wallet instead of the caller's personal wallet; ownerAddress must match the treasury wallet address. Omit to fund from the personal managed wallet." - } - }, - "required": ["ownerAddress", "tokenAddress", "budget"] - }, - "HackathonEscrowOpResponseDto": { - "type": "object", - "properties": { - "id": { + "reason": { "type": "string", - "description": "Internal uuid for the EscrowOp row. Use this for follow-up calls.", - "example": "cmpwiox7u0000yy4404ojbk9t" + "nullable": true }, - "opId": { + "status": { "type": "string", - "description": "Hex-encoded 32-byte op_id derived deterministically from the operation parameters. Used by the on-chain idempotency check.", - "example": "3cc257d743b1b44423dc8dbd417aedfe6e47ad489b5d301a2fbec5284d36de1c" + "description": "PROPOSED | APPROVED | AWAITING_SIGNATURE | REJECTED | EXECUTED" }, - "kind": { + "sourcePublicKey": { "type": "string", - "description": "Contract operation kind.", - "enum": [ - "CREATE_EVENT", - "CANCEL_EVENT", - "ADD_FUNDS", - "APPLY_TO_BOUNTY", - "WITHDRAW_APPLICATION", - "SUBMIT", - "WITHDRAW_SUBMISSION", - "SELECT_WINNERS", - "CLAIM_MILESTONE" - ], - "example": "CREATE_EVENT" + "nullable": true, + "description": "Platform source address the payout is sent from" }, - "status": { + "unsignedXdr": { "type": "string", - "description": "Status of the EscrowOp in its lifecycle.", - "enum": [ - "PENDING_BUILD", - "PENDING_SIGN", - "PENDING_SUBMIT", - "PENDING_CONFIRM", - "COMPLETED", - "FAILED", - "CANCELLED" - ], - "example": "PENDING_SIGN" + "nullable": true, + "description": "Unsigned XDR awaiting an offline signature (when AWAITING_SIGNATURE)" }, - "entityKind": { + "proposedBy": { "type": "string", - "description": "Entity kind the op operates on. Matches the application-level row (hackathon, bounty, grant, etc.).", - "example": "HACKATHON" + "description": "Maker email" }, - "entityId": { + "decidedBy": { "type": "string", - "description": "Application-level row id this op acts on.", - "example": "cmpwihilf0000fd44iln3dzbg" + "nullable": true, + "description": "Checker email" }, - "unsignedXdr": { + "decidedAt": { "type": "string", - "nullable": true, - "description": "Unsigned XDR transaction the wallet must sign. Present after the build phase completes (PENDING_SIGN onwards).", - "example": "AAAAAgAAAACdiamX7q...truncated..." + "nullable": true }, - "signerHint": { + "decisionNote": { "type": "string", - "nullable": true, - "description": "Stellar G-address expected to sign this op. The wallet routing layer on the webapp uses this to pick the right signer.", - "example": "GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ" + "nullable": true }, "txHash": { "type": "string", "nullable": true, - "description": "Soroban tx hash assigned at submit time. Set once the op reaches PENDING_CONFIRM or beyond.", - "example": "daafec9027da007b54eec34c54a5919edd7a8682bc96ccf7c7072982305cfa3b" + "description": "Settled tx hash" }, - "errorCode": { + "executedBy": { "type": "string", - "nullable": true, - "description": "Contract error code when the op transitions to FAILED. Mirrors the on-chain error name (e.g. \"InsufficientEscrow\", \"OpAlreadySeen\", \"txBadAuth\").", - "example": "txBadAuth" + "nullable": true }, - "createdAt": { - "format": "date-time", + "executedAt": { "type": "string", - "description": "Row creation time.", - "example": "2026-06-02T11:45:36.927Z" + "nullable": true }, - "updatedAt": { - "format": "date-time", - "type": "string", - "description": "Row last-updated time.", - "example": "2026-06-02T11:45:44.310Z" + "created": { + "type": "string" } }, "required": [ "id", - "opId", - "kind", + "destinationPublicKey", + "amount", + "currency", + "memo", + "memoType", + "reason", "status", - "entityKind", - "entityId", - "createdAt", - "updatedAt" + "sourcePublicKey", + "unsignedXdr", + "proposedBy", + "decidedBy", + "decidedAt", + "decisionNote", + "txHash", + "executedBy", + "executedAt", + "created" ] }, - "CancelHackathonEscrowDto": { + "PayoutRequestListResponseDto": { "type": "object", "properties": { - "ownerAddress": { - "type": "string", - "description": "Organizer's Stellar G-address. Must match the on-chain hackathon owner.", - "example": "GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ" - }, - "fundingMode": { - "type": "string", - "description": "Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side with the caller's platform-held wallet.", - "enum": ["EXTERNAL", "MANAGED"], - "default": "EXTERNAL" - }, - "sourceWalletId": { - "type": "string", - "description": "For MANAGED, the organization treasury wallet to sign with (the event contract-auth identity). ownerAddress must match it. Omit to use the caller's personal managed wallet." + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PayoutRequestDto" + } } }, - "required": ["ownerAddress"] + "required": ["items"] }, - "HackathonWinnerSelectionDto": { + "ProposePayoutRequestDto": { "type": "object", "properties": { - "submissionId": { + "destinationPublicKey": { "type": "string", - "description": "ID of the winning submission. The payout recipient is resolved server-side = the submitter's (team leader's) Boundless managed wallet; no on-chain submission anchor is required.", - "example": "cmq7sgwst0001abcd1234efgh" + "description": "Stellar destination address (G…)" }, - "position": { - "type": "number", - "description": "Winner position, 1-indexed. Must exist in the hackathon's on-chain winner_distribution.", - "example": 1, - "minimum": 1 + "sourcePublicKey": { + "type": "string", + "description": "Platform Stellar source address (G…) the payout is sent FROM. Defaults to the configured platform payout wallet (PLATFORM_ADDRESS)." }, - "creditEarn": { + "amount": { "type": "number", - "description": "Override the platform default credit_earn for this position. Defaults to 20/10/5 for positions 1/2/3 and 3 for the rest. Capped at 100 by the contract.", - "minimum": 0, - "maximum": 100, - "example": 20 + "description": "Amount to send" }, - "reputationBump": { - "type": "number", - "description": "Override the platform default reputation_bump for this position. Defaults to 50/25/10 for positions 1/2/3 and 5 for the rest.", - "minimum": 0, - "example": 50 - } - }, - "required": ["submissionId", "position"] - }, - "SelectHackathonWinnersDto": { - "type": "object", - "properties": { - "ownerAddress": { + "currency": { "type": "string", - "description": "Organizer's Stellar G-address — a hint only. select_winners is authorized by the event manager resolved on-chain (the org treasury for new events), which the backend signs with server-side; this value is used only as a fallback when that on-chain read is unavailable (legacy/pre-upgrade events). Omit for the MANAGED flow.", - "example": "GDVGP7DWODFVYQ5NHHLLD3WFVLUH5Y3HHELIKSNO4STEFCBETQAWDMKZ" + "default": "USDC" }, - "selections": { - "description": "Winners to declare, each by winning submissionId + position. The payout recipient is resolved server-side = the submitter's (team leader's) Boundless managed wallet; no on-chain submission anchor is required. Positions and submissionIds must be unique within the array.", - "type": "array", - "items": { - "$ref": "#/components/schemas/HackathonWinnerSelectionDto" - } + "memo": { + "type": "string", + "description": "Optional memo (required by some exchanges)" }, - "fundingMode": { + "memoType": { "type": "string", - "description": "Signing path. EXTERNAL (default) returns unsigned XDR; MANAGED signs server-side.", - "enum": ["EXTERNAL", "MANAGED"], - "default": "EXTERNAL" + "enum": ["text", "id"] }, - "sourceWalletId": { + "reason": { "type": "string", - "description": "For MANAGED, the organization treasury wallet to sign with (the event contract-auth identity). ownerAddress must match it. Omit to use the caller's personal managed wallet." + "description": "Why the payout is being sent" } }, - "required": ["selections"] + "required": ["destinationPublicKey", "amount"] }, - "HackathonSubmitSignedXdrDto": { + "DecidePayoutRequestDto": { "type": "object", "properties": { - "signedXdr": { + "decision": { "type": "string", - "description": "The fully-signed XDR returned by the wallet (Freighter, Albedo, platform-managed signer, or a multisig coordinator). Backend submits this verbatim to Soroban RPC.", - "example": "AAAAAgAAAACdiamX7q...truncated..." + "enum": ["approve", "reject"] + }, + "note": { + "type": "string", + "description": "Note recorded with the decision" } }, - "required": ["signedXdr"] + "required": ["decision"] }, - "SubmitHackathonDto": { + "BuildXdrResponseDto": { "type": "object", "properties": { - "applicantAddress": { + "unsignedXdr": { "type": "string", - "description": "Caller's Stellar G-address. Must match the caller's linked wallet.", - "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" + "description": "Unsigned transaction XDR to sign offline (Stellar Lab / hardware / multisig)." }, - "fundingMode": { + "network": { "type": "string", - "description": "Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet.", - "enum": ["EXTERNAL", "MANAGED"], - "default": "EXTERNAL" + "description": "Network the transaction targets.", + "enum": ["public", "testnet"] }, - "contentUri": { + "passphrase": { "type": "string", - "description": "On-chain content URI for the submission. Stored verbatim in the contract's submission anchor; off-chain content lives wherever the URI points (IPFS, S3, GitHub PR, etc.).", - "example": "ipfs://Qm.../project.json", - "minLength": 1, - "maxLength": 1024 + "description": "Network passphrase to select when signing." + }, + "source": { + "type": "string", + "description": "Source G-address that must sign this transaction." + }, + "labUrl": { + "type": "string", + "description": "Deep-link to the Stellar Lab Sign Transaction page. Paste the copied XDR there." } }, - "required": ["applicantAddress", "contentUri"] + "required": ["unsignedXdr", "network", "passphrase", "source", "labUrl"] }, - "WithdrawHackathonSubmissionDto": { + "SubmitPayoutSignedXdrDto": { "type": "object", "properties": { - "applicantAddress": { - "type": "string", - "description": "Caller's Stellar G-address. Must match the caller's linked wallet.", - "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" - }, - "fundingMode": { + "signedXdr": { "type": "string", - "description": "Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet.", - "enum": ["EXTERNAL", "MANAGED"], - "default": "EXTERNAL" + "description": "Fully-signed payout XDR returned by the wallet / multisig coordinator. Verified against the built unsigned XDR before broadcast." } }, - "required": ["applicantAddress"] + "required": ["signedXdr"] }, - "ContributeHackathonDto": { + "ExecutePayoutRequestDto": { "type": "object", "properties": { - "applicantAddress": { - "type": "string", - "description": "Caller's Stellar G-address. Must match the caller's linked wallet.", - "example": "GBXNQFDSBDPOIA3Q4LYIWBOJFFPCCV6IEDHBSJZEAYFKIKZVUO4QEDVS" - }, - "fundingMode": { - "type": "string", - "description": "Signing path. EXTERNAL (default) returns unsigned XDR. MANAGED signs server-side with the caller's platform-held wallet.", - "enum": ["EXTERNAL", "MANAGED"], - "default": "EXTERNAL" - }, - "amount": { + "txHash": { "type": "string", - "description": "Amount in token-native units (e.g. 30 = 30 USDC, NOT stroops). Must be >= 10 USDC (contract minimum).", - "example": "30" + "description": "Hash of the settled, offline-signed payout tx" } }, - "required": ["applicantAddress", "amount"] + "required": ["txHash"] }, - "CreateOrganizationDto": { - "type": "object", - "properties": {} - }, - "OrganizationProfileStatsDto": { + "AdminContentListItemDto": { "type": "object", "properties": { - "projectsCount": { - "type": "number", - "description": "Number of projects under this organization", - "example": 12 + "id": { + "type": "string" }, - "totalHackathons": { - "type": "number", - "description": "Total hackathons run by this organization", - "example": 5 + "title": { + "type": "string" }, - "totalBounties": { - "type": "number", - "description": "Total bounties offered by this organization", - "example": 8 + "slug": { + "type": "string" }, - "totalGrants": { + "status": { + "type": "string", + "description": "Publishing status" + }, + "author": { + "type": "string", + "description": "Author name" + }, + "views": { "type": "number", - "description": "Total grants (projects with grants) under this organization", - "example": 3 + "description": "View count" + }, + "archived": { + "type": "boolean", + "description": "Whether the post is archived (soft-deleted)" + }, + "created": { + "type": "string", + "description": "ISO timestamp the post was created" } }, "required": [ - "projectsCount", - "totalHackathons", - "totalBounties", - "totalGrants" + "id", + "title", + "slug", + "status", + "author", + "views", + "archived", + "created" ] }, - "OrganizationProfileDto": { + "PaginatedContentDto": { "type": "object", "properties": { - "id": { - "type": "string", - "description": "Organization ID", - "example": "org_1234567890" - }, - "name": { - "type": "string", - "description": "Organization name", - "example": "Tech Innovators" + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminContentListItemDto" + } }, - "slug": { - "type": "string", - "description": "Organization slug", - "example": "tech-innovators" + "page": { + "type": "number" }, - "logoUrl": { - "type": "string", - "description": "Logo URL", - "example": "https://example.com/logo.png" + "limit": { + "type": "number" }, - "description": { - "type": "string", - "description": "Organization description (from about or tagline)", - "example": "We are a community of developers building the future." + "total": { + "type": "number" }, - "stats": { - "description": "Key stats for the organization profile", - "allOf": [ - { - "$ref": "#/components/schemas/OrganizationProfileStatsDto" - } - ] + "totalPages": { + "type": "number" } }, - "required": ["id", "name", "slug", "logoUrl", "description", "stats"] - }, - "UpdateOrganizationDto": { - "type": "object", - "properties": {} - }, - "UpdateMemberRoleDto": { - "type": "object", - "properties": {} - }, - "InviteMemberDto": { - "type": "object", - "properties": {} + "required": ["items", "page", "limit", "total", "totalPages"] }, - "TreasuryWalletResponseDto": { + "AdminContentDetailDto": { "type": "object", "properties": { "id": { "type": "string" }, - "organizationId": { + "title": { "type": "string" }, - "kind": { - "type": "string", - "enum": ["MANAGED", "CONNECTED"] - }, - "publicKey": { + "slug": { "type": "string" }, - "label": { - "type": "string" + "content": { + "type": "string", + "description": "Post body in MDX (markdown + JSX)" }, - "isDefault": { - "type": "boolean" + "excerpt": { + "type": "string", + "nullable": true + }, + "coverImage": { + "type": "string", + "nullable": true }, "status": { "type": "string", - "enum": ["ACTIVE", "ARCHIVED", "NEEDS_REVIEW"] + "description": "Publishing status" }, - "isMultisig": { + "categories": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "description": "Tag names", + "type": "array", + "items": { + "type": "string" + } + }, + "isFeatured": { "type": "boolean" }, - "multisigThreshold": { - "type": "number", - "nullable": true + "isPinned": { + "type": "boolean" }, - "connectionMethod": { + "seoTitle": { "type": "string", "nullable": true }, - "lastVerifiedAt": { + "seoDescription": { "type": "string", "nullable": true }, - "createdAt": { + "seoKeywords": { + "type": "array", + "items": { + "type": "string" + } + }, + "scheduledFor": { + "type": "string", + "nullable": true, + "description": "ISO timestamp for a scheduled publish" + }, + "archived": { + "type": "boolean", + "description": "Whether the post is archived (soft-deleted)" + }, + "created": { "type": "string" }, - "updatedAt": { + "updated": { "type": "string" } }, "required": [ "id", - "organizationId", - "kind", - "publicKey", - "label", - "isDefault", + "title", + "slug", + "content", + "excerpt", + "coverImage", "status", - "isMultisig", - "multisigThreshold", - "connectionMethod", - "lastVerifiedAt", - "createdAt", - "updatedAt" + "categories", + "tags", + "isFeatured", + "isPinned", + "seoTitle", + "seoDescription", + "seoKeywords", + "scheduledFor", + "archived", + "created", + "updated" ] }, - "CreateManagedWalletDto": { + "ContentMutationResponseDto": { "type": "object", "properties": { - "label": { + "id": { + "type": "string" + }, + "slug": { "type": "string", - "description": "Display label for the wallet", - "example": "Main treasury" + "description": "Generated (or existing) URL slug" + }, + "status": { + "type": "string", + "description": "Publishing status" } }, - "required": ["label"] + "required": ["id", "slug", "status"] }, - "RegisterConnectedWalletDto": { + "UpdateContentDto": { "type": "object", "properties": { - "publicKey": { + "title": { "type": "string", - "description": "G-address of the external wallet" + "description": "Blog post title", + "example": "Getting Started with Stellar Smart Contracts", + "minLength": 3, + "maxLength": 300 }, - "label": { + "content": { "type": "string", - "description": "Display label", - "example": "Company multisig" + "description": "Blog post content in markdown format", + "example": "# Introduction\n\nThis tutorial will teach you...", + "minLength": 10 }, - "connectionMethod": { + "excerpt": { "type": "string", - "enum": [ - "freighter", - "lobstr", - "albedo", - "xbull", - "hana", - "rabet", - "walletkit_generic" - ] + "description": "Short excerpt or summary", + "example": "Learn how to build your first smart contract on Stellar", + "maxLength": 500 + }, + "coverImage": { + "type": "string", + "description": "Cover image URL", + "example": "https://res.cloudinary.com/demo/image/upload/v1234567890/post-cover.jpg" + }, + "status": { + "type": "string", + "description": "Post status", + "enum": ["DRAFT", "PUBLISHED", "ARCHIVED", "SCHEDULED"], + "example": "DRAFT", + "default": "DRAFT" + }, + "tags": { + "description": "Post tags", + "example": ["smart-contracts", "soroban", "tutorial"], + "type": "array", + "items": { + "type": "string" + } + }, + "categories": { + "description": "Post categories", + "example": ["tutorials"], + "type": "array", + "items": { + "type": "string" + } + }, + "isFeatured": { + "type": "boolean", + "description": "Mark as featured post", + "example": false, + "default": false + }, + "isPinned": { + "type": "boolean", + "description": "Pin post to top", + "example": false, + "default": false + }, + "readingTime": { + "type": "number", + "description": "Reading time in minutes (auto-calculated if not provided)", + "example": 5 + }, + "seoTitle": { + "type": "string", + "description": "SEO title (overrides post title)", + "maxLength": 70 + }, + "seoDescription": { + "type": "string", + "description": "SEO meta description", + "maxLength": 160 + }, + "seoKeywords": { + "description": "SEO keywords", + "example": ["stellar", "blockchain", "smart contracts"], + "type": "array", + "items": { + "type": "string" + } + }, + "scheduledFor": { + "type": "string", + "description": "Schedule publication date (for SCHEDULED status)", + "example": "2025-12-31T10:00:00Z" + }, + "generateAI": { + "type": "boolean", + "description": "Generate AI content (excerpt, reading time, SEO, tags, category) if not provided", + "example": true, + "default": false + } + } + }, + "SetPublishedDto": { + "type": "object", + "properties": { + "published": { + "type": "boolean", + "description": "true publishes the post; false unpublishes (back to draft)." } }, - "required": ["publicKey", "label", "connectionMethod"] + "required": ["published"] }, - "UpdateTreasuryWalletDto": { + "ContentActionResponseDto": { "type": "object", "properties": { - "label": { + "id": { + "type": "string" + }, + "status": { "type": "string", - "description": "New display label" + "description": "Publishing status after the action" }, - "isDefault": { + "published": { "type": "boolean", - "description": "Make this the organization default" + "description": "Whether the post is currently published" + }, + "archived": { + "type": "boolean", + "description": "Whether the post is archived (soft-deleted)" + } + }, + "required": ["id", "status", "published", "archived"] + }, + "ArchiveContentDto": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "description": "Why the post is being archived. Recorded in the audit log.", + "minLength": 3, + "maxLength": 500 } } }, - "WalletBalanceResponseDto": { + "ChecklistItemDto": { "type": "object", "properties": { - "publicKey": { + "id": { "type": "string" }, - "usdc": { + "label": { "type": "string", - "description": "USDC balance" + "description": "What the reviewer should verify" }, - "xlm": { + "description": { "type": "string", - "description": "XLM balance (fee float)" + "nullable": true, + "description": "Optional help text" + }, + "required": { + "type": "boolean", + "description": "Whether this is a required check" + }, + "orderIndex": { + "type": "number", + "description": "Position in the list" } }, - "required": ["publicKey", "usdc", "xlm"] + "required": ["id", "label", "description", "required", "orderIndex"] }, - "TreasuryPolicyRuleDto": { + "CreateChecklistItemDto": { "type": "object", "properties": { - "min_usdc": { - "type": "number", - "example": 0 - }, - "max_usdc": { - "type": "object", - "example": 1000, - "nullable": true + "label": { + "type": "string", + "minLength": 2, + "maxLength": 200 }, - "required_approvals": { - "type": "number", - "example": 1 + "description": { + "type": "string", + "maxLength": 1000 }, - "approver_roles": { - "example": ["owner", "admin"], + "required": { + "type": "boolean", + "default": false + } + }, + "required": ["label"] + }, + "ReorderChecklistDto": { + "type": "object", + "properties": { + "orderedIds": { + "description": "All active item ids in the desired order (a permutation).", "type": "array", "items": { "type": "string" } } }, - "required": ["min_usdc", "required_approvals", "approver_roles"] + "required": ["orderedIds"] }, - "TreasuryPolicyResponseDto": { + "UpdateChecklistItemDto": { "type": "object", "properties": { - "organizationId": { + "label": { + "type": "string", + "minLength": 2, + "maxLength": 200 + }, + "description": { + "type": "string", + "nullable": true, + "maxLength": 1000, + "description": "Pass an empty string to clear the help text" + }, + "required": { + "type": "boolean" + } + } + }, + "AdminCrowdfundingListItemDto": { + "type": "object", + "properties": { + "id": { "type": "string" }, - "defaultWalletId": { + "title": { + "type": "string" + }, + "status": { "type": "string", - "nullable": true + "description": "v2 lifecycle status" }, - "rules": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TreasuryPolicyRuleDto" - } + "creator": { + "type": "string", + "nullable": true, + "description": "Creator name" }, - "isDefault": { - "type": "boolean", - "description": "True when no policy is saved yet (defaults returned)" + "fundingGoal": { + "type": "number", + "description": "Funding goal" }, - "updatedAt": { + "submittedForReviewAt": { "type": "string", - "nullable": true + "nullable": true, + "description": "ISO timestamp the campaign was submitted for review" + }, + "created": { + "type": "string", + "description": "ISO timestamp the campaign was created" } }, "required": [ - "organizationId", - "defaultWalletId", - "rules", - "isDefault", - "updatedAt" + "id", + "title", + "status", + "creator", + "fundingGoal", + "submittedForReviewAt", + "created" ] }, - "UpdateTreasuryPolicyDto": { + "PaginatedCrowdfundingDto": { "type": "object", "properties": { - "rules": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/TreasuryPolicyRuleDto" + "$ref": "#/components/schemas/AdminCrowdfundingListItemDto" } }, - "defaultWalletId": { - "type": "string", - "description": "Default source wallet id" + "page": { + "type": "number" + }, + "limit": { + "type": "number" + }, + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" } }, - "required": ["rules"] + "required": ["items", "page", "limit", "total", "totalPages"] }, - "InitiateSpendDto": { + "AdminCrowdfundingProjectDto": { "type": "object", "properties": { - "sourceWalletId": { + "description": { "type": "string", - "description": "Treasury wallet to spend from" + "nullable": true }, - "destination": { + "summary": { "type": "string", - "description": "Destination G-address or escrow contract id" + "nullable": true }, - "amount": { + "vision": { "type": "string", - "description": "Amount in USDC", - "example": "2500.00" + "nullable": true, + "description": "Vision statement" }, - "purpose": { + "details": { "type": "string", - "description": "What the spend funds", - "example": "fund_hackathon_escrow" + "nullable": true, + "description": "Markdown details / pitch" }, - "referenceType": { + "category": { "type": "string", - "enum": ["hackathon", "bounty", "grant"] + "nullable": true }, - "referenceId": { - "type": "string" - } - }, - "required": ["sourceWalletId", "destination", "amount", "purpose"] - }, - "SpendRequestResponseDto": { - "type": "object", - "properties": { - "id": { - "type": "string" + "tags": { + "type": "array", + "items": { + "type": "string" + } }, - "organizationId": { - "type": "string" + "techStack": { + "description": "Tech stack", + "type": "array", + "items": { + "type": "string" + } }, - "sourceWalletId": { - "type": "string" + "teamMembers": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": true + }, + "description": "Team members ({ name?, role, ... })" }, - "destination": { - "type": "string" + "socialLinks": { + "type": "array", + "nullable": true, + "items": { + "type": "object", + "additionalProperties": true + }, + "description": "Social links ({ platform, url })" }, - "amount": { - "type": "string" + "contact": { + "type": "object", + "nullable": true, + "additionalProperties": true, + "description": "Contact ({ primary, backup })" }, - "currency": { - "type": "string" + "githubUrl": { + "type": "string", + "nullable": true }, - "purpose": { - "type": "string" + "gitlabUrl": { + "type": "string", + "nullable": true }, - "referenceType": { + "bitbucketUrl": { "type": "string", "nullable": true }, - "referenceId": { + "projectWebsite": { "type": "string", "nullable": true }, - "initiatorUserId": { - "type": "string" + "liveUrl": { + "type": "string", + "nullable": true }, - "requiredApprovals": { - "type": "number" + "docsUrl": { + "type": "string", + "nullable": true }, - "approvals": { + "demoVideo": { + "type": "string", + "nullable": true + }, + "pitchVideoUrl": { + "type": "string", + "nullable": true + }, + "whitepaperUrl": { + "type": "string", + "nullable": true + }, + "logo": { + "type": "string", + "nullable": true + }, + "banner": { + "type": "string", + "nullable": true + }, + "thumbnail": { + "type": "string", + "nullable": true + }, + "screenshots": { "type": "array", "items": { - "type": "object" + "type": "string" } + } + }, + "required": [ + "description", + "summary", + "vision", + "details", + "category", + "tags", + "techStack", + "teamMembers", + "socialLinks", + "contact", + "githubUrl", + "gitlabUrl", + "bitbucketUrl", + "projectWebsite", + "liveUrl", + "docsUrl", + "demoVideo", + "pitchVideoUrl", + "whitepaperUrl", + "logo", + "banner", + "thumbnail", + "screenshots" + ] + }, + "AdminCrowdfundingReviewDto": { + "type": "object", + "properties": { + "action": { + "type": "string", + "description": "NOTE | REQUEST_REVISION | APPROVED | REJECTED" }, - "status": { - "type": "string" - }, - "onChainTxHash": { + "reason": { "type": "string", "nullable": true }, + "reviewer": { + "type": "string", + "nullable": true, + "description": "Reviewer name (User) or null when a staff member reviewed" + }, + "reviewerStaffEmail": { + "type": "string", + "nullable": true, + "description": "Staff email when a staff member reviewed" + }, "createdAt": { "type": "string" - }, - "approvedAt": { - "type": "string", - "nullable": true } }, "required": [ - "id", - "organizationId", - "sourceWalletId", - "destination", - "amount", - "currency", - "purpose", - "referenceType", - "referenceId", - "initiatorUserId", - "requiredApprovals", - "approvals", - "status", - "onChainTxHash", - "createdAt", - "approvedAt" + "action", + "reason", + "reviewer", + "reviewerStaffEmail", + "createdAt" ] }, - "SendTreasuryFundsDto": { + "AdminCrowdfundingMilestoneDto": { "type": "object", "properties": { - "sourceWalletId": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "orderIndex": { + "type": "number", + "description": "Position in the release sequence" + }, + "fundingPercentage": { + "type": "number", + "description": "Planned share of the goal (percent)" + }, + "amount": { + "type": "number", + "description": "Planned amount" + }, + "reviewStatus": { "type": "string", - "description": "Wallet to send from" + "description": "Off-chain review status" }, - "destination": { + "description": { "type": "string", - "description": "Recipient Stellar address (starts with G)", - "example": "GA..." + "description": "What the milestone delivers" }, - "amount": { + "deliverable": { "type": "string", - "description": "Amount in USDC", - "example": "250.00" + "nullable": true, + "description": "Concrete deliverable" }, - "note": { + "successCriteria": { "type": "string", - "description": "What this payment is for (shown in your activity log)", - "example": "Contributor payout" - } - }, - "required": ["sourceWalletId", "destination", "amount"] - }, - "SendDestinationReadinessDto": { - "type": "object", - "properties": { - "exists": { - "type": "boolean", - "description": "Whether the recipient account exists on-chain" + "nullable": true, + "description": "Acceptance / success criteria" }, - "hasUsdcTrustline": { - "type": "boolean", - "description": "Whether the recipient has a USDC trustline (so it can receive USDC)" - } - }, - "required": ["exists", "hasUsdcTrustline"] - }, - "SpendDecisionDto": { - "type": "object", - "properties": { - "note": { + "expectedDeliveryDate": { "type": "string", - "description": "Optional note for the decision" - } - } - }, - "BuildSpendXdrResponseDto": { - "type": "object", - "properties": { - "unsignedXdr": { + "nullable": true, + "description": "Expected delivery date" + }, + "submittedAt": { "type": "string", - "description": "Unsigned transaction XDR to sign in-browser" + "nullable": true }, - "request": { - "$ref": "#/components/schemas/SpendRequestResponseDto" - } - }, - "required": ["unsignedXdr", "request"] - }, - "SubmitSpendSignedXdrDto": { - "type": "object", - "properties": { - "signedXdr": { + "escrowAnchorStatus": { "type": "string", - "description": "The browser-signed transaction XDR" - } - }, - "required": ["signedXdr"] - }, - "TreasuryActorDto": { - "type": "object", - "properties": { - "id": { - "type": "string" + "nullable": true, + "description": "On-chain claim anchor: pending_confirm | confirmed | failed" }, - "name": { + "escrowClaimTxHash": { "type": "string", "nullable": true }, - "image": { + "claimedAt": { "type": "string", "nullable": true } }, - "required": ["id", "name", "image"] + "required": [ + "id", + "title", + "orderIndex", + "fundingPercentage", + "amount", + "reviewStatus", + "description", + "deliverable", + "successCriteria", + "expectedDeliveryDate", + "submittedAt", + "escrowAnchorStatus", + "escrowClaimTxHash", + "claimedAt" + ] }, - "TreasuryAuditEntryDto": { + "AdminCrowdfundingDetailDto": { "type": "object", "properties": { "id": { "type": "string" }, - "action": { + "title": { "type": "string" }, - "actorUserId": { + "tagline": { "type": "string", "nullable": true }, - "actorKind": { - "type": "string" + "status": { + "type": "string", + "description": "v2 lifecycle status" }, - "actor": { + "creator": { + "type": "string", "nullable": true, - "description": "Resolved profile of the actor (name + avatar), if a user.", + "description": "Creator name" + }, + "project": { + "description": "Full submitted project content for review", "allOf": [ { - "$ref": "#/components/schemas/TreasuryActorDto" + "$ref": "#/components/schemas/AdminCrowdfundingProjectDto" } ] }, - "walletId": { - "type": "string", - "nullable": true - }, - "spendRequestId": { - "type": "string", - "nullable": true - }, - "details": { - "type": "object", - "additionalProperties": true, - "nullable": true - }, - "createdAt": { - "type": "string" - } - }, - "required": [ - "id", - "action", - "actorUserId", - "actorKind", - "actor", - "walletId", - "spendRequestId", - "details", - "createdAt" - ] - }, - "TreasuryAuditLogResponseDto": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TreasuryAuditEntryDto" - } - }, - "total": { + "fundingGoal": { "type": "number" }, - "page": { + "fundingRaised": { "type": "number" }, - "limit": { - "type": "number" - } - }, - "required": ["data", "total", "page", "limit"] - }, - "ReceiptResponseDto": { - "type": "object", - "properties": { - "id": { + "fundingCurrency": { "type": "string" }, - "receiptNumber": { + "fundingEndDate": { "type": "string", - "example": "RCPT-100001" - }, - "organizationId": { - "type": "string" + "nullable": true, + "description": "Funding deadline" }, - "type": { - "type": "string", - "example": "TREASURY_SEND" + "totalDisbursed": { + "type": "number", + "description": "Total released to the builder so far (across milestones)" }, - "typeLabel": { - "type": "string", - "example": "Funds sent" + "voteGoal": { + "type": "number", + "description": "Per-campaign voting quorum" }, - "status": { + "builderAddress": { "type": "string", - "example": "ISSUED" + "nullable": true, + "description": "Builder's wallet (escrow owner)" }, - "direction": { - "type": "string", - "example": "OUTGOING" + "nMilestones": { + "type": "number", + "nullable": true, + "description": "Number of milestones" }, - "amount": { + "escrowEventId": { "type": "string", - "example": "250.00" + "nullable": true, + "description": "On-chain event id once the escrow is live (FUNDING)" }, - "currency": { + "escrowTxHash": { "type": "string", - "example": "USDC" + "nullable": true, + "description": "create_event tx hash" }, - "fromLabel": { - "type": "object", + "escrowSettledLedger": { + "type": "number", "nullable": true }, - "fromAddress": { - "type": "object", + "escrowToken": { + "type": "string", "nullable": true }, - "toLabel": { - "type": "object", - "nullable": true + "escrowBudget": { + "type": "string", + "nullable": true, + "description": "Total escrow budget (stroops/decimal)" }, - "toAddress": { - "type": "object", - "nullable": true + "escrowFailureCode": { + "type": "string", + "nullable": true, + "description": "Escrow failure code if create_event failed (FAILED)" }, - "description": { - "type": "object", + "escrowFailedAt": { + "type": "string", "nullable": true }, - "onChainTxHash": { - "type": "object", + "completedAt": { + "type": "string", "nullable": true }, - "explorerUrl": { - "type": "object", + "cancelledAt": { + "type": "string", "nullable": true }, - "network": { - "type": "object", + "assignedReviewerId": { + "type": "string", + "nullable": true, + "description": "Assigned delegated reviewer (User id), set at approval" + }, + "submittedForReviewAt": { + "type": "string", "nullable": true }, - "issuedByUserId": { - "type": "object", + "reviewedAt": { + "type": "string", "nullable": true }, - "issuedAt": { - "type": "string" + "created": { + "type": "string", + "description": "ISO timestamp the campaign was created" }, - "voidedAt": { - "type": "object", - "nullable": true + "reviews": { + "description": "Review history", + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminCrowdfundingReviewDto" + } + }, + "milestones": { + "description": "Milestones with review + on-chain claim status", + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminCrowdfundingMilestoneDto" + } } }, "required": [ "id", - "receiptNumber", - "organizationId", - "type", - "typeLabel", + "title", + "tagline", "status", - "direction", - "amount", - "currency", - "fromLabel", - "fromAddress", - "toLabel", - "toAddress", - "description", - "onChainTxHash", - "explorerUrl", - "network", - "issuedByUserId", - "issuedAt", - "voidedAt" + "creator", + "project", + "fundingGoal", + "fundingRaised", + "fundingCurrency", + "fundingEndDate", + "totalDisbursed", + "voteGoal", + "builderAddress", + "nMilestones", + "escrowEventId", + "escrowTxHash", + "escrowSettledLedger", + "escrowToken", + "escrowBudget", + "escrowFailureCode", + "escrowFailedAt", + "completedAt", + "cancelledAt", + "assignedReviewerId", + "submittedForReviewAt", + "reviewedAt", + "created", + "reviews", + "milestones" ] }, - "ReceiptListResponseDto": { + "ApproveCampaignDto": { "type": "object", "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ReceiptResponseDto" - } - }, - "total": { - "type": "number" + "delegatedReviewerId": { + "type": "string", + "description": "StaffUser id of the delegated reviewer who signs off milestones for this campaign. Must be an active staff member." }, - "page": { - "type": "number" + "voteGoal": { + "type": "number", + "description": "Per-campaign voting quorum. Defaults to the contract default.", + "minimum": 1 }, - "limit": { - "type": "number" + "bypassVoting": { + "type": "boolean", + "description": "Bypass community voting and approve straight to launch-ready (REVIEW_APPROVED). Default false: the campaign enters community voting.", + "default": false } }, - "required": ["data", "total", "page", "limit"] + "required": ["delegatedReviewerId"] }, - "SendReceiptDto": { + "CrowdfundingActionResponseDto": { "type": "object", "properties": { - "email": { + "id": { + "type": "string" + }, + "status": { "type": "string", - "description": "Where to email the receipt. Defaults to your account email." + "description": "New v2 lifecycle status" } - } + }, + "required": ["id", "status"] }, - "VoidReceiptDto": { + "RejectCampaignDto": { "type": "object", "properties": { "reason": { "type": "string", - "description": "Why the receipt is being voided" + "description": "Reason shown to the builder in the review history.", + "maxLength": 1000 } } }, - "CreateVoteDto": { + "RequestRevisionDto": { "type": "object", "properties": { - "projectId": { - "type": "string", - "description": "ID of the project being voted on" - }, - "entityType": { - "type": "string", - "enum": [ - "PROJECT", - "CROWDFUNDING_CAMPAIGN", - "HACKATHON_SUBMISSION", - "GRANT" - ], - "description": "Type of entity being voted on" - }, - "voteType": { + "reason": { "type": "string", - "enum": ["UPVOTE", "DOWNVOTE"], - "default": "UPVOTE", - "description": "Type of vote (UPVOTE or DOWNVOTE)" - }, - "weight": { - "type": "number", - "default": 1, - "description": "Weight of the vote" + "description": "What the builder needs to change. Shown in the review history.", + "minLength": 3, + "maxLength": 1000 } }, - "required": ["projectId", "entityType"] + "required": ["reason"] }, - "CreateBlogPostDto": { + "TotpEnrollResponseDto": { "type": "object", "properties": { - "title": { - "type": "string", - "description": "Blog post title", - "example": "Getting Started with Stellar Smart Contracts", - "minLength": 3, - "maxLength": 300 - }, - "content": { - "type": "string", - "description": "Blog post content in markdown format", - "example": "# Introduction\n\nThis tutorial will teach you...", - "minLength": 10 - }, - "excerpt": { - "type": "string", - "description": "Short excerpt or summary", - "example": "Learn how to build your first smart contract on Stellar", - "maxLength": 500 - }, - "coverImage": { - "type": "string", - "description": "Cover image URL", - "example": "https://res.cloudinary.com/demo/image/upload/v1234567890/post-cover.jpg" - }, - "status": { - "type": "string", - "description": "Post status", - "enum": ["DRAFT", "PUBLISHED", "ARCHIVED", "SCHEDULED"], - "example": "DRAFT", - "default": "DRAFT" - }, - "tags": { - "description": "Post tags", - "example": ["smart-contracts", "soroban", "tutorial"], - "type": "array", - "items": { - "type": "string" - } - }, - "categories": { - "description": "Post categories", - "example": ["tutorials"], - "type": "array", - "items": { - "type": "string" - } - }, - "isFeatured": { - "type": "boolean", - "description": "Mark as featured post", - "example": false, - "default": false - }, - "isPinned": { - "type": "boolean", - "description": "Pin post to top", - "example": false, - "default": false - }, - "readingTime": { - "type": "number", - "description": "Reading time in minutes (auto-calculated if not provided)", - "example": 5 - }, - "seoTitle": { + "secret": { "type": "string", - "description": "SEO title (overrides post title)", - "maxLength": 70 + "description": "Base32 secret, shown once for manual entry" }, - "seoDescription": { + "otpauthUri": { "type": "string", - "description": "SEO meta description", - "maxLength": 160 - }, - "seoKeywords": { - "description": "SEO keywords", - "example": ["stellar", "blockchain", "smart contracts"], - "type": "array", - "items": { - "type": "string" - } - }, - "scheduledFor": { + "description": "otpauth:// URI for QR enrollment" + } + }, + "required": ["secret", "otpauthUri"] + }, + "TotpCodeDto": { + "type": "object", + "properties": { + "code": { "type": "string", - "description": "Schedule publication date (for SCHEDULED status)", - "example": "2025-12-31T10:00:00Z" - }, - "generateAI": { - "type": "boolean", - "description": "Generate AI content (excerpt, reading time, SEO, tags, category) if not provided", - "example": true, - "default": false + "description": "Six-digit code from the authenticator app" } }, - "required": ["title", "content"] + "required": ["code"] }, - "UpdateBlogPostDto": { + "OkResponseDto": { "type": "object", - "properties": {} + "properties": { + "ok": { + "type": "boolean", + "default": true + } + }, + "required": ["ok"] }, - "MetricDataDto": { + "AdminAuditListItemDto": { "type": "object", "properties": { - "value": { - "type": "number", - "description": "The metric value", - "example": 1250 + "id": { + "type": "string" }, - "change": { - "type": "number", - "description": "Percentage change", - "example": 12.5 + "actor": { + "type": "string", + "description": "Email of the staff member who acted" }, - "changeType": { + "action": { "type": "string", - "enum": ["positive", "negative", "neutral"], - "description": "Type of change", - "example": "positive" + "description": "Dotted action name, e.g. \"users.ban\"" }, - "label": { + "resource": { "type": "string", - "description": "Metric label", - "example": "Total Users" + "description": "Permission resource the action belongs to" }, - "description": { + "targetId": { "type": "string", - "description": "Additional description", - "example": "Active users in the platform" + "nullable": true, + "description": "Affected entity id" + }, + "details": { + "type": "string", + "nullable": true, + "description": "Human note captured with the action (e.g. ban reason)" + }, + "created": { + "type": "string", + "description": "ISO timestamp the action was recorded" } }, - "required": ["value", "change", "changeType", "label"] + "required": [ + "id", + "actor", + "action", + "resource", + "targetId", + "details", + "created" + ] }, - "HackathonMetricDataDto": { + "PaginatedAuditDto": { "type": "object", "properties": { - "value": { - "type": "number", - "description": "The metric value", - "example": 1250 - }, - "change": { - "type": "number", - "description": "Percentage change", - "example": 12.5 - }, - "changeType": { - "type": "string", - "enum": ["positive", "negative", "neutral"], - "description": "Type of change", - "example": "positive" + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminAuditListItemDto" + } }, - "label": { - "type": "string", - "description": "Metric label", - "example": "Total Users" + "page": { + "type": "number" }, - "description": { - "type": "string", - "description": "Additional description", - "example": "Active users in the platform" + "limit": { + "type": "number" }, - "additionalInfo": { - "type": "string", - "description": "Additional hackathon info", - "example": "3 active, 7 upcoming" + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" } }, - "required": ["value", "change", "changeType", "label"] + "required": ["items", "page", "limit", "total", "totalPages"] }, - "OverviewMetricsDto": { + "FeatureFlagDto": { "type": "object", "properties": { - "totalUsers": { - "$ref": "#/components/schemas/MetricDataDto" + "key": { + "type": "string", + "description": "Stable flag key, e.g. \"crowdfunding.public_launch\"" }, - "organizations": { - "$ref": "#/components/schemas/MetricDataDto" + "description": { + "type": "string", + "description": "Human description of what the flag gates" }, - "projects": { - "$ref": "#/components/schemas/MetricDataDto" + "enabled": { + "type": "boolean" }, - "hackathons": { - "$ref": "#/components/schemas/HackathonMetricDataDto" + "updated": { + "type": "string", + "description": "ISO timestamp the flag was last changed" } }, - "required": ["totalUsers", "organizations", "projects", "hackathons"] + "required": ["key", "description", "enabled", "updated"] }, - "OverviewChartDataDto": { + "FeatureFlagsResponseDto": { "type": "object", "properties": { - "data": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/ChartDataPointDto" + "$ref": "#/components/schemas/FeatureFlagDto" } - }, - "timeRange": { - "type": "string", - "enum": ["7d", "30d", "90d"], - "description": "Time range for the chart", - "example": "7d" } }, - "required": ["data", "timeRange"] + "required": ["items"] }, - "AdminOverviewResponseDto": { + "ToggleFeatureFlagDto": { "type": "object", "properties": { - "metrics": { - "$ref": "#/components/schemas/OverviewMetricsDto" - }, - "chart": { - "$ref": "#/components/schemas/OverviewChartDataDto" - }, - "lastUpdated": { - "type": "string", - "description": "Last updated timestamp", - "example": "2025-12-26T10:30:00Z" + "enabled": { + "type": "boolean", + "description": "Desired enabled state" } }, - "required": ["metrics", "chart", "lastUpdated"] + "required": ["enabled"] }, - "AdminCrowdfundingRejectDto": { + "StaffListItemDto": { "type": "object", "properties": { - "reason": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { "type": "string", - "description": "Reason for rejection", - "example": "Campaign does not meet requirements" + "description": "Staff role token, e.g. \"operations\"" + }, + "status": { + "type": "string", + "description": "active | disabled" + }, + "totpEnabled": { + "type": "boolean", + "description": "Whether the staff has an activated authenticator" + }, + "created": { + "type": "string", + "description": "ISO timestamp the staff record was created" } - } + }, + "required": [ + "id", + "name", + "email", + "role", + "status", + "totpEnabled", + "created" + ] }, - "AdminCrowdfundingRequestRevisionDto": { + "StaffListResponseDto": { "type": "object", "properties": { - "message": { - "type": "string", - "description": "Message for the creator explaining requested revisions", - "example": "Please update the project description to be more detailed" - }, - "reasons": { - "description": "Optional structured reasons", - "example": ["incomplete_description", "missing_team_info"], + "items": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/StaffListItemDto" } } }, - "required": ["message"] + "required": ["items"] }, - "AdminCrowdfundingNoteDto": { + "SetRoleDto": { "type": "object", "properties": { - "note": { + "role": { "type": "string", - "description": "Short admin note or comment", - "example": "Reviewed initial submission" + "enum": [ + "super_admin", + "operations", + "finance", + "compliance", + "content", + "support" + ], + "description": "The role to assign" } }, - "required": ["note"] + "required": ["role"] }, - "AdminCrowdfundingAssignDto": { + "GovernanceProposalDto": { "type": "object", "properties": { - "reviewerId": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { "type": "string", - "description": "Reviewer (user) id to assign", - "example": "550e8400-e29b-41d4-a716-446655440000" + "nullable": true + }, + "contract": { + "type": "string", + "description": "Target contract, e.g. \"boundless-events\"" + }, + "action": { + "type": "string", + "description": "Contract action, e.g. \"upgrade\"" + }, + "params": { + "type": "object", + "additionalProperties": true, + "nullable": true, + "description": "Action parameters for the offline signers" + }, + "status": { + "type": "string", + "description": "PROPOSED | APPROVED | REJECTED | EXECUTED" + }, + "proposedBy": { + "type": "string", + "description": "Email of the maker who proposed" + }, + "decidedBy": { + "type": "string", + "nullable": true, + "description": "Checker email" + }, + "decidedAt": { + "type": "string", + "nullable": true + }, + "decisionNote": { + "type": "string", + "nullable": true + }, + "txHash": { + "type": "string", + "nullable": true, + "description": "Offline-signed tx hash" + }, + "executedBy": { + "type": "string", + "nullable": true + }, + "executedAt": { + "type": "string", + "nullable": true + }, + "created": { + "type": "string" } }, - "required": ["reviewerId"] + "required": [ + "id", + "title", + "description", + "contract", + "action", + "status", + "proposedBy", + "decidedBy", + "decidedAt", + "decisionNote", + "txHash", + "executedBy", + "executedAt", + "created" + ] }, - "ApproveMilestoneDto": { + "GovernanceListResponseDto": { "type": "object", "properties": { - "notes": { - "type": "string", - "description": "Optional approval notes", - "example": "Milestone completed successfully" + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GovernanceProposalDto" + } } - } + }, + "required": ["items"] }, - "RejectMilestoneDto": { + "CreateProposalDto": { "type": "object", "properties": { - "reason": { - "type": "string", - "description": "Rejection reason", - "example": "Incomplete deliverables" + "title": { + "type": "string" }, - "feedback": { + "description": { + "type": "string" + }, + "contract": { "type": "string", - "description": "Detailed feedback for rejection", - "example": "The submitted work does not meet the project requirements. Please revise and resubmit." + "description": "Target contract" }, - "resubmissionDeadline": { + "action": { "type": "string", - "description": "Deadline for resubmission", - "example": "2025-02-01" + "description": "Contract action" + }, + "params": { + "type": "object", + "additionalProperties": true } }, - "required": ["reason", "feedback"] + "required": ["title", "contract", "action"] }, - "RequestMilestoneResubmissionDto": { + "DecideProposalDto": { "type": "object", "properties": { - "feedback": { + "decision": { "type": "string", - "description": "Feedback explaining what needs to change", - "example": "Please improve the documentation and add more test cases" + "enum": ["approve", "reject"] }, - "resubmissionDeadline": { + "note": { "type": "string", - "description": "Deadline for resubmission", - "example": "2025-02-15" + "description": "Note recorded with the decision" } }, - "required": ["feedback", "resubmissionDeadline"] + "required": ["decision"] }, - "AddMilestoneReviewNoteDto": { + "ExecuteProposalDto": { "type": "object", "properties": { - "note": { + "txHash": { "type": "string", - "description": "Review note content", - "example": "Reviewed the code quality and found it satisfactory" + "description": "Hash of the offline-signed, executed transaction" } }, - "required": ["note"] + "required": ["txHash"] }, - "ManualEscrowActionDto": { + "AdminKycListItemDto": { "type": "object", "properties": { - "action": { + "id": { "type": "string", - "enum": ["RELEASE", "REFUND", "PAUSE", "RESUME"], - "description": "Type of escrow action to execute", - "example": "RELEASE" + "description": "User id" }, - "amount": { - "type": "number", - "description": "Amount to transfer (for RELEASE/REFUND)", - "example": 1000 + "name": { + "type": "string" }, - "notes": { + "email": { + "type": "string" + }, + "status": { "type": "string", - "description": "Optional notes for this action", - "example": "Releasing funds for completed milestone" + "enum": ["in_review", "approved", "declined"] }, - "recipientAddress": { + "declineReason": { "type": "string", - "description": "Recipient address (for RELEASE/REFUND)", - "example": "GAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + "nullable": true, + "description": "Decline reason from Didit, when declined" + }, + "reviewedAt": { + "type": "string", + "description": "ISO timestamp of the last verification activity" + }, + "verifiedAt": { + "type": "string", + "nullable": true, + "description": "ISO timestamp the user became verified" } }, - "required": ["action"] + "required": [ + "id", + "name", + "email", + "status", + "declineReason", + "reviewedAt", + "verifiedAt" + ] }, - "AssignDisputeDto": { + "PaginatedKycDto": { "type": "object", "properties": { - "adminId": { - "type": "string", - "description": "Admin user ID to assign dispute to", - "example": "550e8400-e29b-41d4-a716-446655440000" + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminKycListItemDto" + } + }, + "page": { + "type": "number" + }, + "limit": { + "type": "number" + }, + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" } }, - "required": ["adminId"] + "required": ["items", "page", "limit", "total", "totalPages"] }, - "AddDisputeNoteDto": { + "DiditConnectionDto": { "type": "object", "properties": { - "message": { - "type": "string", - "description": "Message content", - "example": "Contacted the project creator for more information" + "apiKey": { + "type": "boolean", + "description": "DIDIT_API_KEY is configured" }, - "isInternal": { + "workflowId": { "type": "boolean", - "description": "Whether this is an internal note (not visible to parties)", - "example": false + "description": "DIDIT_WORKFLOW_ID is configured" + }, + "webhookSecret": { + "type": "boolean", + "description": "DIDIT_WEBHOOK_SECRET is configured" + }, + "connected": { + "type": "boolean", + "description": "API key + workflow present: live calls (sync, re-trigger) work" } }, - "required": ["message"] + "required": ["apiKey", "workflowId", "webhookSecret", "connected"] }, - "ResolveDisputeDto": { + "KycSyncResponseDto": { "type": "object", "properties": { - "resolution": { - "type": "string", - "enum": [ - "APPROVED_WITH_CONDITIONS", - "REQUIRE_RESUBMISSION", - "PARTIAL_REFUND", - "FULL_REFUND", - "DISMISSED", - "ARBITRATION" - ], - "description": "Resolution type", - "example": "APPROVED_WITH_CONDITIONS" + "userId": { + "type": "string" }, - "resolutionNotes": { + "status": { "type": "string", - "description": "Detailed notes explaining the resolution", - "example": "Approved with condition that milestone is completed by next week" + "description": "Raw Didit status after the sync" + }, + "changed": { + "type": "boolean", + "description": "Whether the user record status changed" + }, + "userResolved": { + "type": "boolean", + "description": "False if no Boundless user could be linked to the session" } }, - "required": ["resolution", "resolutionNotes"] + "required": ["userId", "status", "changed", "userResolved"] }, - "EscalateDisputeDto": { + "KycRetriggerResponseDto": { "type": "object", "properties": { - "reason": { + "userId": { + "type": "string" + }, + "sessionId": { + "type": "string", + "description": "The new Didit session id" + }, + "verificationUrl": { + "type": "string", + "description": "Hosted verification URL to share with the user" + }, + "status": { "type": "string", - "description": "Reason for escalation to arbitration", - "example": "Parties cannot agree on resolution terms" + "description": "Initial Didit session status" + }, + "notified": { + "type": "boolean", + "description": "Whether the user was notified (in-app + email) with the link. If false, share the URL manually." } }, - "required": ["reason"] - }, - "RejectManualProjectDto": { - "type": "object", - "properties": {} - }, - "RequestManualProjectChangesDto": { - "type": "object", - "properties": {} - }, - "RejectProjectEditDto": { - "type": "object", - "properties": {} + "required": [ + "userId", + "sessionId", + "verificationUrl", + "status", + "notified" + ] }, - "AdminWalletStatsDto": { + "KycOverrideDto": { "type": "object", "properties": { - "totalWallets": { - "$ref": "#/components/schemas/MetricDataDto" - }, - "activatedWallets": { - "$ref": "#/components/schemas/MetricDataDto" + "decision": { + "type": "string", + "enum": ["approved", "declined"], + "description": "The decision to force onto the user record." }, - "inactiveWallets": { - "$ref": "#/components/schemas/MetricDataDto" + "reason": { + "type": "string", + "description": "Why the automated Didit decision is being overridden. Recorded in the audit log.", + "minLength": 3, + "maxLength": 500 } }, - "required": ["totalWallets", "activatedWallets", "inactiveWallets"] + "required": ["decision", "reason"] }, - "AdminWalletUserDto": { + "KycOverrideResponseDto": { "type": "object", "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "email": { - "type": "string" - }, - "username": { + "userId": { "type": "string" }, - "image": { - "type": "string" + "status": { + "type": "string", + "enum": ["approved", "declined"], + "description": "The resulting normalized state" } }, - "required": ["id", "name", "email"] + "required": ["userId", "status"] }, - "AdminWalletListItemDto": { + "AdminMilestoneListItemDto": { "type": "object", "properties": { "id": { "type": "string" }, - "publicKey": { - "type": "string" + "type": { + "type": "string", + "enum": ["crowdfunding", "grant"] }, - "isActivated": { - "type": "boolean" + "program": { + "type": "string", + "nullable": true, + "description": "Parent program title" }, - "createdAt": { - "format": "date-time", + "title": { "type": "string" }, - "users": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AdminWalletUserDto" - } + "amount": { + "type": "number", + "description": "Milestone amount" + }, + "status": { + "type": "string", + "description": "Review/lifecycle status" + }, + "submitted": { + "type": "string", + "nullable": true, + "description": "ISO timestamp the milestone was submitted, if any" + }, + "releaseStatus": { + "type": "string", + "nullable": true, + "enum": ["NOT_RELEASED", "RELEASING", "RELEASED", "FAILED"], + "description": "Crowdfunding only: on-chain payout release state (derived from the escrow anchor status). Null for grant milestones." } }, - "required": ["id", "publicKey", "isActivated", "createdAt", "users"] + "required": [ + "id", + "type", + "program", + "title", + "amount", + "status", + "submitted", + "releaseStatus" + ] }, - "AdminWalletListResponseDto": { + "PaginatedMilestonesDto": { "type": "object", "properties": { - "wallets": { + "items": { "type": "array", "items": { - "$ref": "#/components/schemas/AdminWalletListItemDto" + "$ref": "#/components/schemas/AdminMilestoneListItemDto" } }, - "total": { - "type": "number" - }, "page": { "type": "number" }, "limit": { "type": "number" }, + "total": { + "type": "number" + }, "totalPages": { "type": "number" } }, - "required": ["wallets", "total", "page", "limit", "totalPages"] + "required": ["items", "page", "limit", "total", "totalPages"] }, - "AdminWalletBalanceDto": { + "AdminMilestoneDetailDto": { "type": "object", "properties": { - "balance": { + "id": { "type": "string" }, - "assetCode": { + "title": { "type": "string" }, - "assetIssuer": { + "description": { "type": "string" }, - "assetType": { - "type": "string" - } - }, - "required": ["balance", "assetCode", "assetType"] - }, - "AdminWalletDetailsDto": { - "type": "object", - "properties": { - "id": { - "type": "string" + "deliverable": { + "type": "string", + "nullable": true }, - "publicKey": { + "successCriteria": { + "type": "string", + "nullable": true + }, + "expectedDeliveryDate": { + "type": "string", + "nullable": true + }, + "reviewStatus": { "type": "string" }, - "isActivated": { - "type": "boolean" + "completedAt": { + "type": "string", + "nullable": true }, - "createdAt": { - "format": "date-time", + "submittedAt": { + "type": "string", + "nullable": true + }, + "campaignId": { "type": "string" }, - "balances": { + "proofOfWorkFiles": { "type": "array", "items": { - "$ref": "#/components/schemas/AdminWalletBalanceDto" + "type": "string" } }, - "users": { + "proofOfWorkLinks": { "type": "array", "items": { - "$ref": "#/components/schemas/AdminWalletUserDto" + "type": "string" } + }, + "submissionNotes": { + "type": "string", + "nullable": true + }, + "fundingPercentage": { + "type": "number" + }, + "orderIndex": { + "type": "number" + }, + "rejectionReason": { + "type": "string", + "nullable": true + }, + "rejectionFeedback": { + "type": "string", + "nullable": true + }, + "resubmissionDeadline": { + "type": "string", + "nullable": true + }, + "releaseTransactionHash": { + "type": "string", + "nullable": true + }, + "claimedAt": { + "type": "string", + "nullable": true + }, + "releaseStatus": { + "type": "string", + "description": "Derived payout release state." } }, "required": [ "id", - "publicKey", - "isActivated", - "createdAt", - "balances", - "users" + "title", + "description", + "deliverable", + "successCriteria", + "expectedDeliveryDate", + "reviewStatus", + "completedAt", + "submittedAt", + "campaignId", + "proofOfWorkFiles", + "proofOfWorkLinks", + "submissionNotes", + "fundingPercentage", + "orderIndex", + "rejectionReason", + "rejectionFeedback", + "resubmissionDeadline", + "releaseTransactionHash", + "claimedAt", + "releaseStatus" ] }, - "ReviewWindowDto": { + "MilestoneActionResponseDto": { "type": "object", "properties": { - "minBusinessDays": { - "type": "number", - "example": 1 + "id": { + "type": "string" }, - "maxBusinessDays": { - "type": "number", - "example": 3 + "status": { + "type": "string", + "description": "New milestone review status" + } + }, + "required": ["id", "status"] + }, + "MilestoneReleaseXdrDto": { + "type": "object", + "properties": { + "opId": { + "type": "string", + "description": "EscrowOp row id tracking this release." + }, + "milestoneId": { + "type": "string" + }, + "source": { + "type": "string", + "description": "On-chain contract admin G-address. This is the transaction source and the account that must sign at the Lab." + }, + "unsignedXdr": { + "type": "string", + "description": "Unsigned transaction XDR (the builder managed auth entry is already signed server-side; the admin signs the envelope offline)." + }, + "labUrl": { + "type": "string", + "description": "Stellar Lab \"Sign Transaction\" deep link." }, - "estimatedCompletionAt": { + "network": { "type": "string", - "description": "ISO timestamp by which the review is expected to complete." + "enum": ["public", "testnet"] + }, + "passphrase": { + "type": "string", + "description": "Network passphrase the signer must use." } }, "required": [ - "minBusinessDays", - "maxBusinessDays", - "estimatedCompletionAt" + "opId", + "milestoneId", + "source", + "unsignedXdr", + "labUrl", + "network", + "passphrase" ] }, - "DeclineDetailsDto": { + "SubmitMilestoneReleaseDto": { "type": "object", "properties": { - "reason": { + "signedXdr": { "type": "string", - "description": "Human-readable reason from Didit, if available." - }, - "canRetry": { - "type": "boolean", - "description": "Whether the user is allowed to start a new verification.", - "example": true + "description": "Base64 transaction XDR signed offline by the admin at the Stellar Lab. Must be the exact transaction returned by build-xdr (hash-checked)." } }, - "required": ["canRetry"] + "required": ["signedXdr"] }, - "VerificationStatusDto": { + "MilestoneReleaseResultDto": { "type": "object", "properties": { - "state": { - "type": "string", - "description": "Normalized verification state. Frontend should hide the verify button unless this is one of: not_started, declined, abandoned, expired.", - "enum": [ - "not_started", - "in_progress", - "in_review", - "approved", - "declined", - "abandoned", - "expired" - ] - }, - "canStartNew": { - "type": "boolean", - "description": "Whether the user can start a new verification session." + "opId": { + "type": "string" }, - "message": { - "type": "string", - "description": "Polite, render-ready copy summarising the current state." + "milestoneId": { + "type": "string" }, - "verifiedAt": { + "status": { "type": "string", - "description": "ISO timestamp when the user became verified." + "description": "EscrowOp status after submission." }, - "reviewedAt": { + "txHash": { "type": "string", - "description": "ISO timestamp of the last status transition." - }, - "reviewWindow": { - "description": "Estimated review window. Present only when state === \"in_review\".", - "allOf": [ - { - "$ref": "#/components/schemas/ReviewWindowDto" - } - ] - }, - "decline": { - "description": "Decline details. Present only when state === \"declined\".", - "allOf": [ - { - "$ref": "#/components/schemas/DeclineDetailsDto" - } - ] + "nullable": true } }, - "required": ["state", "canStartNew", "message"] + "required": ["opId", "milestoneId", "status", "txHash"] }, - "CreateDiditSessionDto": { + "AdminWalletUserPreviewDto": { "type": "object", - "properties": {} + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "image": { + "type": "string", + "nullable": true, + "description": "Profile photo URL, when set" + } + }, + "required": ["id", "name", "image"] }, - "PricingPreviewResponseDto": { + "AdminWalletRowDto": { "type": "object", "properties": { - "feeBps": { - "type": "number", - "description": "Effective rate applied to this preview." + "id": { + "type": "string" }, - "feeStroops": { + "address": { "type": "string", - "description": "Fee in stroops. String to preserve i128 precision." + "description": "Stellar public key (G-address)" }, - "poolStroops": { + "status": { "type": "string", - "description": "Pool released to winners; equals the requested budget." + "enum": ["active", "inactive"], + "description": "Activation state" }, - "totalDepositStroops": { - "type": "string", - "description": "budgetStroops + feeStroops; what the organizer signs for." + "users": { + "type": "number", + "description": "Number of users linked to this wallet" }, - "reason": { + "userPreviews": { + "description": "A capped preview of the linked users, for avatars in the list", + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminWalletUserPreviewDto" + } + }, + "created": { "type": "string", - "description": "Audit label for the rate choice: default | foundation-tier | sales-override:* | waiver:*." + "description": "ISO timestamp the wallet was created" } }, "required": [ - "feeBps", - "feeStroops", - "poolStroops", - "totalDepositStroops", - "reason" + "id", + "address", + "status", + "users", + "userPreviews", + "created" ] }, + "PaginatedWalletsDto": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminWalletRowDto" + } + }, + "page": { + "type": "number" + }, + "limit": { + "type": "number" + }, + "total": { + "type": "number" + }, + "totalPages": { + "type": "number" + } + }, + "required": ["items", "page", "limit", "total", "totalPages"] + }, "Function": { "type": "object", "properties": {} @@ -42868,14 +49900,21 @@ "description": "Bounty description", "maxLength": 5000 }, + "category": { + "type": "string", + "enum": ["DESIGN", "DEVELOPMENT", "CONTENT", "GROWTH", "COMMUNITY"], + "description": "Discipline the bounty falls under. DEVELOPMENT requires githubIssueUrl." + }, + "country": { + "type": "string", + "nullable": true, + "description": "Country where the bounty is created." + }, "githubIssueUrl": { "type": "string", "format": "uri", - "nullable": true - }, - "githubIssueNumber": { - "type": "number", - "nullable": true + "nullable": true, + "description": "Required when category = DEVELOPMENT." }, "projectId": { "type": "string", @@ -42981,6 +50020,46 @@ }, "required": ["rewardCurrency", "prizeTiers"] }, + "BountyResourceItemDto": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Client-generated resource id" + }, + "link": { + "type": "string" + }, + "description": { + "type": "string" + }, + "file": { + "type": "object", + "description": "Uploaded file metadata", + "properties": { + "url": { + "type": "string" + }, + "name": { + "type": "string" + } + } + } + }, + "required": ["id"] + }, + "BountyResourcesSectionDto": { + "type": "object", + "properties": { + "resources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BountyResourceItemDto" + } + } + }, + "required": ["resources"] + }, "BountyDraftDataDto": { "type": "object", "properties": { @@ -42995,6 +50074,9 @@ }, "reward": { "$ref": "#/components/schemas/BountyRewardSectionDto" + }, + "resources": { + "$ref": "#/components/schemas/BountyResourcesSectionDto" } } }, @@ -43100,6 +50182,9 @@ "reward": { "$ref": "#/components/schemas/BountyRewardSectionDto" }, + "resources": { + "$ref": "#/components/schemas/BountyResourcesSectionDto" + }, "autoSave": { "type": "boolean", "description": "Hint that this is an autosave (no completion side effects)." @@ -43172,6 +50257,10 @@ "enum": ["EXTERNAL", "MANAGED"], "default": "EXTERNAL", "example": "MANAGED" + }, + "sourceWalletId": { + "type": "string", + "description": "For MANAGED funding, the organization treasury wallet to fund from. When set, the backend signs with that treasury (managed) wallet instead of the caller's personal wallet; ownerAddress must match the treasury wallet address. Omit to fund from the personal managed wallet." } }, "required": [ @@ -43464,6 +50553,104 @@ }, "required": ["applicantAddress"] }, + "BountyApplicationResponseDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "bountyId": { + "type": "string" + }, + "applicantAddress": { + "type": "string", + "description": "G-address that receives payout if selected." + }, + "status": { + "type": "string", + "description": "Escrow lifecycle: pending_confirm | active | withdrawn | failed." + }, + "applicationStatus": { + "type": "string", + "enum": [ + "SUBMITTED", + "SHORTLISTED", + "SELECTED", + "DECLINED", + "WITHDRAWN" + ], + "nullable": true, + "description": "Application lifecycle (SUBMITTED/SHORTLISTED/SELECTED/DECLINED/WITHDRAWN). Null for legacy OPEN + SINGLE_CLAIM rows." + }, + "proposalShort": { + "type": "string", + "nullable": true + }, + "proposalFull": { + "type": "string", + "nullable": true + }, + "portfolioLinks": { + "type": "array", + "items": { + "type": "string" + } + }, + "estimatedDays": { + "type": "number", + "nullable": true + }, + "qualifications": { + "type": "string", + "nullable": true + }, + "videoIntroUrl": { + "type": "string", + "nullable": true + }, + "declineReason": { + "type": "string", + "nullable": true + }, + "shortlistedAt": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "selectedAt": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "declinedAt": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "withdrawnAt": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "bountyId", + "applicantAddress", + "status", + "portfolioLinks", + "createdAt", + "updatedAt" + ] + }, "EditBountyApplicationDto": { "type": "object", "properties": { @@ -43535,6 +50722,317 @@ }, "required": ["applicantAddress"] }, + "BountySummaryDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "status": { + "type": "string", + "description": "Pillar lifecycle state (lowercase)." + }, + "entryType": { + "type": "string", + "enum": ["OPEN", "APPLICATION_LIGHT", "APPLICATION_FULL"], + "nullable": true + }, + "claimType": { + "type": "string", + "enum": ["SINGLE_CLAIM", "COMPETITION"], + "nullable": true + }, + "rewardCurrency": { + "type": "string" + }, + "deadline": { + "type": "string", + "format": "date-time", + "nullable": true, + "description": "Work/submission deadline (published value, falling back to the draft)." + } + }, + "required": ["id", "title", "status", "rewardCurrency"] + }, + "MyBountyApplicationRowDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "applicationStatus": { + "type": "string", + "enum": [ + "SUBMITTED", + "SHORTLISTED", + "SELECTED", + "DECLINED", + "WITHDRAWN" + ], + "nullable": true, + "description": "SUBMITTED / SHORTLISTED / SELECTED / DECLINED / WITHDRAWN." + }, + "status": { + "type": "string", + "description": "Escrow lifecycle: pending_confirm | active | withdrawn | failed." + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "bounty": { + "$ref": "#/components/schemas/BountySummaryDto" + } + }, + "required": ["id", "status", "createdAt", "updatedAt", "bounty"] + }, + "MyBountyApplicationListDto": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MyBountyApplicationRowDto" + } + }, + "total": { + "type": "number" + }, + "page": { + "type": "number" + }, + "limit": { + "type": "number" + } + }, + "required": ["items", "total", "page", "limit"] + }, + "MyBountySubmissionRowDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "status": { + "type": "string", + "description": "Off-chain review state." + }, + "escrowAnchorStatus": { + "type": "string", + "nullable": true + }, + "githubPullRequestUrl": { + "type": "string", + "nullable": true + }, + "tierPosition": { + "type": "number", + "nullable": true + }, + "tierAmount": { + "type": "string", + "nullable": true, + "description": "Won amount in token-native units (decimal string)." + }, + "rewardTransactionHash": { + "type": "string", + "nullable": true + }, + "paidAt": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "bounty": { + "$ref": "#/components/schemas/BountySummaryDto" + } + }, + "required": ["id", "status", "createdAt", "updatedAt", "bounty"] + }, + "MyBountySubmissionListDto": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MyBountySubmissionRowDto" + } + }, + "total": { + "type": "number" + }, + "page": { + "type": "number" + }, + "limit": { + "type": "number" + } + }, + "required": ["items", "total", "page", "limit"] + }, + "BountyWinnerDto": { + "type": "object", + "properties": { + "submissionId": { + "type": "string" + }, + "tierPosition": { + "type": "number", + "description": "1 = 1st place." + }, + "tierAmount": { + "type": "string", + "description": "Won amount (token-native units, decimal string)." + }, + "submittedBy": { + "type": "string", + "description": "User id of the winner." + }, + "applicantAddress": { + "type": "string", + "nullable": true + }, + "githubPullRequestUrl": { + "type": "string", + "nullable": true + }, + "contentUri": { + "type": "string", + "nullable": true + }, + "rewardTransactionHash": { + "type": "string", + "nullable": true + }, + "paidAt": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "submissionId", + "tierPosition", + "tierAmount", + "submittedBy" + ] + }, + "BountyResultsDto": { + "type": "object", + "properties": { + "bountyId": { + "type": "string" + }, + "status": { + "type": "string", + "description": "Pillar lifecycle state (lowercase)." + }, + "isComplete": { + "type": "boolean", + "description": "True once the bounty has completed." + }, + "rewardCurrency": { + "type": "string" + }, + "winners": { + "description": "Winners, by tier.", + "type": "array", + "items": { + "$ref": "#/components/schemas/BountyWinnerDto" + } + } + }, + "required": [ + "bountyId", + "status", + "isComplete", + "rewardCurrency", + "winners" + ] + }, + "BountySubmissionViewDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "submittedBy": { + "type": "string" + }, + "isOwn": { + "type": "boolean", + "description": "True when this is the caller’s own submission." + }, + "status": { + "type": "string", + "description": "Off-chain review state." + }, + "escrowAnchorStatus": { + "type": "string", + "nullable": true + }, + "applicantAddress": { + "type": "string", + "nullable": true + }, + "githubPullRequestUrl": { + "type": "string", + "nullable": true + }, + "contentUri": { + "type": "string", + "nullable": true + }, + "tierPosition": { + "type": "number", + "nullable": true + }, + "tierAmount": { + "type": "string", + "nullable": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + } + }, + "required": ["id", "submittedBy", "isOwn", "status", "createdAt"] + }, + "BountySubmissionListDto": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BountySubmissionViewDto" + } + }, + "visibility": { + "type": "string", + "enum": ["ORGANIZER_ONLY", "HIDDEN_UNTIL_DEADLINE"] + }, + "peersVisible": { + "type": "boolean", + "description": "Whether peer submissions are visible to the caller (organizer, or HIDDEN_UNTIL_DEADLINE past the deadline). When false, only the caller’s own submission is returned." + } + }, + "required": ["items", "visibility", "peersVisible"] + }, "BountyPrizeTierPublicDto": { "type": "object", "properties": {