# Nixelo Public API Overview

> TLDR: LLM-facing overview of mounted Nixelo HTTP endpoints, authentication, API-key scopes, booking APIs, webhooks, and MCP scheduling.

> Generated by `pnpm run public:markdown:generate`. Edit `src/content/publicMarkdown.ts`, not the generated public file.

Source: docs/API.md

The canonical API source is docs/API.md. This export summarizes the mounted public and authenticated API surface for search, retrieval, and tool planning.

## Base URLs

- Production HTTP actions run on the Convex site domain or through the Railway same-origin /api/* proxy.
- Development uses the package-owned local Convex site at http://127.0.0.1:3211.
- Browser production flows should prefer same-origin app requests where Railway proxies /api/* to Convex.

## Authentication

- API-key protected routes accept Authorization: Bearer sk_casc_<32_random_characters>.
- Short-lived scoped tokens use Authorization: Bearer st_casc_<32_random_characters> for automation workers and future AI tool execution.
- API keys and scoped tokens are stored hashed, shown once, rate-limited, and validated by Convex before route handlers run.
- Hosted MCP scheduling accepts admin-created organization service credentials with the mcp_nxl prefix or Nixelo-issued delegated OAuth access tokens.
- Delegated MCP OAuth may issue mcp:scheduling:intents:create, mcp:meetings:intents:create, and mcp:time:intents:create for user-bound scheduling, Google Meet, and employee-time proposal flows; admin-created service credentials may also opt into the scheduling intent scope.
- Delegated MCP OAuth uses authorization code with PKCE S256, public-client token exchange, rotating refresh tokens, and exact protected-resource audience binding.

## Mounted HTTP Endpoints

- POST /mcp: hosted MCP scheduling server for service credentials and delegated OAuth access tokens; under-scoped tools/list returns an empty tools array, while an unavailable tools/call returns HTTP 200 with JSON-RPC -32602.
- calendar.create_event creates or replays a needs_confirmation intent only. An authorized organization member reviews and confirms it in Nixelo, and only that confirming member may execute it after current credential, policy, resource, and calendar authorization are revalidated.
- GET /.well-known/oauth-protected-resource/mcp: MCP protected-resource metadata.
- GET /.well-known/oauth-authorization-server/oauth: delegated MCP authorization-server metadata.
- POST /oauth/token: public-client authorization-code and refresh-token exchange for the MCP resource.
- GET /api/issues?projectId=<projectId>: API-key protected issue list for a project.
- GET /api/issues/<issueKey>?projectId=<projectId>: exact selected-project issue read with authoritative version.
- POST /api/issues?projectId=<projectId>: selected-project issue creation with mandatory replay-safe operationId.
- PATCH /api/issues/<issueKey>?projectId=<projectId>: selected-project issue update with mandatory expectedVersion.
- DELETE /api/issues/<issueKey>: replay-safe cleanup of an issue created by the same API key owner and operationId.
- GET /api/project-members?projectId=<projectId>: API-key protected assignable-member discovery for a project.
- GET /api/projects: page current accessible projects for an organization key or discover the project bound to a project key.
- POST /api/outreach/complaints: provider-neutral complaint intake requiring outreach_complaints:write on a durable organization-scoped API key whose owner remains an organization owner or admin.
- POST /api/intake and POST /api/intake?token=<intakeToken>: public intake submission flows.
- GET, POST, PATCH /api/booking-webhooks and GET /api/booking-webhooks/:subscriptionId/deliveries: project booking webhook management and delivery status.
- GET /api/public-booking/:slug and GET /api/public-booking/:slug/slots: public booking page lookup and slot discovery.
- POST /api/public-booking/:slug/payment-intent and POST /api/public-booking/:slug/book: payment authorization and booking creation.
- GET /api/public-booking/:slug/manage, POST /api/public-booking/:slug/cancel, and POST /api/public-booking/:slug/reschedule: public booking management-token flows.
- GET /api/public-booking-routing/:slug and POST /api/public-booking-routing/:slug/submit: public routing-form lookup and submission.

## Authenticated Convex Surfaces

- Booking pages, calendar feeds, bookings, analytics, availability, booking webhooks, booking automations, branding, and custom domains are managed through Convex functions documented in docs/API.md.
- API key generation, scope metadata, short-lived scoped tokens, revocation, rotation, and usage logs are owned by convex/apiKeys.ts.
- Calendar provider setup metadata is exposed through Convex functions so settings UI does not duplicate provider contracts.

## API-Key HTTP Operation Support

| Operation | Status | Method and path | Scope | Stability | Limitation |
| --- | --- | --- | --- | --- | --- |
| booking_webhook_deliveries.list | partial | GET /api/booking-webhooks/:subscriptionId/deliveries | booking_webhooks:read | unversioned | Returns at most 100 deliveries without pagination metadata and omits request payloads. |
| booking_webhooks.create | supported | POST /api/booking-webhooks | booking_webhooks:write | unversioned |  |
| booking_webhooks.list | partial | GET /api/booking-webhooks | booking_webhooks:read | unversioned | Project-scoped keys only; results are capped at 100 without pagination metadata. |
| booking_webhooks.update | partial | PATCH /api/booking-webhooks/:subscriptionId | booking_webhooks:write | unversioned | The REST adapter provides no optimistic concurrency contract. |
| issues.create | partial | POST /api/issues | issues:write | pre-stable | Project- and organization-scoped keys can create task, bug, story, and epic issues in one selected editable project with optional description, priority, and assignee; broader create fields remain unmounted. |
| issues.delete | partial | DELETE /api/issues/:key | issues:delete | pre-stable | Project-scoped keys can delete only issues created by the same key owner with the matching create operationId. |
| issues.get | partial | GET /api/issues/:key | issues:read | pre-stable | Reads one issue in the selected project with its authoritative version; broader issue detail subresources remain unmounted. |
| issues.list | partial | GET /api/issues | issues:read | pre-stable | Project- and organization-scoped keys can list one selected project's issues with normalized authoritative versions; cross-project aggregate listing remains unmounted. |
| issues.update | partial | PATCH /api/issues/:key | issues:write | pre-stable | Project- and organization-scoped keys can update title, description, priority, and assignee in one selected editable project with mandatory optimistic concurrency; broader issue fields remain unmounted. |
| outreach_complaints.create | partial | POST /api/outreach/complaints | outreach_complaints:write | unversioned | Accepts provider complaint evidence only through an organization-scoped API key; callers must supply a stable external event ID and the affected email address. |
| project_members.list_assignable | partial | GET /api/project-members | projects:read | pre-stable | Project- and organization-scoped assignable-member discovery paginates one selected project before enrichment and returns no partial data with complete=false and overflow=true when a canonical membership source exceeds its bounded scan. |
| projects.list | partial | GET /api/projects | projects:read | pre-stable | Organization-bound keys return bounded current-access pages with explicit completeness, overflow, and issue-write eligibility; project-scoped keys retain their one-project compatibility response. |
| time_entries.add_weekly_row | supported | POST /api/time-entries/weekly/rows | time:write | beta |  |
| time_entries.copy_previous_week_rows | supported | POST /api/time-entries/weekly/copy | time:write | beta |  |
| time_entries.create | supported | POST /api/time-entries | time:write | beta |  |
| time_entries.delete | supported | DELETE /api/time-entries/:entryId | time:write | beta |  |
| time_entries.get_weekly | supported | GET /api/time-entries/weekly | time:read | beta |  |
| time_entries.link_issue | supported | PATCH /api/time-entries/:entryId/issue | time:write | beta |  |
| time_entries.list | supported | GET /api/time-entries | time:read | beta |  |
| time_entries.remove_weekly_row | supported | DELETE /api/time-entries/weekly/rows | time:write | beta |  |
| time_entries.set_weekly_cell | supported | PATCH /api/time-entries/weekly/cells | time:write | beta |  |
| time_entries.start | supported | POST /api/time-entries/start | time:write | beta |  |
| time_entries.stop | supported | POST /api/time-entries/stop | time:write | beta |  |
| time_entries.summarize | supported | GET /api/time-entries/summary | time:read | beta |  |
| time_entries.unlink_issue | supported | DELETE /api/time-entries/:entryId/issue | time:write | beta |  |
| time_entries.update | supported | PATCH /api/time-entries/:entryId | time:write | beta |  |

## Hosted MCP Operation Support

| Operation | Status | Tool | Required scope | Stability | Limitation |
| --- | --- | --- | --- | --- | --- |
| meeting_recordings.cancel | partial | google_meet.cancel | mcp:meetings:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| meeting_recordings.get | supported | google_meet.get | mcp:meetings:read | beta |  |
| meeting_recordings.list | supported | google_meet.list | mcp:meetings:read | beta |  |
| meeting_recordings.schedule | partial | google_meet.schedule | mcp:meetings:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| meeting_recordings.start | partial | google_meet.start | mcp:meetings:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| scheduling.create_event_intent | partial | calendar.create_event | mcp:scheduling:intents:create | beta | Creates only a needs_confirmation intent and does not write a calendar event until an authorized user confirms and executes it. |
| scheduling.find_slots | partial | availability.find_slots | mcp:scheduling:read | beta | Requires a known non-secret organization page and omits secret, host, routing, delegate, reservation, and duration options. |
| scheduling.get_intent_status | partial | scheduling.intent_status | mcp:scheduling:read | beta | Reads only intents owned by the current stable MCP principal. |
| scheduling.get_manifest | supported | scheduling.manifest | mcp:scheduling:read | beta |  |
| time_entries.add_weekly_row | partial | time_entries.add_weekly_row | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.copy_previous_week_rows | partial | time_entries.copy_previous_week_rows | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.create | partial | time_entries.create | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.delete | partial | time_entries.delete | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.get_weekly | supported | time_entries.get_weekly | mcp:time:read | beta |  |
| time_entries.link_issue | partial | time_entries.link_issue | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.list | supported | time_entries.list | mcp:time:read | beta |  |
| time_entries.remove_weekly_row | partial | time_entries.remove_weekly_row | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.set_weekly_cell | partial | time_entries.set_weekly_cell | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.start | partial | time_entries.start | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.stop | partial | time_entries.stop | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.summarize | supported | time_entries.summarize | mcp:time:read | beta |  |
| time_entries.unlink_issue | partial | time_entries.unlink_issue | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
| time_entries.update | partial | time_entries.update | mcp:time:intents:create | beta | Creates an intent only; an authenticated delegated user must confirm and execute it in Nixelo. |
