Create a paste

POST a paste to paste.hep.gg with a bearer API key. Request body, JSON envelope, and error codes.

Create a paste over HTTP. This is the endpoint behind the CLI, ShareX, and any script you write. Authenticate with a bearer API key minted at dashboard/snippets/keys.

POSThttps://paste.hep.gg/api/pasteAuth required
Create a paste and get a shareable link.

Authentication

Send your key as a bearer token:

Authorization: Bearer hepgg_pst_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The key resolves to your account, so the paste is attributed to you and counts against your plan's size cap and (for Free accounts) total paste count. A disabled or unknown key returns 401.

Request body

Content type is application/json.

Body fields
content
stringrequired
The paste body. Must be non-empty. Capped at 1 MB on Free, 8 MB on Prime; larger returns 413.
title
stringoptionaldefault: null
Optional title, trimmed to 200 characters.
language
stringoptionaldefault: auto
Optional language hint, lowercased and trimmed to 32 characters (for example python, json, bash). Omit it to let the server auto-detect from the content. See Language detection.
visibility
stringoptionaldefault: public
One of public, unlisted, or private. private needs an owner, so it works with a bearer key or a signed-in session; an anonymous web post gets 400. See Visibility.
isPermanent
booleanoptionaldefault: false
Prime only. Marks the paste to never expire. Ignored for Free accounts; on Free, use the dashboard to flag up to 100 pastes as permanent after creation.

Response

A 200 with the standard JSON envelope.

data fields
id
stringoptional
The paste's short ID.
url
stringoptional
The full shareable link, https://paste.hep.gg/<id>.
expiresAt
string | nulloptional
ISO timestamp when the paste expires, or null if it never expires (Prime, or a paste explicitly marked permanent).
anonymous
booleanoptional
false for key-authed and session pastes; true only for captcha-authed anonymous web posts.
{
  "ok": true,
  "data": {
    "id": "aB3dE6kp",
    "url": "https://paste.hep.gg/aB3dE6kp",
    "expiresAt": "2026-08-27T00:00:00.000Z",
    "anonymous": false
  }
}

Examples

curl
curl https://paste.hep.gg/api/paste \
  -H "Authorization: Bearer hepgg_pst_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "deploy log",
    "content": "==> building\n==> done in 4.2s",
    "language": "bash",
    "visibility": "unlisted"
  }'

Pipe a file straight in from the shell:

curl
jq -Rs '{content: ., language: "python"}' main.py | \
  curl https://paste.hep.gg/api/paste \
    -H "Authorization: Bearer hepgg_pst_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
    -H "Content-Type: application/json" \
    --data-binary @-

Visibility

ValueWho can read itNotes
publicAnyone with the linkDefault for /api/paste. Cacheable raw reads (see Read).
unlistedAnyone with the linkNot surfaced in any public listing.
privateThe owner onlyNeeds an owner: a bearer key or a signed-in session. An anonymous web post returns 400.

The default on paste.hep.gg/api/paste is public. (The dashboard's own /api/v1/snippets create path defaults to unlisted instead, so set visibility explicitly if you care.)

Language detection

If you omit language, the server runs auto-detection on the content. To keep the rendered page honest, detection only applies when:

  • the content has at least 20 non-whitespace characters, and
  • the detector is confident, and
  • the detected language is one of a curated common set (JavaScript, TypeScript, Python, Go, Rust, Java, C/C++, C#, Kotlin, Swift, Ruby, PHP, Bash, PowerShell, HTML, CSS, SCSS, JSON, YAML, XML, Markdown, SQL, GraphQL, Dockerfile, diff, Lua, Scala).

Short or ambiguous blobs stay plaintext. Pass language explicitly when you already know it, especially for languages outside that set.

Errors

Errors use { "ok": false, "error": "...", "code"?: "..." } with a matching HTTP status.

StatusWhenMessage / code
400Empty contentPaste content is required
400visibility: "private" on an anonymous web postSign in to create private pastes
400The body is not valid JSONMalformed JSON body (code INVALID_JSON)
400Anonymous web post with a bad captchaCaptcha failed. Try again.
401Unknown bearer keyInvalid API key
401Disabled bearer keyAPI key disabled
403The account behind the key or session is suspended or not approvedYour account is not approved for paste creation
413Content over the plan capPaste too large. Max 1 MB. (or 8 MB on Prime)
413The whole request body is over 10 MBRequest too large (code PAYLOAD_TOO_LARGE)
429Free account at its total paste capcode PASTE_TOTAL_CAP
413 example
{
  "ok": false,
  "error": "Paste too large. Max 1 MB."
}
429 example
{
  "ok": false,
  "error": "You've reached your snippet limit. Delete a few or upgrade to Prime.",
  "code": "PASTE_TOTAL_CAP"
}