Developer Platform
Browser client safety: use hosted per-save approval to keep credentials out of your app, or opt into a limited allowance.
Publish to HashBin from your app
Let your users store 256t content on HashBin.org directly from your web app. Users authorize your app via OAuth 2.0, and uploads are billed to their HashBin balance.
Why register your app?
Security
Redirect URI validation prevents authorization codes from being intercepted. Only your registered origins receive tokens.
User trust
The consent screen shows your app name so users know exactly who is requesting access to their balance.
Spending controls
Users can set per-app monthly spending limits. Revocation and rate limiting are tracked per app.
Integration overview
- Register your app below to get a
client_id. That's the only credential your app needs, because it proves who it is with PKCE (why no client secret?). - Redirect users to
/oauth/authorizewith PKCE parameters. - The user signs in (via their existing HashBin account) and approves your app.
- HashBin redirects back to your
redirect_uriwith an authorization code. - Exchange the code at
/oauth/tokenfor an access token (15 minutes) and refresh token (7 days idle, 90 days maximum). - Use the access token to publish content via
POST /api/content. Uploads use the user's default retention period, are billed to their balance, and return a content URL onhttps://256t.us/{cid}.
Example: app served from GitHub Pages
If your app is hosted on GitHub Pages, register your Pages URL as the redirect URI. The simplest setup is a single page that starts sign-in, receives the user back from HashBin, and publishes. A minimal version using the hosted SDK:
<!-- https://your-username.github.io/your-repo/ (registered as the redirect URI) -->
<button id="publish">Publish "Hello, HashBin!"</button>
<script type="module">
import { HashBinClient } from 'https://hashbin.org/sdk/hashbin.js';
const hb = new HashBinClient({
clientId: 'YOUR_CLIENT_ID',
redirectUri: 'https://your-username.github.io/your-repo/',
baseUrl: 'https://hashbin.org' // also the SDK default
});
// Redirect fallback: verify the result and restore your saved app state.
if (location.hash.includes('hashbin_publish')) {
const result = await hb.handlePublishCallback();
console.log('Published:', result.cid);
history.replaceState(null, '', location.pathname);
}
document.getElementById('publish').onclick = async () => {
const result = await hb.publish('Hello, HashBin!', { contentType: 'text/plain' });
console.log('Published:', result.cid);
};
</script>For a complete app that also handles sign-in errors, token renewal and drafts, see Textpad.
See the SDK documentation for the full API reference.
Example app: Textpad
Textpad is a small text editor in one HTML file. It opens text from a #256t= link,
lets the user edit it, and saves it to their HashBin account through OAuth. The walkthrough
explains every part of the code, so it makes a good starting point for your own app.
Read the Textpad walkthrough · Open Textpad
Building a phone app? Textpad is also available for Expo (React Native) and Flutter, with the same features.
GitHub Pages upload utilities
Upload via API key: fastest manual upload flow, supports selecting retention per upload, but requires handling an API key in the page.
Upload via registered app: OAuth app flow with scoped and revocable access, no API key sharing, and uploads billed using the user's default retention settings.
Available scopes
| Scope | Description |
|---|---|
content:write |
Publish content, billed to the user's balance using their default retention period |
content:extend |
Extend how long content is kept, billed to the user's balance |
content:delete |
Delete content the user uploaded |
uploads:read |
List the content the user uploaded |
balance:read |
View the user's current balance (useful for pre-flight checks) |
transactions:read |
Read the user's balance history |
ratelimit:purchase |
Buy download allowances for content, billed to the user's balance |
downloads:spend |
Pay for downloads from the user's balance, within their download caps |
suppliers:read |
List the alternate suppliers the user registered |
suppliers:write |
Register, change and remove alternate suppliers |
Ask only for what your app needs: the user sees each permission, can uncheck any of them, and sets a
monthly spending limit (required for anything that spends), a retention cap and an expiry. Your app can
suggest a cap with the spending_limit (US dollars) and max_retention_months
parameters; the user can only lower them. A token request may pass scope to get a token with
fewer of the granted scopes. Account management (keys, apps, settings, deposits) is never available to apps.
Register an application
About your client ID
Registering gives you a client ID that starts with app_. It's your app's
public name, not a secret, so it can sit in your page source, your phone app, or a public repo.
Send it as client_id to /oauth/authorize and
/oauth/token, or pass it as the clientId option in the
SDK. HashBin uses it to show your app name on the consent
screen, check that the redirect_uri is one you registered, apply the user's
spending limit for your app, and make sure a code is redeemed by the app it was issued to.
Where's the client secret?
Many OAuth providers give you a client secret too. In standard OAuth, a server app sends its secret to the token endpoint to prove it is the real app (RFC 6749 §2.3.1).
Browser and phone apps can't keep a secret, because anyone can read their code. OAuth calls these public clients (RFC 6749 §2.1). Instead of a secret, they use PKCE: before sending the user to HashBin, your app makes up a random code verifier and sends only its SHA-256 hash. When it trades the code for tokens, it sends the verifier itself, and HashBin checks that it matches. Someone who steals the code doesn't have the verifier, so they can't use it.
HashBin uses PKCE for every app, including apps that run on a server, so there is no
secret to keep: registering an app gives you only a public client_id.
Further reading:
- oauth.net: Client Types: confidential and public clients in brief
- oauth.net: PKCE: a short overview
- RFC 8252: OAuth for phone and desktop apps
- Textpad walkthrough: a full app that signs in with only a client ID and PKCE