Irmu Chat GPT API

Putting a question to ChatGPT through the same crawler.

Operations 1

GET /chatgpt Ask ChatGPT #

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/irmu-com:irmu-com-chat-gpt-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

irmu-com-chat-gpt-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Irmu Com Chat GPT API
  version: 1.0.0
  description: 'Operations tagged ChatGPT across 2 of this provider''s published API definitions: app.irmu.com.yaml, irmu-com-openapi.yaml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://app.irmu.com/api
  description: Production
tags:
- name: Chat GPT
  description: Putting a question to ChatGPT through the same crawler.
paths:
  /chatgpt:
    get:
      tags:
      - Chat GPT
      summary: Ask ChatGPT
      operationId: chatgpt
      description: 'Puts a question to ChatGPT and returns the answer as structured JSON.


        The crawler does the asking: it opens ChatGPT, types the prompt into the

        composer, waits for the streamed answer and converts it into nodes --

        paragraphs, headings, lists, tables, product lists, each keeping the

        citations ChatGPT showed. There is no API key of yours involved anywhere,

        and no model of ours: this drives the website.


        **30 credits, flat.** Unlike `/crawl`, nothing changes that -- `premium`,

        `country` and `city` still choose where the crawl exits, and for this

        target that may well decide whether it is let in at all, but they do not

        move the price. What this costs is a browser held open for up to two

        minutes rather than a page''s worth of bytes.


        Always JSON, never `text/html`. There is nothing to branch on here.


        The key goes in the `Authorization` header, or in `?key=` as on `/crawl`.'
      security:
      - apiKeyHeader: []
      - apiKeyQuery: []
      parameters:
      - name: prompt
        in: query
        required: true
        description: 'The question, up to 1000 characters.


          The limit is not arbitrary. The prompt is typed one character at a

          time, so a thousand characters is already half a minute of typing

          before ChatGPT starts to think -- against a crawler that waits about

          two and a half minutes for the whole job.

          '
        schema:
          type: string
          maxLength: 1000
        example: elon musk
      - name: premium
        in: query
        required: false
        description: 'Ask through the premium proxy pool rather than the standard one. **On

          by default**, because the standard pool is the one ChatGPT turns away;

          send `false` to use the standard pool. Free either way, unlike on

          `/crawl` -- the price is flat.


          Sent as text in a query string, so the spellings a person would reach

          for all work: `true`, `false`, `1`, `0`, `yes`, `no`, `on`, `off`, in

          any case. Anything that is not a yes or a no is refused rather than

          quietly read as `false`.

          '
        schema:
          type: string
          default: 'true'
        example: 'true'
      - name: country
        in: query
        required: false
        description: 'The country to appear to be asking from, as a two-letter ISO 3166-1

          alpha-2 code. Free, and it changes what ChatGPT answers as much as it

          changes anything -- a question about prices asked from Germany is not

          the same question.


          Required to use `city`.

          '
        schema:
          type: string
          minLength: 2
          maxLength: 2
          pattern: ^[A-Za-z]{2}$
        example: de
      - name: city
        in: query
        required: false
        description: 'The city inside that country, as the pool spells it. **Requires

          `country`.** Free here, where on `/crawl` it doubles the price.


          Letters, digits, hyphens and underscores only; a multi-word city is

          written `new_york`.

          '
        schema:
          type: string
          pattern: ^[A-Za-z][A-Za-z0-9_-]{0,63}$
        example: berlin
      - name: key
        in: query
        required: false
        description: 'The API key, as an alternative to the `Authorization` header. Ignored

          when a header is present. A key in a url is copied into access logs,

          proxy logs and `Referer` headers, which is a fair trade for a

          machine-to-machine endpoint and a bad one for anything else.

          '
        schema:
          type: string
      responses:
        '200':
          description: 'ChatGPT answered. `conversation` holds the exchange: your prompt, then

            the answer as a list of nodes.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatGptResult'
              example:
                prompt: elon musk
                conversation:
                - role: user
                  message: elon musk
                - role: assistant
                  response:
                  - type: paragraph
                    text: Elon Musk is a businessman known for Tesla and SpaceX.
                    sources:
                    - attribution: Reuters
                      url: https://example.com/article
                  - type: heading
                    level: 2
                    text: Companies
                  - type: bullet_list
                    items:
                    - text: Tesla
                    - text: SpaceX
                credits_charged: 30
                credits_remaining: 970
                job_id: 0198a9b6-1f4c-7c3e-9a2b-5d8e6f0a1b23_0198a9b6-2a71-7f0d-8c44-9e1b3c5d7f02
                status: done
                position: null
                error: null
        '202':
          description: 'Paid for and still going. A long prompt can outlast the crawler''s

            patience for waiting, though not its patience for working.


            Collect it from `/crawl/{job}` -- the same endpoint a slow crawl is

            collected from, and free in the same way. One difference worth knowing:

            that endpoint answers the crawl envelope, so the answer arrives under

            `data.conversation` rather than lifted into `conversation` the way

            it is here.

            With `debuga=1`, a prompt that is still running also carries `debug`: the url, a

            viewport screenshot and the page source as they stood when the

            crawler stopped waiting, so a slow prompt shows the chat as it was

            rather than nothing at all. Null once it finishes -- the tab is gone

            by then. It costs nothing.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatGptResult'
              example:
                prompt: elon musk
                conversation: []
                credits_charged: 30
                credits_remaining: 970
                job_id: 0198a9b6-1f4c-7c3e-9a2b-5d8e6f0a1b23_0198a9b6-2a71-7f0d-8c44-9e1b3c5d7f02
                status: running
                position: null
                error: null
                debug:
                  url: https://chatgpt.com/
                  screenshot: /9j/4AAQSkZJRgABAQ...
                  html: <!doctype html>...
        '401':
          description: 'No key, an unknown key, or a caller that is not an organization.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                message: This endpoint is reached with an organization API key.
        '402':
          description: 'Not enough credits, or the daily limit is reached. Nothing is charged

            and no attempt is recorded.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: 'A malformed request -- no prompt, a prompt over the limit, a city with

            no country, or a flag that is not a yes or a no.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '500':
          description: 'Nothing came back. Either the crawl failed outright, or ChatGPT did not

            answer within its timeout -- which reads as an empty `conversation` and

            an `error` saying so.


            **The credits are refunded either way**, so `credits_charged` is `0`.

            The attempt is still recorded against `chatgpt.com`, so a customer can

            see that we tried.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatGptResult'
              example:
                prompt: elon musk
                conversation: []
                credits_charged: 0
                credits_remaining: 1000
                job_id: 0198a9b6-1f4c-7c3e-9a2b-5d8e6f0a1b23_0198a9b6-2a71-7f0d-8c44-9e1b3c5d7f02
                status: done
                position: null
                error: ChatGPT did not answer in time. Nothing was charged.
    servers:
    - url: https://app.irmu.com/api
      description: Production
components:
  schemas:
    CrawlSnapshot:
      type: object
      description: 'Where a crawl had got to, for one that is still running or failed. Only

        sent when the request carries `debuga=1`.


        The crawler stops waiting long before it stops working, and when it stops

        waiting it looks at the tab: the url the browser is on, a picture of what

        is on screen, and the page source as it stands. That is what this is --

        a diagnosis for a request that timed out, not a result. Nothing is

        charged for it.


        Null on anything that is not still running. A finished or failed crawl has

        no tab left to look at, and a crawl still in the queue has not opened one

        yet.


        Two things to know when reading one. The image is the **viewport**, not

        the whole page, so it is not the picture `/screenshot` sells -- it is a

        thumbnail at quality 60, meant to be looked at rather than kept. And

        either artefact may be missing: they are captured independently, because a

        navigation can destroy one without touching the other, so half a snapshot

        is ordinary. The missing half reads as null rather than going absent.


        A blank image beside a near-empty `html` is not a broken capture -- it

        means the crawl stalled *inside* a navigation, with the old document

        already replaced. That is itself the answer.

        '
      required:
      - url
      - screenshot
      - html
      properties:
        url:
          type:
          - string
          - 'null'
          format: uri
          description: 'The url the tab was on, which a redirect may have moved away from the

            one you asked for.

            '
          example: https://shop.example/p/1
        screenshot:
          type:
          - string
          - 'null'
          format: byte
          description: 'A base64 JPEG of the viewport, with no `data:` prefix -- decode it as

            it stands. Null when the capture raced a navigation and lost.

            '
          example: /9j/4AAQSkZJRgABAQ...
        html:
          type:
          - string
          - 'null'
          description: 'The page source at that moment, half-loaded and all. Null when the

            capture raced a navigation and lost.

            '
          example: <!doctype html>...
    Error:
      type: object
      required:
      - message
      properties:
        message:
          type: string
    ValidationError:
      type: object
      required:
      - message
      - errors
      properties:
        message:
          type: string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
    ChatGptResult:
      type: object
      description: 'What `/chatgpt` answers. `conversation` is empty while a prompt is still

        running and when it went unanswered; `status` and `error` are what tell

        those two apart.

        '
      required:
      - prompt
      - conversation
      - credits_charged
      - credits_remaining
      - job_id
      - status
      - debug
      properties:
        prompt:
          type: string
          description: The question, as it was asked.
        conversation:
          type: array
          description: 'The exchange. The user turn carries `message`; the assistant turn

            carries `response`, a list of nodes.

            '
          items:
            type: object
            properties:
              role:
                type: string
                enum:
                - user
                - assistant
              message:
                type: string
                description: The prompt. Present on the user turn only.
              response:
                type: array
                description: 'The answer, node by node. `type` says which shape each one is:

                  `paragraph` and `heading` carry `text` (and `heading` a `level`),

                  `bullet_list` and `ordered_list` carry `items`, `table` carries

                  `headers` and `rows`, `product_list` carries `items`, and

                  `divider` carries nothing. Any node may carry `sources`, the

                  citations ChatGPT showed beside it.

                  '
                items:
                  type: object
                  additionalProperties: true
        credits_charged:
          type: integer
          description: '30 for a prompt that was answered or is still running, 0 for one that

            was not.

            '
          example: 30
        credits_remaining:
          type: integer
        job_id:
          type: string
          description: 'What this ran under. Collect a `202` from `/crawl/{job}` with it.

            '
        status:
          type: string
          enum:
          - done
          - queued
          - running
          - failed
        position:
          type:
          - integer
          - 'null'
          description: Where it sits in the crawler's queue while `queued`.
        error:
          type:
          - string
          - 'null'
          description: Why nothing came back. Null otherwise.
        debug:
          description: 'Where the crawl had got to, when the crawler stopped waiting and

            looked. Only sent when the request carries `debuga=1` -- a screenshot

            and the page source run to a megabyte -- and null otherwise.

            '
          oneOf:
          - $ref: '#/components/schemas/CrawlSnapshot'
          - type: 'null'
  securitySchemes:
    apiKeyHeader:
      type: http
      scheme: bearer
      description: '`Authorization: Bearer <key>`. The usual way in.

        '
    apiKeyQuery:
      type: apiKey
      in: query
      name: key
      description: '`?key=<key>`. Accepted on the crawl route only, and only when no

        `Authorization` header was sent.

        '
x-refined-from:
- app.irmu.com.yaml
- irmu-com-openapi.yaml