{"openapi":"3.1.0","info":{"title":"Caretta API","description":"Caretta is a realtime AI copilot for sales calls. This API provides programmatic access to career applications, investor access requests, OAuth-based integrations, knowledge scraping, team management, and call data via the MCP server. Most endpoints require a Bearer token obtained through the Caretta app; public endpoints are marked as such.\n\n## Versioning and deprecation\n\nThe API is versioned in the URL path (`/api/v1/...`; unversioned `/api/...` paths are aliases of v1) and every response carries an `X-API-Version` header with the date-based revision (currently 2026-08-01). Breaking changes ship only in a new path version. Deprecated versions keep working for at least 6 months and announce retirement with `Deprecation` and `Sunset` response headers (RFC 9745 / RFC 8594) plus a notice at https://www.caretta.so/docs.\n\n## Rate limits\n\nResponses include RFC RateLimit headers (`RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`, `RateLimit-Policy`). The default policy is 60 requests per minute per client; exceeding it returns HTTP 429 with a `Retry-After` header.","version":"1.0.0","contact":{"name":"Caretta","url":"https://www.caretta.so/contact","email":"hello@caretta.so"},"license":{"name":"Proprietary","url":"https://www.caretta.so/terms"}},"servers":[{"url":"https://www.caretta.so","description":"Production"}],"x-api-version":"2026-08-01","x-versioning-policy":{"scheme":"url-path","current":"v1","header":"X-API-Version","deprecation":{"minimumNoticeMonths":6,"headers":["Deprecation","Sunset"],"changelog":"https://www.caretta.so/docs"}},"x-rate-limit":{"policy":"60;w=60","headers":["RateLimit-Limit","RateLimit-Remaining","RateLimit-Reset","RateLimit-Policy"],"onExceeded":{"status":429,"header":"Retry-After"}},"tags":[{"name":"Public","description":"Public endpoints requiring no authentication."},{"name":"Auth","description":"OAuth and authentication token management."},{"name":"Integrations","description":"Third-party integration token management."},{"name":"Knowledge","description":"Knowledge base and document scraping."},{"name":"Team","description":"Team invitation and member management."},{"name":"Slack","description":"Slack integration management."},{"name":"Onboarding","description":"Post-signup onboarding workflows."},{"name":"MCP","description":"Model Context Protocol server for AI agent access."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Bearer token obtained from the Caretta app after sign-in."}},"schemas":{"Health":{"type":"object","required":["status","service","version","api_version","time","links"],"properties":{"status":{"type":"string","enum":["ok"],"description":"Service status."},"service":{"type":"string","description":"Service identifier."},"version":{"type":"string","description":"Service version."},"api_version":{"type":"string","description":"API revision date (matches X-API-Version)."},"time":{"type":"string","format":"date-time","description":"Server time (ISO 8601)."},"links":{"type":"object","description":"Discovery links.","additionalProperties":{"type":"string","format":"uri"}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."},"code":{"type":"string","description":"Machine-readable error code when available."},"needsReauth":{"type":"boolean","description":"Indicates the user must re-authenticate."},"requiresFreshConsent":{"type":"boolean","description":"Indicates fresh OAuth consent is required."}}},"SuccessResponse":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","description":"Whether the operation succeeded."}}},"CareerApplicationRequest":{"type":"object","required":["roleSlug","linkedinHandle"],"properties":{"roleSlug":{"type":"string","description":"The slug identifier of the role being applied to (e.g. 'founding-engineer')."},"linkedinHandle":{"type":"string","description":"The applicant's LinkedIn profile URL or handle."}}},"InvestorAccessRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"The investor's business email address."}}},"TeamInviteRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"The email address of the teammate to invite."}}},"KnowledgeScrapeRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","maxLength":2048,"description":"The public URL of the document or page to scrape and import."}}},"IntegrationTokens":{"type":"object","required":["access_token"],"properties":{"access_token":{"type":"string","description":"OAuth access token."},"refresh_token":{"type":"string","description":"OAuth refresh token, if available."},"expires_at":{"type":"string","format":"date-time","description":"Token expiry timestamp."},"scope":{"type":"string","description":"OAuth scopes granted."},"token_type":{"type":"string","description":"Token type, typically 'Bearer'."}}},"PersistTokensRequest":{"type":"object","required":["provider","tokens"],"properties":{"provider":{"type":"string","enum":["slack","hubspot","attio","attention","fathom","fireflies","gong","grain","granola","circleback","salesforce","microsoft-onedrive","notion","mintlify","slite"],"description":"The integration provider to persist tokens for."},"tokens":{"$ref":"#/components/schemas/IntegrationTokens"}}},"IntegrationStatusResponse":{"type":"object","description":"Map of integration provider names to their connected status.","additionalProperties":{"type":"boolean"}},"TokenResponse":{"type":"object","properties":{"tokens":{"type":"array","items":{"$ref":"#/components/schemas/IntegrationTokens"}}}},"AuthUrlResponse":{"type":"object","required":["authUrl"],"properties":{"authUrl":{"type":"string","format":"uri","description":"The OAuth authorization URL to redirect the user to."}}},"Call":{"type":"object","description":"A Caretta call record.","properties":{"id":{"type":"string","description":"Unique call identifier."},"title":{"type":"string","description":"Call title or subject."},"startedAt":{"type":"string","format":"date-time","description":"When the call started."},"endedAt":{"type":"string","format":"date-time","description":"When the call ended."},"summary":{"type":"string","description":"AI-generated call summary."}}},"Todo":{"type":"object","description":"A todo item associated with a call.","properties":{"id":{"type":"string","description":"Unique todo identifier."},"text":{"type":"string","description":"The todo text."},"completed":{"type":"boolean","description":"Whether the todo is complete."},"owner":{"type":"string","description":"The todo owner's name or ID."},"dueDate":{"type":"string","format":"date-time","description":"Optional due date."},"callId":{"type":"string","description":"The associated call ID."}}}}},"paths":{"/api/v1/health":{"get":{"tags":["Public"],"operationId":"getHealthV1","summary":"Health check (v1)","description":"Versioned alias of /api/health. Public health endpoint returning service status, API version, and discovery links. No authentication required.","responses":{"200":{"description":"Service is healthy.","headers":{"X-API-Version":{"description":"API revision date.","schema":{"type":"string"}},"RateLimit-Limit":{"description":"Requests allowed per window.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests remaining in the window.","schema":{"type":"integer"}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"429":{"description":"Rate limit exceeded (60 requests per minute per client). Retry after the RateLimit-Reset / Retry-After interval.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/health":{"get":{"tags":["Public"],"operationId":"getHealth","summary":"Health check","description":"Public health endpoint returning service status, version, and discovery links. No authentication required.","security":[],"responses":{"200":{"description":"Service is healthy.","content":{"application/json":{"schema":{"type":"object","required":["status","service"],"properties":{"status":{"type":"string","enum":["ok"]},"service":{"type":"string","enum":["caretta"]},"version":{"type":"string","description":"API version."},"time":{"type":"string","format":"date-time","description":"Current server time."},"links":{"type":"object","description":"Discovery links to related resources.","properties":{"self":{"type":"string","format":"uri"},"openapi":{"type":"string","format":"uri"},"docs":{"type":"string","format":"uri"},"llms_txt":{"type":"string","format":"uri"}}}}}}}},"429":{"description":"Rate limit exceeded (60 requests per minute per client). Retry after the RateLimit-Reset / Retry-After interval.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/careers/apply":{"post":{"tags":["Public"],"operationId":"submitCareerApplication","summary":"Submit a job application","description":"Submit a job application with a LinkedIn profile. Public endpoint—no authentication required. Rate-limited per IP.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CareerApplicationRequest"}}}},"responses":{"200":{"description":"Application submitted successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request payload.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/investor-access":{"post":{"tags":["Public"],"operationId":"requestInvestorAccess","summary":"Request investor access","description":"Request access to Caretta's investor materials using a business email. Public endpoint—no authentication required. Rate-limited per IP.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestorAccessRequest"}}}},"responses":{"200":{"description":"Access request received.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["success"]},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request payload or non-business email.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/granola":{"get":{"tags":["Auth"],"operationId":"initiateGranolaOAuth","summary":"Initiate Granola OAuth flow","description":"Begins the Granola OAuth authorization flow by discovering the authorization server metadata, registering a client, and returning the authorization URL. Sets state cookies for CSRF protection.","security":[],"parameters":[{"name":"code","in":"query","required":false,"schema":{"type":"string"},"description":"OAuth authorization code (present on callback)."},{"name":"state","in":"query","required":false,"schema":{"type":"string"},"description":"OAuth state parameter (present on callback)."},{"name":"error","in":"query","required":false,"schema":{"type":"string"},"description":"OAuth error (present on error callback)."}],"responses":{"200":{"description":"Authorization URL generated (initial request) or token exchange complete (callback).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthUrlResponse"}}}},"500":{"description":"OAuth initialization or token exchange failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/auth/tokens":{"get":{"tags":["Auth"],"operationId":"getOAuthTokens","summary":"Retrieve stored OAuth tokens","description":"Retrieve and clear OAuth tokens stored in a short-lived cookie after an OAuth callback. The tokens are consumed once and the cookie is deleted.","security":[],"parameters":[{"name":"provider","in":"query","required":true,"schema":{"type":"string","enum":["hubspot","attio","slack","salesforce","microsoft-onedrive","granola","circleback","notion","fathom"]},"description":"The OAuth provider to retrieve tokens for."}],"responses":{"200":{"description":"Tokens retrieved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"description":"Unsupported provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"OAuth session not found or expired.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Invalid OAuth session data; re-authentication needed.","content":{"application/json":{"$ref":"#/components/schemas/Error"}}}}}},"/api/auth/oauth-tokens":{"get":{"tags":["Integrations"],"operationId":"getIntegrationStatus","summary":"Get integration connection status","description":"Returns the connection status for all supported integration providers. Requires a Bearer token.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Integration status for all providers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationStatusResponse"}}}},"401":{"description":"User authentication required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Failed to load integration status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Integrations"],"operationId":"persistIntegrationTokens","summary":"Persist OAuth integration tokens","description":"Persist OAuth tokens for a given integration provider. For Notion, this also triggers indexing setup. Requires a Bearer token.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersistTokensRequest"}}}},"responses":{"200":{"description":"Tokens persisted successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid request payload or provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"User authentication required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Service temporarily unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/knowledge/scrape":{"post":{"tags":["Knowledge"],"operationId":"scrapeKnowledgeDocument","summary":"Scrape and import a document","description":"Scrape a public web page or document by URL and import its text content into the user's knowledge base. SSRF-protected: refuses private/loopback addresses. Requires a Bearer token.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeScrapeRequest"}}}},"responses":{"200":{"description":"Document scraped and imported successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"title":{"type":"string","description":"Extracted document title."},"id":{"type":"string","description":"Identifier of the created knowledge item."}},"required":["success","title","id"]}}}},"400":{"description":"Missing, malformed, or non-public URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"User authentication required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The page was fetched but contained no readable text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"499":{"description":"The client cancelled the request before the scrape completed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The upstream page could not be fetched or parsed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/team/invite":{"post":{"tags":["Team"],"operationId":"inviteTeammate","summary":"Invite a teammate","description":"Send a team invitation email to a new teammate. Rate-limited per IP and per organization. Requires a Bearer token with org admin role.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInviteRequest"}}}},"responses":{"200":{"description":"Invitation sent successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid email or validation error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"User authentication required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/team/suggest":{"get":{"tags":["Team"],"operationId":"suggestTeammates","summary":"Get teammate suggestions","description":"Returns suggested teammates based on the user's recent interactions and call history. Requires a Bearer token.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Suggested teammates list.","content":{"application/json":{"schema":{"type":"object","properties":{"suggestions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"}}}}}}}}},"401":{"description":"User authentication required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/slack/store":{"post":{"tags":["Slack"],"operationId":"storeSlackTokens","summary":"Store Slack OAuth tokens","description":"Persist Slack OAuth tokens and link the Slack user to the Caretta org. Requires a Bearer token.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tokens":{"$ref":"#/components/schemas/IntegrationTokens"}}}}}},"responses":{"200":{"description":"Slack tokens stored successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid request payload.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"User authentication required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/slack/status":{"get":{"tags":["Slack"],"operationId":"getSlackIntegrationStatus","summary":"Get Slack integration status","description":"Check whether the user's organization has a Slack installation connected. Requires a Bearer token.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Slack integration status.","content":{"application/json":{"schema":{"type":"object","properties":{"connected":{"type":"boolean","description":"Whether Slack is connected."}}}}}},"401":{"description":"User authentication required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/onboarding/welcome":{"post":{"tags":["Onboarding"],"operationId":"sendTrialLiveEmail","summary":"Send trial-live onboarding email","description":"Trigger the transactional 'trial is live' email immediately after checkout. Idempotent via a ledger. Requires a Bearer token.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Email sent or already handled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"401":{"description":"User authentication required.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"x-mcp-server":{"url":"https://gateway.caretta.app/mcp","description":"Caretta MCP server providing OAuth-based access to calls, transcripts, and todos for AI agents.","docs":"https://www.caretta.so/docs/caretta-mcp","tools":["caretta_list_calls","caretta_list_my_calls","caretta_search_transcripts","caretta_get_call","caretta_list_todos","caretta_create_todo","caretta_update_todo"],"oauthScopes":["openid"],"permissions":["calls:read","todos:read","todos:write"]},"x-webhooks":{"description":"Caretta sends signed HTTPS webhooks with HMAC-SHA256 signatures (X-Caretta-Signature header).","events":["call.completed","call.notes_ready","call.metrics_ready","call.ready","webhook.test"],"docs":"https://www.caretta.so/docs/webhooks"}}