gronka openapi.json

paste a link, get the file.

public preview: the api runs at api.gronka.dev, but it may still change before the release.

auth

send your api key as Authorization: Bearer <key>. get one on the api key page.

download

send a link as json to POST /v1/download.

curl https://api.gronka.dev/v1/download \
  -H 'Authorization: Bearer <key>' \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://x.com/user/status/123"}'

options: mode is auto (default), audio (an mp3) or mute (the video without its sound); start and end trim, in seconds or m:ss; split: false asks for one finished file instead of separate video and audio parts.

content

the text behind a link, not the file: send a link as json to POST /v1/content. reddit answers with the post and its comment tree; x answers with the post, the post it quotes, and the author's own thread above it.

curl https://api.gronka.dev/v1/content \
  -H 'Authorization: Bearer <key>' \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://www.reddit.com/r/pics/comments/abc123/title/","depth":3}'

options: format is json (default) or text (a plain-text rendering, comments indented); comments (0 to 20, default 0) adds that many replies; on reddit, depth (0 to 10) caps how deep they go; on x, thread: false stops at the linked post; on youtube, transcript: true (or a language code like "en") adds the captions as timed lines in post.extra.transcript. the answer is one Thread: source, url, post, thread (the author's posts in order), comments (a tree) and truncated. every item has author, text, media, links, quoted and stats. errors use the http status: 404 CONTENT_GONE, 400 UNSUPPORTED_SOURCE, 502 CONTENT_FAILED. sites: reddit, x, bluesky, instagram, tiktok, danbooru, e621, yande.re, konachan, pinterest, and youtube, soundcloud and other video sites (title, description, stats and youtube transcripts).

responses

direct

the link points to the file on its source site.

{
  "lane": "direct",
  "files": [
    {
      "url": "https://video.twimg.com/...",
      "filename": null,
      "type": "video"
    }
  ]
}

worker

signed links on dl.gronka.dev, good for an hour. usually one file, with kind video, audio or file (an image or other plain file). with merge: true, the files are separate video and audio streams for you to join, or send split: false to get one file.

{
  "lane": "worker",
  "merge": true,
  "filename": "clip.mp4",
  "files": [
    {
      "url": "https://dl.gronka.dev/f/...",
      "filename": "clip.video.mp4",
      "kind": "video",
      "size": 30123456
    },
    {
      "url": "https://dl.gronka.dev/f/...",
      "filename": "clip.audio.m4a",
      "kind": "audio",
      "size": 1234567
    }
  ]
}

r2

a copy on cdn.gronka.dev, deleted after an hour.

error

a download error has an error.code and error.message.

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "video duration exceeds the maximum allowed (60 minutes)."
  }
}

padded json

a download that finishes within about 80 seconds answers with its http status: 200, 400 when the link or options are the problem, 502 when the source failed. a longer one starts sending spaces to keep the connection open, then json; parse the full response as usual, and look for error in the body, since the status is already 200. closing the connection cancels the download.

errors

common error codes. message is safe to show to users.

  • BAD_REQUESTthe request body or options are invalid.
  • BAD_URLthe url is missing or invalid.
  • CONTENT_FAILEDthe content could not be read.
  • CONTENT_GONEthe post is deleted, private or removed.
  • DOWNLOAD_FAILEDthe download did not finish.
  • FORBIDDENthe request origin is not allowed.
  • INTERNALsomething broke on the server.
  • NETWORK_ERRORthe source refused or could not be reached.
  • NOT_FOUNDno such route.
  • RATE_LIMITEDtoo many requests. retry after retryAfter seconds.
  • UNAUTHORIZEDthe api key is missing or invalid.
  • UNSUPPORTED_SOURCEthat site is not supported, or not for this request.
  • VALIDATION_ERRORthe media or request hit a limit.
  • VERIFICATION_FAILEDthe turnstile check failed.
  • CONTENT_GONEthe post was removed or is no longer available.

keys

there are no accounts. POST /v1/keys (behind a turnstile check) returns a new key once; gronka keeps only a keyed hash of it, so a lost key can't be recovered, only replaced. DELETE /v1/keys with the key as its bearer token revokes it.

limits

50 downloads or content reads per 10 minutes per ip, or per key with an api key. api key checks are capped at 30 per 10 minutes per ip. files fetched by gronka (lane r2) have a 400 mb cap; images have a 50 mb cap. a RATE_LIMITED 429 includes error.retryAfter in seconds and the same value in a Retry-After header.

privacy

no request logs. files are gone after an hour.

reference

  • GET/v1/healthcheck service status
  • POST/v1/downloadget files from a link
  • POST/v1/contentread the text behind a link
  • POST/v1/keyscreate an api key
  • DELETE/v1/keysrevoke an api key