John\'s Essentials OpenAI Compatibility API

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.

GitHub OpenAPI

Operations 1

POST /v1/chat/completions Chat completion (OpenAI-compatible) #

Work with this as data

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 Specification

johnsessentials-com-openai-compatibility-api-openapi.yml Raw ↑
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