# My Custom API > Mock/static API builder on Cloudflare Workers. You create "endpoints": public URLs that return a fixed body with a chosen HTTP status, format (Content-Type), extra headers and optional delay. Endpoints are managed through a REST admin API authenticated with a Bearer token. Base URL: https://mycustomapi.online ## How it works (read this first) - **Accounts**: people sign in to the web dashboard (https://mycustomapi.online/) with Google only. Each Google account has its own private set of endpoints; nobody can see or change another account's endpoints. - **Tokens**: the admin API is called with `Authorization: Bearer `. A human gets their personal token (starts with `mca_`) in the dashboard: sign in with Google, click "LLM Access", then "Generate token". It is shown only once. You cannot create tokens yourself, so if you have no token, ask the user for it. - **A token only manages its own set**: a personal token manages that account's endpoints. The instance-wide `ADMIN_TOKEN` (if the user has it) manages a separate "global" set (legacy). Use whichever token you were given; the API is identical. - **API keys (optional protection)**: by default every endpoint is public. A user can create "API keys" (secrets) and make individual endpoints require one, sent by callers in a header of the endpoint's choosing. Keys are different from the Bearer tokens above: a *token* lets you manage endpoints through `/_admin/*`; an *API key* only guards calls to the public endpoints. API keys exist only for personal tokens, not for `ADMIN_TOKEN`. - **Public URLs**: every endpoint is served, without authentication and with CORS `*`, at ``. `publicBase` depends on the token (see below), so never build public URLs by hand: read it from `GET /_admin/me`. | Token | Manages | publicBase | |---|---|---| | Personal token (`mca_…`) | that account's endpoints | https://mycustomapi.online/api/u// | | ADMIN_TOKEN | global/legacy endpoints | https://mycustomapi.online/api/ | ## Recommended workflow for an agent 1. `GET https://mycustomapi.online/_admin/me` → returns `{"scope","email","publicBase"}`. A 401 means the token is wrong, revoked, or the user's access was removed: ask the user for a new one. 2. `GET https://mycustomapi.online/_admin/endpoints` → see what exists, to avoid slug conflicts (409). 3. Only if the user wants an endpoint protected: `GET /_admin/keys` to see the available keys, or `POST /_admin/keys` to create one (see "Protecting endpoints"). 4. Create (POST) or change (PUT) endpoints. 5. Tell the user the final URL: ``, and optionally verify it with a plain GET (with the key header if protected). ## Rules and gotchas - Send `Content-Type: application/json` whenever you send a body. - `body` is ALWAYS a string. For JSON responses send the JSON serialized as a string (e.g. `"body": "{\"ok\":true}"`), not a nested object. With format "json" the string must parse as JSON. - PUT is a partial update: only the fields you send change. Include `slug` in the body to rename. - Slugs may contain "/" (e.g. `users/list`). In admin URLs just append the segments: `/_admin/endpoints/users/list`. - Public endpoints answer only to their configured `method` (others get 405); `ANY` accepts all methods. - API key routes (`/_admin/keys`) answer 403 to `ADMIN_TOKEN`; use a personal token. - Errors are JSON `{"error":"..."}` with status 400 (validation), 401 (missing/invalid token), 404 (not found), 409 (slug exists). - Tokens can only be created, regenerated or revoked from the dashboard by a signed-in human, never through this API. ## Endpoint fields | field | type | default | notes | |---|---|---|---| | slug | string | — (required on create) | Path after the public base, e.g. `users/list`. Chars: letters, numbers, - _ . ~ / (max 200) | | method | string | ANY | One of ANY, GET, POST, PUT, PATCH, DELETE | | status | integer | 200 | 200–599 | | format | string | json | One of json, text, html, xml, csv, custom. "custom" requires contentType | | contentType | string | — | Only when format is "custom" | | body | string | "" | Response body | | headers | object | {} | Extra response headers | | delayMs | integer | 0 | 0–10000, artificial latency | | description | string | — | Free note (max 500 chars) | | protection | object \| null | null (public) | `{"keyId":"","header":"Authorization"}`. `header` defaults to "Authorization". Send `null` to make the endpoint public again | Read-only: createdAt, updatedAt. ## Protecting endpoints with API keys - Endpoints are public unless they have `protection`. Only protect an endpoint when the user asks for it. - A protected endpoint answers 401 `{"error":"Unauthorized"}` unless the caller sends the key's value in `protection.header`: - header "Authorization" (default): `Authorization: Bearer ` - any other header (e.g. "X-API-Key"): the raw value, `X-API-Key: ` - Typical flow: `POST /_admin/keys {"name":"clients"}` → response includes `id` and `value`; then create/update the endpoint with `"protection":{"keyId":"","header":"X-API-Key"}`. - **The key's `value` is returned only once**, when it is created (only a hash is stored). Show it to the user right away; it cannot be recovered later (create a new key instead). You may pass your own `value` (8–200 printable characters, no spaces) if the user wants a specific secret. - One key can protect many endpoints, and each endpoint uses one key. Max 20 keys per account. - Deleting a key that is still used returns 409 with the list of endpoints; change their protection first. If a key is gone, its endpoints keep answering 401 (they never become public by accident). - Browsers: CORS is enabled (`*`), including preflight for custom headers like Authorization or X-API-Key. ## Admin API (all require `Authorization: Bearer `) - GET /_admin/me — scope of this token and its `publicBase` - GET /_admin/keys — list API keys: `[{"id","name","hint","createdAt"}]` (`hint` = last 4 chars; the value is never returned) - POST /_admin/keys — create `{"name":"...","value":"(optional)"}`; 201 + `{id,name,hint,createdAt,value}` - DELETE /_admin/keys/ — delete; 409 if endpoints still use it - GET /_admin/endpoints — list endpoints (array) - POST /_admin/endpoints — create; 201 + endpoint - GET /_admin/endpoints/ — get one - PUT /_admin/endpoints/ — partial update (also PATCH) - DELETE /_admin/endpoints/ — delete; returns {"deleted":""} ## Examples ```bash TOKEN=mca_... # the user's personal token # Who am I / where will my endpoints be served? curl -H "Authorization: Bearer $TOKEN" https://mycustomapi.online/_admin/me # List curl -H "Authorization: Bearer $TOKEN" https://mycustomapi.online/_admin/endpoints # Create a JSON endpoint curl -X POST https://mycustomapi.online/_admin/endpoints \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"slug":"users","method":"GET","status":200,"format":"json","body":"[{\"id\":1,\"name\":\"Ana\"}]"}' # Create an error response with a delay curl -X POST https://mycustomapi.online/_admin/endpoints \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"slug":"flaky","status":503,"body":"{\"error\":\"unavailable\"}","delayMs":1500}' # Create an API key (save the returned "value": it is shown only once) curl -X POST https://mycustomapi.online/_admin/keys \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"name":"clients"}' # Create a protected endpoint that requires that key in the X-API-Key header curl -X POST https://mycustomapi.online/_admin/endpoints \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"slug":"private/report","body":"{\"secret\":true}","protection":{"keyId":"","header":"X-API-Key"}}' # Call it (without the header you get 401) curl -H "X-API-Key: " private/report # Make it public again curl -X PUT https://mycustomapi.online/_admin/endpoints/private/report \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"protection":null}' # Update only the status curl -X PUT https://mycustomapi.online/_admin/endpoints/users \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"status":503}' # Delete curl -X DELETE -H "Authorization: Bearer $TOKEN" https://mycustomapi.online/_admin/endpoints/users # Call a public endpoint (no auth): curl users ``` ## More - [OpenAPI 3.1 spec](https://mycustomapi.online/openapi.json): machine-readable admin API, usable for function calling / GPT Actions / tool import (auth: Bearer token). - [Dashboard](https://mycustomapi.online/): web UI for humans (Google sign-in, LLM Access token, API Keys, endpoint editor).