MegalaniaDocs
Docs menu
  1. Docs
  2. Start
  3. Troubleshooting
Start

Troubleshooting

llms.txtUpdated 8 Nov 2026

Find what you see in the list below. Each entry says why it happens and what to change. An error is never charged. Every answer carries X-Request-Id: quote it if you write to support. The full list of codes is in Error codes.

Print the status, our headers and the body of any call with -sS -D -:

Shell
curl -sS -D - -o page.out "https://get.megalania.io/v1?url=https://docs.megalania.io/start/quickstart" \
  -H "Authorization: Bearer $MEG_API_KEY"

The key

401 bad_token

The message says which of five it is:

  • “No API key was sent”: no Authorization header reached us.

  • “The Authorization header has no Bearer”: write Authorization: Bearer <key>, not just the key.

  • “The key was sent in an X-Api-Key header”: we read only Authorization.

  • “A key in the URL is refused”: remove api_key from the URL.

  • “The API key is wrong, expired or deleted”: the header is right, the key is not.

  • Run echo ${MEG_API_KEY:0:7}. It must print meg_sk_. Empty means the shell that runs the call has no key: export it in that shell.

  • Send Authorization: Bearer $MEG_API_KEY. A key in the URL (?api_key=) is refused, even next to the header.

  • Copy-paste can add a space or a line break. Paste the key between single quotes, as in the quickstart.

  • Still 401? Make a new key on the API keys page. We store only a hash, so a lost key cannot be shown again.

403 wrong_scope

The key has the wrong scope. A key that starts with meg_ak_ is an account key: it manages the account and cannot scrape. Use a scrape key, meg_sk_. The other way round, a scrape key cannot manage the account; only GET /v1/account takes both.

403 notice_required

You have not accepted the current beta notice. Sign in to the dashboard, read the notice and press I agree. Then make the key, or connect the agent, again.

The address

404 with an empty body on /v1/batches

Batches live on the API host, https://api.megalania.io. The scrape host, https://get.megalania.io, serves only /v1, /v1/map, /v1/tier, /v1/stats/domain and /v1/geos. Change the host, keep the path.

400 bad_parameter

Read error.field: that parameter is missing, misspelled, or has a value we do not accept. The message lists the values that work. The four we see most:

  • An unknown parameter. We never ignore one. render=true from an old script is a 400 naming render. Send engine=browser.
  • A number with a fraction or a sign. timeout, max_credits and max_age take a whole JSON number or a string: "timeout": 30 and "timeout": "30" both work; 30.5 or -1 is a 400 naming the key.
  • A query string we cannot read. On GET /v1, put url last and paste it as it is, or percent-encode it.
  • Idempotency-Key too long or not ASCII. Send 1 to 128 printable ASCII characters. A UUID works.

415 unsupported_media_type

Every POST takes JSON. Add -H "Content-Type: application/json", even with an empty {} body.

The page

200, but the page is empty or is only a script shell

Look at X-Hint. needs_js means the page builds its content with JavaScript. Two fixes, cheapest first:

  1. Ask for "response_types": "page_data". Many pages carry their data as JSON in the HTML, at the HTTP price.
  2. Send "engine": "browser". We render the page in Chrome. It costs more: see Credits and pricing.

No X-Hint and still too little text? A short answer can still be a shell. Try the same two steps.

422 blocked

The site blocked every route we tried, and there is nothing to show. It is free: X-Billing: blocked says so. A block is always this 422, never a 200. Read the headers:

  • X-Hops lists each try, like h:dc:chrome=3826,h:res:chrome=4989.

  • X-Untried names the routes we did not try, such as c:res. The climb stops early when the next step costs more than it is likely to win. To try one yourself, ask for it by name:

    route send
    h:res "engine": "http", "proxy_tier": "residential"
    c:dc "engine": "browser"
    c:res "engine": "browser", "proxy_tier": "residential"

    A residential or browser page costs more: see Credits and pricing.

  • X-Untried-Reason: budget means residential routes are unavailable right now, so the climb skipped every residential route and tried the next open one. A skipped route is never charged.

  • No X-Untried means every route was tried. Retrying will not help today.

  • X-Target-Status is what the site answered, often 403.

X-Target-Status: 404 (or any status under 500)

The site itself answered with that status, and that is the result: you pay for it like any page. Check the URL in a browser.

422 convert_cap or 422 upstream_cap

The page is too large to convert, or pulled more data than one request may use. It is refunded. Ask for html instead of markdown, or fewer response_types, or fetch a smaller page.

422 document_unreadable

The url answered with a PDF, Word, PowerPoint or Excel file we cannot read. It holds only scanned images, it needs a password, it is damaged, or reading it ran past our memory or time limits. It is free. We do not run OCR yet, so a scanned PDF stays unreadable. A file over 64 MiB unpacked, or over 500 slides, is a 422 convert_cap instead.

A host name that does not exist

Today you get 503 fetch_error, free, after we tried the other routes. The 422 unknown_host code is in the error list, but the DNS check behind it is switched off, so it is not sent yet. See errors.

  • Check the spelling of the host, and whether you left out a www..
  • A new domain can take a few minutes to appear in DNS. Retry later.

X-Truncated on a 200

The page reached the most bytes this request may pull, and we kept the part that fit. max_credits: raise it, or remove it, for the whole page. byte_cap: the route’s or your plan’s byte cap, or your balance, stopped it.

Money and limits

402 insufficient_credits

Your balance is lower than the cheapest route for this page. In the beta, write to [email protected] and we add credits. proxy_tier=datacenter makes a request cheaper.

400 max_credits_too_low

Every route for this page costs more than your max_credits. The message names the lowest price on that site. Raise max_credits to at least that. Run check a site first before a big run: it is free.

429 codes

code what to do
over_concurrency Too many requests at once. Wait the seconds in Retry-After.
rate_limited Batches, monitors and the account API take 2 calls a second. Wait the seconds in Retry-After.
target_rate_limited The site is rate limiting. We hold your requests to it until Retry-After ends, so you do not pay for more 429s.
daily_cost_cap Today’s usage limit is used up. It resets at 00:00 UTC.
period_cost_cap Your grant’s usage limit is used up. In the beta, write to [email protected].

409 replayed

You already used this Idempotency-Key in the last 24 hours, and the first call went through. Do not retry. Use a new key for a new request.

503 llm_unavailable with schema

Schema extraction could not run: it is not set up right now, or the model did not answer in time. The extraction is always free. What about the page:

  • The body carries markdown. We fetched the page, and you paid for the page only: X-Credits-Charged and credits in the body say how much, and llm_credits is 0. The page is there, so you can read it yourself.
  • No markdown in the body. We stopped before the fetch. Nothing was charged.

Retry later. extract with CSS rules needs no model and works now: Fetch, extract and lists shows how.

503 busy, timeout or fetch_error

These are refunded. Wait the seconds in Retry-After if there is one, and send the same request with the same Idempotency-Key. You are charged once. timeout: raise timeout, up to "90".

MCP

The client shows no tools, or every call is 401

  • Claude Code: type /mcp, pick megalania and finish the sign-in in the browser. Press Approve on the Megalania page.
  • Cursor and VS Code: the key goes in headers, as "Authorization": "Bearer meg_sk_...". Restart the client after you edit mcp.json.
  • The server address is https://mcp.megalania.io with nothing after it. A ? in the address is a 400.

Check the server from your shell. A 200 with the tools in result.tools means your key and the server are fine, and the problem is the client’s config:

Shell
curl -sS -X POST https://mcp.megalania.io/ \
  -H "Authorization: Bearer $MEG_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -H "Mcp-Method: tools/list" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientInfo":{"name":"curl","version":"8"},"io.modelcontextprotocol/clientCapabilities":{}}}}'

A tool result says ok: false

Do what next_step says. It names the argument to change, or tells the agent to call again later. Blocked pages and errors are free.

Still stuck

Report it at https://app.megalania.io/report, or write to [email protected]. Send the X-Request-Id, what you sent (without the key) and what you expected. We never need your key.