From 00a2fe3e2779d323a5c6ee0ae2eec4a29c1cd0f4 Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 21:47:00 +0000 Subject: [PATCH 1/2] Update calendar and invite API specifications Generated-By: mintlify-agent --- api-reference/calendar.mdx | 48 +++++------ api-reference/invite.mdx | 172 ++++++++++++++++++++++++++++++++----- api-reference/overview.mdx | 6 +- 3 files changed, 179 insertions(+), 47 deletions(-) diff --git a/api-reference/calendar.mdx b/api-reference/calendar.mdx index a94f9da..4e96e51 100644 --- a/api-reference/calendar.mdx +++ b/api-reference/calendar.mdx @@ -7,7 +7,11 @@ description: "Google Calendar integration endpoints for OAuth, event management, Connect a Google Calendar account and manage events, check availability, and schedule directly through the API. -Most calendar endpoints require a connected Google Calendar account. Use the [connect flow](#connect-calendar) to authorize access before calling event endpoints. +All calendar endpoints require an authenticated session. Use the [connect flow](#connect-calendar) to authorize Google Calendar access before calling event endpoints. + +## Authentication + +All calendar endpoints require a valid NextAuth session. The user identity is derived from your session — you never pass a `userId` directly. Unauthenticated requests receive a `401` response. ## Base URL @@ -21,14 +25,13 @@ https://agentbot.raveculture.xyz/api/calendar POST /api/calendar ``` -Initiates the Google Calendar OAuth flow. Returns an authorization URL that the user must visit to grant calendar access. +Initiates the Google Calendar OAuth flow. Returns an authorization URL that the user must visit to grant calendar access. The OAuth state parameter is cryptographically signed (HMAC) to bind the callback to the authenticated session. ### Request body | Field | Type | Required | Description | |-------|------|----------|-------------| | `action` | string | Yes | Must be `connect` | -| `userId` | string | Yes | Your user identifier | ### Response @@ -44,6 +47,7 @@ Redirect the user to `authUrl` to begin the OAuth consent flow. After granting a | Code | Description | |------|-------------| +| 401 | Not authenticated | | 400 | Invalid action | ## OAuth callback @@ -59,17 +63,18 @@ Handles the OAuth authorization code exchange after Google redirects the user ba | Parameter | Type | Description | |-----------|------|-------------| | `code` | string | Authorization code provided by Google | -| `state` | string | The `userId` passed during the connect flow | +| `state` | string | HMAC-signed state token that encodes the authenticated user and a timestamp. The server verifies this signature before accepting the callback. | | `error` | string | Error code if the user denied access or an error occurred | ### Behavior On success, this endpoint: -1. Exchanges the authorization code for access and refresh tokens. -2. Retrieves the user's primary calendar ID and timezone. -3. Stores the connection for future API calls. -4. Redirects to `/dashboard/calendar?connected=true`. +1. Verifies the HMAC signature on the `state` parameter and checks that it has not expired (10-minute window). +2. Exchanges the authorization code for access and refresh tokens. +3. Retrieves the user's primary calendar ID and timezone. +4. Stores the connection for future API calls, keyed to the verified user from the signed state. +5. Redirects to `/dashboard/calendar?connected=true`. ### Error redirects @@ -79,6 +84,8 @@ If an error occurs, the endpoint redirects to `/dashboard/calendar` with an `err |----------------|-------------| | `error=` | The user denied access or Google returned an error | | `error=no_code` | No authorization code was present in the callback | +| `error=missing_state` | The state parameter was not included in the callback | +| `error=invalid_state` | The state signature is invalid or the state has expired | | `error=token_failed` | The authorization code could not be exchanged for tokens | | `error=unknown` | An unexpected error occurred during the callback | @@ -88,7 +95,7 @@ If an error occurs, the endpoint redirects to `/dashboard/calendar` with an `err GET /api/calendar?action=auth ``` -Redirects the browser directly to the Google OAuth consent screen. This is an alternative to the POST-based connect flow — use it when you want a simple link-based authorization. +Redirects the browser directly to the Google OAuth consent screen. This is an alternative to the POST-based connect flow — use it when you want a simple link-based authorization. Requires an authenticated session; unauthenticated users are redirected to the login page. ### Query parameters @@ -99,7 +106,7 @@ Redirects the browser directly to the Google OAuth consent screen. This is an al ## List events ```http -GET /api/calendar?action=list&userId={userId} +GET /api/calendar?action=list ``` Returns calendar events within a date range. @@ -109,7 +116,6 @@ Returns calendar events within a date range. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `action` | string | Yes | Must be `list` | -| `userId` | string | Yes | Your user identifier | | `start` | string | No | ISO 8601 start date. Defaults to now. | | `end` | string | No | ISO 8601 end date. Defaults to 30 days from now. | @@ -134,12 +140,12 @@ Returns calendar events within a date range. | Code | Description | |------|-------------| -| 401 | Calendar not connected | +| 401 | Not authenticated or calendar not connected | ## Check availability ```http -GET /api/calendar?action=availability&userId={userId} +GET /api/calendar?action=availability ``` Returns available and busy time slots for a given date. Slots are one hour each, from 09:00 to 23:00. @@ -149,7 +155,6 @@ Returns available and busy time slots for a given date. Slots are one hour each, | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `action` | string | Yes | Must be `availability` | -| `userId` | string | Yes | Your user identifier | | `date` | string | No | Date in `YYYY-MM-DD` format. Defaults to today. | ### Response @@ -171,7 +176,7 @@ Returns available and busy time slots for a given date. Slots are one hour each, | Code | Description | |------|-------------| -| 401 | Calendar not connected | +| 401 | Not authenticated or calendar not connected | ## Create event @@ -186,7 +191,6 @@ Creates a new calendar event. | Field | Type | Required | Description | |-------|------|----------|-------------| | `action` | string | Yes | Must be `create-event` | -| `userId` | string | Yes | Your user identifier | | `title` | string | Yes | Event title | | `start` | string | Yes | ISO 8601 start time | | `end` | string | Yes | ISO 8601 end time | @@ -199,7 +203,6 @@ Creates a new calendar event. ```json { "action": "create-event", - "userId": "user_123", "title": "DJ Set @ Warehouse", "start": "2026-03-28T22:00:00Z", "end": "2026-03-29T02:00:00Z", @@ -227,7 +230,7 @@ Creates a new calendar event. | Code | Description | |------|-------------| -| 401 | Calendar not connected | +| 401 | Not authenticated or calendar not connected | | 500 | Internal error | ## Update event @@ -243,7 +246,6 @@ Updates an existing calendar event. Only the fields you include are changed. | Field | Type | Required | Description | |-------|------|----------|-------------| | `action` | string | Yes | Must be `update-event` | -| `userId` | string | Yes | Your user identifier | | `eventId` | string | Yes | ID of the event to update | | `title` | string | No | Updated event title | | `description` | string | No | Updated description | @@ -264,7 +266,7 @@ Updates an existing calendar event. Only the fields you include are changed. | Code | Description | |------|-------------| -| 401 | Calendar not connected | +| 401 | Not authenticated or calendar not connected | | 500 | Internal error | ## Delete event @@ -280,7 +282,6 @@ Deletes a calendar event. | Field | Type | Required | Description | |-------|------|----------|-------------| | `action` | string | Yes | Must be `delete-event` | -| `userId` | string | Yes | Your user identifier | | `eventId` | string | Yes | ID of the event to delete | ### Response @@ -295,7 +296,7 @@ Deletes a calendar event. | Code | Description | |------|-------------| -| 401 | Calendar not connected | +| 401 | Not authenticated or calendar not connected | | 500 | Internal error | ## Quick add @@ -311,7 +312,6 @@ Creates an event from a natural language string using Google Calendar's quick-ad | Field | Type | Required | Description | |-------|------|----------|-------------| | `action` | string | Yes | Must be `quick-add` | -| `userId` | string | Yes | Your user identifier | | `text` | string | Yes | Natural language event description (for example, `"Meeting with Sarah tomorrow at 3pm"`) | ### Response @@ -327,5 +327,5 @@ Creates an event from a natural language string using Google Calendar's quick-ad | Code | Description | |------|-------------| -| 401 | Calendar not connected | +| 401 | Not authenticated or calendar not connected | | 500 | Internal error | diff --git a/api-reference/invite.mdx b/api-reference/invite.mdx index fc49120..1f140ef 100644 --- a/api-reference/invite.mdx +++ b/api-reference/invite.mdx @@ -1,73 +1,203 @@ --- title: Invite API -description: "Generate and validate invite codes for platform access" +description: "Create, manage, and verify invite tokens for platform access" --- # Invite API -Generate and validate invite codes for gating access to the Agentbot platform. These endpoints are backend-only. +Create and verify invite tokens for gating access to the Agentbot platform. -Invite codes are now persisted in the database and survive server restarts. Code generation requires internal API key authentication to prevent invite flooding. Code validation remains public. +Invite tokens are 64-character hex strings generated from `crypto.randomBytes(32)`. The older 12-character code format is deprecated — see [legacy format](#legacy-invite-format) below. -## Generate invite code +## Authentication + +| Endpoint | Auth required | +|----------|---------------| +| `POST /api/invite` | Session (any authenticated user) | +| `POST /api/invites/verify` | None | +| `GET /api/admin/invites` | Session (admin only) | +| `POST /api/admin/invites` | Session (admin only) | + +## Create invite ```http -POST /api/invite/generate +POST /api/invite ``` -Generates a new invite code. Requires internal API key authentication via the `Authorization: Bearer ` header. +Creates an invite token linked to your account. Requires an authenticated session. -### Errors +### Request body -| Code | Description | -|------|-------------| -| 401 | Missing or invalid internal API key | -| 500 | Failed to generate invite code | +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `name` | string | Yes | Display name for the invite recipient. Validated against injection patterns. | ### Response ```json { - "code": "a1b2c3d4e5f6" + "success": true, + "inviteUrl": "https://agentbot.raveculture.xyz/invite?token=abc123...&name=Alice", + "token": "a1b2c3d4...64 hex characters" } ``` | Field | Type | Description | |-------|------|-------------| -| `code` | string | A 12-character hex string generated from 6 random bytes | +| `success` | boolean | Whether the invite was created | +| `inviteUrl` | string | Full URL the recipient can use to accept the invite | +| `token` | string | 64-character hex token | -## Validate invite code +### Errors + +| Code | Description | +|------|-------------| +| 400 | Name is missing or contains invalid characters | +| 401 | Not authenticated | +| 404 | User not found | +| 500 | Failed to create invite | + +## Verify invite ```http -POST /api/invite/validate +POST /api/invites/verify ``` -Validates and consumes an invite code. The operation is atomic — only one concurrent request can successfully consume a given code. Once validated, the code is marked as used and cannot be reused. No authentication required. +Verifies an invite token and returns invite details. No authentication required. Tokens must be in the 64-character hex format. ### Request body | Field | Type | Required | Description | |-------|------|----------|-------------| -| `code` | string | Yes | The invite code to validate | +| `token` | string | Yes | 64-character hex invite token | ### Response (valid) ```json { - "valid": true + "valid": true, + "email": "invitee@example.com", + "plan": "solo" } ``` -### Response (invalid) +| Field | Type | Description | +|-------|------|-------------| +| `valid` | boolean | Whether the token is valid | +| `email` | string | Email associated with the invite | +| `plan` | string | Plan tier for the invite (defaults to `solo`) | + +### Errors + +| Code | Description | +|------|-------------| +| 400 | Token is missing, not a string, or not in valid 64-character hex format | +| 404 | Invite not found or expired | +| 410 | Invite has already been used | +| 500 | Verification failed | + +## List invites (admin) + +```http +GET /api/admin/invites +``` + +Returns all invites with summary counts. Requires an authenticated session with an admin email address. + +### Response ```json { - "valid": false + "invites": [ + { + "code": "a1b2c3d4...64 hex characters", + "email": "invitee@example.com", + "createdAt": "2026-03-25T21:00:00.000Z", + "status": "active" + } + ], + "total": 1, + "active": 1 } ``` +| Field | Type | Description | +|-------|------|-------------| +| `invites` | array | List of all invites | +| `invites[].code` | string | 64-character hex invite token | +| `invites[].email` | string | Email the invite was created for | +| `invites[].createdAt` | string | ISO 8601 creation timestamp | +| `invites[].usedAt` | string \| undefined | ISO 8601 timestamp when the invite was used | +| `invites[].status` | string | One of `active`, `used`, or `expired` | +| `invites[].userId` | string \| undefined | User ID of the person who redeemed the invite | +| `total` | number | Total number of invites | +| `active` | number | Number of currently active invites | + ### Errors | Code | Description | |------|-------------| -| 400 | Code is missing, invalid, or already used | +| 403 | Not authorized (requires admin) | +| 500 | Failed to retrieve invites | + +## Create invite (admin) + +```http +POST /api/admin/invites +``` + +Creates an invite for a specific email address. Requires an authenticated session with an admin email address. + +### Request body + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `email` | string | Yes | Email address to associate with the invite | + +### Response + +```json +{ + "success": true, + "code": "a1b2c3d4...64 hex characters", + "email": "invitee@example.com", + "inviteUrl": "https://agentbot.raveculture.xyz/invite?token=a1b2c3d4..." +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `success` | boolean | Whether the invite was created | +| `code` | string | 64-character hex invite token | +| `email` | string | Email the invite was created for | +| `inviteUrl` | string | Full URL the recipient can use to accept the invite | + +### Errors + +| Code | Description | +|------|-------------| +| 400 | Email is missing | +| 403 | Not authorized (requires admin) | +| 500 | Failed to create invite | + +--- + +## Legacy invite format + +The previous invite system used 12-character hex codes with `POST /api/invite/generate` and `POST /api/invite/validate`. These endpoints are deprecated. Migrate to the new endpoints above. + +### Deprecated: generate invite code + +```http +POST /api/invite/generate +``` + +Previously generated a 12-character hex invite code. Replaced by `POST /api/invite` (session auth) and `POST /api/admin/invites` (admin session auth). + +### Deprecated: validate invite code + +```http +POST /api/invite/validate +``` + +Previously validated and consumed a 12-character invite code. Replaced by `POST /api/invites/verify`, which accepts 64-character hex tokens and returns richer response data including `email` and `plan`. diff --git a/api-reference/overview.mdx b/api-reference/overview.mdx index db15cd4..1a5afc9 100644 --- a/api-reference/overview.mdx +++ b/api-reference/overview.mdx @@ -284,8 +284,10 @@ curl -X POST https://agentbot.raveculture.xyz/api/ai/chat \ | `/api/underground/wallets/:address/balance` | GET | Get agent wallet USDC balance (backend only, requires auth) | | `/api/underground/splits` | POST | Create and queue a royalty split (backend only, requires auth) | | `/api/colony/status` | GET | Get colony tree, soul cognitive state, or diagnostics | -| `/api/invite/generate` | POST | Generate an invite code (backend only, requires internal API key) | -| `/api/invite/validate` | POST | Validate and consume an invite code (backend only, no auth) | +| `/api/invite` | POST | Create an invite token (requires session auth) | +| `/api/invites/verify` | POST | Verify an invite token (no auth required) | +| `/api/admin/invites` | GET | List all invites (requires admin session) | +| `/api/admin/invites` | POST | Create an invite for a specific email (requires admin session) | | `/api/summarize` | POST | Summarize a URL — returns title, description, headings, paragraphs, word count (web summarizer service) | | `/api/extract` | POST | Extract links, images, and Open Graph metadata from a URL (web summarizer service) | | `/api/clawmerchants` | GET | List available ClawMerchants data feeds, or fetch a specific feed by `feed` query parameter | From dbf6685a902890defa185954a5d53b12305b2b2c Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 22:00:12 +0000 Subject: [PATCH 2/2] Add encrypted token storage docs and OAuth state expiry details Generated-By: mintlify-agent --- api-reference/calendar.mdx | 44 ++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/api-reference/calendar.mdx b/api-reference/calendar.mdx index 4e96e51..a48f077 100644 --- a/api-reference/calendar.mdx +++ b/api-reference/calendar.mdx @@ -7,11 +7,9 @@ description: "Google Calendar integration endpoints for OAuth, event management, Connect a Google Calendar account and manage events, check availability, and schedule directly through the API. -All calendar endpoints require an authenticated session. Use the [connect flow](#connect-calendar) to authorize Google Calendar access before calling event endpoints. +All calendar endpoints require an authenticated session. The user is identified from the session automatically — you do not pass a `userId` parameter. -## Authentication - -All calendar endpoints require a valid NextAuth session. The user identity is derived from your session — you never pass a `userId` directly. Unauthenticated requests receive a `401` response. +Most calendar endpoints also require a connected Google Calendar account. Use the [connect flow](#connect-calendar) to authorize access before calling event endpoints. ## Base URL @@ -19,13 +17,23 @@ All calendar endpoints require a valid NextAuth session. The user identity is de https://agentbot.raveculture.xyz/api/calendar ``` +## Authentication + +All calendar endpoints require a valid NextAuth session. Requests without an active session receive a `401 Unauthorized` response (or a redirect to `/login` for browser-based flows). + +The authenticated user's identity is derived from the session. You do not need to include a `userId` parameter in any request. + +## Token storage + +Calendar tokens (access and refresh tokens) are encrypted at rest using AES-256-GCM before being persisted to the database. Tokens are never stored in plaintext. + ## Connect calendar ```http POST /api/calendar ``` -Initiates the Google Calendar OAuth flow. Returns an authorization URL that the user must visit to grant calendar access. The OAuth state parameter is cryptographically signed (HMAC) to bind the callback to the authenticated session. +Initiates the Google Calendar OAuth flow. Returns an authorization URL that the user must visit to grant calendar access. ### Request body @@ -47,7 +55,7 @@ Redirect the user to `authUrl` to begin the OAuth consent flow. After granting a | Code | Description | |------|-------------| -| 401 | Not authenticated | +| 401 | Not authenticated (no active session) | | 400 | Invalid action | ## OAuth callback @@ -63,17 +71,17 @@ Handles the OAuth authorization code exchange after Google redirects the user ba | Parameter | Type | Description | |-----------|------|-------------| | `code` | string | Authorization code provided by Google | -| `state` | string | HMAC-signed state token that encodes the authenticated user and a timestamp. The server verifies this signature before accepting the callback. | +| `state` | string | HMAC-signed state token generated during the connect flow. Contains the user ID and a timestamp, verified on callback. Expires after 10 minutes. | | `error` | string | Error code if the user denied access or an error occurred | ### Behavior On success, this endpoint: -1. Verifies the HMAC signature on the `state` parameter and checks that it has not expired (10-minute window). +1. Verifies the HMAC-signed state parameter and checks it has not expired. 2. Exchanges the authorization code for access and refresh tokens. 3. Retrieves the user's primary calendar ID and timezone. -4. Stores the connection for future API calls, keyed to the verified user from the signed state. +4. Encrypts and persists the tokens to the database (AES-256-GCM). 5. Redirects to `/dashboard/calendar?connected=true`. ### Error redirects @@ -84,8 +92,6 @@ If an error occurs, the endpoint redirects to `/dashboard/calendar` with an `err |----------------|-------------| | `error=` | The user denied access or Google returned an error | | `error=no_code` | No authorization code was present in the callback | -| `error=missing_state` | The state parameter was not included in the callback | -| `error=invalid_state` | The state signature is invalid or the state has expired | | `error=token_failed` | The authorization code could not be exchanged for tokens | | `error=unknown` | An unexpected error occurred during the callback | @@ -95,7 +101,9 @@ If an error occurs, the endpoint redirects to `/dashboard/calendar` with an `err GET /api/calendar?action=auth ``` -Redirects the browser directly to the Google OAuth consent screen. This is an alternative to the POST-based connect flow — use it when you want a simple link-based authorization. Requires an authenticated session; unauthenticated users are redirected to the login page. +Redirects the browser directly to the Google OAuth consent screen. This is an alternative to the POST-based connect flow — use it when you want a simple link-based authorization. + +Requires an active session. If the user is not authenticated, this endpoint redirects to `/login`. ### Query parameters @@ -109,7 +117,7 @@ Redirects the browser directly to the Google OAuth consent screen. This is an al GET /api/calendar?action=list ``` -Returns calendar events within a date range. +Returns calendar events within a date range. The user is identified from the session. ### Query parameters @@ -148,7 +156,7 @@ Returns calendar events within a date range. GET /api/calendar?action=availability ``` -Returns available and busy time slots for a given date. Slots are one hour each, from 09:00 to 23:00. +Returns available and busy time slots for a given date. Slots are one hour each, from 09:00 to 23:00. The user is identified from the session. ### Query parameters @@ -184,7 +192,7 @@ Returns available and busy time slots for a given date. Slots are one hour each, POST /api/calendar ``` -Creates a new calendar event. +Creates a new calendar event. The user is identified from the session. ### Request body @@ -239,7 +247,7 @@ Creates a new calendar event. POST /api/calendar ``` -Updates an existing calendar event. Only the fields you include are changed. +Updates an existing calendar event. Only the fields you include are changed. The user is identified from the session. ### Request body @@ -275,7 +283,7 @@ Updates an existing calendar event. Only the fields you include are changed. POST /api/calendar ``` -Deletes a calendar event. +Deletes a calendar event. The user is identified from the session. ### Request body @@ -305,7 +313,7 @@ Deletes a calendar event. POST /api/calendar ``` -Creates an event from a natural language string using Google Calendar's quick-add feature. +Creates an event from a natural language string using Google Calendar's quick-add feature. The user is identified from the session. ### Request body