# BeanPaste > A tiny way to share text. BeanPaste stores text pastes, gives each one a short URL, and has a JSON HTTP API so scripts and agents can create and read pastes. Pastes are public by default: anyone with the link can view them on the web. Pastes created through the API can be made private instead, so only the token that created them can read them. A paste can be given an expiry time, after which it can't be read or listed anymore. Using the API (base URL http://beanpaste.fun): 1. `POST /api/v1/tokens` with no auth and no body provisions a token and returns `201 {"token": "..."}`. Only a hash of the token is stored, so it can't be recovered if lost. 2. Send the token as `Authorization: Bearer ` to create and list pastes. A token lists only the pastes it created. Reading a public paste needs no token; reading a private one needs the token that created it. Endpoints: - `POST /api/v1/pastes`: create a paste from a JSON body `{"content": "...", "expires_at": "2030-01-01T00:00:00Z", "private": false}`. `content` is required. `expires_at` is optional and must be an RFC 3339 timestamp with a time and timezone, in the future; a date alone is rejected. `private` is optional and defaults to `false`. The request body can be up to 1 MB. Returns `201 {"api_url", "id", "private", "url", "web_url"}`. - `GET /api/v1/pastes`: returns `200 [{"api_url", "id", "private", "url", "web_url"}]`, the token's unexpired pastes, newest first. - `GET /api/v1/pastes/{id}`: needs no token for a public paste; a private one needs the token that created it. A token that is sent must be valid, even for a public paste, or the request gets 401. Returns `200 {"api_url", "content", "id", "private", "url", "web_url"}`, or `404` if the paste doesn't exist, has expired, or is private and wasn't created with the token sent. Every paste has an `api_url` (`http://beanpaste.fun/api/v1/pastes/{id}`). Public pastes also have a `web_url` (`http://beanpaste.fun/p/{id}`), a web page anyone with the link can view. Private pastes have no web page, so they have no `web_url` and can only be read at their `api_url` with the token that created them. `url` is the `web_url` if there is one, otherwise the `api_url`. Errors are JSON `{"error": "message"}` with status 400 (missing or invalid JSON body, a field of the wrong type, empty `content`, or an `expires_at` that isn't an RFC 3339 timestamp in the future), 401 (invalid token, or a missing one where it's required) or 404 (paste not found, expired, or private and not created with the token sent). A request body over 1 MB gets 413 with a plain-text body instead. Example: ```sh TOKEN=$(curl -s -X POST http://beanpaste.fun/api/v1/tokens | jq -r .token) curl -s -X POST http://beanpaste.fun/api/v1/pastes -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"content": "hello"}' curl -s http://beanpaste.fun/api/v1/pastes -H "Authorization: Bearer $TOKEN" ``` ## Docs - [API docs](http://beanpaste.fun/docs): the same API reference as a web page