{"openapi":"3.1.0","paths":{"/health":{"get":{"operationId":"HealthController_liveness","parameters":[],"responses":{"200":{"description":""}},"tags":["Health"]}},"/ready":{"get":{"operationId":"HealthController_readiness","parameters":[],"responses":{"200":{"description":"The Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":["object","null"],"example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}},"error":{"type":["object","null"],"example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":["object","null"],"example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}},"error":{"type":["object","null"],"example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"tags":["Health"]}},"/api/internal/sentry-test":{"get":{"operationId":"InternalController_sentryTest","parameters":[{"name":"x-internal-token","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Internal"]}},"/api/internal/heartbeat-test":{"get":{"operationId":"InternalController_heartbeatTest","parameters":[{"name":"x-internal-token","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Internal"]}},"/api/v1/admin/dashboard/summary":{"get":{"operationId":"adminDashboardSummary","parameters":[],"responses":{"200":{"description":""}},"security":[{"internal-token":[]}],"summary":"KPI tiles for /admin/dashboard.","tags":["Admin"]}},"/api/v1/admin/dashboard/deadlines":{"get":{"operationId":"adminDashboardDeadlines","parameters":[{"name":"limit","required":false,"in":"query","schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":""}},"security":[{"internal-token":[]}],"summary":"Upcoming deadlines.","tags":["Admin"]}},"/api/v1/admin/sources/health":{"get":{"operationId":"adminSourcesHealth","parameters":[],"responses":{"200":{"description":""}},"security":[{"internal-token":[]}],"summary":"Connector health overview.","tags":["Admin"]}},"/api/v1/admin/calls/{id}":{"patch":{"description":"Requires `x-internal-token` header. Editor-level mutation: any field touched here is appended to Call.manuallyEditedFields so the next AI re-run leaves it alone.","operationId":"adminPatchCall","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"internal-token":[]}],"summary":"Inline-editor save — sets manuallyEditedFields per spec §5.4 M11.","tags":["Admin"]}},"/api/v1/admin/calls":{"post":{"description":"Requires `x-internal-token` header. Marks all populated fields as locked.","operationId":"adminCreateCall","parameters":[],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"summary":"Manually add a call for a source without an active connector.","tags":["Admin"]}},"/api/v1/admin/calls/bulk-import":{"post":{"description":"For sources whose live connector is blocked (CAPTCHA, JS-only tables) the operator downloads the portal's native export and uploads it here. Keys on (sourceId, externalId); re-imports overwrite cleanly. Bad rows surface in errors[] with their index — one parse failure doesn't kill the whole batch.","operationId":"adminBulkImportCalls","parameters":[],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"summary":"Idempotently upsert many calls for one source from an XLSX/JSON export.","tags":["Admin"]}},"/api/v1/admin/users/{id}":{"patch":{"description":"Requires `x-internal-token`. Called by the /admin/profile Server Action.","operationId":"adminPatchUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"internal-token":[]}],"summary":"Update a user profile (name).","tags":["Admin"]}},"/api/v1/admin/users/{id}/password":{"post":{"description":"Requires `x-internal-token`. **Trust boundary:** the :id parameter is trusted because the web Server Action passes the authenticated NextAuth session.user.id; the API does NOT independently verify :id matches an authenticated session. If `INTERNAL_OPS_TOKEN` is compromised, an attacker can change any user's password. Operational mitigation: every call emits an `auth.password.changed` audit event with userId+ip+userAgent; alerts on cross-IP anomalies should trigger token rotation via scripts/generate-prod-secrets.sh.","operationId":"adminChangePassword","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"summary":"Set or change a user password (scrypt hashed).","tags":["Admin"]}},"/api/v1/admin/auth/verify-credentials":{"post":{"description":"Requires `x-internal-token` so only the web Server Action layer can call this. Returns 200 + user payload on success, 401 on mismatch. Constant-time verify via scrypt.","operationId":"adminVerifyCredentials","parameters":[],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"summary":"Verify (email, password) — used by NextAuth Credentials provider.","tags":["Admin"]}},"/api/v1/admin/auth/register":{"post":{"description":"Called by the web Server Action at /registracia. Returns the new userId + organizationId + plan; the web then signs the user in via the Credentials provider using the freshly hashed password.","operationId":"adminRegister","parameters":[],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"summary":"First-owner registration — creates user + organisation + subscription atomically.","tags":["Admin"]}},"/api/v1/admin/categories/proposed":{"get":{"description":"AI-suggested categories not yet in the controlled vocabulary, ordered newest-first. Default returns only pending; pass ?status=all|approved|rejected to widen.","operationId":"listProposedCategories","parameters":[{"name":"status","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"internal-token":[]}],"summary":"List proposed-category review queue.","tags":["Admin"]}},"/api/v1/admin/categories/proposed/{id}/approve":{"post":{"description":"Creates a Category row from the proposal, marks the proposal approved, and re-attaches the originating call to the new category (so the AI doesn't have to re-propose it).","operationId":"approveProposedCategory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"summary":"Promote a proposal into the Category vocabulary.","tags":["Admin"]}},"/api/v1/admin/categories/proposed/{id}/reject":{"post":{"operationId":"rejectProposedCategory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"summary":"Mark a proposal rejected (kept for audit, deduped on re-propose).","tags":["Admin"]}},"/api/v1/admin/auth/audit-signout":{"post":{"description":"Sign-out fires before the cookie clears, so the web Server Action knows the userId. This endpoint persists it to audit_event so the forensic trail covers both sign-in and sign-out (compliance + incident response needs a complete session timeline).","operationId":"adminAuditSignout","parameters":[],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"summary":"Record an auth.signout audit event — called from NextAuth events.signOut.","tags":["Admin"]}},"/api/v1/api-keys":{"get":{"operationId":"ApiKeysController_list_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Organizations"]},"post":{"operationId":"ApiKeysController_create_v1","parameters":[],"responses":{"201":{"description":""}},"tags":["Organizations"]}},"/api/v1/api-keys/scopes":{"get":{"operationId":"ApiKeysController_scopes_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/api-keys/{publicId}/usage":{"get":{"operationId":"ApiKeysController_usageForKey_v1","parameters":[{"name":"publicId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/api-keys/{publicId}":{"delete":{"operationId":"ApiKeysController_revoke_v1","parameters":[{"name":"publicId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/oauth/register":{"post":{"operationId":"registerOAuthClient","parameters":[],"responses":{"201":{"description":""}},"summary":"Dynamic Client Registration (RFC 7591).","tags":["Organizations"]}},"/api/v1/oauth/token":{"post":{"operationId":"oauthToken","parameters":[],"responses":{"201":{"description":""}},"summary":"Token endpoint — authorization_code / refresh_token / client_credentials.","tags":["Organizations"]}},"/api/v1/oauth/revoke":{"post":{"operationId":"oauthRevoke","parameters":[],"responses":{"201":{"description":""}},"summary":"Revoke an access token (RFC 7009).","tags":["Organizations"]}},"/api/v1/.well-known/oauth-authorization-server":{"get":{"operationId":"OAuthDiscoveryController_authorizationServerMetadata_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["OAuthDiscovery"]}},"/api/v1/.well-known/oauth-protected-resource":{"get":{"operationId":"OAuthDiscoveryController_protectedResourceMetadata_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["OAuthDiscovery"]}},"/api/v1/organizations/current/members":{"get":{"operationId":"OrganizationsController_listMembers_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/organizations/current/members/{userId}":{"patch":{"operationId":"OrganizationsController_changeRole_v1","parameters":[{"name":"userId","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":""}},"tags":["Organizations"]},"delete":{"operationId":"OrganizationsController_removeMember_v1","parameters":[{"name":"userId","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/organizations/current/invitations":{"get":{"operationId":"OrganizationsController_listInvitations_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Organizations"]},"post":{"operationId":"OrganizationsController_createInvitation_v1","parameters":[],"responses":{"201":{"description":""}},"tags":["Organizations"]}},"/api/v1/organizations/current/invitations/{id}":{"delete":{"operationId":"OrganizationsController_revokeInvitation_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/invitations/{token}":{"get":{"operationId":"PublicInvitationsController_preview_v1","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/invitations/{token}/accept":{"post":{"operationId":"PublicInvitationsController_accept_v1","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"internal-token":[]}],"tags":["Organizations"]}},"/api/v1/calls":{"get":{"description":"Pagination via `page`/`perPage`. Filter params accept either a comma-separated string (`?status=open,closing-soon`) or repeated query keys (`?status=open&status=closing-soon`).","operationId":"listCalls","parameters":[],"responses":{"200":{"description":""}},"summary":"List grant calls with optional filters.","tags":["Calls"]}},"/api/v1/calls/search":{"get":{"operationId":"searchCalls","parameters":[],"responses":{"200":{"description":""}},"summary":"Hybrid keyword + semantic search across the grant calls catalogue.","tags":["Calls"]}},"/api/v1/calls/{slug}":{"get":{"operationId":"getCall","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Get a single grant call by slug.","tags":["Calls"]}},"/api/v1/calls/{slug}/versions":{"get":{"description":"Versions are emitted by the normalization pipeline whenever a source-side change is detected. Includes a pre-computed markdown diff summary for the deltas vs the previous version.","operationId":"listCallVersions","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Get the version history of a grant call.","tags":["Calls"]}},"/api/v1/calls/{slug}/similar":{"get":{"description":"pgvector cosine over the stored 1024-d embeddings. Returns the top `limit` calls (default 10, max 50) with a `similarity` score in [0,1]; the source call itself is filtered out.","operationId":"listSimilarCalls","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Calls semantically similar to the given one.","tags":["Calls"]}},"/api/v1/calls/{slug}/insights":{"get":{"description":"Joins Contract.related_call_id (CRZ — signed contracts) and Project.related_call_id (CRP — awarded projects) for the given call slug. Returns counts, totals, and the most recent recipients. Public so the detail page can render insights for anonymous visitors per spec UX screen #3.","operationId":"getCallInsights","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Aggregated CRP/CRZ insights for one call (UX screen #3).","tags":["Calls"]}},"/api/v1/cross-ref/call-history/{ico}":{"get":{"description":"Lazily refreshes the local CRP/CRZ cache from the public registries; returns up to 100 most-recent rows per side plus aggregate stats (count, total amount, most recent date). Use this as a \"track record\" signal next to find_calls_for_organization.","operationId":"getCallHistory","parameters":[{"name":"ico","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Past awarded projects (CRP) and signed contracts (CRZ) for a Slovak IČO.","tags":["Calls"]}},"/api/v1/cross-ref/aid-pipeline/{slug}":{"get":{"description":"Returns the contracts + projects whose related_call_id matches this slug. Use this to answer \"did this call actually pay out?\" and \"who won the previous round?\".","operationId":"getAidPipeline","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Downstream CRP projects and CRZ contracts derived from a grant call.","tags":["Calls"]}},"/api/v1/eligibility/by-ico/{ico}":{"get":{"description":"Resolves the IČO via the RPO (authoritative) + ORSR (statutory bodies) bridge, maps NUTS3 region to a Region slug, and runs the same explainable scoring used by the dashboard. Returns the org metadata + the today / this-week split with per-call reasons.","operationId":"findCallsForOrganization","parameters":[{"name":"ico","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Find grant calls eligible for an organisation looked up by Slovak IČO.","tags":["Calls"]}},"/api/v1/eligibility/match":{"post":{"description":"Powers the /opravnenost wizard. Accepts either a Slovak IČO (we look it up via RPO/ORSR and derive region + NACE) or a manual profile (target-group + region + self-declared sectors). Returns the same { today, thisWeek } shape as the dashboard with per-call fit score and explanation reasons.","operationId":"matchEligibility","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EligibilityMatchRequest"}}}},"responses":{"201":{"description":""}},"summary":"Score open + upcoming calls against a manual eligibility profile.","tags":["Calls"]}},"/api/v1/integrations/hubspot/install":{"get":{"operationId":"hubspotInstallUrl","parameters":[],"responses":{"200":{"description":""}},"summary":"Generate the HubSpot install URL.","tags":["Organizations"]}},"/api/v1/integrations/hubspot/callback":{"get":{"operationId":"hubspotCallback","parameters":[{"name":"code","required":true,"in":"query","schema":{"type":"string"}},{"name":"state","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"HubSpot OAuth redirect handler.","tags":["Organizations"]}},"/api/v1/integrations/hubspot":{"get":{"operationId":"HubSpotController_list_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/hubspot/{id}/revoke":{"post":{"operationId":"HubSpotController_revoke_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"201":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/pipedrive/install":{"get":{"operationId":"pipedriveInstallUrl","parameters":[],"responses":{"200":{"description":""}},"summary":"Generate the Pipedrive install URL.","tags":["Organizations"]}},"/api/v1/integrations/pipedrive/callback":{"get":{"operationId":"pipedriveCallback","parameters":[{"name":"code","required":true,"in":"query","schema":{"type":"string"}},{"name":"state","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Pipedrive OAuth redirect handler.","tags":["Organizations"]}},"/api/v1/integrations/pipedrive":{"get":{"operationId":"PipedriveController_list_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/pipedrive/{id}/revoke":{"post":{"operationId":"PipedriveController_revoke_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"201":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/notion/install":{"get":{"operationId":"notionInstallUrl","parameters":[],"responses":{"200":{"description":""}},"summary":"Generate the Notion install URL.","tags":["Organizations"]}},"/api/v1/integrations/notion/callback":{"get":{"operationId":"notionCallback","parameters":[{"name":"code","required":true,"in":"query","schema":{"type":"string"}},{"name":"state","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Notion OAuth redirect handler.","tags":["Organizations"]}},"/api/v1/integrations/notion":{"get":{"operationId":"NotionController_list_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/notion/{id}/databases":{"get":{"operationId":"notionListDatabases","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":""}},"summary":"List Notion databases the bot has access to (max 100).","tags":["Organizations"]}},"/api/v1/integrations/notion/{id}/database":{"post":{"operationId":"NotionController_configureDatabase_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"201":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/notion/{id}/revoke":{"post":{"operationId":"NotionController_revoke_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"201":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/google-calendar/install":{"get":{"operationId":"googleCalendarInstallUrl","parameters":[],"responses":{"200":{"description":""}},"summary":"Generate the Google Calendar install URL.","tags":["Organizations"]}},"/api/v1/integrations/google-calendar/callback":{"get":{"operationId":"googleCalendarCallback","parameters":[{"name":"code","required":true,"in":"query","schema":{"type":"string"}},{"name":"state","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Google Calendar OAuth redirect handler.","tags":["Organizations"]}},"/api/v1/integrations/google-calendar":{"get":{"operationId":"GoogleCalendarController_list_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/google-calendar/{id}/calendars":{"get":{"operationId":"googleCalendarListCalendars","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":""}},"summary":"List calendars the user can write to (writer/owner role).","tags":["Organizations"]}},"/api/v1/integrations/google-calendar/{id}/calendar":{"post":{"operationId":"GoogleCalendarController_configureCalendar_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"201":{"description":""}},"tags":["Organizations"]}},"/api/v1/integrations/google-calendar/{id}/revoke":{"post":{"operationId":"GoogleCalendarController_revoke_v1","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"201":{"description":""}},"tags":["Organizations"]}},"/api/v1/watchdogs/{watchdogId}/feed.xml":{"get":{"operationId":"RssFeedController_feed_v1","parameters":[{"name":"watchdogId","required":true,"in":"path","schema":{"type":"string"}},{"name":"token","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Notifications"]}},"/api/v1/notifications":{"get":{"operationId":"listNotifications","parameters":[],"responses":{"200":{"description":""}},"summary":"Recent watchdog matches with their delivery status per channel.","tags":["Notifications"]}},"/api/v1/webhooks":{"get":{"operationId":"WebhooksController_list_v1","parameters":[],"responses":{"200":{"description":""}},"tags":["Notifications"]},"post":{"operationId":"WebhooksController_create_v1","parameters":[],"responses":{"201":{"description":""}},"tags":["Notifications"]}},"/api/v1/webhooks/{publicId}":{"patch":{"operationId":"WebhooksController_update_v1","parameters":[{"name":"publicId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Notifications"]},"delete":{"operationId":"WebhooksController_remove_v1","parameters":[{"name":"publicId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Notifications"]}},"/api/v1/webhooks/{publicId}/rotate-secret":{"post":{"operationId":"WebhooksController_rotateSecret_v1","parameters":[{"name":"publicId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Notifications"]}},"/api/v1/webhooks/{publicId}/deliveries":{"get":{"operationId":"WebhooksController_listDeliveries_v1","parameters":[{"name":"publicId","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"perPage","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Notifications"]}},"/api/v1/webhooks/{publicId}/deliveries/{deliveryId}":{"get":{"operationId":"WebhooksController_getDelivery_v1","parameters":[{"name":"publicId","required":true,"in":"path","schema":{"type":"string"}},{"name":"deliveryId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Notifications"]}},"/api/v1/webhooks/{publicId}/deliveries/{deliveryId}/retry":{"post":{"operationId":"WebhooksController_retryDelivery_v1","parameters":[{"name":"publicId","required":true,"in":"path","schema":{"type":"string"}},{"name":"deliveryId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Notifications"]}},"/api/v1/organizations/me":{"get":{"description":"Returns the org metadata + the OrgProfile (when filled) + the current subscription snapshot + aggregate counts for members / active watchdogs. Cache-Control: private, max-age=60 — the profile changes only on explicit admin edits.","operationId":"getMyOrganization","parameters":[],"responses":{"200":{"description":""}},"summary":"The organisation associated with the calling API key.","tags":["Organizations"]}},"/api/v1/sources":{"get":{"operationId":"listSources","parameters":[],"responses":{"200":{"description":""}},"summary":"List configured data sources.","tags":["Calls"]}},"/api/v1/categories":{"get":{"operationId":"listCategories","parameters":[],"responses":{"200":{"description":""}},"summary":"Controlled vocabulary of grant categories.","tags":["Calls"]}},"/api/v1/target-groups":{"get":{"operationId":"listTargetGroups","parameters":[],"responses":{"200":{"description":""}},"summary":"Controlled vocabulary of eligible target groups.","tags":["Calls"]}},"/api/v1/regions":{"get":{"operationId":"listRegions","parameters":[],"responses":{"200":{"description":""}},"summary":"Eligible regions (NUTS3 + country).","tags":["Calls"]}},"/api/v1/aid-types":{"get":{"operationId":"listAidTypes","parameters":[],"responses":{"200":{"description":""}},"summary":"Aid-type catalogue (grant / loan / guarantee / blended).","tags":["Calls"]}},"/api/v1/watchdogs":{"get":{"operationId":"WatchdogsController_list_v1","parameters":[{"name":"x-org-id","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Watchdogs"]},"post":{"operationId":"WatchdogsController_create_v1","parameters":[{"name":"x-org-id","required":true,"in":"header","schema":{"type":"string"}},{"name":"x-user-id","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Watchdogs"]}},"/api/v1/watchdogs/{id}":{"get":{"operationId":"WatchdogsController_findOne_v1","parameters":[{"name":"x-org-id","required":true,"in":"header","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":""}},"tags":["Watchdogs"]},"patch":{"operationId":"WatchdogsController_update_v1","parameters":[{"name":"x-org-id","required":true,"in":"header","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":""}},"tags":["Watchdogs"]},"delete":{"operationId":"WatchdogsController_remove_v1","parameters":[{"name":"x-org-id","required":true,"in":"header","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":""}},"tags":["Watchdogs"]}}},"info":{"title":"Grantus API","description":"Public REST API for grantus.sk — Slovak/EU grant calls catalogue with AI classification, watchdog alerts, and webhook subscriptions.","version":"1","contact":{"name":"grantus support","url":"https://grantus.sk","email":"api@grantus.sk"},"license":{"name":"Apache-2.0","url":"https://www.apache.org/licenses/LICENSE-2.0"}},"tags":[{"name":"Calls","description":"Grant calls catalogue + search."},{"name":"Watchdogs","description":"Saved searches with notifications."},{"name":"Notifications","description":"Inbox + RSS + webhooks."},{"name":"Organizations","description":"Members, invitations, roles."},{"name":"Billing","description":"Subscriptions + plans + invoices."},{"name":"Health","description":"Liveness + readiness probes."}],"servers":[{"url":"https://api.grantus.sk","description":"Default"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"},"api-key":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"API key (Business+ plans)."}},"schemas":{}},"externalDocs":{"description":"grantus.sk","url":"https://grantus.sk"}}