CoopAI

API reference

CoopAI API v1 — chat, inline completion, health, and authentication.

Last updated: 2026-07-15

All routes are served from your API base URL (https://api.coop-ai.dev or self-hosted).

Authentication

Extension and admin portal

Users sign in with email + password, Google, or SSO (SAML). The extension stores a session token after sign-in — not a pasted API key.

Google sign-in requires Google's verified-email flag (email_verified). Unverified Google accounts return email_not_verified (403).

Password email verification is soft: Coop sends a verify link on signup but does not block password login until verified.

Auth rate limiting: login, register, forgot-password, and reset-password are limited to ~20 attempts per 15 minutes per IP+email (429 rate_limited).

Post-login redirects: session tokens in redirect URLs are only sent to Coop surfaces — admin portal, marketing site, and vscode: / vscode-insiders: extension callbacks. Arbitrary https:// hosts are rejected.

Automation and API access

For scripts, CI, and direct HTTP calls to the API:

Authorization: Bearer <org-api-key>

Org API keys (coop_…) are created in the admin portal API Keys page. They are optional for developers using the VS Code extension.

When COOP_REQUIRE_API_AUTH=true (production default), /v1/chat and /v1/completions/inline accept either a valid user session (extension) or a Bearer org API key (automation).

Health

GET /health

Returns server status, cache, webhooks, jobs, and configured LLM providers.

{
  "ok": true,
  "cache": { "backend": "memory", "repos": 2 },
  "webhooks": [],
  "jobs": {},
  "llm": {
    "mockMode": false,
    "configuredProviders": ["anthropic", "openai"]
  }
}

The extension calls this automatically when you are signed in.

Chat

POST /v1/chat

Streams assistant output as Server-Sent Events (SSE).

Request body:

{
  "message": "Why was this handler written this way?",
  "history": [],
  "context": {
    "owner": "acme",
    "repo": "api",
    "branch": "main",
    "file": "src/handler.ts",
    "selectedLines": [10, 42]
  },
  "useCase": "decision_archaeology",
  "stream": true
}

useCase values: comprehension | decision_archaeology | ownership | blast_radius | knowledge_gaps | chat | inline_completion

SSE events:

typeFields
deltatext
doneusage, model, provider, finishReason
errormessage, code?

Errors: 401 unauthorized, 429 rate limited, 502 provider failure

Inline completion

POST /v1/completions/inline

Streaming or batch completion for editor ghost text (useCase: inline_completion). Same auth as /v1/chat.

The VS Code extension sends x-use-case: code-completion-only for zero-retention routing.

Request body:

FieldTypeNotes
messagestring?Prompt with surrounding code (chat-fallback when FIM unavailable)
segmentsobject?FIM mode: { prefix, suffix } — requires non-empty prefix if message omitted
segments.prefixstringCode before cursor (max 4,000 chars)
segments.suffixstring?Code after cursor (max 2,000 chars)
streamboolean?true → SSE (text/event-stream); default false → JSON
repoIdstring?Repo id for quota, audit, and graph context
useGraphContextboolean?Attach indexed graph slice (Pro / Enterprise)
languageIdstring?VS Code language id
filestring?File path (metadata)
providerstring?anthropic | openai | deepseek | gemini | mistral
modelstring?Fast model (e.g. claude-haiku-4-5-20251001, codestral-latest)
maxTokensnumber?Default 96; cap 200 (multi-line completions use higher limit)
temperaturenumber?Default 0.15

Validation: require message or non-empty segments.prefix.

FIM routing (server-side): when segments.prefix is present, the API prefers:

  1. Mistral Codestral FIM (MISTRAL_API_KEY) → codestral-latest
  2. DeepSeek FIM (DEEPSEEK_API_KEY) → deepseek-chat
  3. Chat fallback via message (Anthropic Haiku or OpenAI mini)

Response includes "fim": true when a FIM provider handled the request.

Response 200 (JSON, stream omitted or false):

{
  "text": "completion text only",
  "alternatives": [],
  "model": "codestral-latest",
  "provider": "mistral",
  "latencyMs": 120,
  "fim": true,
  "usage": {
    "inputTokens": 42,
    "outputTokens": 8
  }
}

Response 200 (stream: true):

Content-Type: text/event-stream. Each line is data: {json}\n\n:

typePayload
delta{ "type": "delta", "text": "..." }
done{ "type": "done", "usage": { ... }, "model": "...", "provider": "...", "finishReason": "stop" }
error{ "type": "error", "message": "..." }

Telemetry: successful completions emit completion.requested server-side with metadata.latencyMs and metadata.fim.

When useGraphContext is true, responses may include x-graph-context: degraded if the graph slice timed out or was unavailable.

Errors: 400 invalid request, 401 unauthorized, 429 rate limited, 502 provider failure

Graph (all plans)

  • GET /graph/:repoId/search?pattern=handler
  • GET /graph/:repoId/ownership?file=...

Available on Free, Pro, and Enterprise when the repo is Deep-Indexed. Free orgs are limited to 3 Deep-Indexed repos org-wide.

Zero-clone manifest (all plans)

  • GET /v1/orgs/repos/:repoId/manifest — structure-only manifest (paths and symbols)

SSO configuration (Enterprise)

Org admins configure SAML in the admin portal or via these APIs. All routes require Enterprise plan.

Auth requirements

EndpointWho can call
GET /v1/sso/configOrg admin or owner (session bearer) or org API key on Enterprise (admin_required for members)
GET /v1/sso/policyAny signed-in org member (session bearer) or org API key on Enterprise
PUT /v1/sso/config, PUT /v1/sso/policyOrg admin or owner only (admin_required for members)
GET /v1/auth/saml/startPublic — no bearer token
POST /v1/auth/saml/callbackPublic — browser POST from your IdP (no Coop bearer)
GET /v1/auth/saml/metadataEnterprise bearer (session or org API key)
POST /v1/auth/saml/offboardEnterprise bearer (session or org API key)

Session bearer: Authorization: Bearer coop_sess_… from extension or admin portal sign-in. Org API keys (coop_…) work for automation but do not satisfy interactive sign-in when requireSso is enabled — see SAML SSO troubleshooting.

GET /v1/sso/config

Returns IdP configuration and service provider (SP) values for your org. Admin only (org API keys also allowed).

Response 200 (not configured):

{
  "configured": false,
  "sp": {
    "entityId": "https://api.coop-ai.dev/v1/auth/saml/metadata",
    "acsUrl": "https://api.coop-ai.dev/v1/auth/saml/callback",
    "metadataUrl": "https://api.coop-ai.dev/v1/auth/saml/metadata",
    "publicStartUrl": "https://api.coop-ai.dev/v1/auth/saml/start"
  }
}

Response 200 (configured): adds provider, idpEntityId, idpSsoUrl, enabled, hasCertificate, updatedAt. The raw idpX509Cert is never returned.

Errors: 401 unauthorized, 403 admin_required | plan_required, 503 sso_unavailable

PUT /v1/sso/config

Save or update IdP settings. Admin only.

Request body:

FieldTypeNotes
providerstringokta | azuread | saml
idpEntityIdstringIdP entity ID / issuer
idpSsoUrlstringIdP SSO URL (HTTP-Redirect)
idpX509Certstring?PEM or base64 signing cert; omit on update to keep existing cert
enabledboolean?Default true when saving

Errors: 400 invalid_request | invalid_certificate | sso_required_active (cannot disable SAML while Require SSO is on), 403 admin_required | plan_required, 503 sso_unavailable

GET /v1/sso/policy

Returns sign-in policy for the org.

{
  "requireSso": false,
  "allowPassword": true,
  "allowGoogle": true,
  "updatedAt": "2026-07-09T12:00:00.000Z"
}

When requireSso is true, password and Google sign-in are blocked at login and on /v1/auth/refresh (sso_required). Enabling Require SSO (or disabling password/Google) immediately revokes existing password and Google sessions and refresh tokens for the org; SAML sessions remain valid.

Errors: 401 unauthorized, 403 plan_required, 503 sso_unavailable

PUT /v1/sso/policy

Update sign-in policy. Admin only.

Request body (all fields optional):

FieldTypeNotes
requireSsoboolean?Block password/Google at login and refresh; revokes non-SAML sessions when enabled
allowPasswordboolean?Ignored when requireSso is true
allowGoogleboolean?Ignored when requireSso is true

Errors: 400 sso_not_configured when enabling requireSso before SSO is saved and enabled, 403 admin_required | plan_required, 503 sso_unavailable

SAML authentication (Enterprise)

Coop uses a shared service provider for all Enterprise tenants. Your org is resolved from RelayState at callback time.

GET /v1/auth/saml/start

Public SSO entry for the extension and admin portal. Redirects (302) to your IdP, or returns JSON when format=json.

Query parameters:

ParamRequiredNotes
org or orgIdYesOrganization name (case-insensitive) or UUID
redirectNoPost-sign-in callback URL — must be admin portal, marketing site, or vscode: / vscode-insiders: extension handler
formatNojson{ "redirectUrl": "…" } instead of 302

Errors: 400 missing_org, 403 plan_required, 409 sso_not_configured, 502 sso_login_failed

POST /v1/auth/saml/callback

IdP ACS endpoint. Accepts application/x-www-form-urlencoded with SAMLResponse and RelayState. On success, sets a session cookie/token and redirects to redirect from RelayState.

Errors: 400 missing_saml_response | missing_relay_state, 401 saml_validation_failed, 403 plan_required | sso_not_configured

GET /v1/auth/saml/metadata

SP metadata XML (application/samlmetadata+xml). Same Entity ID and ACS URL for every tenant. Enterprise bearer required.

POST /v1/auth/saml/offboard

Deactivate users when they are removed from your IdP. Enterprise bearer required.

Request body (provide one):

BodyBehavior
{ "userId": "…" }Deactivate a single user in your org
{ "idpSubject": "…" }Deactivate by IdP NameID / subject
{ "activeSubjects": ["…", "…"] }SCIM-style sync — deactivate everyone else with SAML identities for this provider

Response 200: { "ok": true, … } with deactivated or deactivatedIds as applicable.

See Single Sign On (SSO) for IdP setup. Self-hosted operators: Enterprise deployment — SAML SSO.

Environment variables (self-hosted)

VariablePurpose
ANTHROPIC_API_KEYAnthropic provider
OPENAI_API_KEYOpenAI provider
MISTRAL_API_KEYMistral Codestral (FIM inline completion)
DEEPSEEK_API_KEYDeepSeek (FIM inline completion)
COOP_LLM_DEFAULT_PROVIDERDefault provider (anthropic)
COOP_LLM_MOCKtrue = mock stream without provider keys
COOP_REQUIRE_API_AUTHRequire Bearer token (production: true)
COOP_PUBLIC_BASE_URLPublic API base — required for SAML SP URLs and callbacks
COOP_SSO_SP_ENTITY_IDOptional SP entity ID override (default: metadata URL)
COOP_SSO_SESSION_TTL_MSSAML session lifetime in ms (default: 12 hours)

See Zero-retention LLM routing, Enterprise deployment, and Single Sign On (SSO).