Irmu
API Reference

Ask ChatGPT

GET /chatgpt — bearer auth, JSON responses, billed per successful request.

GET/chatgpt

Ask ChatGPT

Sends a prompt to ChatGPT through a browser automation and returns the response as structured JSON nodes—paragraphs, headings, lists, tables, product lists—each preserving citations. The crawler types the prompt into ChatGPT's web interface, waits for the streamed reply, and parses it. No OpenAI API key is required; this drives the public website directly.

When to use it. Use when you need ChatGPT's output with citation metadata intact, or when you lack API access to the underlying model. For simple text extraction from static pages, /crawl is cheaper and faster. This endpoint is priced flat at 30 credits regardless of proxy options.

Notes

  • Prompts are typed character-by-character: the 1000-character limit is a hard ceiling, and long prompts consume significant wait time before generation begins.
  • A 202 response means the job is still running; collect it from /crawl/{job}, but expect the answer nested under data[0].conversation rather than top-level conversation.
  • Failed or unanswered prompts refund credits (credits_charged: 0), though the attempt is still logged against chatgpt.com.
ParameterInTypeDescription
prompt *querystringThe 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.
premiumquerystringAsk through the premium proxy pool instead of the standard one. Free here, unlike on `/crawl` -- the price is flat -- but worth trying if the standard pool is being turned away. 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`.
countryquerystringThe 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`.
cityquerystringThe 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`.
keyquerystringThe 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.
request.sh
curl -X GET "https://app.irmu.com/api/chatgpt?prompt=&premium=&country=&city=&key=" \
  -H "Authorization: Bearer $IRMU_API_KEY"
200.json
{
  "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
}
request.js
const res = await fetch("https://app.irmu.com/api/chatgpt", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.IRMU_API_KEY}`,
    "Content-Type": "application/json",
  }
});

const data = await res.json();
request.py
import os, requests

res = requests.get(
    "https://app.irmu.com/api/chatgpt",
    headers={"Authorization": f"Bearer {os.environ['IRMU_API_KEY']}"}
)

print(res.json())
StatusMeaning
200ChatGPT answered. `conversation` holds the exchange: your prompt, then the answer as a list of nodes.
202Paid 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[0].conversation` rather than lifted into `conversation` the way it is here. 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.
401No key, an unknown key, or a caller that is not an organization.
402Not enough credits, or the daily limit is reached. Nothing is charged and no attempt is recorded.
422A 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.
500Nothing 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.

Start building with Irmu today

200 free credits every month, no card required. Every API, every integration, one key.