Developers

Paste API

Create, list, edit and delete your pastes — and read who's viewing them — from your own scripts, bots and apps. Free with an account.

Get a key

Create an account (or sign in), then open your dashboard → API keys → Create key. The key is shown once — copy it then. You can have up to 10, and revoke any of them there at any time. A key only ever touches the account it belongs to.

Send it on every request. Keep keys on a server: never put one in a web page or an app people can download.

curl https://thpaste.com/api/v1/me \
  -H "Authorization: Bearer tp_YOUR_KEY"

Basics

Base URL https://thpaste.com/api/v1. Requests and responses are JSON; successful responses wrap the result in data. The version is in the path — /v1 won't change in breaking ways; a breaking change would come as /v2, with /v1 kept running. Every response says which version answered in X-API-Version.

Rate limits

60 requests a minute per key, across all endpoints. Creating pastes has its own limit: 30 a minute and 500 a day per account. Every response tells you where you stand with X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (a Unix time); over the limit you get 429 with Retry-After in seconds.

Errors

Every error — the 429 included — has the same shape, so one handler covers them all. details appears on validation errors and names each field that needs fixing.

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Some fields aren't valid.",
    "details": { "expiry": "One of: never, 10m, 1h, 1d, 1w, 1m, burn." }
  }
}
FieldTypeWhat it does
400 BAD_REQUESTThe body isn't a JSON object, or a header is malformed.
401 UNAUTHORIZEDNo key, or it's unknown, revoked, or its account is disabled.
404 NOT_FOUNDNo paste with that id on your account (other people's pastes look the same as missing ones).
409 CONFLICTThat custom link is already taken.
409 IDEMPOTENCY_KEY_REUSEDAn Idempotency-Key was reused with a different body.
422 VALIDATION_FAILEDA field isn't valid — see details.
429 RATE_LIMITEDSlow down — see Retry-After.

The paste object

FieldTypeWhat it does
idstringIts 8-character id.
titlestring | nullThe title, if it has one.
urlstringThe short link — thpaste.com/p/{id}.
custom_urlstring | nullIts custom link, if you gave it one — thpaste.com/s/{slug}.
raw_urlstringPlain-text version.
languagestringSyntax highlighting, e.g. plain or python.
visibilitystringpublic or unlisted.
password_protectedbooleanWhether opening it needs a password.
burn_after_readingbooleanDeleted after it's first opened.
viewsnumberTimes it's been opened.
size_bytesnumberSize of the content.
created_atstringISO 8601 time.
expires_atstring | nullWhen it expires, or null for never.
contentstringThe text itself — included when you fetch, create or edit one paste.

POST /pastes

Create a paste on your account. It shows up in your dashboard like one made on the website.

FieldTypeWhat it does
contentstringRequired. Up to 512 KB.
titlestringOptional. Up to 120 characters (longer is cut).
languagestringOptional, default plain. One of: plain, richtext, javascript, typescript, python, json, html, css, bash, sql, go, rust, java, c, php, yaml, markdown. With richtext, content is HTML — it's rebuilt from a safe list of formatting tags (anything else is dropped).
visibilitystringOptional, default unlisted (link-only). Or public.
expirystringOptional, default never. One of: never, 10m, 1h, 1d, 1w, 1m, burn (burn = deleted after the first view).
passwordstringOptional. Needed to open it.
slugstringOptional custom link: 3–48 lowercase letters, numbers and hyphens → thpaste.com/s/{slug}.

Retrying after a timeout? Send an Idempotency-Key header (any unique string, up to 100 characters). The same key with the same body within 10 minutes returns the first result again — marked Idempotency-Replayed: true — instead of making a second paste.

curl -X POST https://thpaste.com/api/v1/pastes \
  -H "Authorization: Bearer tp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2a9e" \
  -d '{"title": "Setup notes", "content": "Step 1: ...", "language": "plain", "visibility": "public", "slug": "setup-notes"}'

Answers 201 with the new paste in data.

GET /pastes

Your pastes, newest first. Query: page (default 1), per_page (1–100, default 25), q (finds text in titles and content). meta holds page, per_page, total and pages.

curl "https://thpaste.com/api/v1/pastes?page=1&per_page=50" \
  -H "Authorization: Bearer tp_YOUR_KEY"

GET /pastes/{id}

One of your pastes, with its content.

PATCH /pastes/{id}

Change the title, content and/or slug — send only what changes; null clears the title or removes the custom link. The link, settings and view count stay as they are. Any other field is refused with a 422, so a typo never silently does nothing.

curl -X PATCH https://thpaste.com/api/v1/pastes/AbC123xy \
  -H "Authorization: Bearer tp_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title": "Setup notes (v2)"}'

DELETE /pastes/{id}

Deletes it for good — its link stops working straight away.

GET /stats

Who's viewing your pastes — the same numbers as your dashboard's Analytics page. Query: range (24h, 7d, 30d, 90d or all; default 7d) and optionally paste (one paste's id). Returns totals (views, unique visitors), a daily series (hourly for 24h), countries, devices, referrers (null = direct or an app) and, for all pastes, top_pastes.

curl "https://thpaste.com/api/v1/stats?range=30d" \
  -H "Authorization: Bearer tp_YOUR_KEY"

GET /me

The account the key belongs to — id, email, username, profile link and paste count. A quick way to check a key works.

Ready to build?

Make a free account and create your first key in a minute.

Get an API key