REST API

Every action in every app is an endpoint with its own method and path, and it returns JSON. The same operations your agent sees over MCP, for your scripts.

Introduction

All endpoints live under one base URL, https://cotlet.dev/api/v1: the app slug, then the endpoint's path. The method says what it does: GET reads, POST creates or acts, PUT and PATCH change, DELETE removes.

Endpoint pattern

GET    https://cotlet.dev/api/v1/skool/groups/{group}/members
POST   https://cotlet.dev/api/v1/skool/groups/{group}/posts
PATCH  https://cotlet.dev/api/v1/skool/groups/{group}/posts/{post_id}
DELETE https://cotlet.dev/api/v1/skool/groups/{group}/posts/{post_id}

Pick an app in the sidebar to see its endpoints, their inputs and an example response for each one.

Authentication

Send your API key as a bearer token on every call. X-API-Key works too, for tools that cannot set an Authorization header.

Headers

Authorization: Bearer COTLET_API_KEY
Content-Type: application/json

Making a call

Path parameters such as {group} go in the URL. The other inputs go in the query string for GET and DELETE, and in a JSON object body for POST, PUT and PATCH.

Request

curl "https://cotlet.dev/api/v1/skool/groups/yourgroup/members?role=admin" \
  -H "Authorization: Bearer $COTLET_API_KEY"
  • Inputs are validated against the endpoint JSON Schema before anything runs.
  • Unknown fields are rejected, so a typo never runs silently.
  • A known path with the wrong method returns 405 with an Allow header.

Responses

A successful call returns 200 and the endpoint output as JSON, exactly as shown in its example response.

Response 200

{
  "members": [
    {
      "member_id": "m_8c41d2",
      "name": "Ana Lopez",
      "role": "member",
      "joined_at": "2026-10-01T18:21:00Z"
    }
  ],
  "next_cursor": "eyJvZmZzZXQiOjUwfQ"
}
Response headers
HeaderMeaning
X-Request-IdID of the call. Quote it when you contact support.
X-Credits-UsedCredits this call used. Failed calls use none.
LinkDocs of the app, as rel="describedby".

Pagination

List endpoints return up to limit items and a next_cursor. Pass it as cursor to get the next page; null means you have everything.

Next page

GET https://cotlet.dev/api/v1/skool/groups/yourgroup/members?cursor=eyJvZmZzZXQiOjUwfQ

Confirmation

Endpoints marked Confirm reach other people: they publish, message or email. By default each call waits for your approval before it runs.

Response 202

{
  "call_id": "0f3c2a91-6b7e-4d1a-9c55-2e8f1b7d4a60",
  "status": "pending",
  "app": "skool",
  "tool": "send_message",
  "message": "Send message in Skool reaches other people, so it waits for the account owner's approval...",
  "approval_url": "https://cotlet.dev/app/activity?tab=approvals",
  "status_url": "https://cotlet.dev/api/v1/calls/0f3c2a91-6b7e-4d1a-9c55-2e8f1b7d4a60",
  "expires_at": "2026-10-18T09:12:00+00:00"
}

Approve it at the approval_url, then read the outcome with GET on the status_url. Without a decision the call lapses at expires_at and nothing is sent. To run on a schedule without you, switch the endpoint to "Run without approval" in Activity, Approval rules.

Errors

Errors return JSON with an error code, a message written for your agent, and a link when you need to act.

Response 403

{
  "error": "access_not_granted",
  "message": "This API key has no access to Skool.",
  "request_access_url": "https://cotlet.dev/signup?app=skool",
  "docs_url": "https://cotlet.dev/integrations/skool-api-mcp-server"
}
Error codes of the Cotlet REST API
StatusCodeWhat happenedWhat to do
400invalid_inputThe inputs do not match the endpoint schema.Fix the fields named in details.
402insufficient_creditsYour credits ran out.Buy a credit pack in the dashboard; calls and your Cloud Browser resume after the purchase.
401api_key_requiredNo API key on the call.Send Authorization: Bearer.
401invalid_api_keyThe key is unknown, expired or revoked.Create a new key in the dashboard.
403access_not_grantedThe key has no access to this app.Request the app with the link in the error.
404unknown_app, unknown_endpointNo such app, or no endpoint at this path.The error lists the valid routes.
405method_not_allowedThe path is an endpoint, but not with this method.Use a method from the Allow header.
403AUTH_REQUIREDThe app is not signed in to in your Cloud Browser, or not enabled for agents.Open the browser_url, sign in and press Enable for agents.
403AUTH_EXPIREDThe app signed you out.Open the browser_url and sign in again.
403CAPTCHA_REQUIRED, MFA_REQUIREDThe app asked for a check only you can pass.Finish it in your Cloud Browser at the browser_url.
403SCOPE_DENIEDThe action is outside what you allowed.Switch the app to read and write at the browser_url, or create a new key with a wider scope in the dashboard.
403APP_PERMISSION_DENIEDYour account in the app lacks the role for this, e.g. it is not a group admin.Use a group or item your account manages. Nothing was charged.
403BROWSER_SUSPENDEDWe suspended your Cloud Browser.Contact us at the support_url.
429rate_limitedToo many requests.Wait for Retry-After seconds.
403TARGET_BLOCKEDThe app refused the account.Nothing was charged; tell the user.

We never sign in for you, solve a CAPTCHA or skip two-factor checks. When the app asks for one, the error carries a browser_url to your Cloud Browser (also sent as connect_url, the older name).

Reporting a problem

Send bugs, errors and missing features straight to us with your key. Same fields as the MCP tool cotlet_report_issue (MCP docs).

Request

POST https://cotlet.dev/api/v1/reports
Authorization: Bearer COTLET_API_KEY

{
  "kind": "error",
  "title": "approve_membership_request fails with TARGET_BLOCKED",
  "description": "Three calls in a row since 14:00, the user can approve members by hand.",
  "app": "skool",
  "tool": "approve_membership_request",
  "call_id": "0f3c2a91-6b7e-4d1a-9c55-2e8f1b7d4a60"
}

kind is one of bug, error, feature_request, missing_feature or other. The answer is 201 with a report_id.

Drive your Cloud Browser

Your scripts can drive your Cloud Browser over Chrome DevTools. You have one browser per app, signed in to that app only. Ask for a session of an app with your key, then connect any CDP client to cdp_url. Same as the MCP tool cotlet_browser_connect (MCP docs).

Request

POST https://cotlet.dev/api/v1/browser/cdp-sessions
Authorization: Bearer COTLET_API_KEY
Content-Type: application/json

{"app": "skool"}

The answer is 201 with cdp_url, expires_at and credits_per_minute. Every started minute of an open connection is charged up front; 402 means no credits left.

Rate limits

Rate limits
WhatLimit
Calls to endpoints60 a minute per key
Listing apps, endpoints and schemas120 a minute per IP
MCP messages120 a minute per key
Problem reports20 an hour per account

Over the limit you get 429 with a Retry-After header. Apps have limits of their own; we pace calls so your account stays within them.

Discovery

These endpoints need no key. Agents use them to find the right endpoint and its schema before the first call.

Discovery endpoints
EndpointReturns
GET /api/v1/appsEvery app with its endpoint count and links.
GET /api/v1/apps/{app}One app: what it is, how it connects, its endpoints with their method and path.
GET /api/v1/apps/{app}/endpoints/{endpoint}One endpoint by name: full JSON Schema of the input and an example response.

List apps

curl https://cotlet.dev/api/v1/apps

Sign in once. Your agent does the rest.

Sign up and add the apps you need. Free 7-day trial with 2,000 credits, no card needed.