Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/johnsessentials-com:johnsessentials-com-openai-compatibility-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
contact:
email: support@johnsessentials.com
name: John's Essentials Support
url: https://johnsessentials.com
description: 'Programmatic access to every tool on John''s Essentials. Compress PDFs,
convert images, OCR documents, run AI agents that orchestrate any of
the above — all behind a single bearer-token API key. ## Authentication
All endpoints under `/api/v1/public/*` require a bearer token whose
value is an API key starting with `je_live_sk_`. Generate keys in
the dashboard at `/integrations?tab=api-keys`. ## Rate limits
Tier-based limits are enforced per key on a 1-hour sliding window. Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`,
and `X-RateLimit-Reset`. 429 responses include the standard
`Retry-After` header. ## Credits
Every tool call spends the tool''s published credit price from your
account''s monthly allowance — the same credits and the same prices
the website charges (Starter 1,500 / Business 40,000 a month). The
price of each tool is the `credits` field on `GET /tools`. Tool
responses carry `X-Credits-Cost` (what this call cost) and
`X-Credits-Remaining` (credits left this month, or `unlimited`). `GET /usage` is the meter: credits used and left this month, when
the allowance resets and what each API key spent; it spends
nothing. When
the allowance is spent the call fails with 402 `file_limit_reached`;
the body names the call''s cost (`credits`) and carries
`add_credits_url`. Credit packs (500 for $7, 5,000 for $25, 25,000
for $59) are bought on the billing page, top up the website and the
API alike, and stay spendable for twelve months. Free accounts also
have a daily cap of 100 credits (402 `daily_limit_reached`, with
`resets_at_utc`); a pack does not lift that cap, a paid plan does. Agent runs additionally draw on the key''s monthly USD budget for
model tokens (`cost_cap_exceeded`). ## Idempotency
Send `Idempotency-Key: ` on any unsafe request
(POST/PUT/PATCH) to make retries safe. Identical key + body within
24h replays the cached response and adds `Idempotency-Replayed: true`. Reusing a key with a different body returns 409 `idempotency_key_in_use`. ## Errors
All error responses share the same shape:
```json
{ "error": { "code": "auth_invalid_key",
"message": "Invalid API key",
"doc_url": "https://docs.johnsessentials.com/api/errors#auth_invalid_key",
"request_id": "uuid" } }
```
The full error catalogue is at `/api/errors`. ## Schema extensions (keys beginning `x-`)
A tool''s `parameters_schema` is the JSON Schema describing its inputs. Some properties in it also carry keys beginning `x-` — today `x-ui` and
`x-show-when`. These are presentation hints: instructions to our own web
interface about labelling, units, and which controls to hide. They are not
part of the API contract, so they may be added, changed, or removed at any
time, without a new API version and without a deprecation notice. An `x-` key never changes the value a parameter accepts or returns. `type`, `enum`, `minimum`, `maximum`, `default` and `required` are
authoritative. `x-ui.wire_scale` is the unit our form displays, not the
unit the API accepts. `x-ui.unit_from` names another parameter whose
value decides the unit and range our form shows for this one — a corner
radius read as pixels up to 5000, or as a percentage up to 50 — and it
only ever narrows the declared `minimum` and `maximum`, which remain
what the API accepts. `x-show-when` says when our interface hides a
control, never whether the API accepts it — a parameter our interface
never shows is still accepted. `x-ui.draw` says which part of a drawing
a parameter is (see `x-draw` below): our interface sets it by drawing on
the file instead of typing it, and writes the same value the parameter
accepts. Three `x-` keys sit on the schema itself, beside `properties` and
`required`, and describe the tool rather than one parameter. They are
advisory in the same way: our own interface and plan checks read them,
and the tool''s endpoint remains what decides.'
license:
name: Proprietary
url: https://johnsessentials.com/license
summary: Deterministic file-processing tools, AI agent orchestration, and a public REST surface for both.
title: John's Essentials OpenAI Compatibility API
version: 1.0.0
servers:
- description: Production
url: https://api.johnsessentials.com/api/v1
- description: Local development
url: http://localhost:3000/api/v1
security:
- BearerAuth: []
tags:
- description: 'Drop-in replacement for OpenAI''s chat completions surface. Set your
OpenAI SDK''s `base_url` to `https://api.johnsessentials.com/v1` and
every existing call works unchanged. `model` accepts `johns-agent`
(default), `johns-fast`, `johns-smart`, or any free-form value — all
currently routed to the same provider pool (`model` is a
forward-compatible hint, not a hard selector). Error envelope matches
OpenAI''s exactly, NOT our canonical envelope — the OpenAI SDK
pattern-matches on it.'
name: OpenAI Compatibility
paths:
/v1/chat/completions:
servers:
- description: Production root
url: https://api.johnsessentials.com
- description: Local dev root
url: http://localhost:3000
post:
description: 'Drop-in for OpenAI''s chat completions. Set your OpenAI SDK''s
`base_url` to `https://api.johnsessentials.com/v1` and the rest
of your code is unchanged.
- **Auth:** `Authorization: Bearer je_live_sk_…` (same header OpenAI uses).
- **Models:** `johns-agent` (default — runs our orchestrator with the full tool catalogue). `johns-fast`/`johns-smart` are accepted aliases; today all values (including free-form ones) route through the same provider pool, so `model` is a forward-compatible hint rather than a hard selector.
- **Streaming:** set `stream: true` → response is `text/event-stream` with OpenAI''s `data: {…}\n\n` … `data: [DONE]\n\n` shape.
- **Tools:** when `tools=[…]` is present, BYPASSES our orchestrator and calls the LLM provider directly with your tool definitions. ~40× cheaper per request.
- **Cost cap:** if your key''s monthly USD cap is reached, returns 402 in OpenAI''s error envelope shape, NOT 429.
**⚠ "Try it" caveat — streaming:** Scalar''s in-page request runner
renders one-shot JSON responses cleanly but is not built for
SSE. If you send `stream: true` from the Try it button you will
see raw event-stream bytes accumulating rather than a parsed
chunk-by-chunk view. For interactive streaming evaluation, use
the OpenAI Python or TypeScript SDK with `base_url` swapped to
ours — copy the snippet from this page''s code-sample switcher.'
operationId: createChatCompletion
requestBody:
content:
application/json:
examples:
simple:
summary: Plain text completion
value:
messages:
- content: Summarize the OpenAPI 3.1 spec in one sentence.
role: user
model: johns-agent
streaming:
summary: Streamed completion
value:
messages:
- content: Hello
role: user
model: johns-fast
stream: true
with_tools:
summary: Caller-supplied tools (bypass orchestrator)
value:
messages:
- content: Compress report.pdf
role: user
model: johns-smart
tools:
- function:
description: Compress a PDF in-place
name: my_pdf_compressor
parameters:
properties:
quality:
type: string
type: object
type: function
schema:
$ref: '#/components/schemas/OAIChatRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/OAIChatResponse'
text/event-stream:
schema:
description: 'OpenAI-shape SSE. Each frame is `data: <OAIChatResponse chunk>\n\n`,
terminated by `data: [DONE]\n\n`.
'
type: string
description: Completion result (non-stream) OR opening SSE chunk (stream).
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/OAIErrorEnvelope'
description: Invalid request (OpenAI error envelope).
'401':
content:
application/json:
schema:
$ref: '#/components/schemas/OAIErrorEnvelope'
description: Auth failed (OpenAI error envelope).
'402':
content:
application/json:
schema:
$ref: '#/components/schemas/OAIErrorEnvelope'
description: Monthly cost cap reached (OpenAI error envelope, code `quota_cost_exceeded`).
'429':
content:
application/json:
schema:
$ref: '#/components/schemas/OAIErrorEnvelope'
description: Rate limited (OpenAI error envelope, type `rate_limit_exceeded`).
summary: Chat completion (OpenAI-compatible)
tags:
- OpenAI Compatibility
components:
schemas:
OAIChatResponse:
properties:
choices:
items:
$ref: '#/components/schemas/OAIChoice'
type: array
created:
description: Unix seconds.
format: int64
type: integer
id:
example: chatcmpl-9k0F5...
type: string
model:
type: string
object:
enum:
- chat.completion
- chat.completion.chunk
type: string
system_fingerprint:
type: string
usage:
$ref: '#/components/schemas/OAIUsage'
required:
- id
- object
- created
- model
- choices
type: object
OAIChatRequest:
properties:
max_tokens:
minimum: 1
type: integer
messages:
items:
$ref: '#/components/schemas/OAIMessage'
minItems: 1
type: array
model:
description: '`johns-agent` (default — runs our orchestrator with the full tool
catalogue). `johns-fast` and `johns-smart` are accepted aliases
reserved for low-latency / high-quality routes; today they and
any other value (e.g. `gpt-4o`) route through the same
health-ordered provider pool. Treat `model` as a
forward-compatible hint — your code keeps working unchanged.
'
example: johns-agent
type: string
stop:
description: string | string[]
stream:
default: false
type: boolean
temperature:
maximum: 2
minimum: 0
type: number
tool_choice:
description: '"auto" | "none" | { "type": "function", "function": { "name": "x" } }'
tools:
description: 'When present, BYPASSES our orchestrator and calls the LLM
provider directly with your tool definitions. Response will
include `tool_calls` in the OpenAI shape; you execute the
tools on your side. ~40× cheaper per request than the
orchestrator path.
'
items:
$ref: '#/components/schemas/OAITool'
type: array
user:
description: End-user identifier for abuse tracking.
type: string
required:
- model
- messages
type: object
OAIErrorEnvelope:
description: 'OpenAI''s error shape — different from our canonical envelope so the
OpenAI SDK''s pattern-matching keeps working. If you''re writing a
client by hand, switch on `error.type` and `error.code`.
'
properties:
error:
properties:
code:
description: Optional fine-grained code.
type: string
message:
type: string
param:
type: string
type:
enum:
- invalid_request_error
- authentication_error
- rate_limit_exceeded
- server_error
type: string
required:
- message
- type
type: object
required:
- error
type: object
OAIChoice:
properties:
delta:
$ref: '#/components/schemas/OAIMessage'
finish_reason:
enum:
- stop
- length
- tool_calls
- content_filter
type: string
index:
type: integer
logprobs:
type: 'null'
message:
$ref: '#/components/schemas/OAIMessage'
required:
- index
- finish_reason
type: object
OAIUsage:
properties:
completion_tokens:
type: integer
prompt_tokens:
type: integer
total_tokens:
type: integer
type: object
OAIFunctionDef:
properties:
description:
type: string
name:
type: string
parameters:
description: JSON Schema for the function's arguments.
type: object
required:
- name
type: object
OAITool:
properties:
function:
$ref: '#/components/schemas/OAIFunctionDef'
type:
enum:
- function
type: string
required:
- type
- function
type: object
OAIMessage:
properties:
content:
description: string OR array of content parts.
name:
type: string
role:
enum:
- system
- user
- assistant
- tool
type: string
tool_call_id:
type: string
tool_calls:
items:
$ref: '#/components/schemas/OAIToolCall'
type: array
required:
- role
type: object
OAIToolCall:
properties:
function:
properties:
arguments:
description: JSON-encoded string per OpenAI's wire shape — NOT an object.
type: string
name:
type: string
required:
- name
- arguments
type: object
id:
type: string
type:
enum:
- function
type: string
required:
- id
- type
- function
type: object
securitySchemes:
BearerAuth:
bearerFormat: API Key
description: 'Bearer token = your API key, prefixed `je_live_sk_`.
Example: `Authorization: Bearer je_live_sk_abc123...`
'
scheme: bearer
type: http